D3js:如何生成独立的SVG文件? (的NodeJS)

给定一个D3js代码 , 如 :

function () { var svg = window.d3.select("body") .append("svg") .attr("width", 100) .attr("height", 100); svg.append("rect") .attr("x", 10) .attr("y", 10) .attr("width", 80) .attr("height", 80) .style("fill", "orange"); } 

如何使用我的D3js代码和NodeJS生成正确的独立* .svg文件?

Github存储库svgcreator.node.js试试。


D3根本不关心实际生成SVG的内容。 创build只有SVG的主要问题是,你不能有Javascript,这当然意味着你不能使用D3。 除了这个基本的不,没有任何东西阻止你:)

概念validation:受其他答案的启发,下面是一些使用jsdom的概念validation代码。

1.安装NodeJS( 1 )。

 curl http://npmjs.org/install.sh | sh #this should work (not tested) 

2.使用Node Packages Manager( 2 )安装jsdom:

 $npm install jsdom 

3.将你的D3js代码包装在一些jsdom代码中,粘贴到jsdom.node.js文件中

 var jsdom = require('jsdom'); jsdom.env( "<html><body></body></html>", [ 'http://d3js.org/d3.v3.min.js' ], function (err, window) { var svg = window.d3.select("body") .append("svg") .attr("width", 100).attr("height", 100); svg.append("rect") .attr("x", 10) .attr("y", 10) .attr("width", 80) .attr("height", 80) .style("fill", "orange"); // PRINT OUT: console.log(window.d3.select("body").html()); // fs.writeFileSync('out.svg', window.d3.select("body").html()); // or this } ); 

4.在terminal运行

 $node jsdom.node.js > test.svg 

标准输出是SVG,然后被注入test.svg文件。 任务完成。

正如Gilly在评论中指出的那样,你可能需要使用jsdom的第3版才能工作。

node.js是要走的路。 你可以用npm直接安装d3。 (它也会添加jsdom作为依赖来提供一个“假”的DOM)。在d3代码生成SVG之后,只需抓住它的内容并写入一个文件即可。

我最近想这样做,并在这里问了一个问题。 我被指向幻影JS 。 使用PhantomJS,我创build了一个JS –

svggen.js:

 var page = require('webpage').create(), url = 'http://www.example.com/wordcloud.html'; page.open(url, function (status) { if (status !== 'success') { console.log('Unable to access network'); } else { var svgData = page.evaluate(function(s){ var serializer = new XMLSerializer(); var element = document.getElementById("svg1"); return serializer.serializeToString(element); }); console.log("<?xml version=\"1.0\"?>"+svgData); } phantom.exit(); }); 

wordcloud.html:

 <!DOCTYPE html> <meta charset="utf-8"> <body> <script src="d3.min.js"></script> <script src="d3.layout.cloud.js"></script> <script> var fill = d3.scale.category20(); d3.layout.cloud().size([500, 800]) .words([ "Hello", "world", "normally", "you", "want", "more", "words", "than", "this"].map(function(d) { return {text: d, size: 10 + Math.random() * 90}; })) .padding(5) .rotate(function() { return ~~(Math.random() * 2) * 90; }) .font("Impact") .fontSize(function(d) { return d.size; }) .on("end", draw) .start(); function draw(words) { d3.select("body").append("svg") .attr("width", 500) .attr("height", 800) .attr("id","svg1") .attr("xmlns","http://www.w3.org/2000/svg") .attr("xmlns:xlink","http://www.w3.org/1999/xlink") .append("g") .attr("transform", "translate(150,150)") .selectAll("text") .data(words) .enter().append("text") .style("font-size", function(d) { return d.size + "px"; }) .style("font-family", "Impact") .style("fill", function(d, i) { return fill(i); }) .attr("text-anchor", "middle") .attr("transform", function(d) { return "translate(" + [dx, dy] + ")rotate(" + d.rotate + ")"; }) .text(function(d) { return d.text; }); } </script> </body></html> 

然后我跑

 phantomjs svggen.js > svgFile.svg 

生成的svgFile.svg是一个独立的SVG文件。 对于d3cloud检查这一点 。

这是一个非常短的节点脚本,它将输出一个svg到由d3.js生成的stdout。

 #!/usr/bin/env node var d3 = require("d3"), jsdom = require("jsdom").jsdom; var body = d3.select(jsdom().documentElement).select("body"); var svg = body.append("svg"); process.stdout.write(body.node().innerHTML); 

链接到bl.ocks.org上的片段

如果你不想使用node.js,那么使用phantomJs,在这里你可以find一个演示https://github.com/subramanya2107/d3js-phantomjs-demo.git