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?
CodePudding user response:
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'
}
}
}
};
CodePudding user response:
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>