'Creating chart.js chart directly to PNG in Node js?

Is there any way I could use Chart.js to create a bar chart directly to a PNG file? I don't want to display the chart on my webpage, I want to send it directly to Facebook Messenger as an image.

I have used the following code to create a bar chart on my webpage:

var ctx = document.getElementById("myChart").msGetInputContext("2d");
                var myChart = new Chart(ctx, {
                    type: 'bar',
                    data: {
                        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
                        datasets: [{
                            label: '# of Votes',
                            data: [12, 19, 3, 5, 2, 3],
                            backgroundColor: [
                                'rgba(255, 99, 132, 0.2)',
                                'rgba(54, 162, 235, 0.2)',
                                'rgba(255, 206, 86, 0.2)',
                                'rgba(75, 192, 192, 0.2)',
                                'rgba(153, 102, 255, 0.2)',
                                'rgba(255, 159, 64, 0.2)'
                            ],
                            borderColor: [
                                'rgba(255,99,132,1)',
                                'rgba(54, 162, 235, 1)',
                                'rgba(255, 206, 86, 1)',
                                'rgba(75, 192, 192, 1)',
                                'rgba(153, 102, 255, 1)',
                                'rgba(255, 159, 64, 1)'
                            ],
                            borderWidth: 1
                        }]
                    },
                    options: {
                        scales: {
                            yAxes: [{
                                ticks: {
                                    beginAtZero:true
                                }
                            }]
                        }
                    }
                });

But in this particular case, my users would be interacting with my Node js app through Facebook messenger rather than a webpage. I would need a way to create a chart without needing the html canvas element and I can convert the chart to image using .toBase64Image().

Thanks in advance for any help!



Solution 1:[1]

Chart.js is built on the HTML5 canvas element.

To use it on node.js you need to mimic this element in node.

There is a package that try to handle all the needed libraries for this purpose, you can find it here chartjs-node

Solution 2:[2]

I had this problem and wound up building a web service that renders Chart.js charts as PNG images. I open sourced my work on this

The service is called QuickChart. For example, if your chart config is:

{
  type: 'bar',
  data: {
    labels: ['January', 'February', 'March', 'April', 'May'],
    datasets: [{
      label: 'Dogs',
      data: [ 50, 60, 70, 180, 190 ]
    }, {
      label: 'Cats',
      data: [ 100, 200, 300, 400, 500 ]
    }]
  }
}

You can embed the Chart.js config in the URL like so:

https://quickchart.io/chart?c={ type: 'bar', data: { labels: ['January', 'February', 'March', 'April', 'May'], datasets: [{ label: 'Dogs', data: [ 50, 60, 70, 180, 190 ] }, { label: 'Cats', data: [ 100, 200, 300, 400, 500 ] }] }}

...and it renders your chart as an image!

Note that for more complex charts, you'd want to URL encode the chart options.

There's an interactive editor on the QuickChart website which you can use to generate a URL for a given chart config. You may also view/fork the source code here (it's built on top of node-canvas and chartjs-node-canvas).

Solution 3:[3]

const express = require("express")
const { CanvasRenderService } = require('chartjs-node-canvas');
let app = express()

var configuration = {
    type: 'bar',
    data: {
        labels: ["Africa", "Asia", "Europe", "Latin America", "North America"],
        datasets: [{
                label: 'Scored',
                data: [2478,5267,734,784,433],
                        backgroundColor: [
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255,99,132,1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
    }]},
    options: {
        scales: {
            yAxes: [{
                ticks: {
                precision:0,
                beginAtZero: true
                }
            }]
        }
    }
}


const mkChart = async (params) => {
    const canvasRenderService = new CanvasRenderService(400, 400)
    return await canvasRenderService.renderToBuffer(configuration);
}

app.get('/chart', async function (req, res) {
    var image = await mkChart(req.query)
    res.type("image/png")
    res.send(image) 
})

app.listen(3061, () => {

})

Run the node script, and goto "http://localhost:3061/chart" which responses the chart png

Reference : https://www.npmjs.com/package/chartjs-node-canvas

Solution 4:[4]

You can create image from Canvas using toDataURL, so after charts.js renders the graph into the canvas (myChart)

var canvas = document.getElementById('myChart');
var dataURL = canvas.toDataURL();

dataURL will not contain the base64 string of the image. You can write it to file and use the file or use the string any other way.

Check that reference for converting the string to image file if you will. https://gist.github.com/madhums/e749dca107e26d72b64d

Hope this is what you mean you needed to do.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ty.
Solution 3
Solution 4 user6437700