我正在尝试使用react-chartjs-2更新图表。我正在使用日期选择器过滤不同的数据并相应地重新呈现图表,例如今天,昨天,过去7天等。从我的数据库中获取数据
但是,当图表被重绘并重新呈现时,它被添加到我不想要的状态上。我只想重新呈现不请求的新数据,然后将其添加到图表中的旧数据上。
实际上我之前使用香草JavaScript修复了此问题,因为我没有使用react,我使用了图表文档规定使用的destroy()
方法,但是我不确定如何将它与react一起使用? >
因此,经过进一步检查,看来我的图表正在重新渲染。但是,当它重新呈现时,我不希望将其他数据添加到我的chartData状态中,我只希望被请求显示在图表上的新数据。我仍在设法弄清楚那部分。
这是我的代码,很多,所以我只显示相关部分:
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;
答案 0 :(得分:2)
因此,您描述的问题是在重新渲染组件时将数据添加到组件状态。在您提供的代码片段中,您没有使用React中可以在重新渲染时触发的任何生命周期方法。而且我看不到任何其他应在重新渲染时触发的钩子。因此,我找不到您问题的任何来源。
但是,我看到了其他问题,这些问题可能会使您难以调试。解决这些问题可能有助于您确定实际问题。在componentDidMount
方法中,调用仅用于更新状态的函数。这不是一个好的设计,因为它会迫使该组件在安装后立即立即重新渲染几次。
更好的设计是在构造函数中完全准备chartData-objekt。例如,您可以更改chartColors
函数以将chartData对象作为参数,然后返回添加了颜色的新对象。然后使您的构造函数如下所示:
constructor(props) {
super(props);
const chartDataWithoutColors = {
labels: [],
datasets: [
{
//label: "Quotes",
data: [],
backgroundColor: []
}
]
}
const chartDataWithColor = this.chartColors(chartDataWithoutColors);
this.state = {
chartData: chartDataWithColor
};
}
通过删除对setState
的不必要的调用,您可以使组件的寿命更简单,更高效。简化组件后,请一次删除一个非关键部件来开始调试,并在问题消失时尝试确定故障原因。这应该足以找到该错误。
祝你好运!