How to enable react state to update a chartjs label?

Viewed 78

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?

1 Answers

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} />
)
Related