3

How to create a pie chart using NodeJs with chartjs? want to create different types of charts using chartjs but when I tried to run the code shows "cannot set the property of width"

TypeError: Cannot set property 'width' of undefined
    at ni.resize (node_modules\chart.js\dist\Chart.min.js:7:93312)
    at ni.initialize (node_modules\chart.js\dist\Chart.min.js:7:92818)
    at ni.construct (node_modules\chart.js\dist\Chart.min.js:7:92559)
    at new ni (node_modules\chart.js\dist\Chart.min.js:7:91964)
    at Object.<anonymous> (chartjs\chart.js:7:15)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)

I tried to run this code to produce a pie chart image but found this error.

let Canvas = require("canvas"),
  canvas = Canvas.createCanvas(400, 400),
  ctx = canvas.getContext("2d"),
  Chart = require('chart.js'),
  fs = require("fs");

var myChart = new Chart(ctx, {
  type: "pie",
  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
          }
        }
      ]
    }
  }
});

canvas.toBuffer(function(err, buf) {
  if (err) throw err;
  fs.writeFileSync("chart.png", buf);
});

Should be an image in the current folder

Yaser Darzi
  • 1,480
  • 12
  • 24
Mohit Bansal
  • 31
  • 1
  • 2
  • Possible duplicate of [How to create charts using NodeJS?](https://stackoverflow.com/questions/15477008/how-to-create-charts-using-nodejs) – Sushant Paudel Oct 03 '19 at 10:11

3 Answers3

2

I suggest using ChartJS for Node: https://www.npmjs.com/package/chartjs-node

It draws a chart which you can then save to the file system and insert accordingly.

Here's a snippet of code as an example:

import * as ChartjsNode from 'chartjs-node'; // Import the library

const chartNode = new ChartjsNode(600, 600); // Create an instance with dimensions

const barGraphOptions = {
  type: 'bar',
  data: []
};

// Draw the chart and write the file to the file system
await new Promise(resolve => {
  chartNode
    .drawChart(barGraphOptions)
    .then(() => {
      chartNode.getImageBuffer('image/png');
    })
    .then(() => {
      chartNode.writeImageToFile('image/png', 'some_file.png').then(() => {
        resolve();
      });
    })
    .catch(e => {
      console.log('Caught', e);
    });
});

Taylor LaMar
  • 75
  • 2
  • 10
  • [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). Also, this is confusing because there's nothing returned by the `then` blocks, so they aren't awaiting anything. – ggorlen Mar 02 '23 at 00:49
1

ChartJS is an HTML5 based file which is used in front-end development only. For more information visit this site.

You can refer to this answer if you want to use nodejs to create Charts.

P.S. This question is duplicate to this

  • It's not really a duplicate--the other question asks how to draw charts in Node, while this one asks how to use chart.js specifically. – ggorlen Mar 02 '23 at 00:51
  • @ggorlen The answer is already in [this](https://stackoverflow.com/a/71750361/7514132). The question is not exactly the same but, the implementation is same. – Sushant Paudel Mar 30 '23 at 02:25
0

I had the same issue as OP. I couldn't figure out a way to do it using the standard approach of combining Node Canvas and Chart.JS, but I found using ChartjsNodeCanvas works.

import { CanvasRenderService } from 'chartjs-node-canvas';

canvasRenderService: CanvasRenderService;

async createGraph(data: any) {

    const configuration = {
        type: 'bar',
        data: {
            labels: // Your labels,
            datasets: [
                data
            ]
        },
        options: {
           // Your options
        }
    };

    const canvasRenderService = new CanvasRenderService(300, 500);

    return await canvasRenderService.renderToDataURL(configuration);
    // or return canvasRenderService.renderToBuffer(configuration);
    // or return canvasRenderService.renderToStream(configuration);
}


await this.createGraph(data);

Note, ChartjsNodeCanvas requires ChartJS as a dependency.

timray
  • 588
  • 1
  • 9
  • 24