apexcharts / react-apexcharts

📊 React Component for ApexCharts
https://apexcharts.com
MIT License
1.31k stars 156 forks source link

Candlestick chart does not redraw at every state change #159

Closed flolege closed 1 month ago

flolege commented 4 years ago

I have a Chart component which gets chart data from two sources: The first provides historic candlestick data every minute. The second provides real time data of the current candlestick. Both update the series object via setState.

The issue is, that only the first source updates the chart.

I expect that after the second source sends a current candle stick data and i update the state, the last candlestick updates on the chart, but it doesnt. It doesn't move. Although the render is triggered after both updates (from first and second source), which i can seek in the console output. Also I can see in the log that this.state.series has exactly the same format after both kind of updates.

Here is the code of my chart component:

`import React from "react"; import Chart from "react-apexcharts"; import moment from "moment";

export default class ChartComponent extends React.Component { constructor(props) { super(props);

  this.state = {
      series: [{data:[]}],
      options: {chart: {id: "basic-bar"}}
    }
}

componentDidMount() {     
  this.startEventSource();
}

startEventSource() {
  this.eventSource = new EventSource(`http://localhost:9000/candleStream`);
  this.eventSource.onmessage = e => this.updateChart(JSON.parse(e.data), "Minute");

  this.eventSource2 = new EventSource(`http://localhost:9000/priceStream`);
  this.eventSource2.onmessage = e => this.updatePrice(JSON.parse(e.data))         
}        

updatePrice = (newCandleData) => {

  var candleData = newCandleData.split(";");
  let momentWithoutSeconds = moment(parseInt(candleData[4])).seconds(0).milliseconds(0).valueOf();      
  let candle = [momentWithoutSeconds, parseFloat(candleData[0]), parseFloat(candleData[1]), parseFloat(candleData[2]), parseFloat(candleData[3]) ]    
  let newCandleList = this.state.series[0].data;

  if(newCandleList.filter(c => c[0] == momentWithoutSeconds).length == 0) {        
    newCandleList.push(candle);        

  } else {
    newCandleList[newCandleList.length - 1] = candle;
  }    

  this.updateChart([{data:newCandleList}], "Price");      
}    

updateChart = (data, source) => {                 
  this.setState({series: data},  console.log(source, this.state.series));
}  

render() {
  console.log("render triggered!")
  return (
    <div className="app">
      <div className="row">
        <div className="mixed-chart">
          <Chart
            options={this.state.options}
            series={this.state.series}
            type="candlestick"
            width="1000"
          />
        </div>
      </div>
    </div>
  );  
}

}`

And here an example console output where the structure of series is visible: image

flolege commented 4 years ago

EDIT: The chart DOES update while I am/keep resizing the browser window.

Dancia commented 4 years ago

+1 Easy to reproduce problem.

vibexpro commented 4 years ago

Any workaround/Solution?

yohainnn commented 4 years ago

same problem here

hanupratap commented 3 years ago

same problem

github-actions[bot] commented 1 month ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.