Skip to content

Commit b6ac64a

Browse files
Enable mobile zoom and panning on uplot charts (cu progression and bank txn bars)
1 parent acc9d6d commit b6ac64a

File tree

10 files changed

+238
-43
lines changed

10 files changed

+238
-43
lines changed

src/features/Overview/SlotPerformance/ComputeUnitsCard/CuChart.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
getMaxTsWithBuffer,
2828
} from "../../../../transactionUtils";
2929
import { cuIsFullXRangePlugin } from "./cuIsFullXRangePlugin";
30+
import { touchPlugin } from "../../../../uplotReact/touchPlugin";
3031

3132
function getChartData(transactions: SlotTransactions) {
3233
const events = [
@@ -363,6 +364,7 @@ export default function CuChart({
363364
cuTooltipPlugin(setTooltipData),
364365
syncXScalePlugin(),
365366
cuIsFullXRangePlugin(),
367+
touchPlugin(),
366368
],
367369
};
368370
}, [

src/features/Overview/SlotPerformance/TransactionBarsCard/BarsChart.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { wheelZoomPlugin } from "../../../../uplotReact/wheelZoomPlugin";
1717
import { txnBarsUplotIdPrefix } from "./consts";
1818
import { syncXScalePlugin } from "../../../../uplotReact/syncXScalePlugin";
1919
import { leftAxisSizeAtom, rightAxisSizeAtom } from "../ComputeUnitsCard/atoms";
20+
import { touchPlugin } from "../../../../uplotReact/touchPlugin";
2021

2122
/** Buffer of the canvas past the axes of the chart to prevent the first and last tick labels from being cut off */
2223
const xBuffer = 20;
@@ -131,6 +132,7 @@ export default function BarsChart({
131132
timeScaleDragPlugin(),
132133
wheelZoomPlugin({ factor: 0.75 }),
133134
syncXScalePlugin(),
135+
touchPlugin(),
134136
],
135137
hooks: {
136138
ready: [

src/features/Overview/SlotPerformance/TransactionBarsCard/ChartControls.tsx

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
import { groupBy, max } from "lodash";
2424
import { CSSProperties, useEffect, useMemo, useState } from "react";
2525
import ToggleGroupControl from "./ToggleGroupControl";
26-
import { useMeasure, useUnmount } from "react-use";
26+
import { useMeasure, useMedia, useUnmount } from "react-use";
2727
import { errorCodeMap, FilterEnum, TxnState } from "./consts";
2828
import ToggleControl from "./ToggleControl";
2929
import toggleControlStyles from "./toggleControl.module.css";
@@ -41,10 +41,8 @@ interface ChartControlsProps {
4141
maxTs: number;
4242
}
4343

44-
export default function ChartControls({
45-
transactions,
46-
maxTs,
47-
}: ChartControlsProps) {
44+
export default function ChartControls(props: ChartControlsProps) {
45+
const { transactions, maxTs } = props;
4846
const setChartFilters = useSetAtom(chartFiltersAtom);
4947
const setBarCount = useSetAtom(barCountAtom);
5048
const setSelectedBank = useSetAtom(selectedBankAtom);
@@ -61,8 +59,12 @@ export default function ChartControls({
6159
setTxnState(TxnState.DEFAULT);
6260
});
6361

62+
if (useMedia("(max-width: 500px)")) {
63+
return <MobileViewChartControls {...props} />;
64+
}
65+
6466
return (
65-
<Flex align="center" gap="2" wrap="wrap">
67+
<Flex gap="2" align="center" wrap="wrap">
6668
<Separator orientation="vertical" size="2" />
6769
<ErrorControl transactions={transactions} maxTs={maxTs} />
6870
<Separator orientation="vertical" size="2" />
@@ -72,24 +74,33 @@ export default function ChartControls({
7274
<Separator orientation="vertical" size="2" />
7375
<SimpleControl transactions={transactions} maxTs={maxTs} />
7476
<Separator orientation="vertical" size="2" />
75-
<FeeControl transactions={transactions} />
76-
<TipsControl transactions={transactions} />
77-
<IncomeControl transactions={transactions} />
77+
<ToggleSeriesControls transactions={transactions} />
7878
<Separator orientation="vertical" size="2" />
79-
<Flex gap="2">
80-
<Text className={toggleControlStyles.label}>CU</Text>
81-
<CuConsumedControl transactions={transactions} />
82-
<CuRequestedControl transactions={transactions} />
83-
</Flex>
79+
<CuControls transactions={transactions} />
8480
<Separator orientation="vertical" size="2" />
8581
<ArrivalControl transactions={transactions} />
8682
</Flex>
8783
);
8884
}
8985

86+
function MobileViewChartControls({ transactions, maxTs }: ChartControlsProps) {
87+
return (
88+
<Flex direction="column" gap="3">
89+
<ErrorControl transactions={transactions} maxTs={maxTs} />
90+
<BundleControl transactions={transactions} maxTs={maxTs} isMobileView />
91+
<LandedControl transactions={transactions} maxTs={maxTs} isMobileView />
92+
<SimpleControl transactions={transactions} maxTs={maxTs} isMobileView />
93+
<ToggleSeriesControls transactions={transactions} />
94+
<CuControls transactions={transactions} />
95+
<ArrivalControl transactions={transactions} />
96+
</Flex>
97+
);
98+
}
99+
90100
interface ToggleGroupControlProps {
91101
transactions: SlotTransactions;
92102
maxTs: number;
103+
isMobileView?: boolean;
93104
}
94105

95106
function ErrorControl({ transactions, maxTs }: ToggleGroupControlProps) {
@@ -98,7 +109,7 @@ function ErrorControl({ transactions, maxTs }: ToggleGroupControlProps) {
98109
const [value, setValue] = useState<"All" | "Success" | "Errors">("All");
99110

100111
return (
101-
<>
112+
<Flex gap="2">
102113
<ToggleGroupControl
103114
options={["All", "Success", "Errors"]}
104115
optionColors={{ Success: "#30A46C", Errors: "#E5484D" }}
@@ -118,7 +129,7 @@ function ErrorControl({ transactions, maxTs }: ToggleGroupControlProps) {
118129
transactions={transactions}
119130
isDisabled={value === "Success"}
120131
/>
121-
</>
132+
</Flex>
122133
);
123134
}
124135

@@ -197,7 +208,11 @@ function HighlightErrorControl({
197208
);
198209
}
199210

200-
function BundleControl({ transactions, maxTs }: ToggleGroupControlProps) {
211+
function BundleControl({
212+
transactions,
213+
maxTs,
214+
isMobileView,
215+
}: ToggleGroupControlProps) {
201216
const uplotAction = useSetAtom(txnBarsUplotActionAtom);
202217
const filterBundle = useSetAtom(filterBundleDataAtom);
203218

@@ -212,11 +227,16 @@ function BundleControl({ transactions, maxTs }: ToggleGroupControlProps) {
212227
filterBundle(u, transactions, bankIdx, maxTs, value),
213228
)
214229
}
230+
hasMinTextWidth={isMobileView}
215231
/>
216232
);
217233
}
218234

219-
function LandedControl({ transactions, maxTs }: ToggleGroupControlProps) {
235+
function LandedControl({
236+
transactions,
237+
maxTs,
238+
isMobileView,
239+
}: ToggleGroupControlProps) {
220240
const uplotAction = useSetAtom(txnBarsUplotActionAtom);
221241
const filterLanded = useSetAtom(filterLandedDataAtom);
222242

@@ -231,11 +251,16 @@ function LandedControl({ transactions, maxTs }: ToggleGroupControlProps) {
231251
filterLanded(u, transactions, bankIdx, maxTs, value),
232252
)
233253
}
254+
hasMinTextWidth={isMobileView}
234255
/>
235256
);
236257
}
237258

238-
function SimpleControl({ transactions, maxTs }: ToggleGroupControlProps) {
259+
function SimpleControl({
260+
transactions,
261+
maxTs,
262+
isMobileView,
263+
}: ToggleGroupControlProps) {
239264
const uplotAction = useSetAtom(txnBarsUplotActionAtom);
240265
const filterSimple = useSetAtom(filterSimpleDataAtom);
241266

@@ -250,6 +275,7 @@ function SimpleControl({ transactions, maxTs }: ToggleGroupControlProps) {
250275
filterSimple(u, transactions, bankIdx, maxTs, value),
251276
)
252277
}
278+
hasMinTextWidth={isMobileView}
253279
/>
254280
);
255281
}
@@ -258,6 +284,16 @@ interface WithTransactionsProps {
258284
transactions: SlotTransactions;
259285
}
260286

287+
function ToggleSeriesControls({ transactions }: WithTransactionsProps) {
288+
return (
289+
<Flex gap="2">
290+
<FeeControl transactions={transactions} />
291+
<TipsControl transactions={transactions} />
292+
<IncomeControl transactions={transactions} />
293+
</Flex>
294+
);
295+
}
296+
261297
function FeeControl({ transactions }: WithTransactionsProps) {
262298
const [isEnabled, setIsEnabled] = useState(false);
263299
const uplotAction = useSetAtom(txnBarsUplotActionAtom);
@@ -308,6 +344,16 @@ function TipsControl({ transactions }: WithTransactionsProps) {
308344
);
309345
}
310346

347+
function CuControls({ transactions }: WithTransactionsProps) {
348+
return (
349+
<Flex gap="2">
350+
<Text className={toggleControlStyles.label}>CU</Text>
351+
<CuConsumedControl transactions={transactions} />
352+
<CuRequestedControl transactions={transactions} />
353+
</Flex>
354+
);
355+
}
356+
311357
function CuConsumedControl({ transactions }: WithTransactionsProps) {
312358
const [isEnabled, setIsEnabled] = useState(false);
313359
const uplotAction = useSetAtom(txnBarsUplotActionAtom);

src/features/Overview/SlotPerformance/TransactionBarsCard/ToggleGroupControl.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ import { ToggleGroup } from "radix-ui";
22
import { Flex, Text } from "@radix-ui/themes";
33
import styles from "./toggleGroupControl.module.css";
44
import { useState } from "react";
5+
import clsx from "clsx";
56

67
interface ToggleGroupControlProps<T extends string> {
78
label?: string;
89
options: T[];
910
defaultValue?: T;
1011
onChange: (value: T) => void;
1112
optionColors?: Partial<Record<T, string>>;
13+
hasMinTextWidth?: boolean;
1214
}
1315

1416
export default function ToggleGroupControl<T extends string>({
@@ -17,12 +19,21 @@ export default function ToggleGroupControl<T extends string>({
1719
defaultValue,
1820
onChange,
1921
optionColors,
22+
hasMinTextWidth,
2023
}: ToggleGroupControlProps<T>) {
2124
const [value, setValue] = useState(defaultValue);
2225

2326
return (
2427
<Flex align="center">
25-
{label && <Text className={styles.groupLabel}>{label}</Text>}
28+
{label && (
29+
<Text
30+
className={clsx(styles.groupLabel, {
31+
[styles.minTextWidth]: hasMinTextWidth,
32+
})}
33+
>
34+
{label}
35+
</Text>
36+
)}
2637
<ToggleGroup.Root
2738
className={styles.group}
2839
type="single"

src/features/Overview/SlotPerformance/TransactionBarsCard/toggleGroupControl.module.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
.group-label {
22
margin-right: 8px;
3+
4+
&.min-text-width {
5+
min-width: 50px;
6+
}
37
}
48

59
.group {

src/uplotReact/UplotReact.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { dataMatch, optionsUpdateState } from "./utils";
55
import { useThrottledCallback } from "use-debounce";
66
import { uplotChartsAtom } from "./uplotAtoms";
77
import { useSetAtom } from "jotai";
8+
import clsx from "clsx";
9+
import styles from "./uplot.module.css";
810

911
interface UplotReactProps {
1012
id: string;
@@ -146,5 +148,7 @@ export default function UplotReact({
146148
setDbSize();
147149
}
148150

149-
return target ? null : <div ref={targetRef} className={className}></div>;
151+
return target ? null : (
152+
<div ref={targetRef} className={clsx(styles.uplot, className)}></div>
153+
);
150154
}

0 commit comments

Comments
 (0)