关于d3.js:如何在Node.js中正确使用D3?

How to use D3 in Node.js properly?

我一直在尝试在Node.js中调用D3。 我首先尝试使用脚本标签从D3的网站导入d3.v2.js,但随后阅读了该线程:

我想从Cakefile运行d3

D3的作者建议一个人应该" npm install d3" ...我做到了,我可以在节点控制台中成功调用它:

1
2
3
4
5
dpc@ananda:$ node
> var d3 = require("d3");
undefined
> d3.version;
'2.8.1'

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

1
2
3
4
5
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

我意识到,在其他地方,D3的作者明确规定了应该使用画布:

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

如:

1
var Canvas = require("canvas");

但是即使这样,(即使在app.js的require语句中特别要求使用index.js而不是d3.v2.js),我也无法在Jade模板中进行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
- 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

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

1
2
3
4
5
6
7
{
 "name":"my-awesome-package",
 "version":"0.0.1",
 "dependencies": {
   "d3":"3"
  }
}

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

1
var d3 = require("d3");

就是这样。

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


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

1
import * as d3 from 'd3';

对于任何经验丰富的babel / ES6用户而言,这也许都是显而易见的,我知道这是一个古老的问题,但是我来到这里试图解决这个问题。希望这对某人有帮助。

importrequire的更多信息在此处找到。


尝试基于JS-Dom构建的d3-node。有D3的助手。


您需要使用yarn或npm安装jsdom。
Node.js默认情况下不支持dom,因此需要使用jsdom创建dom元素。使用d3进行除提取操作以外的所有其他操作。即d3.xml,d3.tsv

1
2
3
4
5
6
7
8
9
10
11
12
13
import jsdom from 'jsdom';
import * as d3 from 'd3';
const { JSDOM } = jsdom;
JSDOM.fromURL(
    'your resource url',
  ).then((dom) => {
    const doc = dom.window.document;
    const states = d3
      .select(doc)
      .select('path')
      .attr(':fme:ID');
    console.log(states);
  });

从文件创建dom

1
2
3
4
5
JSDOM.fromURL(
    'your resource url',
  ).then((dom) => {
    const doc = dom.window.document;
}

html字符串中的dom

1
2
3
4
5
6
7
8
const dom = new JSDOM(
  `<p>
Hello
    <img src="foo.jpg">
 
</p>`,
  { includeNodeLocations: true }
);