【问题标题】:D3js: how to generate standalone SVG files? (Nodejs)D3js:如何生成独立的 SVG 文件? (节点)
【发布时间】:2013-09-29 17:15:09
【问题描述】:

给定一个 D3js 代码such as

var square= 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");
    }
square();
svg { border: 1px solid grey;} /* just to visualized the svg file's area */
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<body></body>

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

【问题讨论】:

标签: node.js svg d3.js


【解决方案1】:

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


D3 根本不关心实际生成 SVG 的内容。仅创建 SVG 的主要问题是您无法使用 Javascript,这当然意味着您无法使用 D3。除了这个基本的禁忌之外,没有什么能阻止你:)

概念证明:受其他答案的启发,这里有一些使用 jsdom 的概念证明代码。

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.在终端运行

$node jsdom.node.js > test.svg

stdout 输出是 SVG,然后将其注入到 test.svg 文件中。任务完成。

正如 Gilly 在 cmets 中指出的那样,您可能需要 jsdom 版本 3 才能使其工作。

【讨论】:

  • 你好拉尔斯。我是 JS 的初学者,我不明白。你在考虑 nodejs 解决方案吗?将我的 D3js 代码放在纯 .js 中,在节点中运行,然后掌握输出?
  • 嗯,大多数示例都生成纯 SVG,它们只是嵌入在 HTML 中。没错,使用类似 node.js 的东西可以在没有 HTML 的情况下运行 JS。我的观点是,你生成什么并不重要。您有具体的应用吗?
  • This。我想使用 D3js 输出成百上千个这样的文件。如果我直接输出SVG会更好。
  • 那么生成这些 SVG 有什么问题?
  • 我想要 .svg 文件以编程方式。当我们希望生成数百个(如果不是数千个)文件时,生成一个我可以单击以下载文件的 html 不是一个合适的工作流程。最高估计是要生成 20,000 svg。
【解决方案2】:

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

#!/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);

Link to snippet on bl.ocks.org

【讨论】:

    【解决方案3】:

    我最近想这样做并问了一个问题here。我被指向phantomJS。使用 PhantomJS,我创建了一个 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(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
            })
            .text(function(d) { return d.text; });
      }
    </script>
    </body></html>
    

    然后我运行

    phantomjs svggen.js > svgFile.svg
    

    生成的 svgFile.svg 是一个独立的 SVG 文件。对于 d3cloud,请查看 this

    【讨论】:

      【解决方案4】:

      node.js 是要走的路。您可以直接使用 npm 安装 d3。 (它还会添加 jsdom 作为依赖项以提供“假”DOM。)在 d3 代码生成 SVG 后,只需获取其内容并写入文件即可。

      【讨论】:

      • 在 html &lt;div&gt; 中插入图形,然后使用 $('whatever').html() 获取其内容。使用普通的旧 nodejs 文件系统 (fs) 将内容写入文件。 (如果您希望有人真正为您编写代码,请给我发私信。我收费 90 美元/小时。)
      • 我设计并提出了这个项目,它还没有资金。但感谢您的通知。
      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-30
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多