Ответ 1
При подходе, который вы предпринимаете (например, при создании нового объекта диаграммы каждый раз, когда изменяется диапазон дат), вы должны сначала уничтожить предыдущую диаграмму, а затем создать новую.
Для этого вы можете использовать метод прототипа .destroy()
. Вот что говорит API.
Используйте это, чтобы уничтожить созданные экземпляры диаграмм. Это очистит любые ссылки, хранящиеся в объекте диаграммы в Chart.js, а также любые связанные с ними прослушиватели событий, прикрепленные Chart.js. Это нужно вызвать до того, как холст будет повторно использован для новой диаграммы.
Поэтому ваш код будет выглядеть примерно так (обратите внимание, что мы уничтожаем и воссоздаем).
// define a variable to store the chart instance (this must be outside of your function)
var myChart;
function loadFTPRChart(startdate, enddate) {
var BCData = {
labels: [],
datasets: [{
label: "Pass %",
backgroundColor: "#536A7F",
data: [],
stack: 1
}, {
label: "Fail %",
backgroundColor: "#e6e6e6",
data: [],
stack: 1
}, {
label: "Auto %",
backgroundColor: "#286090",
data: [],
stack: 2
}, {
label: "Manual %",
backgroundColor: "#f0f0f0",
data: [],
stack: 2
}]
};
$.getJSON("content/FTPR_AM_Graph_ajax.php", {
startdate: startdate,
enddate: enddate,
location: "M"
})
.done(function(data) {
console.log("data", data);
$.each(data.aaData, function(key, val) {
if (val == "") {
return true
}
BCData.labels.push("Coater " + val[0]);
BCData.datasets[0].data.push(parseFloat(val[2]));
BCData.datasets[1].data.push(parseFloat(100 - val[2]));
BCData.datasets[2].data.push(parseFloat(val[1]));
BCData.datasets[3].data.push(parseFloat(100 - val[1]));
});
var option = {
responsive: true,
};
console.log("BCData", BCData);
// if the chart is not undefined (e.g. it has been created)
// then destory the old one so we can create a new one later
if (myChart) {
myChart.destroy();
}
var ctx = document.getElementById("mybarChart2").getContext("2d");
myChart = new Chart(ctx, {
type: 'groupableBar',
data: BCData,
options: {
scales: {
yAxes: [{
ticks: {
max: 100,
},
stacked: true,
}]
}
}
});
});
}
С учетом сказанного это дорого разрушает/создает снова и снова, и на самом деле это даже не нужно. Существует еще один метод прототипа, называемый .update()
который вы можете использовать, чтобы просто перерисовать диаграмму, если вы изменили ее на базовые данные или объекты метки.
Вот пример jsfiddle, показывающий пример изменения базовых данных и меток, а затем повторного рендеринга диаграммы. Я бы очень рекомендовал, чтобы вы использовали этот подход.
Вот как будет выглядеть ваш код с таким лучшим подходом.
// define a variable to store the chart instance (this must be outside of your function)
var myChart;
function loadFTPRChart(startdate, enddate) {
var BCData = {
labels: [],
datasets: [{
label: "Pass %",
backgroundColor: "#536A7F",
data: [],
stack: 1
}, {
label: "Fail %",
backgroundColor: "#e6e6e6",
data: [],
stack: 1
}, {
label: "Auto %",
backgroundColor: "#286090",
data: [],
stack: 2
}, {
label: "Manual %",
backgroundColor: "#f0f0f0",
data: [],
stack: 2
}]
};
$.getJSON("content/FTPR_AM_Graph_ajax.php", {
startdate: startdate,
enddate: enddate,
location: "M"
})
.done(function(data) {
console.log("data", data);
$.each(data.aaData, function(key, val) {
if (val == "") {
return true
}
BCData.labels.push("Coater " + val[0]);
BCData.datasets[0].data.push(parseFloat(val[2]));
BCData.datasets[1].data.push(parseFloat(100 - val[2]));
BCData.datasets[2].data.push(parseFloat(val[1]));
BCData.datasets[3].data.push(parseFloat(100 - val[1]));
});
var option = {
responsive: true,
};
console.log("BCData", BCData);
// if the chart is not undefined (e.g. it has been created)
// then just update the underlying labels and data for each
// dataset and re-render the chart
if (myChart) {
myChart.data.labels = BCData.labels;
myChart.data.datasets[0].data = BCData.datasets[0].data;
myChart.data.datasets[1].data = BCData.datasets[1].data;
myChart.data.datasets[2].data = BCData.datasets[2].data;
myChart.data.datasets[3].data = BCData.datasets[3].data;
myChart.update();
} else {
// otherwise, this is the first time we are loading so create the chart
var ctx = document.getElementById("mybarChart2").getContext("2d");
myChart = new Chart(ctx, {
type: 'groupableBar',
data: BCData,
options: {
scales: {
yAxes: [{
ticks: {
max: 100,
},
stacked: true,
}]
}
}
});
}
});
}