Reputation: 77
It is my first time working with Chartjs, and I'm not really a pro in React either. I am trying to implement a bar chart that should take its data possibly from CONSTs that are calculater using numbers provided by user inputs. This is how the chart works right now. The values in data are harcoded, and I don't know how to make them dynamic.
constructor(props) {
super(props);
this.state = {
chartData:{},
visitors: "",
conversion: 4,
value: "",
smileeconversion: "",
smileevalue: "",
swcost: "",
labourcost: "",
roi: ""
};
}
componentWillMount(){
this.getChartData();
}
getChartData(){
// Ajax calls here
this.setState({
chartData:{
labels: ['Before', 'After'],
datasets:[
{
label:'Population',
data:[
617594,
181045,
],
backgroundColor:[
'rgba(255, 99, 132, 0.6)',
'rgba(54, 162, 235, 0.6)',
'rgba(255, 206, 86, 0.6)',
'rgba(75, 192, 192, 0.6)',
'rgba(153, 102, 255, 0.6)',
'rgba(255, 159, 64, 0.6)',
'rgba(255, 99, 132, 0.6)'
]
}
]
}
});
}
this is the chart component:
import React, {Component} from 'react';
import {Bar, Line, Pie} from 'react-chartjs-2';
class Chart extends Component{
constructor(props){
super(props);
this.state = {
chartData:props.chartData
}
}
static defaultProps = {
displayTitle:true,
displayLegend: true,
legendPosition:'right',
location:'City'
}
render(){
return (
<div className="chart">
<Bar
data={this.state.chartData}
options={{
title:{
display:this.props.displayTitle,
text:'Return of investments',
fontSize:25
},
legend:{
display:this.props.displayLegend,
position:this.props.legendPosition
}
}}
/>
</div>
)
}
}
export default Chart;
and its parent component:
<Chart chartData={this.state.chartData} location="Massachusetts" legendPosition="bottom"/>
Upvotes: 3
Views: 9671
Reputation: 2612
This is a slightly different approach, but I think it's simpler than what you're doing:
Stop using state
Try passing arrays as parameters into your function, and then send the parameters directly to the chart data object, and then initiating the chart directly from inside the function (I avoid using React state in this case because it has a lag, and Chart.js wants to initiate instantly).
Here's a small example:
let barChart;
let newLabels = ["Label1", "Label2", "Label3"];
let newData = ["Data1", "Data2", "Data3"];
createBarChart = (labels, data) => {
let ctx = "bar_l1_chart";
barChart = new Chart(ctx, {
type: 'horizontalBar',
data: {
labels: [labels],
datasets: [{
label: 'Sentiment',
data: [data],
}]
},
});
};
this.createBarChart(newLabels, newData);
Now you just update the "newLabels" or "newData" arrays, and re-call the function. A good way to do that is with React state managers, like:
componentWillRecieveProps(newProps){
if(newProps.labels && newProps.data) {
if(barChart){barChart.destroy()};
this.createBarChart(newProps.labels, newProps.data)
}
}
You will also need to "destroy()" the chart, before you recreate it. Hopefully this is helpful!
Upvotes: 1