Reputation: 1499
I'm using Charts.js
library and my <canvas>
element is acting strangely when i try to re scale it by changing it's width
and height
attributes
I'm definitely missing something , keep in mind that i capture the whole window
here are some examples:
Try it here , this is supposed to be a 10x10
square (pretty small right?)
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
}
}]
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<canvas id="myChart" width="10" height="10"></canvas>
Why can't i make it a 100x100
square? and not be placed in the whole browser?do i need a placeholder
for this?
Here is the playground that makes a graph non-resizable as you might notice in the desktop
view although the mobile
view is perfect
Note:
When <div>
is not included and <canvas>
has not attributes
in browser it's huge , and on mobile resolution is perfect. If you apply width
and height
to <div>
which contains <canvas>
you can resize it but on mobile will be stretched.
Edit: added code snippet
Edit2: added code playground
Upvotes: 1
Views: 334
Reputation: 7080
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
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/[email protected]"></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>
Upvotes: 1
Reputation: 548
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
}
}]
}
}
Upvotes: 2