server-side generate d3 svg

929 阅读1分钟

背景:最近有需求要通过 nodeJs 在命令行生成 d3.js 生成的svg,百度了一些 headless ,因为我们前端的页面并没有做 SSR ,即使 headless 去截图可能会存在请求数据异步延迟,图不准确的问题,所以决定,用 nodeJs + jsdom + d3.js 虚拟生成 dom 结构,最后 output svg 标签的内容。

解决办法:

1.安装依赖 

d3@4.7.1
jsdom@15.0.0

2. js 代码 

const d3 = require('d3');
const jsdom = require('jsdom');
const { JSDOM } = jsdom;

const document = new JSDOM().window.document;
const size = {
  width: 900,
  height: 1200
};
const svg = d3.select(document.body)
              .append('svg')
              .attr("xmlns",'http://www.w3.org/2000/svg')
              .attr('width', size.width)
              .attr('height', size.height)
              .style('background-color', "#363b44");

// 可以按照正常 js 的写法 append 一些元素,例如 g, circle, rect ...

console.log(document.body.innerHTML)

3.运行 command line

node xxx.js > xxx.svg

就可以看到当前目录下多了一个 svg 文件!

ps:如果不想手动在命令行输入导出的文件名称,可以直接利用 fs 模块,写入文件

fs.writeFile('./img/xxx.svg', document.body.innerHTML, (err) => {
    if (err) {
      console.log(err);
    }
  })

BTW, 在这里说一下遇到的一个坑,力导向图计算力的时候,会发现和平时页面里的 script 中打印的 graph.nodes 值不一样,研究了两天,最后发现加了一个 setTimeout 得以解决,看来是 nodeJs 默认同步处理,如果遇到 d3 和平时不太一样的效果,不妨加个延时器试试~~


参考链接

力导向图详解