我正面临D3.js的问题。将数据渲染到画布时,选项卡在处于非活动状态时会冻结。在几分钟的标签背景下,它很容易变得明显。
我创建了example JSFiddle来重现问题,也可以在本地环境中轻松完成,源代码如下。
(() => {
// data container script
$(() => {
let $dataContainer = $('.data');
setInterval(() => {
$dataContainer.empty();
let numbers = [];
for (let i = 0; i < 10; i++) {
let randNumber = Math.floor(Math.random() * 100);
numbers.push(randNumber);
$dataContainer.append(`<p>${randNumber}</p>`);
}
$(document).trigger('data:updated', [numbers])
}, 1000);
});
// actual canvas render
$(() => {
// boring stuff
let base = d3.select(".viz");
let chart = base.append("canvas")
.attr("width", 400)
.attr("height", 300);
let context = chart.node().getContext("2d");
let detachedContainer = document.createElement("custom");
let dataContainer = d3.select(detachedContainer);
// d3 stuff and data binding
let drawCustom = (data) => {
let scale = d3.scale.linear()
.domain(d3.extent(data))
.range([10, 280]);
let dataBinding = dataContainer.selectAll("custom.rect")
.data(data, (d) => { return d; });
dataBinding.enter()
.append("custom")
.classed("rect", true)
.attr("size", 0)
.attr("x", 11)
.attr("y", scale)
.transition()
.duration(500)
.attr("size", 8)
.attr("fillStyle", "red");
dataBinding.exit()
.transition()
.duration(500)
.attr("size", 0)
.remove()
}
let drawCanvas = () => {
// clear canvas
context.fillStyle = "#fff";
context.rect(0,0,chart.attr("width"),chart.attr("height"));
context.fill();
let elements = dataContainer.selectAll("custom.rect");
elements.each(function(d) {
let node = d3.select(this);
context.beginPath();
context.fillStyle = node.attr("fillStyle");
context.rect(node.attr("x"), node.attr("y"), node.attr("size"), node.attr("size"));
context.fill();
context.closePath();
});
}
$(document).on('data:updated', (e, numbers) => {
drawCustom(numbers);
});
d3.timer(drawCanvas);
});
})();
.data {
outline: 1px solid #777777;
min-width: 10px;
height: 300px;
background-color: rgb(238, 238, 238);
display: inline-block;
vertical-align: top;
}
p {
margin: 0.7em;
}
.viz {
display: inline-block;
}
canvas {
outline: 1px solid #777777;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="data"></div>
<div class="viz"></div>
我希望渲染无缝。在这种情况下可以做些什么?我认为它可能与d3.timer
函数有关,但可能是错误的。