如何使用React功能组件在CanvasJS中为动态更新制作动画?

时间:2019-12-16 17:40:34

标签: reactjs react-hooks canvasjs

使用React功能组件,我无法找到一种方法来用异步接收的动态数据为图表制作动画。下面的沙箱说明了计时器模拟异步读取的问题。

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

运行示例代码时,您应该看到5个高度递增的垂直条动画。然后,在5秒钟后,它立即切换到4个下降高度的条形图。我正在寻找更新动画。

以下是我已查看的一些参考信息: CanvasJS React Demos:其中许多动画会在初始绘制时进行动画处理,但我找不到在初始渲染后加载动态数据进行动画处理的动画。

Chart using JSON Data是一个具有动态数据但没有动画的演示。

在查看CanvasJS论坛时,我发现了几个链接,但都没有涉及React功能组件

Vishwas from Team Canvas说:

  

要动态更新dataPoints并设置图表动画,可以实例化图表,通过chart-options更新dataPoints,然后调用此更新的JSFiddle中所示的chart.render。

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();

该示例是纯JS,但我尝试使该原理适应我的React功能组件。为了更好地与React最佳实践保持一致,我结合了useState钩子来存储数据和useEffect钩子来处理提取。但是,a,我无法让沙箱为动态数据制作动画。

我认为问题在于,CanvasJS希望仅在第一个渲染上进行动画处理,如Sanjoy in the CanvasJS forum on 7/19/2016所述。

我发现this SO question from Jan 2015提示:

  

我当前的丑陋变通办法是每次我重新实例化图表   更新只是为了获得动画效果。

我希望情况在过去四年中有所改善,但是,如果这种黑客攻击仍然是最好/唯一的方法,我需要一些有关如何每次重新初始化图表的指导使用React功能组件。

3 个答案:

答案 0 :(得分:0)

我找到了部分答案。完整的执行代码位于this code sandbox中,但关键的一点是要延迟图表的初始渲染,直到状态变量指示数据可用为止。

  return (
<div className="App">
  {!initialized ? (
    <h1> Loading...</h1>
  ) : (
    <CanvasJSChart containerProps={containerProps} options={options} />
  )}
</div>

);

这只是部分解决方案,因为后续数据更新仍然没有动画。

答案 1 :(得分:0)

要强制重新安装组件,当您要重新安装组件时,请通过不同的key

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

Working example

答案 2 :(得分:-1)

两个示例都可以正常工作。

您总是可以通过某种调用为char设置动画。在这种情况下,我使用setInterval。

<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
 
<script>
 
 var chart;
 
window.onload = function () {

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

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

}

var max = 0;
var s = {c: 0, i: 0};
function ANIMATE() {
 
    if (typeof chart === 'undefined') return;
    
    chart.options.data[0].dataPoints.forEach(function(item, index, array) {
    
      if (index == s.i) {
         array[index].y += 3;
         s.c++;
      }
      
      if (s.c > 12) {
        s.i++;
        s.c = 0;
        if (s.i == 15) { s.i = 0}
      }
      
    
    });
    
    if (max < 12) {
    chart.options.data[0].dataPoints.push({label: "apple" + Math.random(), y: 1 + Math.random() * 10});
     max++;
    }
    
   chart.render()
}


setInterval(function(){
 ANIMATE()
}, 1)

</script>

<div id="chartContainer" style="height: 370px; width: 100%;"></div>