I'm trying to update my chart using react-chartjs-2. I'm using date picker to filter different data and re-render the chart accordingly such as display data today, yesterday, last 7 days etc.. The data is being fetched from my database
However, when the chart gets redrawn, and re-rendered, it gets added onto the state which I don't want. I simply want to re-render the new data that was requested not re-render and add onto the old data that was in the chart.
I actually fixed this issue before with vanilla JavaScript because I wasn't using react I used the destroy()
method that the chart documentation says to use but i'm not sure how to use it with react?
So upon further inspection, it seems my chart is re-rendering fine. However, when it gets re-rendered, additional data is being added onto my chartData state which I don't want, I just want the new data that got requested to show on the chart. I'm still trying to figure that portion out.
Here is my code I have a lot of it so I'll only show the relevant parts:
import React from "react";
import reportsService from "../../services/reportsService";
import update from "react-addons-update";
import moment from "moment";
import { Bar } from "react-chartjs-2";
import "chartjs-plugin-labels";
import "chartjs-plugin-datalabels";
class Reportspage extends React.Component {
constructor(props) {
super(props);
this.state = {
chartData: {
labels: [],
datasets: [
{
//label: "Quotes",
data: [],
backgroundColor: []
}
]
}
};
}
chartColors() {
let colors = [];
for (let i = 0; i < 100; i++) {
let r = Math.floor(Math.random() * 200);
let g = Math.floor(Math.random() * 200);
let b = Math.floor(Math.random() * 200);
let c = "rgb(" + r + ", " + g + ", " + b + ")";
colors.push(c);
}
// Update deep nested array of objects in state
this.setState({
chartData: update(this.state.chartData, {
datasets: { 0: { backgroundColor: { $set: colors } } }
})
});
}
datePicker() {
let _this = this;
let start = moment().subtract(29, "days");
let end = moment();
let showReports;
let data;
let reloNames = [];
let reloCount = [];
function focusDate(start, end) {
$("#daterangePicker span").html(
start.format("MMMM D, YYYY") + " - " + end.format("MMMM D, YYYY")
);
}
$("#daterangePicker").daterangepicker(
{
startDate: start,
endDate: end,
ranges: {
Today: [moment(), moment()],
Yesterday: [
moment().subtract(1, "days"),
moment().subtract(1, "days")
],
"Last 7 Days": [moment().subtract(6, "days"), moment()],
"Last 30 Days": [moment().subtract(29, "days"), moment()],
"This Month": [moment().startOf("month"), moment().endOf("month")],
"Last Month": [
moment()
.subtract(1, "month")
.startOf("month"),
moment()
.subtract(1, "month")
.endOf("month")
]
}
},
focusDate
);
focusDate(start, end);
$("#daterangePicker").on("apply.daterangepicker", async function(
event,
picker
) {
switch (picker.chosenLabel) {
case "Today":
showReports = await reportsService.reloQuotes({
reportStatus: "Today"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
case "Yesterday":
showReports = await reportsService.reloQuotes({
reportStatus: "Yesterday"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
case "Last 7 Days":
showReports = await reportsService.reloQuotes({
reportStatus: "Last 7 Days"
});
data = showReports.recordsets[0];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
_this.setState({
chartData: update(_this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
console.log(_this.state);
break;
}
});
//console.log(this.state);
}
async reloQuotes() {
const showreloQuotes = await reportsService.reloQuotes();
let data = showreloQuotes.recordsets[0];
let reloNames = [];
let reloCount = [];
data.forEach((element, index, array) => {
reloNames.push(element.reloNames);
reloCount.push(element.NoofOrders);
});
this.setState({
chartData: update(this.state.chartData, {
labels: { $set: reloNames },
datasets: { 0: { data: { $set: reloCount } } }
})
});
}
async componentDidMount() {
await this.chartColors();
await this.datePicker();
// Execute models real time thus re-rendering live data on the chart real time
await this.reloQuotes();
}
render() {
return (
<div className="fluid-container">
<div className="container">
<h1>Reports</h1>
<div className="row">
<div className="daterangeContainer">
<div
id="daterangePicker"
style={{
background: "#fff",
cursor: "pointer",
padding: "5px 10px",
border: "1px solid #ccc",
width: "100%"
}}
>
<i className="fa fa-calendar" />
<span /> <i className="fa fa-caret-down" />
</div>
</div>
</div>
<div className="row">
<div className="col-md-12">
<Bar
data={this.state.chartData}
height={800}
options={{
maintainAspectRatio: false,
legend: {
display: false
},
scales: {
xAxes: [
{
ticks: {
beginAtZero: true,
autoSkip: false
},
scaleLabel: {
display: true
}
}
]
},
title: {
display: true,
text: "Quotes",
fontSize: 16
},
plugins: {
datalabels: {
display: true,
color: "white"
}
}
}}
redraw
/>
</div>
</div>
</div>
</div>
);
}
}
export default Reportspage;