122 lines
2.7 KiB
TypeScript
122 lines
2.7 KiB
TypeScript
import {
|
|
Axis,
|
|
Grid,
|
|
buildChartTheme,
|
|
LineSeries,
|
|
XYChart,
|
|
Annotation,
|
|
AnnotationLabel,
|
|
AnnotationConnector,
|
|
AnnotationCircleSubject,
|
|
} from "@visx/xychart";
|
|
import React from "react";
|
|
import { Color } from "utils/Color";
|
|
|
|
import styles from "./LineGraph.module.css";
|
|
|
|
interface LineGraphData {
|
|
x: string;
|
|
y: number;
|
|
}
|
|
|
|
interface BarGraphProps {
|
|
data: LineGraphData[][];
|
|
width: number;
|
|
height: number;
|
|
margin: {
|
|
top: number;
|
|
bottom: number;
|
|
left: number;
|
|
right: number;
|
|
};
|
|
xLabelSize?: number;
|
|
yLabelSize?: number;
|
|
}
|
|
|
|
const DEFAULT_LABEL_SIZE = 16;
|
|
|
|
export function LineGraph({
|
|
data,
|
|
width,
|
|
height,
|
|
margin,
|
|
xLabelSize = DEFAULT_LABEL_SIZE,
|
|
yLabelSize = DEFAULT_LABEL_SIZE,
|
|
}: BarGraphProps) {
|
|
if (width < 10) return null;
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
|
const customTheme = buildChartTheme({
|
|
// colors
|
|
backgroundColor: Color.secondaryBackground, // used by Tooltip, Annotation
|
|
colors: [Color.primaryAccent, Color.primaryHeading], // categorical colors, mapped to series via `dataKey`s
|
|
|
|
tickLength: 5,
|
|
|
|
// grid
|
|
gridColor: Color.tertiaryBackground,
|
|
gridColorDark: Color.tertiaryBackground, // used for axis baseline if x/yxAxisLineStyles not set
|
|
});
|
|
|
|
// accessors
|
|
const xAccessor = (d: LineGraphData) => d.x;
|
|
const yAccessor = (d: LineGraphData) => d.y;
|
|
|
|
return (
|
|
<XYChart
|
|
height={height}
|
|
width={width}
|
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
theme={customTheme}
|
|
margin={margin}
|
|
xScale={{ type: "band" }}
|
|
yScale={{ type: "linear" }}
|
|
>
|
|
<rect
|
|
x={0}
|
|
y={0}
|
|
width={width}
|
|
height={height}
|
|
fill={Color.primaryBackground}
|
|
/>
|
|
|
|
{data.map((d, i) => (
|
|
<LineSeries
|
|
dataKey={i.toString()}
|
|
key={i}
|
|
data={d}
|
|
xAccessor={xAccessor}
|
|
yAccessor={yAccessor}
|
|
/>
|
|
))}
|
|
<Axis
|
|
orientation="bottom"
|
|
hideAxisLine
|
|
hideTicks
|
|
tickLabelProps={() => {
|
|
return {
|
|
dy: "0.25rem",
|
|
fontSize: `${xLabelSize / 16}rem`,
|
|
className: styles.axisLabel,
|
|
};
|
|
}}
|
|
/>
|
|
<Axis
|
|
orientation="left"
|
|
hideAxisLine
|
|
hideTicks
|
|
numTicks={4}
|
|
rangePadding={100}
|
|
tickLabelProps={() => {
|
|
return {
|
|
dy: "0.25rem",
|
|
className: styles.axisLabel,
|
|
fontSize: `${yLabelSize / 16}rem`,
|
|
};
|
|
}}
|
|
/>
|
|
<Grid numTicks={data[0].length} strokeWidth={0.5} strokeDasharray="6" />
|
|
</XYChart>
|
|
);
|
|
}
|