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

Jay*_*tta 5 reactjs canvasjs react-hooks

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

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

运行示例代码时,您应该看到 5 个高度增加的竖条动画。然后,在 5 秒后,它立即切换到 4 个下降高度的小节。我希望有那个更新动画。

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

使用 JSON 数据的图表是一个具有动态数据但没有动画的演示。

查看 CanvasJS 论坛,我找到了几个链接,但没有一个是针对 React 功能组件的

来自 Canvas 团队的 Vishwas说:

要动态更新数据点并为图表设置动画,您可以实例化图表,通过图表选项更新数据点,然后调用 chart.render,如此更新的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();
Run Code Online (Sandbox Code Playgroud)

这个示例是纯 JS,但我尝试将原理调整到我的 React 功能组件中。为了更好地符合 React 最佳实践,我合并了useState用于存储数据的useEffect钩子和用于处理提取的钩子。但是,唉,我无法让我的沙箱使用动态数据制作动画。

我认为问题在于 CanvasJS 期望仅在第一次渲染时进行动画处理,正如Sanjoy 在 7/19/2016 的 CanvasJS 论坛中所述

从 2015 年 1 月发现这个 SO 问题表明:

我目前丑陋的解决方法是每次更新时重新实例化图表以实现该动画效果。

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

Nik*_*kic -1

这两个例子都运行良好。

您始终可以通过某种调用为字符设置动画。在本例中我使用 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>
Run Code Online (Sandbox Code Playgroud)