简体   繁体   中英

How to size/scale a chart in Chart.js

I use chart.js in my code. Basically, it works well, but I have an issue with creating nth time a chart in the same canvas. I got error message telling me that I suppose to destroy chart first. Then I found here some ideas how to do this and adapted this part of code as a solution:

let chartStatus = Chart.getChart("line-chart"); 
if (chartStatus != undefined) {
    chartStatus.destroy();
    //$("div.line-chart").remove();
    //$("div.line-chart").append('<canvas id="line-chart" style="width: 1221px; height: 280px;"></canvas>');
}

It works fine - at least I do not get any errors any more, but when I create chart for second and more times, it gets resized. Please look at the attached pictures: 第一次使用图表...

第二次图表使用...

If you look at the scale you notice it is changed.

My question is: How can I destroy a chart and recreate its size/scale etc correctly or how can I update a chart instead of destroying it?

The code looks like this:

javascript:

let chartStatus = Chart.getChart("line-chart"); 
if (chartStatus != undefined) {
    chartStatus.destroy();
    //$("div.line-chart").remove();
    //$("div.line-chart").append('<canvas id="line-chart" style="width: 1221px; height: 280px;"></canvas>');
}

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
        }
    }
});

HTML:

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

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.

The canvas will get resized each time the chart is drawn, to accommodate the contents of the chart. It could be done the other way around - to accommodate the contents to the size, but that's a complicated and time consuming, and will not always work ok if the sizes are very unequal, so chart.js chooses to adjust the size.

Therefore you cannot count on the styled size of the canvas, so it is recommended to style the size of the container div, like in the following example, loosely based on your code excerpt.

 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; border: 1px solid red"> <canvas id="line-chart"></canvas> </div> <button id="reset">Reset</button>

Still, 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; border: 1px solid red"> <canvas id="line-chart"></canvas> </div> <button id="reset">Reset</button> </body>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM