页面上的两个 chartjs 图表抛出数据未定义错误
2020-09-23
772
我创建了以下问题
水平重叠条形图,而不是整个图形
,并得到了友好的回答(我被建议创建一个新问题!)。虽然答案很有效 - 我在同一页面上有 2 个图表,但由于某种原因,它会引发
无法读取未定义的属性“数据”
错误。
我不想包含我的 2 个图表的全部内容,但移动条形的 afterUpdate 代码如下:
function(chart) {
var datasets = chart.config.data.datasets;
console.log(datasets);
for (let iDs = 1; iDs < datasets.length; iDs++) {
let dataset = datasets[iDs];
// I added the following line however stacks the graph and doesn't display it correctly like the first
if (typeof dataset._meta[0] !== 'undefined'){
for (var i = 0; i < dataset._meta[0].data.length; i++) {
let model = dataset._meta[0].data[i]._model;
model.x += iDs * offset;
model.controlPointNextX += iDs * offset;
model.controlPointPreviousX += iDs * offset;
}
}
}
}
我已经将
typeof
检查添加到至少可以呈现图表的代码中,但我希望两个图表以相同的方式运行,而添加 typeof 检查只会堆叠图表并忽略移动条形的代码。
这可以在以下小提琴中最好地看到: https://jsfiddle.net/ycpj7g8w/
1个回答
所描述的行为很奇怪,因为如果两个图表彼此独立创建,它们都可以正常工作。可以通过更改
afterUpdate
函数并使用图表的
.getDatasetMeta(index)
函数获取数据集的元数据来解决该问题。
afterUpdate: function(chart) {
let datasets = chart.config.data.datasets;
for (let iDs = 1; iDs < datasets.length; iDs++) {
let meta = chart.getDatasetMeta(iDs);
for (var i = 0; i < meta.data.length; i++) {
let model = meta.data[i]._model;
model.x += iDs * offset;
model.controlPointNextX += iDs * offset;
model.controlPointPreviousX += iDs * offset;
}
}
}
请查看以下修改后可运行的代码:
Chart.defaults.global.legend.labels.usePointStyle = true;
Chart.defaults.scale.gridLines.drawOnChartArea = false;
var offset = 6;
new Chart('graph_1', {
"type": "bar",
"data": {
"labels": ["2020-08-01", "2020-09-01", "2020-10-01"],
"datasets": [{
"label": "Title test 1",
"data": [30, 20, 60],
"xAxisID": "bar-x-axis-1",
"barThickness": 14,
"backgroundColor": "rgba(241,213,157,1)",
"borderColor": "rgba(241,213,157,1)",
"pointBackgroundColor": "rgba(241,213,157,1)"
},
{
"label": "Title test 2",
"data": [30, 20, 60],
"xAxisID": "bar-x-axis-2",
"barThickness": 14,
"backgroundColor": "rgba(237,141,120,1)",
"borderColor": "rgba(237,141,120,1)",
"pointBackgroundColor": "rgba(237,141,120,1)"
},
{
"label": "Title test 3",
"data": [30, 20, 60],
"xAxisID": "bar-x-axis-3",
"barThickness": 14,
"backgroundColor": "rgba(120,199,212,1)",
"borderColor": "rgba(120,199,212,1)",
"pointBackgroundColor": "rgba(120,199,212,1)"
}
]
},
"plugins": [{
"afterUpdate": function(chart) {
let datasets = chart.config.data.datasets;
for (let iDs = 1; iDs < datasets.length; iDs++) {
let meta = chart.getDatasetMeta(iDs);
for (var i = 0; i < meta.data.length; i++) {
let model = meta.data[i]._model;
model.x += iDs * offset;
model.controlPointNextX += iDs * offset;
model.controlPointPreviousX += iDs * offset;
}
}
}
}],
"curvature": 0.2,
"options": {
"legend": {
"display": true,
"position": "bottom"
},
"scales": {
"yAxes": [{
"ticks": {
"beginAtZero": true,
"stepSize": 25
}
}],
"xAxes": [{
"id": "bar-x-axis-3",
"display": false
},
{
"id": "bar-x-axis-2",
"display": false,
"offset": true
},
{
"id": "bar-x-axis-1",
"display": false,
"offset": true
}
]
},
"barRoundness": 0.5
}
});
new Chart('graph_2', {
"type": "bar",
"data": {
"labels": ["2020-06-01", "2020-07-01", "2020-08-01", "2020-09-01", "2020-10-01"],
"datasets": [{
"label": "Stage 1",
"data": [30, 75, 60, 90],
"xAxisID": "bar-x-axis-1",
"barThickness": 14,
"backgroundColor": "rgba(241,213,157,1)",
"borderColor": "rgba(241,213,157,1)",
"pointBackgroundColor": "rgba(241,213,157,1)"
},
{
"label": "Stage 2",
"data": [40, 66, 60, 90],
"xAxisID": "bar-x-axis-2",
"barThickness": 14,
"backgroundColor": "rgba(237,141,120,1)",
"borderColor": "rgba(237,141,120,1)",
"pointBackgroundColor": "rgba(237,141,120,1)"
},
{
"label": "Stage 3",
"data": [50, 45, 60, 90],
"xAxisID": "bar-x-axis-3",
"barThickness": 14,
"backgroundColor": "rgba(120,199,212,1)",
"borderColor": "rgba(120,199,212,1)",
"pointBackgroundColor": "rgba(120,199,212,1)"
},
{
"label": "Stage 4",
"data": [60, 35, 60, 90],
"xAxisID": "bar-x-axis-4",
"barThickness": 14,
"backgroundColor": "rgba(5,114,159,1)",
"borderColor": "rgba(5,114,159,1)",
"pointBackgroundColor": "rgba(5,114,159,1)"
},
{
"label": "Stage 5",
"data": [70, 25, 60, 90],
"xAxisID": "bar-x-axis-5",
"barThickness": 14,
"backgroundColor": "rgba(2,41,112,1)",
"borderColor": "rgba(2,41,112,1)",
"pointBackgroundColor": "rgba(2,41,112,1)"
}
]
},
"plugins": [{
"afterUpdate": function(chart) {
let datasets = chart.config.data.datasets;
for (let iDs = 1; iDs < datasets.length; iDs++) {
let meta = chart.getDatasetMeta(iDs);
for (var i = 0; i < meta.data.length; i++) {
let model = meta.data[i]._model;
model.x += iDs * offset;
model.controlPointNextX += iDs * offset;
model.controlPointPreviousX += iDs * offset;
}
}
}
}],
"curvature": 0.2,
"options": {
"legend": {
"display": true,
"position": "bottom"
},
"scales": {
"yAxes": [{
"ticks": {
"beginAtZero": true,
"stepSize": 25
}
}],
"xAxes": [{
"id": "bar-x-axis-5",
"display": false,
},
{
"id": "bar-x-axis-4",
"display": false,
"offset": true
},
{
"id": "bar-x-axis-3",
"display": false,
"offset": true
},
{
"id": "bar-x-axis-2",
"display": false,
"offset": true
},
{
"id": "bar-x-axis-1",
"display": false,
"offset": true
}
]
},
"barRoundness": 0.5
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="graph_1"></canvas>
<canvas id="graph_2"></canvas>
Please note that when all charts contained on a page use the same plugin function, you don't have to repeat the code but can simply register it once through
Chart.pluginService.register
as shown in this answer .
uminder
2020-09-23