Skip to content

Commit 6226f61

Browse files
chore: dynamic shreds chart scale
1 parent 71659dc commit 6226f61

File tree

1 file changed

+53
-9
lines changed

1 file changed

+53
-9
lines changed

src/features/Overview/ShredsProgression/ShredsChart.tsx

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
11
import UplotReact from "../../../uplotReact/UplotReact";
22
import AutoSizer from "react-virtualized-auto-sizer";
3-
import { useCallback, useMemo, useRef } from "react";
3+
import { useCallback, useEffect, useMemo, useRef } from "react";
44
import type uPlot from "uplot";
55
import { chartAxisColor, gridLineColor, gridTicksColor } from "../../../colors";
66
import type { AlignedData } from "uplot";
77
import { xRangeMs } from "./const";
88
import { shredsProgressionPlugin } from "./shredsProgressionPlugin";
9-
import { useRafLoop } from "react-use";
9+
import { useMedia, useRafLoop } from "react-use";
1010
import { Box } from "@radix-ui/themes";
1111

1212
const REDRAW_INTERVAL_MS = 40;
13+
1314
// prevent x axis tick labels from being cut off
1415
const chartXPadding = 15;
15-
const chartData: AlignedData = [[-xRangeMs, 0], new Array(2)];
1616

17-
const minXIncrement = 1600;
18-
const getXIncrs = () => {
19-
const incrs = [minXIncrement];
20-
while (incrs[incrs.length - 1] < xRangeMs) {
17+
const minXIncrRange = {
18+
min: 200,
19+
max: 1_600,
20+
};
21+
22+
/**
23+
* Get dynamic x axis tick increments based on chart scale
24+
*/
25+
const getXIncrs = (scale: number) => {
26+
const scaledIncr = scale * minXIncrRange.max;
27+
// round to multiples of minimum increment
28+
const minIncrMultiple =
29+
Math.trunc(scaledIncr / minXIncrRange.min) * minXIncrRange.min;
30+
31+
const incrs = [minIncrMultiple];
32+
while (incrs[incrs.length - 1] < xRangeMs * scale) {
2133
incrs.push(incrs[incrs.length - 1] * 2);
2234
}
2335
return incrs;
2436
};
25-
const xIncrs = getXIncrs();
2637

2738
interface ShredsChartProps {
2839
chartId: string;
@@ -32,13 +43,46 @@ export default function ShredsChart({
3243
chartId,
3344
isOnStartupScreen,
3445
}: ShredsChartProps) {
46+
const isXL = useMedia("(max-width: 2100px)");
47+
const isL = useMedia("(max-width: 1800px)");
48+
const isM = useMedia("(max-width: 1500px)");
49+
const isS = useMedia("(max-width: 1200px)");
50+
const isXS = useMedia("(max-width: 900px)");
51+
const isXXS = useMedia("(max-width: 600px)");
52+
const scale = isXXS
53+
? 1 / 7
54+
: isXS
55+
? 2 / 7
56+
: isS
57+
? 3 / 7
58+
: isM
59+
? 4 / 7
60+
: isL
61+
? 5 / 7
62+
: isXL
63+
? 6 / 7
64+
: 1;
65+
3566
const uplotRef = useRef<uPlot>();
3667
const lastRedrawRef = useRef(0);
3768

3869
const handleCreate = useCallback((u: uPlot) => {
3970
uplotRef.current = u;
4071
}, []);
4172

73+
const [chartData, xIncrs] = useMemo(() => {
74+
return [
75+
[[Math.trunc(scale * -xRangeMs), 0], new Array(2)] satisfies AlignedData,
76+
getXIncrs(scale),
77+
];
78+
}, [scale]);
79+
80+
useEffect(() => {
81+
if (!uplotRef.current) return;
82+
uplotRef.current.axes[0].incrs = () => xIncrs;
83+
uplotRef.current.setData(chartData, true);
84+
}, [chartData, xIncrs]);
85+
4286
const options = useMemo<uPlot.Options>(() => {
4387
return {
4488
padding: [0, chartXPadding, 0, chartXPadding],
@@ -94,7 +138,7 @@ export default function ShredsChart({
94138
],
95139
plugins: [shredsProgressionPlugin(isOnStartupScreen)],
96140
};
97-
}, [isOnStartupScreen]);
141+
}, [isOnStartupScreen, xIncrs]);
98142

99143
useRafLoop((time: number) => {
100144
if (!uplotRef) return;

0 commit comments

Comments
 (0)