Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotting a very large number of points on HTML5 canvas with JavaScript

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

I am generating the data set with random values as follows:

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

Would it help to break generation of data into sections? I feel that this might be caused by trying to store such a large data set at one time as I have shown.

Is there any way that I can prevent this from happening? Such as drawing and saving smaller 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();
    });
like image 345
Bob R Avatar asked Dec 08 '15 00:12

Bob R


1 Answers

Since you are asking a completely different question in the comment section I thought of put it another answer.

Comments and working code 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>

Working code on Plunker.

like image 194
Cyril Cherian Avatar answered Oct 20 '22 01:10

Cyril Cherian