I'm facing an issue with D3.js. When rendering data to canvas the tab freezes when it being inactive. It easily become noticeable after several minutes of tab being in a background.
I've created an example JSFiddle to reproduce the issue, it can be easily be done on local environment as well, source code follows.
(() => { // 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>
I want the rendering be seamless. What can be done in this case? I believe it may be something to do with d3.timer
function, but may be wrong.
0 comments:
Post a Comment