Wednesday 5 March 2014

JavaScript: simple line graph on canvas element

Simple line graph demo code.

The underlying data is an array of objects with x and y properties of type Number. Change the data and the graph will update when focus is lost on the text area.

Script listing

    <script type="text/javascript">
    (function() {
      var maxMin = function(data, prop) {
        var min, max;
        for (i = 0; i < data.length; i++) {
          if (min !== undefined) {
            min = data[i][prop] < min ? data[i][prop] : min;
            max = data[i][prop] > max ? data[i][prop] : max;
          } else {
            min = data[i][prop];
            max = data[i][prop];
          }
        }
        return {
          min : min,
          max : max,
          range : max - min
        };
      };
      
      var update = function() {
        var data = eval(document.getElementById("graph_data").value.trim());

        var canvas = document.getElementById("graph_canvas");
        if (typeof canvas.getContext !== "function") {
          document.getElementById("graph_err").innerHTML = "CANVAS NOT SUPPORTED";
        }
        canvas.width = canvas.width;
        var context = canvas.getContext("2d");
        context.fillStyle = "#DDD";
        context.fillRect(0, 0, canvas.width, canvas.height);

        var xRng = maxMin(data, "x");
        var yRng = maxMin(data, "y");

        var last;
        var BORDER = 10;
        var xRatio = xRng.range / (canvas.width - 2 * BORDER)
        var yRatio = yRng.range / (canvas.height - 2 * BORDER);
        for (i = 0; i < data.length; i++) {
          var d = data[i];
          var x = (d.x - xRng.min) / xRatio;
          var y = (d.y - yRng.min) / yRatio;
          if (last) {
            context.moveTo(x + BORDER, canvas.height - y - BORDER);
            context.lineTo(last.x + BORDER, canvas.height - last.y - BORDER);
          }
          last = {
            x : x,
            y : y
          };
        }
        context.strokeStyle = "#000";
        context.stroke();
      };
      update();
      document.getElementById("graph_data").onchange = update;
    }())
    </script>

No comments:

Post a Comment

All comments are moderated