【问题标题】:How to animate dynamic updates in CanvasJS using React functional components?如何使用 React 功能组件在 CanvasJS 中为动态更新设置动画?
【发布时间】:2019-12-16 17:40:34
【问题描述】:

使用 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,然后调用 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();

这个示例是纯 JS,但我尝试将原理调整到我的 React 功能组件。为了更好地适应 React 最佳实践,我合并了 useState 挂钩来存储数据和 useEffect 挂钩来处理获取。但是,很遗憾,我无法让我的沙盒使用动态数据制作动画。

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

我发现this SO question from Jan 2015 表明:

我目前丑陋的解决方法是每次我都重新实例化图表 更新只是为了实现那个动画效果。

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

【问题讨论】:

  • 您需要处置(销毁)反应图表组件,然后他们重新创建它。为此,您需要一个根 App 类,然后创建子组件(chrts)。这是only way(带有反应)不是针对这种情况,而是针对其他人。在您的案例示例中,我看到了使用反应的程序方式。看github.com/zlatnaspirala/react-vs-typescript-starter

标签: reactjs react-hooks canvasjs


【解决方案1】:

要强制重新安装组件,请在要重新安装组件时传递不同的key

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

Working example

【讨论】:

    【解决方案2】:

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

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

    );

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

    【讨论】:

      【解决方案3】:

      这两个例子都很好。

      您始终可以通过某种调用为字符设置动画。我在这种情况下使用 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>

      【讨论】:

      • 我的问题是关于通过 React 功能组件中的 animationEnabled 属性利用 CanvasJS 内置的动画功能。这个答案没有解决这个问题。请参考这个沙盒:codesandbox.io/s/…
      猜你喜欢
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2015-05-02
      • 2021-03-14
      • 1970-01-01
      • 2021-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多