繁体   English   中英

如何在节点中将图形渲染为图像

[英]How to render a graph as image in node

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

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

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

您可以使用Vega完成此操作

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

例如,使用堆积条形图示例规范,您可以使用以下代码将图表渲染为 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 文件: 堆积条形图示例

我使用 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 示例库以获取图表示例并查看 C3 图表定义的外观。

您还可以手动使用 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);
        });

我已经在我的博客上更广泛地写过这方面的文章

我还在我的书Data Wrangling with JavaScript 中专门用了一整章来讨论这个问题。

简单的 Headless NodeJS(不是本地主机或基于网络的)

出于我的目的,我只想 plot 图表而不启动本地主机服务器或任何东西。 所以我使用chartjs-node-canvaschart.js安装:

npm i chartjs-node-canvas chart.js

在这里我将它写入一个文件以显示它有效但我个人只需要 Base64 字符串上传到某个地方

// Install libs with: npm i chartjs-node-canvas chart.js
// Docs https://www.npmjs.com/package/chartjs-node-canvas
// Config documentation https://www.chartjs.org/docs/latest/axes/
const fs = require('fs');
const { ChartJSNodeCanvas } = require('chartjs-node-canvas');

const width = 400; //px
const height = 400; //px
const backgroundColour = 'white'; // Uses https://www.w3schools.com/tags/canvas_fillstyle.asp
const chartJSNodeCanvas = new ChartJSNodeCanvas({ width, height, backgroundColour });

const configuration = {
    type: 'line',   // for line chart
    data: {
        labels: [2018, 2019, 2020, 2021],
        datasets: [{
            label: "Sample 1",
            data: [10, 15, -20, 15],
            fill: false,
            borderColor: ['rgb(51, 204, 204)'],
            borderWidth: 1,
            xAxisID: 'xAxis1' //define top or bottom axis ,modifies on scale
        },
        {
            label: "Sample 2",
            data: [10, 30, 20, 10],
            fill: false,
            borderColor: ['rgb(255, 102, 255)'],
            borderWidth: 1,
            xAxisID: 'xAxis1'
        },
        ],

    },
    options: {
        scales: {
            y: {
                suggestedMin: 0,
            }
        }
    }
}

async function run() {
    const dataUrl = await chartJSNodeCanvas.renderToDataURL(configuration);
    const base64Image = dataUrl

    var base64Data = base64Image.replace(/^data:image\/png;base64,/, "");


    fs.writeFile("out.png", base64Data, 'base64', function (err) {
        if (err) {
            console.log(err);
        }
    });
    return dataUrl
}
run()

这是文档https://www.npmjs.com/package/chartjs-node-canvas ,配置文档在这里https://www.chartjs.org/docs/latest/axes/

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM