You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Hi,

    I started work on a library to make graphing a bit easier. The code below runs on a Pixl.js, or any other device as long as you create a Graphics instance called g.

    Currently it does:

    • Line graphs
    • Auto-scaling for Y, with a 'grid marks'
    • Y axis labels

    What kind of functionality is needed to you think? Bearing in mind the display is quite low-res...

    Thoughts so far:

    • Title
    • Bar graph
    • another module to handle keeping track of a 'history' array

      var history = new Float32Array(64);
      
      /*
      
      Graph the given array of data.
      
      options = {
      miny // optional - minimum y value
      maxy // optional - maximum y value
      gridy // optional - grid value for y. Also enables labels
      x // optional - pixel x offset on screen
      y // optional - pixel y offset on screen
      width // optional - pixel width on screen
      height // optional - pixel height on screen
      };
      
      */
      function graph(g, data, options) {
      options = options||{};
      var miny = (options.miny!==undefined) ? options.miny :
      options.miny=data.reduce((a,b)=>Math.min­(a,b), data[0]);
      var maxy = (options.maxy!==undefined) ? options.maxy :
      options.maxy=data.reduce((a,b)=>Math.max­(a,b), data[0]);
      if (options.gridy) {
      var gy = options.gridy;
      miny = gy*Math.floor(miny/gy);
      maxy = gy*Math.ceil(maxy/gy);
      }
      var ox = options.x||0;
      var oy = options.y||0;
      var ow = options.width||g.getWidth();
      var oh = options.height||g.getHeight();
      // draw axes
      if (options.axes) {
      var o = 6; // size of axes
      ox += o;
      ow -= o;
      oh -= o;
      g.drawLine(ox,oy,ox,oy+oh/*+o*/);
      g.drawLine(ox/*-o*/,oy+oh,ox+ow,oy+oh);
      }  
      var dy = maxy-miny;
      function getx(x) { return ox+ow*x/data.length; }
      function gety(y) { return oy+oh*(maxy-y)/dy; }
      // Draw grid pips and labels
      if (options.gridy) {
      g.setFontAlign(0,0,1); // rotate 90
      for (var i=miny;i<=maxy;i+=options.gridy) {
        var y = gety(i);
        var t = i;
        g.drawLine(ox-1, y, ox+1, y);
        if (y>g.stringWidth(t)/2) // does it fit?
          g.drawString(t, ox-5, y+2);
      }    
      }
      // Draw actual data
      g.moveTo(getx(0), gety(data[0]));
      for (var i=1;i<data.length;i++) {
      g.lineTo(getx(i), gety(data[i]));
      }
      // back to defaults
      g.setFontAlign(0,0,0); 
      }
      
      function onTimer() {
      // quickly move all elements of history back one
      history.set(new Float32Array(history.buffer,4));
      // add new history element at the end
      var temp = E.getTemperature();
      history[history.length-1] = temp;
      // 
      g.clear();
      graph(g, history, {
      miny: 0, 
      axes : true,
      gridy : 10
      });
      // Update the screen
      g.flip();
      }
      
      // Update temperature every 2 seconds
      setInterval(onTimer,2000);
      // Update temperature immediately
      onTimer();
      

    1 Attachment

    • graph.png
About

Avatar for Gordon @Gordon started