3👍
The Plugin Core API offers a range of hooks that may be used for performing custom code. You can use the afterLayout hook for creating a linear gradients considering the specified threshold. Then you’ll have to assign it to the borderColor
property of the dataset
.
Please take a look at the runnable code below and see hot it works.
const threshold = 25;
new Chart('myChart', {
type: 'line',
plugins: [{
afterLayout: chart => {
let ctx = chart.chart.ctx;
ctx.save();
let yAxis = chart.scales["y-axis-0"];
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
}]
},
options: {
legend: {
display: false
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="100"></canvas>
1👍
To make a graph with two bounds (one upper and one lower) as below, proceed as follows:
1. Set the thresholds
let yThresholdMax = yAxis.getPixelForValue(YOUR_MAX_THRESHOLD);
let yThresholdMin = yAxis.getPixelForValue(YOUR_MIN_THRESHOLD);
2. Create offsets
let offsetMax = 1 / yAxis.bottom * yThresholdMax;
let offsetMin= 1 / yAxis.bottom * yThresholdMin;
3. Instantiate the gradient
let gradient = ctx.createLinearGradient(0, yAxis.top, 0, yAxis.bottom);
4. Choose colours for each layer (from top to bottom)
//colour of the highest value of the chart
gradient.addColorStop(0, 'red');
//colour at the upper limit
gradient.addColorStop(offsetMax, 'darkred');
//colour from the upper limit to the lower limit
gradient.addColorStop(offsetMax, 'blue');
gradient.addColorStop(offsetMin, 'blue');
//colour at the lower limit
gradient.addColorStop(offsetMin,'darkred');
//colour at the lowest value of the chart
gradient.addColorStop(1,"red");
- Attribute gradient to the line
chart.data.datasets[0].borderColor = gradient;
Complete code :
var myLineChart = new Chart(ctx, {
type: 'line',
plugins: [{
afterLayout: chart => {
let ctx = chart.chart.ctx;
ctx.save();
let yAxis = chart.scales["y-axis-0"];
let yThresholdMax = yAxis.getPixelForValue(data.limits.max);
let yThresholdMin = yAxis.getPixelForValue(data.limits.min);
let offsetMax = 1 / yAxis.bottom * yThresholdMax;
let offsetMin= 1 / yAxis.bottom * yThresholdMin;
let gradient = ctx.createLinearGradient(0, yAxis.top, 0, yAxis.bottom);
gradient.addColorStop(0, 'red');
gradient.addColorStop(offsetMax, 'darkred');
gradient.addColorStop(offsetMax, 'blue');
gradient.addColorStop(offsetMin, 'blue');
gradient.addColorStop(offsetMin,'darkred');
gradient.addColorStop(1,"red");
chart.data.datasets[0].borderColor = gradient;
ctx.restore();
}
}],
// The data for our dataset
data: {
......
},
options: {
........
}
});
1👍
There’s a small issue with the other answers, the normalization is incorrect.
This line
let offset = 1 / yAxis.bottom * yThreshold;
It should be (Min-max normalization)
let offset = (yThreshold - yAxis.top) / (yAxis.bottom - yAxis.top);
Modifying uminder’s code, now you can see the color changes exactly at 25
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 = (yThreshold - yAxis.top) / (yAxis.bottom - yAxis.top);
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>