143 lines
3.2 KiB
TypeScript
143 lines
3.2 KiB
TypeScript
import {
|
|
Axis,
|
|
Grid,
|
|
buildChartTheme,
|
|
LineSeries,
|
|
XYChart,
|
|
Annotation,
|
|
AnnotationLabel,
|
|
AnnotationConnector,
|
|
AnnotationCircleSubject,
|
|
} from "@visx/xychart";
|
|
import React from "react";
|
|
|
|
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;
|
|
};
|
|
}
|
|
|
|
const COLOURS = {
|
|
background: "#252D41",
|
|
salmon: "#ffcad0",
|
|
navy: "#2c3651",
|
|
white: "#ffffff",
|
|
pink: "#ef83b1",
|
|
darkpink: "#cc5773",
|
|
darkblue: "#354265",
|
|
};
|
|
|
|
const DEFAULT_LABEL_SIZE = 16;
|
|
|
|
export function LineGraph({ data, width, height, margin }: 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: COLOURS.background, // used by Tooltip, Annotation
|
|
colors: [COLOURS.pink], // categorical colors, mapped to series via `dataKey`s
|
|
|
|
tickLength: 5,
|
|
|
|
// grid
|
|
gridColor: "#354265",
|
|
gridColorDark: "#222831", // 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={COLOURS.background}
|
|
/>
|
|
|
|
<LineSeries
|
|
dataKey="Line 1"
|
|
data={data}
|
|
xAccessor={xAccessor}
|
|
yAccessor={yAccessor}
|
|
/>
|
|
|
|
<Annotation
|
|
dataKey="Line 1" // use this Series's accessor functions, alternatively specify x/yAccessor here
|
|
datum={data[2]}
|
|
dx={-40}
|
|
dy={-50}
|
|
>
|
|
<AnnotationLabel
|
|
title="Title"
|
|
subtitle="Subtitle deets"
|
|
showAnchorLine={false}
|
|
backgroundFill="#FFFFFF"
|
|
showBackground
|
|
/>
|
|
{/** Draw circle around point */}
|
|
<AnnotationCircleSubject />
|
|
{/** Connect label to CircleSubject */}
|
|
<AnnotationConnector />
|
|
</Annotation>
|
|
|
|
<Axis
|
|
orientation="bottom"
|
|
hideAxisLine
|
|
hideTicks
|
|
tickLabelProps={() => {
|
|
return {
|
|
dy: "0.25rem",
|
|
fill: COLOURS.white,
|
|
fontSize: `${width / 700}rem`,
|
|
fontFamily: "Inconsolata",
|
|
fontWeight: 800,
|
|
};
|
|
}}
|
|
/>
|
|
<Axis
|
|
orientation="left"
|
|
hideAxisLine
|
|
hideTicks
|
|
numTicks={4}
|
|
rangePadding={100}
|
|
tickLabelProps={() => {
|
|
return {
|
|
dy: "0.25rem",
|
|
fill: COLOURS.white,
|
|
fontSize: `${height / 300}rem`,
|
|
fontFamily: "Inconsolata",
|
|
fontWeight: 800,
|
|
};
|
|
}}
|
|
/>
|
|
<Grid numTicks={data.length} strokeWidth={0.5} strokeDasharray="6" />
|
|
</XYChart>
|
|
);
|
|
}
|