'Changing line color below specific value in Chart.js
I am trying to color the line below a specific value a certain color. I am using Chart.js v3.7.1
I have implemented the solution found in this answer with partial success...
let posColour= 'rgb(86,188,77)';
let negColour= 'rgb(229,66,66)';
let config = {
type: 'line',
data: {
labels: labels,
datasets: [{
label: tempData.sensorName,
data: data,
backgroundColor: 'rgba(60,141,188,0.9)',
borderColor: posColour,
pointRadius: false,
pointColor: '#3b8bba',
pointStrokeColor: posColour,
pointHighlightFill: '#fff',
pointHighlightStroke: posColour,
segment: {
borderColor: (ctx2) => (ctx2.chart.data.datasets[0].data[ctx2.p0DataIndex] < 40 ? negColour : posColour)
}
}]
}
/* items below here are not necessary to reproduce the issue */
,
options: {
reponsive: true,
scales: {
x: {
type: 'time',
time: {
displayFormats: timeFormat,
format: 'day'
},
ticks: {
major: {
enabled: true
},
maxTicksLimit: 15
},
title: {
display: true,
text: 'Date'
}
},
y: {
title: {
display: true,
text: 'Temp (\u00b0C)'
}
}
}
}
/* items above here are not necessary to reproduce the issue */
}
I am aware that I can do it very simply with a fill, but the visible impact of the inversed area chart is not the visual effect I am seeking.
I am looking for something like this answer, but I cannot get the last two lines to work (I am not familiar enough with ChartJS).
let posColour= 'rgb(86,188,77)';
let negColour= 'rgb(229,66,66)';
plugins: [{
beforeRender: (x, options) => {
const c = x.chartArea; //tweaked for chart.js3
const dataset = x.data.datasets[0];
const yScale = x.scales.y; //tweaked for chart.js3
const yPos = yScale.getPixelForValue(40); //I want everything under 40 red, not 0 as the original answer...
const gradientFill = c.ctx.createLinearGradient(0, 0, 0, c.height);
gradientFill.addColorStop(0, posColour);
gradientFill.addColorStop(yPos / c.height, posColour);
gradientFill.addColorStop(yPos / c.height, negColour);
gradientFill.addColorStop(1, negColour);
//these two lines are the ones i can't figure out how to convert to chart.js3...
const model = x.data.datasets[0]._meta[Object.keys(dataset._meta)[0]].dataset._model;
model.borderColor = gradientFill;
},
}];
Solution 1:[1]
The solution provided by this answer can easily be adapted to also work with Chart.js v3.7.1.
Please take a look at below runnable code and see how it works.
const threshold = 25;
new Chart('myChart', {
type: 'line',
plugins: [{
afterLayout: chart => {
let ctx = chart.ctx;
ctx.save();
let yAxis = chart.scales.y;
let yThreshold = yAxis.getPixelForValue(threshold);
let gradient = ctx.createLinearGradient(0, yAxis.top, 0, yAxis.bottom);
gradient.addColorStop(0, 'green');
let offset = 1 / yAxis.bottom * yThreshold;
gradient.addColorStop(offset, 'green');
gradient.addColorStop(offset, 'red');
gradient.addColorStop(1, 'red');
chart.data.datasets[0].borderColor = gradient;
ctx.restore();
}
}],
data: {
labels: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
datasets: [{
label: 'My Dataset',
data: [32, 44, 29, 33, 18, 15, 30],
fill: false,
lineTension: 0.2
}]
},
options: {
plugins: {
legend: {
display: false
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
<canvas id="myChart" height="80"></canvas>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |