【问题标题】:How to render a graph as image in node如何在节点中将图形渲染为图像
【发布时间】:2017-11-16 13:03:46
【问题描述】:

我想在服务器上以图像格式呈现堆积条形图。

预期用途是推送到不支持 SVG 的 twitter 等服务。以及可部署到 Heroku 等服务的代码

我已经尝试过 Plotly(他们的节点包已经过时了,而且他们的 API 文档很差)。我还查看了 Google Graph、Chart.js 和 AnyChart,但据我所知,它们不支持渲染图像

【问题讨论】:

    标签: node.js image graph visualization


    【解决方案1】:

    我使用 Nightmare 无头浏览器在 Node.js 下捕获图表、可视化和报告。

    使用 Nightmare,您可以使用 Node.js 下的各种基于浏览器的可视化框架,包括 C3D3,它们都很棒。

    我实际上创建了一个名为 c3-chart-maker 的 npm 模块,它封装了 Nightmare,并允许您通过向其提供一些数据和 C3 图表定义来在 Node.js 下呈现图表。

    这样安装:

    npm install --save c3-chart-maker
    

    像这样使用它:

    const c3ChartMaker = require('c3-chart-maker');
    
    const yourData = ... your data ...
    const chartDefinition = { ... c3 chart definition ... }
    const outputFilePath = "your-chart-output-file.png";
    
    c3ChartMaker(yourData, chartDefinition, outputFilePath)
        .then(() => { 
            console.log('Done');
        })
        .catch(err => {
            console.error(err);
        });
    

    请查看C3 example gallery 以获取图表示例并查看 C3 图表定义的样子。

    您还可以手动使用 Nightmare 来捕获任何网页或基于浏览器的可视化。

    要安装 Nightmare:

    npm install --save nightmare
    

    这是一个可以捕获网页的示例:

    const Nightmare = require('nightmare');
    
    // This is the web page to capture.
    // It can also be a local web server! 
    // Or serve from the file system using file://
    const urlToCapture = "http://my-visualization.com"; 
    const outputFilePath = "your-chart-output-file.png";
    
    const nightmare = new Nightmare(); // Create Nightmare instance.
    nightmare.goto(urlToCapture) // Point the browser at the requested web page.
            .wait("svg") // Wait until the specified HTML element appears on the screen. 
            .screenshot(outputImagePath) // Capture a screenshot to an image file.
            .end() // End the Nightmare session. Any queued operations are completed and the headless browser is terminated.
            .then(() => {
                console.log("Done!");
            })
            .catch(err => {
                console.error(err);
            });
    

    I've written more extensively about this on my blog.

    我还在我的书Data Wrangling with JavaScript 中专门写了一整章。

    【讨论】:

      【解决方案2】:

      您可以通过Vega 完成此操作

      Vega 是一种可视化语法,一种用于创建、保存和共享交互式可视化设计的声明性格式。使用 Vega,您可以以 JSON 格式描述数据可视化,并使用 HTML5 Canvas 或 SVG 生成交互式视图。

      例如,使用stacked bar chart example spec,您可以使用以下代码将图表渲染为PNG文件:

      // START vega-demo.js
      var vega = require('vega')
      var fs = require('fs')
      
      var stackedBarChartSpec = require('./stacked-bar-chart.spec.json');
      
      // create a new view instance for a given Vega JSON spec
      var view = new vega
        .View(vega.parse(stackedBarChartSpec))
        .renderer('none')
        .initialize();
      
      // generate static PNG file from chart
      view
        .toCanvas()
        .then(function (canvas) {
          // process node-canvas instance for example, generate a PNG stream to write var
          // stream = canvas.createPNGStream();
          console.log('Writing PNG to file...')
          fs.writeFile('stackedBarChart.png', canvas.toBuffer())
        })
        .catch(function (err) {
          console.log("Error writing PNG to file:")
          console.error(err)
        });
      // END vega-demo.js
      
      // START stacked-bar-chart.spec.json 
      {
        "$schema": "https://vega.github.io/schema/vega/v3.0.json",
        "width": 500,
        "height": 200,
        "padding": 5,
      
        "data": [
          {
            "name": "table",
            "values": [
              {"x": 0, "y": 28, "c":0}, {"x": 0, "y": 55, "c":1},
              {"x": 1, "y": 43, "c":0}, {"x": 1, "y": 91, "c":1},
              {"x": 2, "y": 81, "c":0}, {"x": 2, "y": 53, "c":1},
              {"x": 3, "y": 19, "c":0}, {"x": 3, "y": 87, "c":1},
              {"x": 4, "y": 52, "c":0}, {"x": 4, "y": 48, "c":1},
              {"x": 5, "y": 24, "c":0}, {"x": 5, "y": 49, "c":1},
              {"x": 6, "y": 87, "c":0}, {"x": 6, "y": 66, "c":1},
              {"x": 7, "y": 17, "c":0}, {"x": 7, "y": 27, "c":1},
              {"x": 8, "y": 68, "c":0}, {"x": 8, "y": 16, "c":1},
              {"x": 9, "y": 49, "c":0}, {"x": 9, "y": 15, "c":1}
            ],
            "transform": [
              {
                "type": "stack",
                "groupby": ["x"],
                "sort": {"field": "c"},
                "field": "y"
              }
            ]
          }
        ],
      
        "scales": [
          {
            "name": "x",
            "type": "band",
            "range": "width",
            "domain": {"data": "table", "field": "x"}
          },
          {
            "name": "y",
            "type": "linear",
            "range": "height",
            "nice": true, "zero": true,
            "domain": {"data": "table", "field": "y1"}
          },
          {
            "name": "color",
            "type": "ordinal",
            "range": "category",
            "domain": {"data": "table", "field": "c"}
          }
        ],
      
        "axes": [
          {"orient": "bottom", "scale": "x", "zindex": 1},
          {"orient": "left", "scale": "y", "zindex": 1}
        ],
      
        "marks": [
          {
            "type": "rect",
            "from": {"data": "table"},
            "encode": {
              "enter": {
                "x": {"scale": "x", "field": "x"},
                "width": {"scale": "x", "band": 1, "offset": -1},
                "y": {"scale": "y", "field": "y0"},
                "y2": {"scale": "y", "field": "y1"},
                "fill": {"scale": "color", "field": "c"}
              },
              "update": {
                "fillOpacity": {"value": 1}
              },
              "hover": {
                "fillOpacity": {"value": 0.5}
              }
            }
          }
        ]
      }
      // END stacked-bar-chart.spec.json
      

      将输出PNG文件:

      【讨论】:

      • Vega 是我最喜欢的它,Plotly 和我发现用来包装 graphjs 的几个不同的库。最初我在 Vega 上苦苦挣扎,但通过在 Codepen 上使用 Playground,我能够弄清楚我哪里出错了。现在它绝对是我的最爱:D
      • 另外,github.com/vega/vega-lite 在 vega 之上有一个更高级别的 api。如果您首先想要简单(而不是灵活性),那么值得检查
      猜你喜欢
      • 2017-10-06
      • 2020-01-03
      • 2015-02-22
      • 1970-01-01
      • 2021-05-26
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多