Javascript 多个图表相互叠加渲染
我通过AJAX调用加载了一些图表数据,并使用一个支持工具提示的修改过的图标显示这些数据。它在第一次调用时运行良好,但当我通过更改日期范围进行后续调用时,它会在旧图表数据的基础上绘制新的图表数据。我已将图表刷新代码放入“调整窗口大小”事件中,以便它能够响应。然而,这实际上可能是导致问题的原因。这是我的密码:Javascript 多个图表相互叠加渲染,javascript,knockout.js,knockout-validation,durandal-2.0,chart.js,Javascript,Knockout.js,Knockout Validation,Durandal 2.0,Chart.js,我通过AJAX调用加载了一些图表数据,并使用一个支持工具提示的修改过的图标显示这些数据。它在第一次调用时运行良好,但当我通过更改日期范围进行后续调用时,它会在旧图表数据的基础上绘制新的图表数据。我已将图表刷新代码放入“调整窗口大小”事件中,以便它能够响应。然而,这实际上可能是导致问题的原因。这是我的密码: var BreakDowns = [ 'Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly' ]; v
var BreakDowns = [
'Daily',
'Weekly',
'Monthly',
'Quarterly',
'Yearly'
];
var BreakDown = ko.observable(BreakDowns[0]);
BreakDown.subscribe(function (newValue) {
switch (newValue) {
case 'Daily':
EndDate(StartDate());
break;
case 'Weekly':
EndDate(moment(StartDate()).add('d', 7).format('MM/DD/YYYY'));
break;
case 'Monthly':
EndDate(moment(StartDate()).add('M', 1).format('MM/DD/YYYY'));
break;
case 'Quarterly':
EndDate(moment(StartDate()).add('M', 3).format('MM/DD/YYYY'));
break;
case 'Yearly':
EndDate(moment(StartDate()).add('y', 1).format('MM/DD/YYYY'));
break;
}
GetChartData();
});
var date = new Date();
var StartDate = ko.observable(moment(date).format('MM/DD/YYYY'));
var EndDate = ko.observable(moment(date).format('MM/DD/YYYY'));
var Form = ko.validatedObservable({
StartDate: StartDate.extend({ isDate: true }),
EndDate: EndDate.extend({ isDate: true })
});
StartDate.subscribe(function (newValue) {
GetChartData();
});
EndDate.subscribe(function (newValue) {
GetChartData();
});
var chart = {};
var GetChartData = function () {
if (Form.isValid()) {
$.ajax({
url: serviceUri + 'api/Document/ChartData/?breakdown=' + BreakDown().toLowerCase() + '&startDate=' + StartDate() + '&endDate=' + EndDate(),
method: 'GET',
dataType: 'json',
success: function (d) {
var chartData = {
labels: d.AxisLabels,
datasets: [
{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: d.DataSets[0]
}
]
};
var max = Math.max.apply(Math, d.DataSets[0]);
var steps = 10;
var c = $('#summary');
var ctx = c.get(0).getContext("2d");
var container = c.parent();
$(window).resize(respondCanvas);
function respondCanvas() {
var $container = $(container);
if ($container.width() >= 900)
c.attr('width', $container.width());
else
c.attr('width', 900);
if ($container.height() >= 400)
c.attr('height', $container.height());
else
c.attr('height', 400);
ctx.width = ctx.width;
//Call a function to redraw other content (texts, images etc)
chart = new Chart(ctx).Bar(chartData, {
scaleOverride: true,
scaleSteps: steps,
scaleStepWidth: Math.ceil(max / steps),
scaleStartValue: 0,
annotateDisplay: true
});
}
respondCanvas();
}
});
}
}
下面是生成的图表的图像:
如何使Chart.js不绘制以前的数据并绘制新图表?在移动$(窗口)后。从我的AJAX成功回调中调整大小(respondCanvas)
,下面是一个简化版本的我所拥有的正在工作的功能:
var chartData = {};
var max = 0;
var steps = 10;
function respondCanvas() {
var c = $('#summary');
var ctx = c.get(0).getContext("2d");
var container = c.parent();
var $container = $(container);
c.attr('width', $container.width()); //max width
c.attr('height', $container.height()); //max height
//Call a function to redraw other content (texts, images etc)
var chart = new Chart(ctx).Bar(chartData, {
scaleOverride: true,
scaleSteps: steps,
scaleStepWidth: Math.ceil(max / steps),
scaleStartValue: 0,
annotateDisplay: true
});
}
var GetChartData = function () {
$.ajax({
url: serviceUri,
method: 'GET',
dataType: 'json',
success: function (d) {
chartData = {
labels: d.AxisLabels,
datasets: [
{
fillColor: "rgba(220,220,220,0.5)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
data: d.DataSets[0]
}
]
};
max = Math.max.apply(Math, d.DataSets[0]);
steps = 10;
respondCanvas();
}
});
};
$(document).ready(function() {
$(window).resize(respondCanvas);
GetChartData();
});
注意,如果要在更新之间插入一个小延迟,可以使用超时:
$(document).ready(function() {
$(window).resize(setTimeout(respondCanvas, 500));
GetChartData();
});
您需要移动
$(窗口)。调整大小(respondCanvas)代码>在ajax成功回调之外。使用当前方法,您将多次对resize事件进行细分,这可能会导致多重图表呈现…ctx.width=ctx.width
在清除画布时似乎不是100%可靠(请参阅上的注释)。尝试使用ctx.clearRect(0,0,ctx.width,ctx.height)
代替。更正,最后一条注释应该是:尝试使用ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height)
代替。没有一个答案对我有效,所以我删除了元素,并使用document.createElement('canvas')动态地重新创建它们
并重新创建上下文和图形实例,然后在新画布上重新绘制图表并修复我的问题-清除逻辑从未起作用(chart.js api的版本为1,因此这可能是我的问题)