So I have written some code to display a chart and I have also written a function which will allow me to change the timeframe of the chart. However, when this function is invoked, a duplicate chart pops up.
Here is the Chart.js
let chartProperties = {
width: 1000,
height: 500,
timeScale: {
timeVisible: true,
secondsVisible: false
}
}
const Chart = (props) => {
useEffect(() => {
fetchData()
}, [])
const lightweightChart = createChart(document.body, chartProperties);
const candleSeries = lightweightChart.addCandlestickSeries();
const fetchData = () => {
axios.get(`https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1m&limit=1000`)
.then(response => response.data)
.then(data => {
const candlestickData = data.map(d => {
return { time: d[0] / 1000, open: parseFloat(d[1]), high: parseFloat(d[2]), low: parseFloat(d[3]), close: parseFloat(d[4]) }
});
candleSeries.setData(candlestickData);
}).catch(error => console.log(error))
}
return (
<div>
</div>
);
}
const mapStateToProps = (state) => {
return {
chartData: state.chartOptionsReducer
}
}
export default connect(mapStateToProps)(Chart);
Here is the action creator chartActions.js
export const changeTimeframe = (timeframe) => {
return {
type: 'CHANGE_TIMEFRAME',
payload: {
timeframe: timeframe
}
}
}
Here is the reducer chartOptionsReducer.js
const initState = {
symbol: 'BTCUSDT',
timeframe: '4h'
}
const chartOptionsReducer = (state = initState, action) => {
console.log(action)
if (action.type === 'CHANGE_TIMEFRAME') {
let newTimeframe = action.payload.timeframe
return {
...state,
timeframe: newTimeframe
}
} else {
return state;
}
}
export default chartOptionsReducer;
And finally this is where the action gets called from OptionsColumn.js
const OptionColumn = (props) => {
const handleTimeframe = (timeframe) => {
props.changeTimeframe(timeframe)
}
return (
<Menu
label="Timeframe"
items={[
{ label: '1m', onClick: () => { handleTimeframe('1m') } },
{ label: '4h', onClick: () => { handleTimeframe('4h') } },
]}
/>
)
}
const mapDispatchToProps = (dispatch) => {
return {
changeTimeframe: (timeframe) => { dispatch(changeTimeframe(timeframe)) }
}
}
export default connect(mapStateToProps, mapDispatchToProps)(OptionColumn);
I think the issue may be coming from this line in Chart.js though i'm not sure, and i'm also not sure how to avoid it:
const lightweightChart = createChart(document.body, chartProperties);
BONUS ISSUE: Anybody who is familiar with the lightweightChart package, is there a way to display the chart within a container instead of document.body? Thanks
In React, the component will re-render under certain conditions which include props changes.
This code bellow will re-run whenever the Chart.js re-render (which it will create new chart targeting document.body
every time)
const lightweightChart = createChart(document.body, chartProperties);
Put it in your useEffect
with your fetchData()
call
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.