2017-10-18 1 views
1

J'ai créé un graphique linéaire en utilisant react-highcharts. Il a 3 séries et des données différentes pour chacun d'eux. Et j'ai un sélecteur de gamme qui change les données de la série dynamiquement. Le graphique ressemble à ceci: crg Cela fonctionne très bien, mais le problème est que chaque fois que je change la valeur de risque sur le sélecteur de gamme, le graphique est rendu avec les données de la nouvelle série. Je ne veux pas que ça se répète à chaque fois. Je veux que les données de la série changent avec l'animation. Quelque chose comme ça: Live random data. Et voici mon code connexe:Modifier dynamiquement les données de la série dans les diagrammes hautes de réaction sans rendre le graphique de nouveau.

class ContributionRiskGraph extends React.Component { 
    constructor() { 
    super(); 

    this.state = { 
     riskValue: 8.161736 
    }; 

    this.handleChange = this.handleChange.bind(this); 
    } 

    handleChange(value) { 
    this.setState({ 
     riskValue: value 
    }); 
    } 

    render() { 
    const riskValue = this.state.riskValue/100; 
    const LBData = getGraphPlotData(riskValue, 'lowerBound'); 
    const EVData = getGraphPlotData(riskValue, 'expectedValue'); 
    const UBData = getGraphPlotData(riskValue, 'upperBound'); 

    const config = { 
     chart: { 
     animation: { 
      duration: 1000 
     } 
     }, 
     title: { 
     text: 'Contribution Risk Graph' 
     }, 
     series: [ 
     { 
      name: 'Lower Bound', 
      data: LBData, 
      type: 'spline', 
      tooltip: { 
      valueDecimals: 2 
      } 
     }, 
     { 
      name: 'Expected Value', 
      data: EVData, 
      type: 'spline', 
      tooltip: { 
      valueDecimals: 2 
      } 
     }, 
     { 
      name: 'Upper Bound', 
      data: UBData, 
      type: 'spline', 
      tooltip: { 
      valueDecimals: 2 
      } 
     } 
     ], 
     yAxis: { 
     gridLineWidth: 0, 
     opposite: true 
     }, 
     xAxis: { 
     gridLineWidth: 2, 
     labels: { 
      formatter: function() { 
      if (this.value <= 1) { 
       return this.value + ' month'; 
      } 
      return this.value + ' months'; 
      } 
     } 
     }, 
    }; 

    return(
     <div> 
     <ReactHighcharts config={config} /> 
     <div style={{ display: 'flex', justifyContent: 'center', marginTop: 30 }}> 
      <RangeSlider 
      label="Risk Value" 
      defaultValue={8} 
      min={1} 
      max={62} 
      handleChange={this.handleChange} 
      /> 
     </div> 
     </div> 
    ) 
    } 
} 

Répondre

2

Donc, j'ai trouvé une solution de contournement. Cela fonctionne parfaitement. Je reçois le graphique par ref, puis définissez une nouvelle donnée en utilisant setData. Cela ne fait que mettre à jour les données plutôt que de rendre à nouveau l'ensemble du composant de graphique. Et j'utilise la méthode du cycle de vie des composants shouldComponentUpdate pour arrêter le rendu du composant. Voici le code associé:

class ContributionRiskGraph extends React.PureComponent { 
    constructor() { 
    super(); 

    this.state = { 
     riskValue: 8.161736 
    }; 

    this.handleChange = this.handleChange.bind(this); 
    } 

    shouldComponentUpdate(nextProps, nextState) { 
    if(this.state.riskValue !== nextState.riskValue) { 
     return false; 
    } 
    } 

    handleChange(value) { 
    this.setState({ 
     riskValue: value 
    }); 

    let riskValue = this.state.riskValue/100; 
    let chart = this.crg.getChart(); 
    chart.series[0].setData(getGraphPlotData(riskValue, 'lowerBound'), true); 
    chart.series[1].setData(getGraphPlotData(riskValue, 'expectedValue'), true); 
    chart.series[2].setData(getGraphPlotData(riskValue, 'upperBound'), true); 
    } 

    render() { 
    // other code 
    return(
     <div> 
     <ReactHighcharts config={config} ref={a => this.crg = a} /> 
     <div style={{ display: 'flex', justifyContent: 'center', marginTop: 30 }}> 
      <RangeSlider 
      label="Risk Value" 
      defaultValue={8} 
      min={1} 
      max={62} 
      handleChange={this.handleChange} 
      /> 
     </div> 
     </div> 
    ) 
    } 
}