如何制作Google材质条形图的动画

问题描述

我在react项目中绘制了一个react google条形图(主要的一个),我正在尝试制作动画。我已经读过这种图表不支持动画,但是我需要这样做,必须有任何方法可以做到。我很难认为新事物比旧事物更糟。有人知道我该怎么做吗?我尝试了许多不同的方法,但是没有任何效果。这是我的代码

import React from 'react';
import './App.css';
import Chart from 'react-google-charts'

function App() {

  return (
    <div className="App">      
      <Chart
        width={'500px'}
        height={'300px'}
        // Note here we use Bar instead of BarChart to load the material design version
        chartType="Bar"
        loader={<div>Loading Chart</div>}
        data={[
          ['City','2010 Population','2000 Population'],['New York City,NY',8175000,8008000],['Los Angeles,CA',3792000,3694000],['Chicago,IL',2695000,2896000],['Houston,TX',2099000,1953000],['Philadelphia,PA',1526000,1517000],]}
        options={{
          // Material chart options
          chart: {
            title: 'Population of Largest U.S. Cities',subtitle: 'Based on most recent and prevIoUs census data',},hAxis: {
            title: 'Total Population',minValue: 0,animation: {
            duration: 1000,easing: 'out',startup: true,vAxis: {
            title: 'City',bars: 'horizontal',axes: {
            y: {
              0: { side: 'right' },}}
      />
    </div>
  );
}

export default App;

解决方法

Demo using react | Demo Using vanilla javascript

Google材质图表上不支持动画。

如果要将动画添加到重要的Google图表中,则可以使用CSS动画手动进行。让我们来做(Demo):

首先,我们应该为实际的柱线选择器。似乎第三个svg组(g标签)是图表中的实际条形图(其他组用于标签/标题/等):

.animated-chart g:nth-of-type(3) {...}

然后我们应该在其中添加一个CSS过渡:

.animated-chart g:nth-of-type(3) {
  transition: 1s;
}

然后我们可以创建一个类(.animated-chart-start)在transform: scaleX(1);transform: scaleX(0);之间进行切换,如下所示:

.animated-chart g:nth-of-type(3) {
  transition: 1s;
  transform: scaleX(1);
}
.animated-chart.animated-chart-start g:nth-of-type(3) {
  transform: scaleX(0);
}

到目前为止,我们已经添加了CSS,现在我们应该将这些类添加到图表中,并在短暂的延迟后切换.animated-chart-start类。我们可以在componentDidMount上执行此操作,但是在准备好图表后执行此操作更干净:

<Chart
    ...
    className={`animated-chart animated-chart-start`}
    chartEvents={[
      {
        eventName: "ready",callback: ({ chartWrapper,google }) => {
          const chartEl = chartWrapper.getChart().container;
          setTimeout(() => {
            chartEl.classList.remove('animated-chart-start')
          },100)
        },}
    ]}
  />

它将.animated-chart-start类添加到图表中,并在100毫秒后将其删除。 (100ms是可选的,您也可以立即切换它。)

还要注意,Google图表似乎不支持将数据绑定到className(如className={this.state.dynamicClass}),这就是为什么我们不能使用状态变量来切换动画类的原因。 / p>

最后,我们可以将此动画图表包装到一个单独的组件中,例如AnimatedChart,以使其更具可重用性。 (您可以在stackblitz代码上看到它。)

Run it live

已知限制:

  • 在图表动画期间设置状态将导致重新渲染,并且破坏了CSS过渡。
  • 我们认为第三个svg组是图表。但它可能会根据图表类型甚至图表属性而有所不同。

更新:对于垂直图表,您可以使用scaleY进行动画制作,还可能需要设置转换原点,例如:transform-origin: 0 calc(100% - 50px);以使其看起来更好。 (Run vertical version On Stackblitz

更新2:有关原始javascript版本(无任何框架),请参见here

,

您可以尝试通过短时间交换图表数据来模拟动画。这是我的建议,分三步进行。

  1. 初始加载图表值为“ 0”的图表。
  2. 然后加载数据的部分值。
  3. 最后设置实际数据值。
lapply(names(stocks.Cl),function(i) plot(acf(stocks.Cl[,i]),main = i))

使用State Hook和useEffect帮助来操纵我们要呈现的数据。在function ChartBox() { let initialData = [ ['City','2010 Population','2000 Population'],['New York City,NY',0],['Los Angeles,CA',['Chicago,IL',['Houston,TX',['Philadelphia,PA',]; let n = 250; // divider let dataLoading = [ ['City',8175000/n,8008000/n],3792000/n,3694000/n],2695000/n,2896000/n],2099000/n,1953000/n],1526000/n,1517000/n],]; let finalData = [ ['City',8175000,8008000],3792000,3694000],2695000,2896000],2099000,1953000],1526000,1517000],]; const [chartData,setChartData] = useState(initialData); useEffect(() => { const timer = setTimeout(() => { setChartData(dataLoading) },100); const timer2 = setTimeout(() => { setChartData(finalData) },300); return () => {clearTimeout(timer); clearTimeout(timer2)} },[]); return ( <div className="App"> <Chart {...} data={chartData} {...} 组件中,我传递了<Chart/>,该值将在100ms和300ms之后改变。当然,您可以使用值的一部分添加更多的步骤(例如dataLoading),这样您的“动画”将看起来更加流畅。

,

只是更新了代码,并试图以更好的方式重新实现它,但找不到更好的解决方案。

您需要与CSS配合使用

用于Y轴动画

g:nth-of-type(3) transition: 2s; transform: scaleX(1);

OR

用于X轴动画

g:nth-of-type(3) transform: scaleX(0);

https://codesandbox.io/s/google-react-chart-do602?file=/src/styles.css

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...