javascript - 使用 JavaScript 更新画布时如何避免分离的 HTMLCanvasElements?
问题描述
所以我的问题是,当我使用 Chart.js 库创建的折线图循环更新我的 HTML 中的画布元素时,我得到了一堆分离的 HTMLCanvasElements。当我修复代码中的一些内存泄漏时,我注意到了这一点,这些泄漏导致我的网页崩溃(chrome 给出了“aw snap”错误页面)。我能够修复大部分内存泄漏,但这仍然困扰着我,我很无助,因为不知道为什么会发生这种情况..
我的 HTML 代码中有画布元素,如下所示:
<div class="kuvaaja"><canvas id="etaisyyskuvaaja"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja2"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja3"></canvas></div>
<div class="kuvaaja"><canvas id="etaisyyskuvaaja4"></canvas></div>
这就是我在 JavaScript 中获取这些元素的方式(在 window.onload 函数中):
pohjacanvas = document.getElementById("etaisyyskuvaaja");
pohjacanvas2 = document.getElementById("etaisyyskuvaaja2");
pohjacanvas3 = document.getElementById("etaisyyskuvaaja3");
pohjacanvas4 = document.getElementById("etaisyyskuvaaja4");
然后我开始循环更新这些画布(也在window.onload内):
paivitysvali = setInterval(haeetaisyysmittaukset, 1000);
painepaivitys = setInterval(haepainemittaukset, 1000);
在这些函数中,我首先像这样从数据库中获取数据(haepainemittaukset() 类似于这个,只是获取了不同的数据):
function haeetaisyysmittaukset() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
etaisyys = [];
ajat = [];
var mittaukset = JSON.parse(xmlhttp.response);
for (var i = 0; i < mittaukset.length; i++) {
etaisyys.push(mittaukset[i]["etaisyys"]);
ajat.push(mittaukset[i]["timestamp"]);
}
if (paivitysbitti == 1) {
etaisyys.reverse();
ajat.reverse();
luokuvaaja2(pohjacanvas, etaisyys, ajat);
luokuvaaja2(pohjacanvas4, etaisyys, ajat);
}
}
}
xmlhttp.open("POST", "haeetaisyysmittaukset.php", true);
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("limit=" + mittausmaara);
}
在全局数组(etaisyys[] 和 ajat[])中获取数据后,我使用要更新的画布和这些数据数组调用 luokuvaaja2() 函数。这是问题开始的阶段,至少我认为是这样。这是我尝试实现画布更新的方式:
function luokuvaaja2(pohja, data, ajat) {
pohja.height = 400;
pohja.width = 700;
myChart = new Chart(pohja, {
type: 'line',
data: {
labels: ajat,
datasets: [{
data: data,
label: "Etaisyys",
borderColor: "blue",
fill: false
}
]
},
options: {
animation: {
duration: 0, // general animation time
},
hover: {
animationDuration: 0, // duration of animations when hovering an item
},
title: {
display: true,
text: 'Etaisyysmittaus'
},
scales: {
yAxes: [{
ticks: {
min: 0,
max: 6000
}
}]
}
}
});
}
所以我认为我在这里做的是设置画布的高度和宽度,然后我在旧的画布(或者我是?)的同一画布中创建新图表。但是看起来有问题,我当前的代码正在创建一堆分离的画布元素,但我不明白为什么以及在哪里发生这种情况?所以现在我的页面的内存占用在每个周期(画布更新)后都会慢慢增加。
这里也是内存分布的快照: 内存分布 在这个内存分布中,有许多独立的画布元素都指向这些画布(pohjacanvas、pohjacanvas2、pohjacanvas3、pohjacanvas4)。
解决方案
您应该跟踪(例如,在数组中)之前创建的图表,然后当从服务器获取新数据时,您需要检索图表以更新、更新其数据和/或选项,然后调用
chart.update();
刷新图表。在这种情况下,您不会在每次更新时创建新图表。您可以在Chart.js 文档中找到更多详细信息。
推荐阅读
- http - Jmeter:如何为每个断言创建单独的报告?
- azure - 是否可以在 Azure Pipelines 中将“文件夹”视图设为默认?
- websocket - 在 Tomcat 上运行 cometd 的 websocket 传输的“未知 Bayeux 传输”
- git - Git 多个存储库(第三个存储库的本地更改的远程副本)
- c++ - 无法打开输入文件 Poco.obj 或 Find PocoFoundationd.lib
- elasticsearch - 订单条款聚合桶按热门点击子聚合
- java - 是否可以在 @RequestScope bean 中创建一个新线程
- keras - Exception when loading a Keras Model in Java with deeplearning4j
- python - 如何修复异常处理中的打印语句{except block}?
- r - 合并csv文件时如何有效处理列名不匹配?