如何使javascript画布绘制更快?

如何使javascript画布绘制更快?,javascript,canvas,Javascript,Canvas,我有以下代码来显示ECG。我使用画布绘制图形背景(每个网格的尺寸为2.5 mm)。稍后,我将从一个数组中获取y坐标(x坐标在程序中计算)。这种方法的问题是绘制整个图形大约需要40秒,因为arrayarray_1中有1250个值。我所能做的就是在循环中进行绘图部分,在这种情况下,页面一加载,整个图形就被绘制出来。但是,我需要在5秒内完成密谋。不多了。不少。我将如何修改代码来实现这一点?请帮忙 <!DOCTYPE html> <html> <head> &

我有以下代码来显示ECG。我使用画布绘制图形背景(每个网格的尺寸为2.5 mm)。稍后,我将从一个数组中获取y坐标(x坐标在程序中计算)。这种方法的问题是绘制整个图形大约需要40秒,因为arrayarray_1中有1250个值。我所能做的就是在循环中进行绘图部分,在这种情况下,页面一加载,整个图形就被绘制出来。但是,我需要在5秒内完成密谋。不多了。不少。我将如何修改代码来实现这一点?请帮忙

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <canvas id="canvas" width="1350" height="1300" style="background-color: white;"></canvas>
    <script type='text/javascript'>

    var canvas = document.getElementById("canvas");
    var ctxt = canvas.getContext("2d");
    var n1 = 1;
    var n1_x=49; //Graph x coordinate starting pixel.
    var n1_y=72;//Graph y coordinate starting pixel.
    var array_1 = []// array from which y coordinates are taken. Has 1250 elements
     var ctx = canvas.getContext("2d");
    var x=0;
    var y=0;
    var Line_position=-1;
    while(x<=1350)//graph width
    {
        ctxt.lineWidth = "0.5";
        Line_position=Line_position+1;
        if(Line_position%5==0)
        {
            ctxt.lineWidth = "1.5";
        }

        ctxt.strokeStyle = "black";
        ctxt.beginPath();
        ctxt.moveTo(x, 0);
        ctxt.lineTo(x, 1300);
        ctxt.stroke();
        x=x+9.43;

    }

    Line_position=-1;
    while(y<=1300)//graph height
    {
        ctxt.lineWidth = "0.5";
        Line_position=Line_position+1;
        if(Line_position%5==0)
        {
            ctxt.lineWidth = "1.5";
        }

        ctxt.strokeStyle = "black";
        ctxt.beginPath();
        ctxt.moveTo(0, y);
        ctxt.lineTo(1350,y);
        ctxt.stroke();
        y=y+9.43;
    }
   drawWave();
        function drawWave()
        {
          requestAnimationFrame(drawWave);
                ctx.lineWidth = "1";
                ctx.strokeStyle = 'blue';
               ctx.beginPath();
                ctx.moveTo(n1_x- 1, n1_y+array_1[n1-1]);//move to the pixel position
                ctx.lineTo(n1_x, n1_y+array_1[n1]);//Draw to the pixel position
                ctx.stroke();
                n1_x=n1_x+0.374;//Incrementing pixel so as to traverse x axis.
                n1++;
 }

    </script>
</body>
</html>

var canvas=document.getElementById(“canvas”);
var ctxt=canvas.getContext(“2d”);
var n1=1;
var n1_x=49//图形x坐标起始像素。
var n1_y=72//图形y坐标起始像素。
var array_1=[]//从中获取y坐标的数组。有1250个元素
var ctx=canvas.getContext(“2d”);
var x=0;
var y=0;
var Line_position=-1;

而(x更新

现在我看到你提供了更多的信息,我得到了你想要的

问题是您需要在时间
t
内绘制固定数量的线段

由于您不知道每帧需要多长时间,因此不能依赖固定的帧速率。另一种方法是只使用当前时间并保存结束时间

获取开始时间,然后每个帧绘制都应绘制到当前时间。由于要绘制的线段在下一次屏幕刷新之前不会显示,因此您获得的时间将落后约16ms,因此需要对此进行调整

我所做的是跟踪平均帧时间,并使用一半的时间来估计何时将显示新的画布更新

这有点迂腐,但也可以展示如何尽可能接近所需的时间。如果你不在乎它有几毫秒,那么只需删除平均帧时间的内容。在一台速度较慢的机器上,你最多只需要30毫秒

var canvas; // canvas
var ctx; 

function getCanvas () {
    // to do 
    // get canvas and context
}
function drawGrid () {
    // to do
    // draw the grid
}
function drawTimedLine(){
    if(canvas === undefined){ // if the canvas not available get it
       getCanvas();
    }
    // clear the canvas is repeating animation
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawGrid();

    var array_1 = ; // your data


    // All stuff needed for timed animation.
    // The frame you render will not be displayed untill the next
    // vertical refresh which is unknown, Assume it is one frame.
    var startDelay = 1000;      // if Needed time in milliseconds to delay start
    var endTime;                // hold the time that the animation has to end
    var lastDataPoint;          // holds the last point drawn to
    var timeToDraw = 5 * 1000;  // how long the animation should last
    var repeatAfter = 1 *1000;  // if you want to repeat the animatoin
    var frameCount = 0;         // count the frames to get average frame time
    var startTime;              //the start time;
    var numberPoints = array_1.length; // number of points;
    var startX = 49;            // line starts at
    var yOffset = 72;           // line Y offset
    var endX = 512;             // line ends at. 
    var width = endX - startX;  // width  
    var xStep = width / numberPoints;   // X step per point
    var pointsPerMS = numberPoints / timeToDraw; // get how many points per ms should be drawn

    // function to draw
    function drawWave() {
        // variable needed
        var averageframeTime, timeLeft, i, currentTime;
        currentTime = new Date().valueOf();     // gets the time in millisecond;
        if (startTime === undefined) {          // Is this the first frame      
            startTime = currentTime;            // save the start time;
            endTime = currentTime + timeToDraw; // workout when the end time is;
            lastDataPoint = 0;                  // set the data position to the start;
            averageframeTime = 0;               // no frames counted so frame time is zero          
        } else {
            frameCount += 1;                    // count the frames
            // get the average frame time
            averageframeTime = (currentTime - startTime) / frameCount; 
        }
        // get the time this frame
        // will most likely be displayed
        // then calculate how long
        // till the end
        timeLeft = endTime - Math.min(endTime, currentTime + averageframeTime / 2); 

        // now get where we should
        // be when the frame is presented
        pointPos = Math.floor(pointsPerMS * (timeToDraw - timeLeft)); 


        // now draw the points from where we last left of
        // till the new pos;
        ctx.lineWidth = 4;
        ctx.strokeStyle = 'blue';

        ctx.beginPath();
        ctx.moveTo(  // move to first point
            lastDataPoint * xStep + startX,
            array_1[lastDataPoint] + yOffset 
        ); 
        // draw each line from the last drawn to the new position 
        for (i = lastDataPoint + 1; i <= pointPos && i < numberPoints; i++) { 
            // Add the line segment
            ctx.lineTo(
                i * xStep + startX, 
                array_1[i] + yOffset
            );
        }
        ctx.stroke();                   // execute the render commands
        lastDataPoint = pointPos;       // update the last point
        if (pointPos < numberPoints) {  // are we there yet???
            requestAnimationFrame(drawWave); // no so request another frame
        }else{
            // if you want to repeat the animation
            setTimeout(drawTimedLine , repeatAfter ); 
        } 
    }
    // start the line animation with delay if needed
    setTimeout(drawWave,startDelay);
}    

// use this if you want it to start as soon as page is ready.    
document.addEventListener("DOMContentLoaded",drawTimedLine);
// or use if you want it to start when page has images loaded and is ready
// document.addEventListener("load",drawTimedLine);
这将等待页面加载并解析页面。图像和其他媒体可能尚未加载,但页面已准备好进行操作

不知道你5秒钟是什么意思。假设你想在5秒钟内完成任务

下面的步骤可以做到这一点

document.addEventListener("DOMContentLoaded",function() {setTimeout(startFunction,5000);});
我想问一下,为什么要用
requestAnimationFrame
1250一次绘制一个条目的图形,要画的线条不是那么多。如果添加
ctx.beginPath()
ctx.moveTo(/*first point*/)
然后用
ctx.moveTo(/*points*/)
循环所有点将在速度最慢的设备上实时运行


顺便说一句,lineWidth是一个
数字
而不是字符串。还有两个上下文?在画布上使用一个上下文。删除
ctxt
,只需使用
ctx
,最后不需要将
type='text/javascript'
添加到脚本标记中,因为javascript是默认值。

我可能会这样做方法是这样的。正如评论中提到的,我们需要在每帧中绘制一些数据点。绘制多少取决于浏览器能够提供动画帧的速度

我已经将值硬编码为4,因为这似乎在我的机器上起作用,但没有更多的工作,您可能可以自行设置代码时间并动态调整此值,以便动画尽可能接近目标时间。我尝试了一下,但结果很糟糕,我将此作为研究或思考中的练习这是给读者的

通过跟踪我们已经为当前“刷新周期”绘制了多少帧,我们知道为每个帧绘制的第一个点在数组中的索引距离

我试图尽可能多地对代码进行参数化,但是已经很晚了,我很累,我可能忽略了某些地方

<!doctype html>
<html>
<head>
<script>
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}

window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
    drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    drawCurFrame();
}

var dataSamples = [69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,72,72,72,72,72,72,72,73,73,74,74,74,74,74,74,74,73,73,73,73,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,73,73,73,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,71,72,72,72,73,73,73,72,72,72,73,73,73,74,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,73,73,73,72,72,72,71,101,71,70,70,70,69,68,68,67,67,66,66,67,67,69,70,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,74,76,77,76,70,57,40,22,11,11,22,40,57,69,73,73,71,71,71,72,72,73,73,74,74,74,73,72,72,72,72,72,72,72,72,72,72,72,72,71,71,70,70,71,71,71,71,70,70,69,69,69,69,69,69,69,68,68,68,67,67,66,66,65,65,64,63,63,62,62,62,62,62,62,62,62,63,63,64,65,66,67,68,68,69,70,71,72,72,72,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,73,73,72,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,73,73,74,74,74,74,74,74,73,73,72,73,73,73,74,73,73,72,72,72,73,73,73,72,72,73,73,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,70,70,70,70,70,69,69,68,67,67,67,67,68,69,71,72,72,73,73,73,73,74,74,74,74,74,73,73,73,73,75,77,78,76,67,53,35,18,8,10,23,41,58,69,73,72,71,70,71,72,73,73,73,73,73,73,73,73,72,72,73,73,73,73,72,71,71,70,70,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,68,67,67,67,67,67,66,65,65,65,64,63,62,61,61,61,60,60,60,59,60,60,60,61,62,63,65,66,66,67,68,69,70,71,72,72,72,72,73,73,73,72,72,72,72,72,72,72,73,73,73,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,71,72,72,73,73,73,72,72,72,72,72,72,73,73,73,73,73,73,73,73,73,72,73,73,73,73,73,73,72,73,73,73,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,71,71,70,70,69,69,69,68,67,67,66,65,66,66,68,69,70,71,72,72,73,73,73,73,73,73,74,74,74,74,74,74,76,78,78,74,64,48,29,13,5,10,26,45,62,71,73,72,71,71,72,73,73,73,73,73,74,74,74,73,72,72,72,73,73,73,73,73,73,73,72,72,72,72,71,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,67,66,66,66,66,65,65,64,63,62,62,61,61,60,60,60,60,61,62,62,63,64,65,66,67,68,70,71,72,72,72,72,72,72,73,73,73,73,73,73,73,74,74,75,75,74,74,74,73,73,73,74,73,73,73,73,73,74,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,74,74,74,73,73,73,73,73,73,73,73,73,73,72,72,72,72,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,72,72,71,70,70,70,69,69,68,68,67,67,66,67,67,68,69,70,71,72,73,73,74,74,73,73,73,74,75,75,74,73,73,74,76,78,75,67,52,32,15,5,8,22,41,59,69,73,72,71,70,71,72,72,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,71,71,71,70,70,70,70,70,70,70,69,69,69,69,68,68,68,68,67,67,66,65,65,64,64,64,63,62,61,60,60,60,60,60,61,61,62,62,63,64,65,65,66,67,68,69,70,71,71,71,71,71,71,72,72,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,72,71,71,71,72,72,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,71,71,71,70,70,70,70,69,69,68,67,67,68,69,71,72,73,73,73,73,73,73,73,73,74,75,75,75,74,74,74,75,77,77,75,67,52,34,18,10,12,26,45,62,71,74,73,72,72,72,73,74,74,74,75,75,74,74,74,74,74,74,74,74,74,73,73,73,73,74,74,73,73,73,73,73,73,73,72,72,71,71,71,71,71,70,70,70,69,69,69,68,68,68,68,67,66,65,64,63,63,62,62,62,63,63,63,63,64,65,66,67,69,69,70,71,72,72,73,73,74,74,74,74,75,75,76,76,74,72,70,70,69,69 ];

function drawBkg(canvasElem, squareSize, numSquaresPerBlock, minorLineWidthStr, majorLineWidthStr, lineColStr)
{
    var nLinesDone = 0;
    var i, curX, curY;
    var ctx = canvasElem.getContext('2d');
    ctx.clearRect(0,0,canvasElem.width,canvasElem.height);

    // draw the vertical lines
    curX=0;
    ctx.strokeStyle = lineColStr;
    while (curX < canvasElem.width)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(curX, 0);
        ctx.lineTo(curX, canvasElem.height);
        ctx.stroke();

        curX += squareSize;
        nLinesDone++;
    }

    // draw the horizontal lines
    curY=0;
    nLinesDone = 0;
    while (curY < canvasElem.height)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(0, curY);
        ctx.lineTo(canvasElem.width, curY);
        ctx.stroke();

        curY += squareSize;
        nLinesDone++;
    }
}

// position that will be treated as 0,0 when drawing our points.
var originX=49;
var originY=72;

function drawSamples(nSamplesToDraw, firstSample, lineWidthStr, lineColourStr)
{
    var can = byId('canvas');
    var ctx = can.getContext('2d');

    ctx.strokeStyle = lineColourStr;
    ctx.lineWidth = lineWidthStr;
    console.log(firstSample);
    ctx.beginPath();

    ctx.moveTo( originX+firstSample-1, dataSamples[firstSample-1]+originY );
    for (var i=0; i<nSamplesToDraw; i++)
    {
        var curSample = dataSamples[i + firstSample];
        ctx.lineTo( originX+firstSample+i, curSample+originY );
    }
    ctx.stroke();
}

var curFrame=0;
var nPointsPerFrame = 4;
function drawCurFrame()
{
    if ((dataSamples.length - (nPointsPerFrame * curFrame)) < nPointsPerFrame)      // will we over-run the end of the array of datapoints?
    {
        curFrame = 0;                                                               // if so, reset
        drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    }
    drawSamples(nPointsPerFrame, nPointsPerFrame*curFrame, "1", "blue");
    curFrame++;
    requestAnimationFrame( drawCurFrame );
}
</script>

<style>
#canvas
{
    border: solid 1px black;
    background-color: #FFFFFF;
}
</style>

</head>
<body>
    <div id='txt'></div>
    <canvas id="canvas" width="1350" height="1300"></canvas>

</body>
</html>

函数byId(id,parent){return(parent==未定义?文档:parent).getElementById(id);}
window.addEventListener('load',onDocLoaded,false);
函数onDocLoaded(evt)
{
drawBkg(byId(“画布”)、9.43、5、“0.5”、“1.5”、“黑色”);
drawCurFrame();
}
变量数据样本=[69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,72,72,72,72,72,72,72,73,73,74,74,74,74,74,74,74,73,73,73,73,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,73,73,73,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,71,72,72,72,73,73,73,72,72,72,73,73,73,74,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,73,73,73,72,72,72,71,101,71,70,70,70,69,68,68,67,67,66,66,67,67,69,70,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,74,76,77,76,70,57,40,22,11,11,22,40,57,69,73,73,71,71,71,72,72,73,73,74,74,74,73,72,72,72,72,72,72,72,72,72,72,72,72,71,71,70,70,71,71,71,71,70,70,69,69,69,69,69,69,69,68,68,68,67,67,66,66,65,65,64,63,63,62,62,62,62,62,62,62,62,63,63,64,65,66,67,68,68,69,70,71,72,72,72,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,73,73,72,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,73,73,74,74,74,74,74,74,73,73,72,73,73,73,74,73,73,72,72,72,73,73,73,72,72,73,73,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,70,70,70,70,70,69,69,68,67,67,67,67,68,69,71,72,72,73,73,73,73,74,74,74,74,74,73,73,73,73,75,77,78,76,67,53,35,18,8,10,23,41,58,69,73,72,71,70,71,72,73,73,73,73,73,73,73,73,72,72,73,73,73,73,72,71,71,70,70,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,68,67,67,67,6
<!doctype html>
<html>
<head>
<script>
function byId(id,parent){return (parent == undefined ? document : parent).getElementById(id);}

window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
    drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    drawCurFrame();
}

var dataSamples = [69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,69,72,72,72,72,72,72,72,73,73,74,74,74,74,74,74,74,73,73,73,73,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,74,74,74,73,73,73,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,71,72,72,72,73,73,73,72,72,72,73,73,73,74,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,73,73,73,72,72,72,71,101,71,70,70,70,69,68,68,67,67,66,66,67,67,69,70,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,74,76,77,76,70,57,40,22,11,11,22,40,57,69,73,73,71,71,71,72,72,73,73,74,74,74,73,72,72,72,72,72,72,72,72,72,72,72,72,71,71,70,70,71,71,71,71,70,70,69,69,69,69,69,69,69,68,68,68,67,67,66,66,65,65,64,63,63,62,62,62,62,62,62,62,62,63,63,64,65,66,67,68,68,69,70,71,72,72,72,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,73,73,73,73,72,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,73,73,74,74,74,74,74,74,73,73,72,73,73,73,74,73,73,72,72,72,73,73,73,72,72,73,73,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,70,70,70,70,70,69,69,68,67,67,67,67,68,69,71,72,72,73,73,73,73,74,74,74,74,74,73,73,73,73,75,77,78,76,67,53,35,18,8,10,23,41,58,69,73,72,71,70,71,72,73,73,73,73,73,73,73,73,72,72,73,73,73,73,72,71,71,70,70,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,68,67,67,67,67,67,66,65,65,65,64,63,62,61,61,61,60,60,60,59,60,60,60,61,62,63,65,66,66,67,68,69,70,71,72,72,72,72,73,73,73,72,72,72,72,72,72,72,73,73,73,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,71,71,72,72,73,73,73,72,72,72,72,72,72,73,73,73,73,73,73,73,73,73,72,73,73,73,73,73,73,72,73,73,73,73,73,73,73,72,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,71,71,70,70,69,69,69,68,67,67,66,65,66,66,68,69,70,71,72,72,73,73,73,73,73,73,74,74,74,74,74,74,76,78,78,74,64,48,29,13,5,10,26,45,62,71,73,72,71,71,72,73,73,73,73,73,74,74,74,73,72,72,72,73,73,73,73,73,73,73,72,72,72,72,71,71,71,71,71,71,71,71,71,70,70,69,69,69,69,68,67,66,66,66,66,65,65,64,63,62,62,61,61,60,60,60,60,61,62,62,63,64,65,66,67,68,70,71,72,72,72,72,72,72,73,73,73,73,73,73,73,74,74,75,75,74,74,74,73,73,73,74,73,73,73,73,73,74,74,74,74,74,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,74,74,74,73,73,73,73,73,73,73,73,73,73,72,72,72,72,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,73,73,72,72,71,70,70,70,69,69,68,68,67,67,66,67,67,68,69,70,71,72,73,73,74,74,73,73,73,74,75,75,74,73,73,74,76,78,75,67,52,32,15,5,8,22,41,59,69,73,72,71,70,71,72,72,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,72,72,72,71,71,71,70,70,70,70,70,70,70,69,69,69,69,68,68,68,68,67,67,66,65,65,64,64,64,63,62,61,60,60,60,60,60,61,61,62,62,63,64,65,65,66,67,68,69,70,71,71,71,71,71,71,72,72,73,73,73,72,72,73,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,72,72,72,71,71,71,71,71,71,71,72,72,72,72,72,72,72,72,72,71,71,71,72,72,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,72,72,73,73,73,73,73,72,72,72,73,73,74,73,73,73,73,73,73,73,73,73,73,73,73,72,72,72,72,71,71,71,70,70,70,70,69,69,68,67,67,68,69,71,72,73,73,73,73,73,73,73,73,74,75,75,75,74,74,74,75,77,77,75,67,52,34,18,10,12,26,45,62,71,74,73,72,72,72,73,74,74,74,75,75,74,74,74,74,74,74,74,74,74,73,73,73,73,74,74,73,73,73,73,73,73,73,72,72,71,71,71,71,71,70,70,70,69,69,69,68,68,68,68,67,66,65,64,63,63,62,62,62,63,63,63,63,64,65,66,67,69,69,70,71,72,72,73,73,74,74,74,74,75,75,76,76,74,72,70,70,69,69 ];

function drawBkg(canvasElem, squareSize, numSquaresPerBlock, minorLineWidthStr, majorLineWidthStr, lineColStr)
{
    var nLinesDone = 0;
    var i, curX, curY;
    var ctx = canvasElem.getContext('2d');
    ctx.clearRect(0,0,canvasElem.width,canvasElem.height);

    // draw the vertical lines
    curX=0;
    ctx.strokeStyle = lineColStr;
    while (curX < canvasElem.width)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(curX, 0);
        ctx.lineTo(curX, canvasElem.height);
        ctx.stroke();

        curX += squareSize;
        nLinesDone++;
    }

    // draw the horizontal lines
    curY=0;
    nLinesDone = 0;
    while (curY < canvasElem.height)
    {
        if (nLinesDone % numSquaresPerBlock == 0)
            ctx.lineWidth = majorLineWidthStr;
        else
            ctx.lineWidth = minorLineWidthStr;

        ctx.beginPath();
        ctx.moveTo(0, curY);
        ctx.lineTo(canvasElem.width, curY);
        ctx.stroke();

        curY += squareSize;
        nLinesDone++;
    }
}

// position that will be treated as 0,0 when drawing our points.
var originX=49;
var originY=72;

function drawSamples(nSamplesToDraw, firstSample, lineWidthStr, lineColourStr)
{
    var can = byId('canvas');
    var ctx = can.getContext('2d');

    ctx.strokeStyle = lineColourStr;
    ctx.lineWidth = lineWidthStr;
    console.log(firstSample);
    ctx.beginPath();

    ctx.moveTo( originX+firstSample-1, dataSamples[firstSample-1]+originY );
    for (var i=0; i<nSamplesToDraw; i++)
    {
        var curSample = dataSamples[i + firstSample];
        ctx.lineTo( originX+firstSample+i, curSample+originY );
    }
    ctx.stroke();
}

var curFrame=0;
var nPointsPerFrame = 4;
function drawCurFrame()
{
    if ((dataSamples.length - (nPointsPerFrame * curFrame)) < nPointsPerFrame)      // will we over-run the end of the array of datapoints?
    {
        curFrame = 0;                                                               // if so, reset
        drawBkg(byId('canvas'), 9.43, 5, "0.5", "1.5", "black");
    }
    drawSamples(nPointsPerFrame, nPointsPerFrame*curFrame, "1", "blue");
    curFrame++;
    requestAnimationFrame( drawCurFrame );
}
</script>

<style>
#canvas
{
    border: solid 1px black;
    background-color: #FFFFFF;
}
</style>

</head>
<body>
    <div id='txt'></div>
    <canvas id="canvas" width="1350" height="1300"></canvas>

</body>
</html>