WIP: Line Graph Component #21
|
@ -33,4 +33,4 @@
|
|||
font-family: "Inconsolata", monospace;
|
||||
font-weight: 800;
|
||||
fill: var(--label);
|
||||
}
|
||||
}
|
|
@ -5,13 +5,12 @@
|
|||
fill: var(--label);
|
||||
}
|
||||
|
||||
.lineGroup:hover .line {
|
||||
fill: var(--primary-accent);
|
||||
filter: drop-shadow(0 0 calc(4rem / 16) var(--primary-accent));
|
||||
.lineSeries {
|
||||
/* fill: var(--label); */
|
||||
}
|
||||
|
||||
.lineGroup:hover .lineText {
|
||||
visibility: visible;
|
||||
.lineSeries:hover {
|
||||
filter: drop-shadow(0 0 calc(4rem / 16) var(--primary-accent));
|
||||
}
|
||||
|
||||
.axisLabel {
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import { localPoint } from "@visx/event";
|
||||
import {
|
||||
useTooltip,
|
||||
useTooltipInPortal,
|
||||
TooltipWithBounds,
|
||||
} from "@visx/tooltip";
|
||||
import {
|
||||
Axis,
|
||||
Grid,
|
||||
buildChartTheme,
|
||||
LineSeries,
|
||||
XYChart,
|
||||
Annotation,
|
||||
AnnotationLabel,
|
||||
AnnotationConnector,
|
||||
AnnotationCircleSubject,
|
||||
} from "@visx/xychart";
|
||||
import React from "react";
|
||||
import { Color } from "utils/Color";
|
||||
|
@ -19,7 +21,7 @@ interface LineGraphData {
|
|||
y: number;
|
||||
}
|
||||
|
||||
interface BarGraphProps {
|
||||
interface LineGraphProps {
|
||||
data: LineGraphData[][];
|
||||
width: number;
|
||||
height: number;
|
||||
|
@ -33,7 +35,12 @@ interface BarGraphProps {
|
|||
yLabelSize?: number;
|
||||
|
||||
}
|
||||
|
||||
interface TooltipData {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
const DEFAULT_LABEL_SIZE = 16;
|
||||
let tooltipTimeout: number;
|
||||
|
||||
export function LineGraph({
|
||||
a258wang
commented
Is it possible to cast this to a type (maybe visx has a type we can import?) to get rid of the unsafe assignment complaints? Is it possible to cast this to a type (maybe visx has a type we can import?) to get rid of the unsafe assignment complaints?
|
||||
data,
|
||||
|
@ -42,8 +49,31 @@ export function LineGraph({
|
|||
margin,
|
||||
xLabelSize = DEFAULT_LABEL_SIZE,
|
||||
yLabelSize = DEFAULT_LABEL_SIZE,
|
||||
}: BarGraphProps) {
|
||||
if (width < 10) return null;
|
||||
}: LineGraphProps) {
|
||||
const {
|
||||
tooltipData,
|
||||
tooltipLeft,
|
||||
tooltipTop,
|
||||
tooltipOpen,
|
||||
showTooltip,
|
||||
hideTooltip,
|
||||
} = useTooltip();
|
||||
|
||||
const { containerRef, TooltipInPortal } = useTooltipInPortal({
|
||||
// use TooltipWithBounds
|
||||
detectBounds: true,
|
||||
// when tooltip containers are scrolled, this will correctly update the Tooltip position
|
||||
scroll: true,
|
||||
});
|
||||
|
||||
const handleMouseOver = (event: React.MouseEvent<SVGRectElement>, datum) => {
|
||||
const coords = localPoint(event);
|
||||
showTooltip({
|
||||
tooltipLeft: coords.x,
|
||||
tooltipTop: coords.y,
|
||||
tooltipData: datum,
|
||||
});
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
||||
const customTheme = buildChartTheme({
|
||||
|
@ -63,59 +93,81 @@ export function LineGraph({
|
|||
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}
|
||||
ref={containerRef}
|
||||
width={width}
|
||||
height={height}
|
||||
fill={Color.primaryBackground}
|
||||
/>
|
||||
>
|
||||
<XYChart
|
||||
height={height}
|
||||
width={width}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
theme={customTheme}
|
||||
margin={margin}
|
||||
xScale={{ type: "band" }}
|
||||
yScale={{ type: "linear" }}
|
||||
>
|
||||
<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={50}
|
||||
strokeDasharray="10"
|
||||
/>
|
||||
{data.map((d, i) => (
|
||||
<LineSeries
|
||||
enableEvents
|
||||
className={styles.lineSeries} // Why doesn't work???
|
||||
dataKey={i.toString()}
|
||||
key={i}
|
||||
data={d}
|
||||
xAccessor={xAccessor}
|
||||
yAccessor={yAccessor}
|
||||
// onFocus={handleMouseOver}
|
||||
// onMouseOut={hideTooltip}
|
||||
/>
|
||||
))}
|
||||
</XYChart>
|
||||
</rect>
|
||||
|
||||
{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>
|
||||
{tooltipOpen && (
|
||||
<TooltipInPortal
|
||||
// set this to random so it correctly updates with parent bounds
|
||||
key={Math.random()}
|
||||
top={tooltipTop}
|
||||
left={tooltipLeft}
|
||||
>
|
||||
Data value <strong>{tooltipData}</strong>
|
||||
</TooltipInPortal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
This probably shouldn't be hard coded in the final component 😛