Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate dynamic updates in CanvasJS using React functional components?

Using React functional components, I have not been able to find a way to animate my chart with dynamic data received asynchronously. The sandbox below illustrates the problem with a timer simulating the asynchronous read.

https://codesandbox.io/s/basic-column-chart-in-react-canvasjs-0gfv6?fontsize=14&hidenavigation=1&theme=dark

When running the example code, you should see 5 vertical bars of increasing heights animate. Then, after 5 seconds, it switches immediately to 4 bars of descending heights. I am looking to have that update animate.

Here is some reference information I've reviewed: CanvasJS React Demos: many of which animate on initial draw, but I couldn't find one that animates with dynamic data loaded after the initial render.

Chart using JSON Data is an demo that has dynamic data, but doesn't animate.

Reviewing the CanvasJS forum, I found a couple links, but none that address React functional components

Vishwas from Team Canvas said:

To update dataPoints dynamically and to animate chart, you can instantiate the chart, update dataPoints via chart-options and then call chart.render as shown in this updated JSFiddle.

var chart = new CanvasJS.Chart("chartContainer", {
  title: {
    text: "Animation test"
  },
  animationEnabled: true,  
  data: [{
    type: "column",
    dataPoints: []
  }]
});

chart.options.data[0].dataPoints =  [{ label: "Apple", y: 658 },
                                     { label: "Orange", y: 200 },
                                     { label: "Banana", y: 900 }];
chart.render();

This sample is pure JS, but I tried to adapt the principle to my React functional component. To better comport with React best practices, I incorporated the useState hook for storing the data and the useEffect hook to handle the fetch. But, alas, I couldn't get my sandbox to animate with the dynamic data.

I think the problem is that CanvasJS expects to animate only on the first render, as stated by Sanjoy in the CanvasJS forum on 7/19/2016.

I found this SO question from Jan 2015 that suggests:

My current ugly workaround is to reinstantiate the chart every time I update just to achieve that animation effect.

I'm hopeful that the situation has improved in the last four years, but if this hack is still the best/only way to go, I need some guidance on how to reinstantiate the chart every time using a React functional component.

like image 586
Jay Cincotta Avatar asked Nov 15 '22 20:11

Jay Cincotta


1 Answers

To force a remount of a component pass a different key when you want to remount the component

<CanvasJSChart
  key={dataPoints.toString()} // force a remount when `dataPoints` change
  containerProps={containerProps}
  options={options}
  onRef={ref => (chart.current = ref)}
/>

Working example

like image 162
Asaf Aviv Avatar answered Dec 04 '22 08:12

Asaf Aviv