@Legends I tried the code pen in chrome (simulating mobile mode) and I could see the Y axis. Can you post a screenshot of what you're seeing? Are you using a specific device or browser?
Did you resize it to a width of 320px? below 320px is also goes into negative!
Using chrome 55 (64bit). Updating the chart on window resize doesn't help either.

ah, that's what you meant. That's happening because there isn't enough room to draw the y axis because the canvas is not tall enough. I'm not sure why the axis reverses though.
Any workaround for this or is chart.js not compatible when using narrow screens?
The chart is dependent on the width of the parent container, below a certain width, the y axis collapses or does even turn the chart upside down with negative y axis values.
Just took a look at CanvasJS, it does not happen there, their chart renders fine also on very narrow screen sizes.

I think the media queries is the right way to go. Then set responsive: true and maintainAspectRatio: false otherwise the width will still take precedence. I tested out just changing the config settings in the codepen and it already looked better.
If you change the height the canvas gets stretched, redraw does not help, because as I have found out, the aspect ratio is tight to the width of the container...
And the chart turns into negative Y axis.
The content of the page controlls the width of the parent container.
Question: How to show the chart correctly on screen sizes below 400px.

This is really a bug and should be fixed or is there at least an workaround for this?
I want to be able to show
This is my current config:
<canvas class="chartjs" id="lineChart" height="120"></canvas>
function lineData() {
return {
type: 'line',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
borderColor: chartColors.red,
backgroundColor: chartColors.red,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Second dataset",
borderColor: chartColors.blue,
backgroundColor: chartColors.blue,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Third dataset",
borderColor: chartColors.green,
backgroundColor: chartColors.green,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}, {
label: "My Third dataset",
borderColor: chartColors.yellow,
backgroundColor: chartColors.yellow,
data: [
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor(),
randomScalingFactor()
],
}]
},
options: {
maintainAspectRatio:true,
responsive: true,
title: {
display: true,
text: "Line Chart - Stacked Area"
},
tooltips: {
mode: 'index',
},
hover: {
mode: 'index'
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
stacked: true,
scaleLabel: {
display: true,
labelString: 'Value'
}
}]
}
}
}; // end return object
}
MaintainAspectRatio set to false:
Chart.js

This is really a bug and should be fixed or is there at least an workaround for this?
The only work-arounds that I can think of are:
Tagging @simonbrunel since he owns the resizing/responsive stuff
If you change the height the canvas gets stretched
What do you mean? How do you change the height? When using responsive: true, you need to wrap the canvas inside a dedicated div, relatively positioned and then change the div size, not the canvas:
<div id="chart-wrapper" style="position:relative; height:120px">
<canvas id="chart"></canvas> // responsive: true
</div>
This is really a bug and should be fixed ...
That's more a feature than a bug, the term responsive is quite confusing: Chart.js implements an adaptative canvas (responsive: true) which mean that the canvas render size (height and width attributes) is synchronized to the canvas display size to avoid the canvas to appear blurry. But that only works when the parent container size changes, not when modifying the canvas size directly.
But Chart.js does NOT implement chart (content) responsiveness, so you can't have the chart elements to change based on the canvas size (e.g., hide the legend when the canvas is too small, reduce font size, etc.). You need to do that manually by modifying the chart config when the size change and call update(). Something like that should work (not tested):
new Chart(ctx, {
options: {
onResize: function(chart, size) {
chart.options.legend.display = size.height > 128;
// ... do whatever changes you need to have your chart display correctly ...
chart.update();
}
}
});
I agree that's not very handy, an idea would be to support responsive rules:
// NOT IMPLEMENTED
new Chart(ctx, {
options: {
responsive: {
'height < 128': {
legend: {
display: false
}
}
}
}
})
@simonbrunel
I will try this out. But one further question:
Is the resize event handler throttled or debounced?
Yes, the resize event is throttled.
This works perfect on my line chart, but I get errors for all other charts.
Question:
1.) Is there a way to adjust the throttle timespan?
2.) How to call the onResize eventhandler on first page load?
3.) The resizehandler seems to be the solution, but I get errors in the update method.
chart.bundle.js:9050 Uncaught TypeError: Cannot read property 'undefined' of undefined
at ChartElement.getScaleForId (chart.bundle.js:9050)
at ChartElement.updateElement (chart.bundle.js:6209)
at ChartElement.(chart.bundle.js:6202)
at Object.helpers.each (chart.bundle.js:9351)
at ChartElement.update (chart.bundle.js:6201)
at ChartElement.reset (chart.bundle.js:9054)
at chart.bundle.js:8574
at Object.helpers.each (chart.bundle.js:9351)
at Chart.Controller.update (chart.bundle.js:8573)
at showHideLabels (chartjs.js:50)
and:
chart.bundle.js:8553 Uncaught TypeError: Cannot set property '_data' of undefined
at Chart.Controller.update (chart.bundle.js:8553)
at showHideLabels (chartjs.js:50)
at Object.onResize (chartjs.js:145)
at Chart.Controller.resize (chart.bundle.js:8412)
at new Chart.Controller (chart.bundle.js:8339)
at new Chart (chart.bundle.js:10687)
at HTMLDocument.(chartjs.js:133)
at fire (jquery-2.1.1.js:3183)
at Object.add [as done] (jquery-2.1.1.js:3242)
at jQuery.fn.init.jQuery.fn.ready (jquery-2.1.1.js:3492)
-->
update: function (animationDuration, lazy) {
var me = this;
Chart.plugins.notify('beforeUpdate', [me]);
me.tooltip._data = me.data; // <-- **tooltip is undefined**
helper:
function showHideLabels(chart, size) {
chart.options.legend.display = size.width > 500;
chart.update();
}
1) No, could be a new responsive option / feature.
2) Do you mean right after the chart is created?
3) Actually, I think you don't need to call (and you should not) chart.update() because when the chart is resized, update() is called after the onResize handler is notified. If that doesn't solve the error you get, can you please create a codepen that reproduce this issue?
2.) Yes, right after the chart is created.
3.) Removing the chart.update() in the onresize eventhandler fixes the issue, perfect!
The only issue is point 2, as I have to call it somehow right after the chart is created initially, in order to render the chart correctly.
I was going to suggest calling resize explicitly on the chart after creation:
let myChart = new Chart(...);
myChart.resize();
We've publicly documented it in http://www.chartjs.org/docs/#advanced-usage-prototype-methods so I consider it safe to use. The implementation is https://github.com/chartjs/Chart.js/blob/master/src/core/core.controller.js#L158 which will call onResize.
However, I don't think it will work due to line Line 170 which bails out early if there is no size change.
I tried calling resize, but as you already assumed, doesn't work.
But if I trigger the resize event after the charts have been rendered by resizing the browser, they render perfectly.
So it would be good if I could manually call it after initial render!
On very narrow screens sizes I also get this error. I think it is because the chart goes into negative.

Ok I have added a forceResize method to chart.js which is a 1:1 copy of the resize method
but I have removed the code you mentioned:
if (chart.width === newWidth && chart.height === newHeight) {
return;
}
Now it works. Thanks for your help guys !
Another solution without modifying the sources would be to use plugins:
Inline plugins will be released in 2.5, so you need to checkout master and build the lib by yourself:
function doResponsive(instance) {
var width = instance.chart.width;
chart.options.legend.display = width > 500;
// ...
}
new Chart(ctx, {
plugins: {
beforeInit: doResponsive,
resize: doResponsive
}
});
Or you can write a global plugin, which should work in 2.4:
// GLOBAL PLUGIN (apply to all charts)
Chart.plugins.register({
beforeInit: doResponsive,
resize: doResponsive
});
That could be a really interesting plugin to implement!
Closing since it looks like all of the issues were resolved
Yes it is, thanks!
Most helpful comment
Another solution without modifying the sources would be to use plugins:
Inline plugins will be released in 2.5, so you need to checkout master and build the lib by yourself:
Or you can write a global plugin, which should work in 2.4:
That could be a really interesting plugin to implement!