Chartjs-How to size/scale a chart in Chart.js

0👍

I have found a solution that works for me here.
Now, my code looks like this:

let chartStatus = Chart.getChart("line-chart"); 
if (chartStatus != undefined) {
    document.getElementById('line-chart').remove();
    let canvas = document.createElement('canvas');     
    canvas.setAttribute('id','line-chart');     
    canvas.setAttribute('width','1221');     
    canvas.setAttribute('height','280');     
    document.querySelector("#line-chart-wrapper").appendChild(canvas);
}

and HTML part…

<div id="line-chart-wrapper"><canvas id="line-chart" style="width: 1221px; height: 280px;"></canvas></div>

Now chart looks OK no matter how many times it is created.

0👍

If you set the size of the canvas in css, it will be resized each time the chart is drawn, and the second time you lose its height completely.

The solution you propose – to size the canvas in code is less than ideal because chart.js draws the plot at its own devised size and then you just scale the resulted image to your desired size, which may look OK in your specific case, but in most cases you lose the quality of the result with possible overlapping items or lost resolution.

The standard way to have chart.js (re)draw the plot at your intended size is to have a div that includes only the canvas and set the css size of the div, not the canvas, together with the option maintainAspectRatio: false (which you already set). See also this section from the docs.

The following example, loosely based on your code excerpt, does that.

let labelX = [], waga = [];
    function resetData(){
        const d0 = Date.now() - 3*365*24*3600*1000*Math.random();
        // change the whole arrays, since the chart is destroyed and rebuilt
        labelX = Array.from({length: 10}, (_, i) =>
            new Date(d0 + i * 24 * 3600 * 1000).toLocaleDateString(undefined,
                {year: 'numeric', month: 'numeric', day: 'numeric'}));
        waga = Array.from({length: 10}, (_, i) => Math.random());
    }

    let chart;
    function drawChart(){
        chart = new Chart(document.getElementById("line-chart"), {
            type: 'line',
            data: {
                labels: labelX,
                datasets: [{
                    data: waga,
                    label: "Waga",
                    borderColor: "#3e95cd",
                    borderWidth: 1,
                    fill: false
                }]
            },
            options: {
                title: {
                    display: true,
                    responsive: true,
                    maintainAspectRatio: false
                },
                scales: {
                    x: {
                        bounds: 'ticks',
                        type: 'category',
                    },
                    y: {
                        type: 'linear',
                        display: true,
                        min: 0,
                        max: 1
                    }
                }
            }
        });
    }

    resetData();
    drawChart();

    document.getElementById('reset').onclick = function(){
        resetData();
        document.querySelector('canvas#line-chart').innerHTML = '';
        chart.destroy();
        drawChart();
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.1.2/chart.umd.js"
        integrity="sha512-t41WshQCxr9T3SWH3DBZoDnAT9gfVLtQS+NKO60fdAwScoB37rXtdxT/oKe986G0BFnP4mtGzXxuYpHrMoMJLA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<div id="line-chart-container" style="height:300px; width:1000px; border: 1px solid red">
<canvas id="line-chart"></canvas>
</div>
<button id="reset">Reset</button>

Alternatively (with the same setting for styling the div not the canvas), the more efficient solution would be to just change the data and then call chart.update, if it fits your purpose, like this:

const labelX = [], waga = [];
function resetData(){
    const d0 = Date.now() - 3*365*24*3600*1000*Math.random();
    // using splice 0 to infinity to replace all data *inside* the arrays
    labelX.splice(0, 1/0, ...Array.from({length: 10}, (_, i) =>
        new Date(d0 + i * 24 * 3600 * 1000).toLocaleDateString(undefined,
            {year: 'numeric', month: 'numeric', day: 'numeric'})));
    waga.splice(0, 1/0, ...Array.from({length: 10}, (_, i) => Math.random()));
}

resetData();
const chart = new Chart(document.getElementById("line-chart"), {
    type: 'line',
    data: {
        labels: labelX,
        datasets: [{
            data: waga,
            label: "Waga",
            borderColor: "#3e95cd",
            borderWidth: 1,
            fill: false
        }]
    },
    options: {
        title: {
            display: true,
            responsive: true,
            maintainAspectRatio: false
        },
        scales: {
            x: {
                bounds: 'ticks',
                type: 'category',
            },
            y: {
                type: 'linear',
                display: true,
                min: 0,
                max: 1
            }
        }
    }
});

document.getElementById('reset').onclick = function(){
    resetData();
    chart.update();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.1.2/chart.umd.js"
        integrity="sha512-t41WshQCxr9T3SWH3DBZoDnAT9gfVLtQS+NKO60fdAwScoB37rXtdxT/oKe986G0BFnP4mtGzXxuYpHrMoMJLA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<body>
<div id="line-chart-container" style="height:300px; width:1000px; border: 1px solid red">
<canvas id="line-chart"></canvas>
</div>
<button id="reset">Reset</button>
</body>

Leave a comment