O'Reilly logo

JavaScript Cookbook by Shelley Powers

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

15.3. Creating a Dynamic Line Chart in Canvas

Problem

You want to display a line chart in your web page, but the data changes over time, and you want to dynamically update it.

Solution

Use the canvas element and the path method to create the chart. When the data changes, update the chart:

 var array1 = [[100,100], [150, 50], [200,185],
               [250, 185], [300,250], [350,100], [400,250],
               [450, 100], [500,20], [550,80], [600, 120]];

 var imgcanvas = document.getElementById("imgcanvas");

 if (imgcanvas.getContext) {
   var ctx = imgcanvas.getContext('2d');


   // rect one
   ctx.strokeRect(0,0,600,300);

   // line path
   ctx.beginPath();
   ctx.moveTo(0,100);
   for (var i = 0; i < array1.length; i++) {
     ctx.lineTo(array1[i][0], array1[i][1]);
   }
   ctx.stroke();
}

Discussion

Canvas paths are the way to create arbitrary shapes in Canvas. After getting the canvas context, ctx, the path is begun with a call to ctx.beginPath(). This marks the beginning of the path, and calling the method again starts a new path. The next line of code is ctx.moveTo, which moves the drawing “pen” to a beginning location without drawing. From that point, several calls are made to lineTo, using an array of paired values representing the x,y location for each line endpoint.

After all of the line points have been defined, the path is drawn. We’re not creating a closed path, so I’m not using ctx.closePath(), which would attempt to draw a line from the ending point to the beginning point. Instead, I’m drawing the line given the points that have been defined, using ctx.stroke().

This creates a single path. To dynamically update the chart, you can incorporate timers, and either replace the path (by creating an entirely new context, which would erase the old), or add the new line chart to the same chart. Example 15-2 shows a web page that creates the line in the solution and then creates two others, each drawn after a short period of time using timers. The colors for the stroke path are changed between lines.

Example 15-2. Using timers to dynamically update a line chart

<!DOCTYPE html>
<head>
<title>Canvas Chart</title>
<meta charset="utf-8" />
<!--[if IE]><script src="excanvas.js"></script><![endif]-->

<script type="text/javascript">

window.onload=function() {

 var array1 = [[100,100], [150, 50], [200,185],
               [250, 185], [300,250], [350,100], [400,250],
               [450, 100], [500,20], [550,80], [600, 120]];

 var array2 = [[100,100], [150, 150], [200,135],
               [250, 285], [300,150], [350,150], [400,280],
               [450, 100], [500,120], [550,80], [600, 190]];

 var array3 = [[100,200], [150, 100], [200,35],
               [250, 185], [300,10], [350,15], [400,80],
               [450, 100], [500,120], [550,80], [600, 120]];

 var imgcanvas = document.getElementById("imgcanvas");

 if (imgcanvas.getContext) {
   var ctx = imgcanvas.getContext('2d');


   // rectangle wrapping line chart
   ctx.strokeRect(0,0,600,300);

   // first line
   ctx.beginPath();
   ctx.moveTo(0,100);
   for (var i = 0; i < array1.length; i++) {
     ctx.lineTo(array1[i][0], array1[i][1]);
   }
   ctx.stroke();

   setTimeout(function() {

       ctx.strokeStyle="#ff0000";

       // second line
       ctx.beginPath();
       ctx.moveTo(0,100);
       for (var i = 0; i < array2.length; i++) {
         ctx.lineTo(array2[i][0], array2[i][1]);
       }

       ctx.stroke();

       // second time out
       setTimeout(function() {
          ctx.strokeStyle="#00ff00";
          ctx.fillStyle="rgba(255,255,0,.1)";

          // third line
          ctx.beginPath();
          ctx.moveTo(0,100);
          for (var i = 0; i < array3.length; i++) {
             ctx.lineTo(array3[i][0],array3[i][1]);
          }

          ctx.stroke();
       }, 5000);
   }, 5000);

 }
}

</script>
</head>
<body>
<canvas id="imgcanvas" width="650" height="350">
<p>Include an image that has a static representation of the chart</p>
</canvas>
</body>

Figure 15-2 shows the line chart after all three lines have been drawn. Notice that the web page makes use of the explorercanvas library, excanvas.js, to ensure the chart also draws in Internet Explorer.

Canvas drawing from using the path method

Figure 15-2. Canvas drawing from Example 15-2 using the path method

There are other path methods: arc, to draw curves, and quadraticCurveTo and bezierCurveTo, to draw quadratic and bezier curves. All of these methods can be combined in one path to create complex images.

See Also

See Recipe 15.2 for how to incorporate explorercanvas into your applications. A good Canvas tutorial can be found at Mozilla.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required