[Chartjs]-Render chartjs and export image to data not in the DOM

2👍

its not possible to render without attaching canvas to dom, but you can hide it and it will work as expected.


const chartEl = document.createElement("canvas");
const ctx = chartEl.getContext("2d");
chartEl.setAttribute("width", "400");
chartEl.setAttribute("height", "400");
chartEl.style.display = "none";

document.body.append(chartEl);
let chart = new Chart(ctx, {
  type: "bar",
  data: {
    datasets: [
      {
        barPercentage: 0.5,
        barThickness: 6,
        maxBarThickness: 8,
        minBarLength: 2,
        data: [10, 20, 30, 40, 50, 60, 70]
      }
    ]
  },
  options: {
    scales: {}
  }
});

chart.render();
console.log(chart.toBase64Image());
chartEl.remove();

1👍

The only way to render a chart without you specifically adding it to the dom is by making use of the offscreen-canvas as explained here in the documentation of chart.js:
https://www.chartjs.org/docs/3.7.1/general/performance.html#parallel-rendering-with-web-workers-chromium-only

Downside is that the offscreen canvas API is only available in chromium based browsers.

Other approach you can take is by adding the canvas to the dom, let chart.js render to it, get the base64 representation and then remove the canvas directly after that like so:

let ctx = document.createElement("canvas")
document.documentElement.appendChild(ctx)
ctx.setAttribute("width", "400")
ctx.setAttribute("height", "400")
let chart = new Chart(ctx, {
  type: "bar",
  data: {
    labels: ['a', 'b', 'c', 'd', 'e', 'f', ' g'],
    datasets: [{
      barPercentage: 0.5,
      barThickness: 6,
      maxBarThickness: 8,
      minBarLength: 2,
      data: [10, 20, 30, 40, 50, 60, 70]
    }]
  },
  options: {
    scales: {}
  }
})

const base64 = chart.toBase64Image();

ctx.remove();

console.log(base64)
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.js"></script>
</body>

Leave a comment