Building a very large number of points on an HTML5 canvas using JavaScript

I am trying to draw a huge (60k) number (x, y) of points on an HTML5 canvas and simulate streaming data from D3.js in Chrome and Firefox and find that the browser freezes and crashes after about 10 seconds.

I generate a data set with random values ​​as follows:

var data = d3.range(60000).map(function() { return Math.random() * 500; });

Would this help partition the data generation? I feel this may be due to an attempt to save such a large dataset at a time, as I showed.

Is there any way to prevent this? For example, drawing and saving small sections as tiled images?

Added code:

var margin = {top: 20, right: 20, bottom: 20, left: 40},
    w = 100 - margin.left - margin.right,
    h = 100 - margin.top - margin.bottom;

    var canvas = d3.select("canvas")
      .node();

    var context = canvas.getContext('2d');

    var scale = d3.scale.linear()
    . range([0,w])
    .domain([0,h]);


    data = d3.range(60000).map(function(){return Math.random()*500});
    data.forEach(function(d,i) {
      context.strokeStyle="red";
      context.lineWidth="1";
      context.lineTo(scale(++k),scale(d));
      context.stroke();
    });
+4
source share
2 answers

, , .

inline.

var margin = {top: 20, right: 20, bottom: 20, left: 40},
    w = 100 - margin.left - margin.right,
    h = 100 - margin.top - margin.bottom;

    var canvas = d3.select("canvas")
      .node();

    var context = canvas.getContext('2d');

 var data = d3.range(11).map(function(){return Math.random()*10})
    var x = d3.scale.linear().domain([0, 10]).range([0, 700]);
    var y = d3.scale.linear().domain([0, 10]).range([10, 290]);
    var line = d3.svg.line()
      .interpolate("cardinal")
      .x(function(d,i) {console.log(x(i));return x(i);})
      .y(function(d) {return y(d);})
    //making a dummy SVG
    var path = d3.select("body").append("svg").append("path")
      .attr("d", line(data))
      .attr("stroke", "steelblue")
      .attr("stroke-width", "2")
      .attr("fill", "none").remove();
   d3.select("body svg").remove();

    //going from 0 to the paths total length and storing all the points
    var points = [];
    for(var i =0; i < path.node().getTotalLength(); i++){
        points.push(path.node().getPointAtLength(i));//store point @ that length
    }
    var id = window.setInterval(function(){
      console.log("Doing")
      var point = points.shift();//take each point
      context.strokeStyle="red";
      context.lineWidth="1";
      context.lineTo(point.x,point.y);
      context.stroke();
      if(points.length <= 0){
        console.log("Finished")
        window.clearInterval(id);//clear the interval since the drawing is complete
      }
    }, 10)
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!DOCTYPE html>
<html>

  <head>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.10/d3.js"></script>
    
  </head>

  <body>
    <canvas id="myCanvas" width="500" height="500" style="border:1px solid #000000;">
</canvas>
  <script src="script.js"></script>
  </body>

</html>

Plunker.

+1

:

data.forEach(function(d,i) {
      context.strokeStyle="red";
      context.lineWidth="1";
      context.lineTo(scale(++k),scale(d));
      context.stroke();//this should be out of the for loop you should be doing it once not everytime
    });

- :

data.forEach(function(d,i) {
  context.strokeStyle="red";
  context.lineWidth="1";
  var j = scale(d);
  var m = scale(d++);
  context.lineTo(j,m);
});
context.stroke();

, !

+1

Source: https://habr.com/ru/post/1618971/


All Articles