amcharts / amcharts3-react

Official amCharts V3 React component
Apache License 2.0
118 stars 50 forks source link

I can not using amcharts3-animate plugins and the related method "animateData" in react #20

Closed bleachdugu closed 7 years ago

bleachdugu commented 7 years ago

here is the part code of the charts component :

import React, { Component } from 'react' import styles from './style.scss' import style from './style.css' import AmCharts from 'amcharts3-react' import jsonData from './data.js'

// https://github.com/amcharts/amcharts3-react/issues/10 import 'amcharts3/amcharts/serial' // import 'amcharts3-animate'

class BarChartTest extends Component { constructor (props) { super(props) this.state = { num: 100 } this.onClick = this.onClick.bind(this) }

componentDidMount() {

}

onClick () { setTimeout(()=>{ this.setState({ num: this.state.num + 20 }) } , 100); }

render () {

const data = [{
  date: 0,
  value: this.state.num
}]
// const selfRef  = this 

// function redraw () {
//   selfRef.chartRef.animateData(data, {
//     duration: 1000,
//     complete: function () {

//     }
//   })
// }

const config = {
  'type': 'serial',
  'theme': 'light',
  'dataProvider': data,
  'startDuration': 1,
  'addClassNames' : true,
  'graphs': [{
    id: 'g1',
    valueField:  'value',
    title:  'value',
    type:  'column',
    fillAlphas:  0.9,
    valueAxis:  'a1',
    legendPeriodValueText:  'total: [[value.sum]] mi',
    lineColor:  '#263138',
    alphaField:  'alpha'
  }],
  'valueAxes': [{
    'minimum': -100,
    'maximum': 500
  }],
  'chartCursor': {},
  'zoomOutOnDataUpdate': false,
  // 'listeners' : [{
  //   'event' : 'init',
  //   'method' : redraw
  // }],
  'animateData' : data,
  'categoryField': 'date'
}

return (
  <div className={styles.barChart}>
    <AmCharts {...config} ref={(ref) => {this.chartRef = ref;}}/>
    <div className={styles.scrollmenu} />
    <button onClick={this.onClick}>add</button>
  </div>
)

} }

export default BarChartTest

bleachdugu commented 7 years ago

I can call the animateData function now in the listeners but when I add duration , it can add the bar scale but not trigger the smooth animation.

the updated code is :

import React, { Component } from 'react' import styles from './style.scss' import style from './style.css' import AmCharts from 'amcharts3-react' import jsonData from './data.js'

// https://github.com/amcharts/amcharts3-react/issues/10 import 'amcharts3/amcharts/serial' import 'amcharts3-animate'

class BarChartTest extends Component { constructor (props) { super(props) this.state = { num: 100 } this.onClick = this.onClick.bind(this) }

onClick () { this.setState({ num: this.state.num + 20 }) }

render () { const data = [{ date: 0, value: 100 }]

function update (event) {

  event.chart.animateData(data, {
    duration : 1000,
    complete : function () {
      data[0].value += 50;
      setTimeout(update(event) , 500);
    }
  })
}

const config = {
  'type': 'serial',
  'theme': 'light',
  'dataProvider': data,
  // 'startDuration': 1,
  'addClassNames' : true,
  'graphs': [{
    id: 'g1',
    valueField:  'value',
    title:  'value',
    type:  'column',
    fillAlphas:  0.9,
    valueAxis:  'a1',
    legendPeriodValueText:  'total: [[value.sum]] mi',
    lineColor:  '#263138',
    alphaField:  'alpha'
  }],
  'valueAxes': [{
    'minimum': -100,
    'maximum': 500
  }],
  'chartCursor': {},
  'zoomOutOnDataUpdate': false,
  'listeners' : [{
    'event' : 'init',
    'method' : update
  }],
  'categoryField': 'date'
}

return (
  <div className={styles.barChart}>
    <AmCharts {...config} ref={(ref) => { this.chartRef = ref }} />
    <div className={styles.scrollmenu} />
    <button onClick={this.onClick}>add</button>
  </div>
)

} }

export default BarChartTest

thx a lot

bleachdugu commented 7 years ago

use function in listener and using event.chart.function

Pauan commented 7 years ago

@bleachdugu I'm sorry for taking so long to get back to you on this.

As explained on the animate plugin page, you must first copy the dataProvider before calling animateData

In addition, you were calling update(event) immediately. Instead, you must wrap it in function () {} so that it is delayed for 500 milliseconds.

Here is the correct code:

let data = [{
  date: 0,
  value: 100
}]

function update (event) {
  data = JSON.parse(JSON.stringify(data));

  data[0].value += 50;

  event.chart.animateData(data, {
    duration : 1000,
    complete : function () {
      setTimeout(function () {
        update(event);
      }, 500);
    }
  })
}