我有一个SVG地图和一个轮询数据更改的间隔,并相应地更新地图上的颜色。除非我使用过渡淡入新颜色,否则一切正常。然后标签慢慢地消耗掉越来越多的记忆,直到它崩溃。
我做了一个显示相同行为的简化示例:
var size = 500;
var num = 25;
var boxSize = size / num;
function color(d) {
return '#' + Math.random().toString(16).slice(2,8);
}
var svg = d3.select('body')
.append("svg")
.attr("width", size)
.attr("height", size);
var squares = svg.selectAll(".square")
.data(d3.range(num * num))
.enter().append("rect")
.attr("class", "square")
.attr("width", boxSize)
.attr("height", boxSize)
.attr("x", function (d) { return boxSize * (d % num);})
.attr("y", function (d) { return boxSize * Math.floor(d / num); })
.style("fill", color);
function shuffleColors() {
squares.interrupt().transition().duration(500).style("fill", color);
timer = setTimeout(shuffleColors, 1000);
}
var timer = setTimeout(shuffleColors, 1000);
我已经在Linux上的Chromium(49)和Firefox(45)中尝试过它。它似乎在前者上爆炸得更快,但这两者都是一个问题。它既没有出现在内存分析器中,也出现在:内存显示标签增长。
我从文档中理解的是,向选择添加转换会替换任何先前的转换名称(包括空名称),但我的假设是为实现转换而创建的函数实际上并没有获得抛出。但我还没有设法让他们确认或解决这个问题。
所以,这是一个由两部分组成的问题:
编辑:
d3_selectionPrototype.transition
每次都会使用递增ID创建一个新的d3_transition
,但如果旧版本被垃圾收集,那就没问题了。而且我仍然不能指出它是否或为何被保留。答案 0 :(得分:1)
我相当肯定它必须在这里做这件事:
function shuffleColors() {
squares.interrupt().transition().duration(500).style("fill", color);
timer = setTimeout(shuffleColors, 1000);
}
var timer = setTimeout(shuffleColors, 1000);
每次调用函数shuffleColors()
时,它都会再次调用自身,实质上是创建一个没有基本情况的递归循环。它没有立即爆炸的原因是它延迟了1000ms的函数的每次调用,但是,我认为squares.interrupt().transition().duration(500).style("fill", color);
完成的时间要比调用setTimeout()
需要更长的时间。 。因此,即使你每隔1000毫秒调用它,它也可能以某种方式堆叠,因为某些颜色变化可能需要更多时间来处理。
虽然技术上不应该这样做,但了解异步JavaScript是如何做的,它可能有一个角色。我建议改为执行此操作并报告结果:
function shuffleColors() {
squares.interrupt().transition().duration(500).style("fill", color);
}
var timer = setInterval(shuffleColors, 1000);
如果您需要,也可以随时致电clearInterval(timer)
。 setInterval()
的创建原因是您实施setTimeout()
。
编辑:这可能无法完全正常工作,因为您可能仍然需要等待颜色更改完成,但是,它至少会是一种更清洁的方法。您可以实现某种wait()
函数来等待颜色更改完成。
虽然矢量(SVG)图像很轻,但与解码JPEG图像相比,它需要不断改变颜色或其他类似的处理量。
如果您将原始图像尺寸设置得更小,然后将其扩展到分辨率,则可能会找到更好的效果。你可以制作一个100x100的画布SVG并将其扩展到2000x2000或其他东西,所以它不必绘制如此大的图像。