1๐
A safe solution is to use the plugin chartjs-plugin-annotation
that has a line annotation.
A line at the bottom of the axis y2
can be obtained by using the options:
options:{
// other options .....
plugins: {
// other plugins ....
annotation: {
annotations: {
line_y2_bottom: {
type: 'line',
scaleID: 'y2',
value: function({chart}, props){
const scale = chart.scales[props.scaleID];
return scale.getValueForPixel(scale.bottom - 1) || scale.min;
},
borderColor: 'black',
borderWidth: 3,
},
}
}
}
}
If known apriori, the value
can be set to a fixed numeric value. However, the fact that value
, as well as most other properties, is scriptable is a great advantage in this context, when the axes have offset: true
, so the actual minimal value (as well as maximal one) are not dictated exclusively by the data, but also by the objective of making all axes fit in the available space.
The line id
, in the example above, line_y2_bottom
is arbitrary, I chose it to be meaningful for humans, the only
requirement is that each annotation has a different id
.
A minimal snippet example that draws a line at the bottom of each chart:
const x = Array.from({length: 101}, (_, i)=>({x: i/100}));
const data = {
datasets: [
{
data: x.map(({x})=>({x, y: Math.exp(x+1)})),
borderColor: 'red',
yAxisID: 'y1'
},
{
data: x.map(({x})=>({x, y: Math.exp(-x+1)})),
borderColor: 'blue',
yAxisID: 'y2',
},
{
data: x.map(({x})=>({x, y: Math.sin(x+1)})),
borderColor: 'green',
yAxisID: 'y3',
}
]
};
const config = {
type: 'line',
data: data,
options: {
responsive: true,
aspectRatio: 1,
plugins: {
legend: {
display: false,
},
annotation: {
annotations: Object.fromEntries(['y1', 'y2', 'y3'].map(
scaleID => [
`line_${scaleID}_bottom`,
{
type: 'line',
scaleID,
value: function({chart}, props){
const scale = chart.scales[props.scaleID];
return scale.getValueForPixel(scale.bottom-1) || scale.min;
},
borderColor: 'black',
borderWidth: 3,
}
])
)
}
},
scales: {
x: {
type: 'linear',
},
y1: {
stack: 'demo',
offset: true,
stackWeight: 1,
},
y2: {
stack: 'demo',
stackWeight: 2,
border:{
color: 'black',
width: 2
},
offset: true
},
y3: {
stack: 'demo',
offset: true,
stackWeight: 1
}
}
},
};
new Chart(document.querySelector('#chart1'), config);
<div style="width: 95vw">
<canvas id="chart1"></canvas>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-annotation/3.0.1/chartjs-plugin-annotation.min.js" integrity="sha512-Hn1w6YiiFw6p6S2lXv6yKeqTk0PLVzeCwWY9n32beuPjQ5HLcvz5l2QsP+KilEr1ws37rCTw3bZpvfvVIeTh0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>