chartjs-plugin-datalabels icon indicating copy to clipboard operation
chartjs-plugin-datalabels copied to clipboard

Bug: NodeJS Canvas Render Aligns Labels Wrongly

Open USMortality opened this issue 5 months ago • 0 comments

With this example: https://codepen.io/usmortality/pen/KKjbzrj the datalabels render correctly. Screenshot 2024-09-05 at 6 23 50 PM

And the same rendered via simple nodejs/canvas server side renderer do not: localhost

import express from 'express'
import path from 'path'
import { createCanvas } from 'canvas'
import { Chart, registerables } from 'chart.js'
import ChartDataLabels from 'chartjs-plugin-datalabels'

import { fileURLToPath } from 'url'

global.window = Object.assign(globalThis, {})

Chart.register(...registerables, ChartDataLabels)

const app = express()
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
app.use(
  express.static(path.resolve(__dirname, '../../client/dist/'), {
    index: false,
  })
)

app.get('/', async (_, res) => {
  const canvas = createCanvas(600, 600)
  const ctx = canvas.getContext('2d')

  Chart.register(ChartDataLabels)
  const data = {
    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
    datasets: [
      {
        type: 'bar',
        label: '1st Cycle',
        data: [65, 59, 80, 81, 56, 55, 40],
        datalabels: {
          align: 'end',
          anchor: 'end',
        },
        borderColor: ['rgb(54, 162, 235)'],
        backgroundColor: ['rgba(54, 162, 235, 0.2)'],
        borderWidth: 1,
      },
      {
        type: 'bar',
        label: '2nd Cycle',
        data: [45, -29, 40, 51, -36, 75, -60],
        borderColor: ['rgb(255, 159, 64)'],
        backgroundColor: ['rgba(255, 159, 64, 0.2)'],
        borderWidth: 1,
      },
      {
        type: 'line',
        label: 'Target',
        data: [100, 100, 100, 100, 100, 100, 100],
        datalabels: {
          align: 'start',
          anchor: 'start',
        },
        borderColor: 'rgb(75, 192, 192)',
      },
    ],
  }

  const config = {
    type: 'scatter',
    data: data,
    options: {
      scales: {
        y: {
          beginAtZero: true,
          title: {
            display: true,
            text: 'Percentage',
          },
        },
      },
      plugins: {
        title: {
          display: true,
          text: 'Locality Coverage For IRS Jan-Jun, Year xxxx (Target 100%)',
        },
        legend: {
          position: 'bottom',
        },
        datalabels: {
          display: true,
          color: 'black',
          anchor: 'end',
          align: 'top',
          formatter: (value, context) => {
            return value + '%'
          },
        },
      },
    },
  }

  new Chart(ctx, config)
  const image = canvas.toBuffer()
  res.set('Content-Type', 'image/png')
  res.send(image)
})

const port = process.env.PORT ?? 5000
app.listen(port, () =>
  console.log('Server is running on http://localhost:' + port)
)

Any ideas why?

USMortality avatar Sep 06 '24 01:09 USMortality