Javascript function which draws on canvas takes way too much time...?

Viewed 33

I already posted a question on this issue: Recursive javascript requests: delay between requests gets bigger with time...?

My problem is that I run a function which triggers a loop which continuously fetches data from a server and draws it on a canvas.

I did some testing and the canvas drawing part takes the longest, as here I iterate through the entire dataset and draw every element, so that I have an overview of the data fetched. As this takes a lot of time, the next request is delayed and there are large gaps where no data is fetched.

I can think of two possible solutions:

  1. Preferred method: Run the whole canvas drawing process on a different thread or somehow in the background, separate from the main function. It is not an issue for my application if the data is visualized later than it is fetched. But how could I implement this in Javascript?

  2. Don't redraw the whole overview and only add the new data. But as my canvas represents an overview for the whole fetched data, I would need to scale down every element in the canvas to the new length and then add the new data. However here I can't find a method to scale down the already drawn elements to a new length... Is this even a realistic approach?

Thanks

EDIT: Code added

function drawScrollChart(Logs) {

overviewContext.clearRect(0, 0, overviewCanvas.width, overviewCanvas.height);

overviewContext.globalAlpha = 0.45;
var startY = 0;
var startX = 0;
var grd = 0;
var scale = 5;

var measurementDuration = ((MeasurementPeriods[MeasurementPeriods.length - 1].end - MeasurementPeriods[0].start) / 1000)
var xscale = (overviewCanvas.width / window.devicePixelRatio) / measurementDuration;

overviewContext.beginPath();

for (var i = 1; i < Logs.length; i++) {

    if (Logs[i].event == startEvent) {


        startY = ((overviewCanvas.height / scaleRatio) - 10) - (scale * block_ident);
        startX = ((Logs[i].timestamp / 1000) * xscale);

        grd = overviewContext.createLinearGradient(startX, startY, startX, startY + scale);
        grd.addColorStop(0, getStartCol(block_ident));
        grd.addColorStop(1, getEndCol(block_ident));
        overviewContext.fillStyle = grd;

        overviewContext.fillRect(startX, startY, ((Logs[i].durationWithoutInterrupt / 1000) * xscale), scale);

        if ((i + 1) >= Logs.length) {

            overviewContext.fillRect(startX, startY, ((Logs[i].durationWithInterrupt / 1000) * xscale), scale);

        } else {

            if (Logs[i + 1].event == endEvent) {

                overviewContext.fillRect(startX, startY, ((Logs[i].durationWithoutInterrupt / 1000) * xscale), scale);

            } else {

                overviewContext.fillRect(startX, startY, ((Logs[i].durationWithInterrupt / 1000) * xscale), scale);

            }
        }

    }

    if (Logs[i].event == continueEvent) {


        startY = ((overviewCanvas.height / scaleRatio) - 10) - (scale * block_ident);
        startX = ((Logs[i].timestamp / 1000) * xscale);

        grd = overviewContext.createLinearGradient(startX, startY, startX, startY + scale);
        grd.addColorStop(0, getStartCol(block_ident));
        grd.addColorStop(1, getEndCol(block_ident));
        overviewContext.fillStyle = grd;

        overviewContext.fillRect(startX, startY, ((Logs[i].durationWithInterrupt / 1000) * xscale), scale);

        overviewContext.fill();
    }

}


for (var i = 0; i < MeasurementPeriods.length - 1; i++) {
    overviewContext.globalAlpha = 0.75;

    var startY = ((overviewCanvas.height / scaleRatio) - 10) - (scale * block_ident);
    var startX = (((MeasurementPeriods[i].end - MeasurementPeriods[0].start) / 1000) * xscale);

    var grd = overviewContext.createLinearGradient(startX, startY, startX, startY + scale);
    grd.addColorStop(0, 'rgb(255,0,0)');
    grd.addColorStop(1, 'rgb(255,150,150)');
    overviewContext.fillStyle = grd;

    overviewContext.beginPath();

    var width = (((MeasurementPeriods[i + 1].start - MeasurementPeriods[i].end) / 1000) * xscale);

    overviewContext.fillRect(startX, startY, width, scale);

}

}

EDIT2: Dataset sample:

There are around 25 000 of these items, but technically my application should allow way and way more of these items. The block ident varies between -1 and 5-6.

{
    "block_ident": -1,
    "event": "e",
    "timestamp": 0,
    "durationWithInterrupt": 0,
    "durationWithoutInterrupt": 0
},
{
    "block_ident": 1,
    "event": "s",
    "timestamp": 0,
    "durationWithInterrupt": 16640,
    "durationWithoutInterrupt": 16640
},
{
    "block_ident": 1,
    "event": "e",
    "timestamp": 16640,
    "durationWithInterrupt": 0,
    "durationWithoutInterrupt": 0
},
{
    "block_ident": -1,
    "event": "s",
    "timestamp": 16640,
    "durationWithInterrupt": 1132288,
    "durationWithoutInterrupt": 1132288
},
{
    "block_ident": -1,
    "event": "e",
    "timestamp": 1148928,
    "durationWithInterrupt": 0,
    "durationWithoutInterrupt": 0
},
{
    "block_ident": 3,
    "event": "s",
    "timestamp": 1148928,
    "durationWithInterrupt": 24064,
    "durationWithoutInterrupt": 24064
},
{
    "block_ident": 3,
    "event": "e",
    "timestamp": 1172992,
    "durationWithInterrupt": 0,
    "durationWithoutInterrupt": 0
},
0 Answers
Related