如何在Node.js中正确使用D3?

pla*_*and 39 node.js d3.js

我一直在尝试在Node.js中调用D3.我首先尝试使用脚本标记从D3的网站导入d3.v2.js,但随后阅读此主题:

我想从Cakefile运行d3

D3的作者建议应该'npm install d3'......我这样做了,我可以在节点控制台中成功调用它:

dpc@ananda:$ node
> var d3 = require("d3");
undefined
> d3.version;
'2.8.1' 
Run Code Online (Sandbox Code Playgroud)

但是,当尝试使用'node app.js'从app.js调用它时,我得到:

node.js:201
    throw e; // process.nextTick error, or 'error' event on first tick
          ^
TypeError: Cannot read property 'BSON' of undefined
at     /Users/dpc/Dropbox/sync/Business/MindfulSound/Development/nad.am/nadam/node_modules/mongoose/node_modules/mongodb/lib/mongodb/index.js:45:44
Run Code Online (Sandbox Code Playgroud)

我意识到在其他地方,D3的作者已明确指出应该需要画布:

https://github.com/mbostock/d3/blob/master/examples/node-canvas/us-counties.js

如:

var Canvas = require("canvas");
Run Code Online (Sandbox Code Playgroud)

但即便如此,(即使在app.js中的require语句中特别要求index.js而不是d3.v2.js),我也无法在Jade模板中使用以下内容:

- script('/javascripts/d3.v2.js')
h1 Dashboard
  section.css-table
    section.two-column
      section.cell
        hr.grey
        h2 Statistics
        #mainGraph
            script(type="text/javascript") 
              var Canvas = require("canvas");
              var w = 400,
                  h = 400,
                  r = Math.min(w, h) / 2,
                  data = d3.range(10).map(Math.random).sort(d3.descending),
                  color = d3.scale.category20(),
                  arc = d3.svg.arc().outerRadius(r),
                  donut = d3.layout.pie();
              var vis = d3.select("body").append("svg")
                  .data([data])
                  .attr("width", w)
                  .attr("height", h);
              var arcs = vis.selectAll("g.arc")
                  .data(donut)
                  .enter().append("g")
                  .attr("class", "arc")
                  .attr("transform", "translate(" + r + "," + r + ")");
              var paths = arcs.append("path")
                  .attr("fill", function(d, i) { return color(i); });
              paths.transition()
                  .ease("bounce")
                  .duration(2000)
                  .attrTween("d", tweenPie);
              paths.transition()
                  .ease("elastic")
                  .delay(function(d, i) { return 2000 + i * 50; })
                  .duration(750)
                  .attrTween("d", tweenDonut);

              function tweenPie(b) {
                b.innerRadius = 0;
                var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
                return function(t) {
                  return arc(i(t));
                };
              }

              function tweenDonut(b) {
                b.innerRadius = r * .6;
                var i = d3.interpolate({innerRadius: 0}, b);
                return function(t) {
                  return arc(i(t));
                };

      section.cell
        hr.grey
        h2 Achievements
Run Code Online (Sandbox Code Playgroud)

mbo*_*ock 67

在Node中使用D3的正确方法是使用NPM安装d3然后再安装require它.您可以使用npm install d3或使用package.json文件,然后npm install:

{
  "name": "my-awesome-package",
  "version": "0.0.1",
  "dependencies": {
    "d3": "3"
  }
}
Run Code Online (Sandbox Code Playgroud)

在node_modules目录中有d3之后,通过require加载它:

var d3 = require("d3");
Run Code Online (Sandbox Code Playgroud)

就是这样.

关于您的其他问题:Canvas不需要使用D3.您链接的节点画布示例需要画布,因为它渲染到画布.TypeError(无法读取未定义的属性'BSON')似乎与您使用mongoose/monogdb有关,而不是D3.

  • 现在我将node.js中的d3作为模块,如何用它选择元素?我想在服务器上创建一个svg并将其返回给客户端.可以d3.select()采用像'<div> </ div>'这样的html片段吗? (2认同)
  • 这是一个容易混淆的主题,所以让我试着帮助澄清一下 - "npm install d3"加载d3节点模块,它允许你在服务器的内存中构建数据驱动文档,这样它们就可以像预先构建的那样传递给浏览器(渲染)html/svg/etc.将其与传统的d3用法相比较,传统的d3用法是在html中包含库,并在浏览器中渲染dom中的元素.在客户端和服务器端的渲染方面存在细微但显着的差异.另见:http://mango-is.com/blog/engineering/pre-render-d3-js-charts-at-server-side.html (2认同)

Tho*_*ger 5

与ES6一起使用import而不是require:

import * as d3 from 'd3';
Run Code Online (Sandbox Code Playgroud)

对于任何有经验的babel/ES6用户来说,这可能是显而易见的,我知道这是一个老问题,但我来到这里试图解决这个问题.希望这对某人有帮助.

更多关于importvs. require这里找到.