I just want to change the graph color based on previous value. Like if previous value is greater than present value-- means graph declining, I've to show red if it's vice-versa then I've to show green like this.
###Expected output###
For now what I'm doing is I've setting some threshold & I'm doing it.
const threshold = 97.5;
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: ['1', '2', '3', '4', '5', '6','7', '8', '9','10', '11', '12','13', '14', '15','16', '17', '18','19', '20', '21','22', '23'],
datasets: [{
label: 'My Dataset',
data: [97.5, 98, 99.2, 98.2, 97, 98, 98.5,97.5, 98, 99.2, 98.2, 97, 98, 98.5,97.5, 98, 99.2, 98.2, 97, 98, 98.5,98, 98.1 ],
fill: false
}]
},
options: {
legend: {
display: false
}
}
});
You guys can help me with any suggestions pls?. Have you guys worked on similar scenarios?
it's not exactly the same as your requirement, but results in kinda similar output,
logic: separated the points into two lines, and plotted both on the graph,
you can tune some graph settings to get the same view.
let redLine = [];
let greenLine = [];
let points = [
{ x: 1, y: 1 },
{ x: 2, y: 2 },
{ x: 3, y: 1 },
{ x: 4, y: 5 },
{ x: 5, y: 2 },
{ x: 6, y: 5 },
{ x: 7, y: 8 },
{ x: 8, y: 9 },
{ x: 9, y: 2 },
{ x: 10, y: 1 },
{ x: 11, y: 9 },
{ x: 12, y: 6 },
{ x: 13, y: 7 },
{ x: 14, y: 3 },
{ x: 15, y: 6 },
];
points.forEach((point, index) => {
let isIncreasing = false;
if (index > 0) {
isIncreasing = point.y > points[index - 1].y;
(isIncreasing ? redLine : greenLine).push(NaN);
greenLine.push(point);
redLine.push(point);
} else {
// index === 1 && (isIncreasing ? greenLine : redLine).push(points[0]);
greenLine.push(point);
redLine.push(point);
}
});
const data = {
datasets: [
{
data: greenLine,
backgroundColor: 'rgb(165, 95, 0,0.3)',
borderColor: 'rgb(0, 255, 0)',
borderWidth: 1,
showLine: true,
spanGaps: false,
fill: "start",
tension:0.2
},
{
data: redLine,
backgroundColor: 'rgb(165, 95, 0,0.3)',
borderColor: 'rgb(255, 0, 0)',
borderWidth: 1,
showLine: true,
spanGaps: false,
fill: "start",
tension:0.2
}],
};
const config = {
type: 'scatter',
data: data,
options: {
scales: {
x: {
type: 'linear',
position: 'bottom'
}
}
}
};
You can use segments for this:
const options = {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
segment: {
borderColor: (ctx) => (ctx.p0.parsed.y < ctx.p1.parsed.y ? 'green' : 'red')
}
}]
},
options: {}
}
const ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.js"></script>
</body>