1

Trying to update the text in the center of a doughnut chart when the prop month changes.

Screenshot of chart, as you can see January did not update, but price did.

However chartJS never updates past the initial month, January, even though it will update when the data changes.

  const plugins = [{
    beforeDraw: (chart: any) => {
      var width = chart.width,
          height = chart.height,
          ctx = chart.ctx;
      ctx.restore();
      
      var price = chart.config.data.datasets[0].data[0];
      var item = month;

      //Price
      var fontSize = (height / 200).toFixed(2);
      ctx.font = fontSize + "em sans-serif";
      ctx.textBaseline = "top";
      var text = `$${price.toFixed(2)}`,
          textX = Math.round((width - ctx.measureText(text).width) / 2),
          textY = height / 2;
      
      ctx.fillText(text, textX, textY);
      ctx.save();

      // Item Type
      fontSize = (height / 400).toFixed(2);
      ctx.font = fontSize + "em sans-serif";
      ctx.textBaseline = "top";
      text = `${item}`;
      textX = Math.round((width - ctx.measureText(text).width) / 2);
      textY = height / 2 + 50;
      ctx.fillText(text, textX, textY);
      ctx.save();
    }
  }];

  const chartRef = useRef<Chart>(null);

  return <Doughnut 
    // @ts-ignore
    ref={chartRef}
    options={options} 
    data={data}
    // @ts-ignore
    plugins={plugins}
  />;

How are we supposed to properly pass information to a chartjs component?

Kevin Z
  • 11
  • 2
  • Were you able to come up with a workaround? It seems anything drawn onto the canvas in a plugin only renders once when it loads up and can't change. – James Finn Jul 06 '22 at 08:10

1 Answers1

1

I had the same issue and the problem seems to be the beforeDraw() function won't see any change in variables contained outside of it including any data you pass through the parent component. My workaround was to pass the required data you want into the options object that gets passed into the chart. You will then be able to access it in the beforeDraw() function through the automatic chart parameter like so chart.config.options.nameOfUpdatedData

const options = {
   ...
   price, 
   month,
}

const plugins = [
   {
      ...
      beforeDraw: (chart: any) => {
         ...
         const updatedPrice = chart.config.options.price;
         const updatedMonth = chart.config.options.month;
      }
   },
];

return (
   <Chart type="doughnut" data={data} options={options} plugins={plugins} />
)
James Finn
  • 366
  • 2
  • 12