Chartjs-Chart.plugins.register beforeDraw does not work when using ChartsJS 3.x

1👍

Plugins need an ID to function as stated in the error message so chart.js knows where to get the options from for example so your plugin should look like this:

Chart.register({
  id: 'customPluginName',
  beforeDraw: (chart, args, opts) => {
    // Actual plugin code
  }
})

-1👍

In 2022 we have ChartJS version 4.0.1

The way we add plugins is this way. Also, they can have a particular configuration using plugins: { ‘customLabels’: {} }` we can add some parameters and process them in the hook.

const datasets = [{
  label: 'Dataset 1',
  data: [
    50.09173525,
    9.40843621,
    25.41237997,
    10.44924554,
    84.27211934
  ],
  backgroundColor: [
    'rgb(255, 99, 132)',
    'rgb(255, 159, 64)',
    'rgb(255, 205, 86)',
    'rgb(75, 192, 192)',
    'rgb(54, 162, 235)',
    'rgb(153, 102, 255)',
    'rgb(201, 203, 207)'
  ]
}]

const data = {
  labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
  datasets,
}


const plugin = {
  id: 'customLabels',
  defaults: {
    labels: []
  },
  beforeDraw: (chart, args, options) => {
    if (chart.config.type !== 'doughnut') return

    const {width, height, ctx} = chart

    const labels = options.labels
    if (!labels) return
    
    ctx.save()
      
    ctx.beginPath()
    ctx.clearRect(0, 0, 0, 0)
    
    const index = 1
    const total = labels.length
    for (const label of labels) {
        const text = label.text || `Circle: ${index}/${total}` 
        const size = label.size || 100
        const color = label.color || '#FFFEFE'
        const weight = label.weight || 400
        const pos = label.pos || 3.30

        ctx.fillStyle = color

        const fontSize = (height / size).toFixed(2)
        ctx.font = `${weight} ${fontSize * 13}px "Titillium Web"`

        
        const textX = Math.round((width - ctx.measureText(text).width) / 2)
        const textY = (height / pos) //3.30    
        ctx.fillText(text, textX, textY)
    }

    ctx.restore()
  }
}


const options = {
  type: 'doughnut',
  data,
  options: {
    maintainAspectRatio: false,
    plugins: {
      'customLabels': {
        labels: [
          {
            size: 250,
          },
          {
            size: 90,
            weight: 700,
          },
          {
            size: 150,
            weight: 100,
            pos: 1.90,
          },
          {
            size: 200,
            pos: 1.50,
          },
        ]
      },
    },
  },
  plugins: [plugin],
}


const $canvas = document.getElementById('chart')
const chart = new Chart($canvas, options)
<div class="wrapper" style="width: 98vw; height: 180px">
  <canvas id="chart"></canvas>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.0.1/chart.umd.js" integrity="sha512-gQhCDsnnnUfaRzD8k1L5llCCV6O9HN09zClIzzeJ8OJ9MpGmIlCxm+pdCkqTwqJ4JcjbojFr79rl2F1mzcoLMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Leave a comment