I am attempting to create a line chart where the color of the line is dependant upon the value being plotted. For example if the value is above the following thresholds [0,60,80] then the color would be either ['green', 'yellow', 'red'] respectively. currently I am using @nivo/line here is the code
import { ResponsiveLine } from "@nivo/line";
const lineData = [
{
id: "linechart",
data: [
{
x: "12 AM",
y: 40,
},
{
x: "1 AM",
y: 50,
},
{
x: "2 AM",
y: 70,
},
{
x: "3 AM",
y: 75,
},
{
x: "4 AM",
y: 90,
},
{
x: "5 AM",
y: 85,
},
{
x: "6 AM",
y: 65,
},
{
x: "7 AM",
y: 60,
},
{
x: "8 AM",
y: 50,
},
{
x: "9 AM",
y: 70,
},
{
x: "10 AM",
y: 90,
},
{
x: "11 AM",
y: 50,
},
{
x: "12 PM",
y: 30,
},
],
},
];
const getColorForValue = (value: number) => {
if (value <= 60) return "green";
if (value <= 80) return "yellow";
return "red";
};
const CustomLineLayer = ({ data, xScale, yScale }: any) => {
return data.map((dataSeries: any, lineIndex: any) => {
const lineSegments = [];
for (let i = 0; i < dataSeries.data.length - 1; i++) {
const point1 = dataSeries.data[i];
const point2 = dataSeries.data[i + 1];
const x1 = xScale(point1.x);
const y1 = yScale(point1.y);
const x2 = xScale(point2.x);
const y2 = yScale(point2.y);
const color = getColorForValue(point1.y);
lineSegments.push(
<line
key={`line-segment-${lineIndex}-${i}`}
x1={x1}
y1={y1}
x2={x2}
y2={y2}
stroke={color}
strokeWidth={2}
/>
);
}
return <g key={`line-${lineIndex}`}>{lineSegments}</g>;
});
};
export const MyResponsiveLineChart = () => (
<ResponsiveLine
data={lineData}
margin={{ top: 50, right: 50, bottom: 50, left: 50 }}
xScale={{ type: "point" }}
yScale={{
type: "linear",
min: 0,
max: 100,
}}
layers={["grid", "markers", "axes", CustomLineLayer]}
gridYValues={[60, 80, 100]}
lineWidth={3}
yFormat=" >-.2f"
axisTop={null}
axisRight={null}
theme={{
fontSize: 14,
grid: {
line: {
strokeDasharray: "6 6",
},
},
}}
axisBottom={{
tickSize: 5,
tickPadding: 10,
tickRotation: 0,
}}
axisLeft={{
tickSize: 0,
tickPadding: 10,
tickRotation: 0,
}}
enableGridX={false}
enableGridY={true}
curve="natural"
# animate={true}
/>
);
And the output looks like this output is not as smooth curve and the line is changing the color but not in specified range like 0 to 60 it should be green ,61 to 80 it should be yellow and 81 to 100 red. If anybody know the solution for this please let me know.
For anyone interested, i had the same problem and came up with this:
It's using the same data, hope it helps.
It looks like this