Initializing Chart.js multiple times over same canvas changes its size for some devices

    //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
    if (window.devicePixelRatio) {
        context.canvas.style.width = width + "px";
        context.canvas.style.height = height + "px";
        context.canvas.height = height * window.devicePixelRatio;
        context.canvas.width = width * window.devicePixelRatio;
        context.scale(window.devicePixelRatio, window.devicePixelRatio);
    }

When devicePixelRation != 1 doing

ctx = canvas.getContext("2d")
new Chart(ctx).drawSomething
//then later drawing another chart on the same canvas with
new Chart(ctx).drawSomething
//
//then later another one
new Chart(ctx).drawSomething

keeps changing (getting smaller or bigger depending on devicePixelRatio) the chart size.

This can be easily reproduced if you zoom-in or zoom-out in firefox, refresh (verify that window.devicePixelRatio is not 1) and keep doing the mentioned procedure (creting new charts on the same canvas). The charts are getting smaller or bigger with every Chart initialization.

My workaround for now is to reset width/height again to initial values before creating chart again:

ctx = canvas.getContext("2d")
new Chart(ctx).drawSomething

//then later drawing another chart on the same canvas with
canvas.width = 400
canvas.height = 400
ctx = canvas.getContext("2d")
new Chart(ctx).drawSomething

Author: Fantashit

2 thoughts on “Initializing Chart.js multiple times over same canvas changes its size for some devices

  1. I had the same distressing hover effect using one canvas for changing charts. For me the following was the solution. I found it @ http://stackoverflow.com/questions/24815851/how-do-clear-a-chart-from-a-canvas-so-that-hover-events-cannot-be-triggered – Answer from xchiltonx (modified):

    // initialising variable for charts
    var myChart = null;
    //setting options
    var options = {
        datasetFill : false,
        };
    
    // funciton executed on clicking button "10"
    function twenty() {
    $.getJSON( "ltwen", function(data) {
    var my_data = data;
    var ctx = document.getElementById("myChart").getContext("2d");
    // --> this is the key to solution - no hover effects of old charts anymore
    if(myChart != null){
            myChart.destroy();
        }
    myChart = new Chart(ctx).Line(my_data, options);
    });
    }
    
    // funciton executed on pressing button "20"
    function ten() {
    $.getJSON( "lten", function(data) {
    var my_data = data;
    var ctx = document.getElementById("myChart").getContext("2d");
    // --> this is the key to solution - no hover effects of old charts anymore
    if(myChart != null){
            myChart.destroy();
        }
    myChart = new Chart(ctx).Line(my_data, options);
    });
    }

    I tried something with typeof myChart != 'undefined' – but it didnt work out. I hope it will work for you aswell.

  2. You can use update() for v2.x

    var chart_ctx = document.getElementById("chart").getContext("2d");
    
    var chart = new Chart(chart_ctx, {
    	type: "pie",
    	data: {}
    	options: {}
    }
    
    $.ajax({
    	...
    }).done(function (response) {
        chart.data = response;
        chart.update();
    });

Comments are closed.