Search code examples
javascripthtmlgraphhtml5-canvas

Ecg graph with html5 canvas


My need is to draw a ECG graph on canvas for socket data per every data iteration.

enter image description here

I tried to look into several graph plugins which use canvas to plot graphs, tried http://www.flotcharts.org/ but didn't succeed.

I Tried to plot graph using below basic html5 canvas drawline with sample data.

var fps = 60;
var n = 1;

drawWave();
    function drawWave() {
        setTimeout(function() {
                requestAnimationFrame(drawWave2);
                ctx.lineWidth = "2";
                ctx.strokeStyle = 'green';
                // Drawing code goes here
                n += 1;
                if (n >= data.length) {
                    n = 1;
                }
                ctx.beginPath();
                ctx.moveTo(n - 1, data[n - 1] * 2);
                ctx.lineTo(n, data[n] * 2);
                ctx.stroke();
                ctx.clearRect(n + 1, 0, 10, canvas.height);
            }, 1000 / fps);
    }

But it is not giving me the exact graph view as attached image. I'm not able to understand how to achieve graph like ecg graph. Please help me to get rid of this problem.


Solution

  • The characteristics with an ECG is that is plots the signal horizontally headed by a blank gap. When the end of the right side is reached is returns to left side and overdraw the existing graph.

    DEMO

    ECG

    Setup

    var ctx = demo.getContext('2d'),
        w = demo.width,
        h = demo.height,
    
        /// plot x and y, old plot x and y, speed and scan bar width
        speed = 3,
        px = 0, opx = 0, 
        py = h * 0.8, opy = py,
        scanBarWidth = 20;
    
    ctx.strokeStyle = '#00bd00';
    ctx.lineWidth = 3;
    
    /// for demo we use mouse as signal input source    
    demo.onmousemove = function(e) {
        var r = demo.getBoundingClientRect();
        py = e.clientY - r.top;
    }
    loop();
    

    The main loop:

    The loop will plot whatever the signal amplitude is at any moment. You can inject a sinus or some other signal or read from an actual sensor over Web socket etc.

    function loop() {
    
        /// move forward at defined speed
        px += speed;
        
        /// clear ahead (scan bar)
        ctx.clearRect(px,0, scanBarWidth, h);
    
        /// draw line from old plot point to new
        ctx.beginPath();
        ctx.moveTo(opx, opy);
        ctx.lineTo(px, py);
        ctx.stroke();
        
        /// update old plot point
        opx = px;
        opy = py;
        
        /// check if edge is reached and reset position
        if (opx > w) {
            px = opx = -speed;
        }
        
        requestAnimationFrame(loop);
    }
    

    To inject a value simply update py (outside loop).