[Chartjs]-I can not properly re scale <canvas> with width and height attributes

2👍

This is happening because you have “reponsive” activated by default. In this case , the attributes width and height will be ignored.

The solution is to desactivate the responsive option like this :

 options: {
    responsive:false,
    scales: {
        yAxes: [{
            ticks: {
                beginAtZero: true
            }
        }]
    }
}

1👍

If you look at it through your console, you will notice that an extra element div.chartjs-size-monitor is added to the DOM right before your target canvas.

This is done by ChartJS to ensure the canvas can be resized properly.

To solve the it, you simply need to

  1. Move the canvas into a container element
  2. Set your size at the container element.

Note that the parent element must be display: block (i.e., div).

ChartJS will change the width and height attribute of your canvas anyway, so there is no point setting it from your end.

var ctx = document.getElementById('myChart');
var myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
    datasets: [{
      label: '# of Votes',
      data: [12, 19, 3, 5, 2, 3],
      backgroundColor: [
        'rgba(255, 99, 132, 0.2)',
        'rgba(54, 162, 235, 0.2)',
        'rgba(255, 206, 86, 0.2)',
        'rgba(75, 192, 192, 0.2)',
        'rgba(153, 102, 255, 0.2)',
        'rgba(255, 159, 64, 0.2)'
      ],
      borderColor: [
        'rgba(255, 99, 132, 1)',
        'rgba(54, 162, 235, 1)',
        'rgba(255, 206, 86, 1)',
        'rgba(75, 192, 192, 1)',
        'rgba(153, 102, 255, 1)',
        'rgba(255, 159, 64, 1)'
      ],
      borderWidth: 1
    }]
  },
  options: {
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    }
  }
});


/* CODE BELOW ONLY EXIST TO IMITATE BROWSER SIZE */

const wrapper = document.querySelector('#window');
const desktop = document.querySelector('#desktop');
const mobile = document.querySelector('#mobile');

desktop.addEventListener('click', resize.bind(this, 'desktop'));
mobile.addEventListener('click', resize.bind(this, 'mobile'));

function resize(size, event){
  event.preventDefault();
  wrapper.classList.remove('desktop', 'mobile')
  wrapper.classList.add(size);
}
/* CSS HERE ONLY EXIST TO IMITATE BROWSER SIZE */

#window {
  margin-top: 10px;
  border: 1px solid black;
  transition: all 0.3s;
}

#window.desktop {
  width: 450px;
  height: 253px;
}

#window.mobile {
  width: 320px;
  height: 568px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>

<!-- Ignore these -->
<button id="desktop">Desktop</button>
<button id="mobile">Mobile</button>

<!-- #window is to imitate browser window size -->
<!-- imagine #container as the direct children of <body> -->
<div id="window" class="desktop">

  <!-- Moved all CSS to HTML as your requirement -->
  <div id="container" style="width: 100%; height: 100%; position: relative;">
    <canvas id="myChart"></canvas>
  </div>
  
</div>

Leave a comment