I made a React.JS component, which draws charts using react-chartjs
wrapper around the chart.js
library. I am getting an error on update, as if my data was corrupted. I am thinking that maybe something is wrong with the context, maybe, as I don't see anything wrong with my code. When the chart is drawn first time, it shows up fine. setState
causes: Uncaught Type Error: Cannot read property 'points' of undefined(...)
happens at core.js
anonymous function inside set.data.forEach()
.
Below is my code:
class Usage extends Component {
constructor(props) {
super(props);
this.state = {
active: true,
new: false,
chartData: []
}
}
componentWillMount() {
this.buildChartData();
}
buildChartData() {
const daysInMonth = 30;
const graphs = [
{title: 'Active Users', key: 'active', color: 'rgba(255, 99, 132, 1)'},
{title: 'New Users', key: 'new', color: 'rgba(50, 25, 255, 1)'}
];
let datasets = [];
let labels = [];
let labelsDone = false;
graphs.forEach((graph) => {
if (this.state[graph.key]) {
let data = [];
let backgroundColor = [];
let borderColor = [];
// XXX !!! for now
if (!labelsDone) {
for (let i = daysInMonth; i > 0; i--) {
let d = new Date();
// we stop yesterday
d.setDate(d.getDate() - i);
labels.push( (d.getUTCMonth() + 1) + '/' + d.getUTCDate() );
}
}
labelsDone = true;
for (let i = daysInMonth; i > 0; i--) {
let d = new Date();
// we stop yesterday
d.setDate(d.getDate() - i);
data.push( Math.round(Math.random() * 200));
borderColor.push(graph.color);
backgroundColor.push('rgba(0,0,0,0)');
}
let dataset = {
data: data,
borderWidth: 1,
label: graph.title,
fillColor: 'rgba(0,0,0,0.0)',
strokeColor: borderColor
};
datasets.push(dataset);
}
})
this.setState({
chartData: {datasets: datasets, labels: labels}
});
}
toggleCheckbox = label => {
switch(label) {
case 'Active Users':
this.setState({
active: !this.state.active
});
break;
case 'New Users':
this.setState({
new: !this.state.new
});
break;
default:
console.log('Error: unhandled action');
break;
}
this.buildChartData();
}
render() {
return (
<div style={{display: 'flex', flexDirection: 'row'}}>
<div style={{flexDirection: 'column', marginLeft: '50px', marginRight: '50px', flexGrow: 1}}>
<div style={{height: '20vh'}}>
<div style={{flexDirection: 'row'}}>
<Checkbox
label={'Active Users'}
handleCheckboxChange={this.toggleCheckbox}
isChecked={true}
/>
<Checkbox
label={'New Users'}
handleCheckboxChange={this.toggleCheckbox}
isChecked={false}
/>
</div>
</div>
<div style={{height: '75vh'}}>
<Line data={this.state.chartData} options={chartOptions} />
</div>
</div>
</div>
);
}
}
export default Usage;
I printed out smaller dataset, where the same thing happens. Don't see any difference except for randomly generated values. Still, the initial rendering is fine, yet setState
, which I understand calls update
results in the above error.
If data passed into the component changes, points will animate between values using chart.js' .update(). If you want the chart destroyed and redrawn on every change, pass in redraw as a prop. For example <LineChart data={this.state.chartData} redraw />
Adding redraw
solves the problem.