Skip to content

Commit 7db0ee5

Browse files
committed
gps is presentable now ig
1 parent d61c6c2 commit 7db0ee5

File tree

11 files changed

+175
-361
lines changed

11 files changed

+175
-361
lines changed

frontend/app/components/FlexLayoutComponent.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,25 @@ const model = Model.fromJson({
1818
type: "row",
1919
weight: 30,
2020
children: [
21+
// {
22+
// type: "tabset",
23+
// weight: 30,
24+
// children: [
25+
// {
26+
// type: "tab",
27+
// name: "Suspension",
28+
// component: "suspension-gauge",
29+
// },
30+
// ],
31+
// },
2132
{
2233
type: "tabset",
23-
weight: 30,
34+
weight: 33,
2435
children: [
2536
{
2637
type: "tab",
27-
name: "Suspension",
28-
component: "suspension-gauge",
38+
name: "GPS",
39+
component: "gps",
2940
},
3041
],
3142
},
@@ -52,17 +63,6 @@ const model = Model.fromJson({
5263
type: "row",
5364
weight: 70,
5465
children: [
55-
{
56-
type: "tabset",
57-
weight: 33,
58-
children: [
59-
{
60-
type: "tab",
61-
name: "GPS",
62-
component: "gps",
63-
},
64-
],
65-
},
6666
{
6767
type: "tabset",
6868
weight: 33,
@@ -175,7 +175,7 @@ export default function FlexLayoutComponent() {
175175
]}
176176
/>
177177
),
178-
"gps": <GPSInternal />,
178+
gps: <GPSInternal />,
179179
skeleton: <div className="w-full h-full bg-neutral-500"></div>,
180180
};
181181

frontend/app/components/visualizations/GPS/GPS.tsx

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
"use client";
2-
import React, { useState } from "react";
2+
import React, { useCallback, useState } from "react";
33

4-
import { ActionIcon, Checkbox, Menu, Slider } from "@mantine/core";
4+
import { Text, Button, ActionIcon, Checkbox, Menu, Slider } from "@mantine/core";
55
import { Gear, GlobeHemisphereWest, LineVertical } from "@phosphor-icons/react";
66
import GPSInternal from "./GPSInternal";
77

88
export default function GPS() {
99
const [useLeaflet, setUseLeaflet] = useState(true);
1010
const [useBgSeries, setUseBgSeries] = useState(false);
11+
const [trackThickness, setTrackThickness] = useState(25);
12+
const [carLineThickness, setCarLineThickness] = useState(5);
13+
const reset = useCallback(() => {
14+
setUseBgSeries(false);
15+
setUseLeaflet(true);
16+
setTrackThickness(25);
17+
setCarLineThickness(5);
18+
}, []);
1119

1220
return (
1321
<>
@@ -37,17 +45,40 @@ export default function GPS() {
3745
// {<LineVertical size={14} weight="bold" />}
3846
/>
3947
</Menu.Item>
48+
<Menu.Divider />
4049
<Menu.Item>
41-
<Slider step={1} min={10} max={50} value={25} label="Track thickness" />
50+
<Text>Track Thickness</Text>
51+
<Slider
52+
step={1}
53+
min={10}
54+
max={50}
55+
value={trackThickness}
56+
onChange={setTrackThickness}
57+
/>
4258
</Menu.Item>
4359
<Menu.Item>
44-
<Slider step={1} min={10} max={50} value={25} label="Line thickness" />
60+
<Text>Car Line Thickness</Text>
61+
<Slider
62+
step={1}
63+
min={1}
64+
max={15}
65+
value={carLineThickness}
66+
onChange={setCarLineThickness}
67+
/>
4568
</Menu.Item>
69+
<Menu.Divider />
70+
<Menu.Item onClick={reset}>Reset</Menu.Item>
71+
4672
{/* todo: configure gradient keynames via dropdown */}
4773
</Menu.Dropdown>
4874
</Menu>
4975
<div>
50-
<GPSInternal useLeaflet={useLeaflet} useBgSeries={useBgSeries} />
76+
<GPSInternal
77+
useLeaflet={useLeaflet}
78+
useBgSeries={useBgSeries}
79+
trackThickness={trackThickness}
80+
carLineThickness={carLineThickness}
81+
/>
5182
</div>
5283
</>
5384
);

frontend/app/components/visualizations/GPS/GPSInternal.tsx

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
transparentFill,
1414
emptyLine,
1515
ChartXY,
16+
PointLineAreaSeries,
1617
} from "@lightningchart/lcjs";
1718
import { LightningChartsContext } from "../lightning-charts/GlobalContext";
1819
import globalTheme from "../lightning-charts/GlobalTheme";
@@ -26,11 +27,24 @@ const Leaflet = dynamic(() => import("./Leaflet").then((o) => o), { ssr: false }
2627
const LAT_COLNAME = "VDM_GPS_Latitude"; // "GPSi_Latitude";
2728
const LNG_COLNAME = "VDM_GPS_Longitude"; // "GPSi_Longitude";
2829

30+
const defaultBgSeriesStrokeStyle = new SolidLine({
31+
// this is just the default; its set again below
32+
thickness: 25,
33+
fillStyle: new SolidFill({ color: ColorHEX("#808080") }),
34+
});
35+
2936
interface GPSInternalProps {
3037
useLeaflet: boolean;
3138
useBgSeries: boolean;
39+
trackThickness: number;
40+
carLineThickness: number;
3241
}
33-
export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProps) {
42+
export default function GPSInternal({
43+
useLeaflet,
44+
useBgSeries,
45+
trackThickness,
46+
carLineThickness,
47+
}: GPSInternalProps) {
3448
const {
3549
subscribeViewInterval,
3650
subscribeLatestArrays,
@@ -43,10 +57,13 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
4357
const containerRef = useRef(null);
4458
const lc = useContext(LightningChartsContext);
4559
const chartRef = useRef<ChartXY>(null);
46-
// const previousViewIntervalRef = useRef<[left: number, right: number]>([0, 0]);
60+
4761
// referenced in multiple places bellow. Only for avoiding frequent allocation
4862
const allZeroArray = useMemo(() => new Float32Array(MAX_DATA_ROWS).fill(0), []);
49-
// const allOneArray = useMemo(() => new Float32Array(MAX_DATA_ROWS).fill(1), []);
63+
const allOneArray = useMemo(() => new Float32Array(MAX_DATA_ROWS).fill(1), []);
64+
65+
const bgSeriesRef = useRef<PointLineAreaSeries | null>(null);
66+
const visibleSeriesRef = useRef<PointLineAreaSeries | null>(null);
5067

5168
// Based on https://lightningchart.com/js-charts/docs/features/xy/freeform-line/
5269
useEffect(() => {
@@ -62,7 +79,8 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
6279
defaultAxisX: { type: "linear-highPrecision" },
6380
defaultAxisY: { type: "linear-highPrecision" },
6481
})
65-
.setCursorMode(undefined) // "show-pointed"
82+
// afaik you can't easily share pointer events between two overlapping divs
83+
.setCursorMode(useLeaflet ? undefined : "show-pointed")
6684
.setPadding(0)
6785
.setSeriesBackgroundFillStyle(transparentFill)
6886
.setSeriesBackgroundStrokeStyle(emptyLine);
@@ -74,24 +92,24 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
7492
.addPointLineAreaSeries({
7593
dataPattern: null,
7694
dataStorage: Float32Array,
77-
automaticColorIndex: 0,
7895
lookupValues: true,
7996
// todo: enable an LUT for color based on lap #???
8097
})
8198
.setDrawOrder({ seriesDrawOrderIndex: 2 })
8299
.setSamples({
83100
xValues: viewableArraysRef.current[LNG_COLNAME]!,
84101
yValues: viewableArraysRef.current[LAT_COLNAME]!,
85-
lookupValues: allZeroArray.subarray(0, viewableArraysRef.current[timeColumnName]!.length + 1),
102+
lookupValues: allOneArray.subarray(
103+
0,
104+
viewableArraysRef.current[timeColumnName]?.length ?? 0 + 1,
105+
),
86106
})
87107
.setAreaFillStyle(emptyFill)
88108
.setPointFillStyle(emptyFill)
89-
.setPointSize(0)
90-
// .setPointFillStyle(new SolidFill({ color: ColorRGBA(0, 200, 0, 100) })) // TODO: some sort of LUT gradient
91-
// .setPointSize(2)
109+
// .setPointSize(0)
92110
.setStrokeStyle(
93111
new SolidLine({
94-
thickness: 5,
112+
thickness: carLineThickness,
95113
fillStyle: new PalettedFill({
96114
lookUpProperty: "value",
97115
lut: new LUT({
@@ -104,31 +122,33 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
104122
}),
105123
}),
106124
)
107-
.setCurvePreprocessing({ type: "spline" });
125+
// splines aren't supported for freeform (non-progressive) data :/
126+
// .setCurvePreprocessing({ type: "spline" });
127+
visibleSeriesRef.current = visibleSeries;
128+
108129
let bgSeries = chart
109130
.addPointLineAreaSeries({
110131
dataPattern: null,
111132
dataStorage: Float32Array,
112-
automaticColorIndex: 0,
113133
})
114134
.setDrawOrder({ seriesDrawOrderIndex: 1 })
115135
.setSamples({
116136
xValues: dataArraysRef.current[LNG_COLNAME]!,
117137
yValues: dataArraysRef.current[LAT_COLNAME]!,
118138
})
119139
.setAreaFillStyle(emptyFill)
120-
.setPointFillStyle(emptyFill)
121-
.setStrokeStyle(
122-
new SolidLine({
123-
thickness: 25,
124-
fillStyle: new SolidFill({ color: ColorHEX("#808080") }),
125-
}),
126-
);
140+
.setPointFillStyle(emptyFill);
141+
bgSeriesRef.current = bgSeries;
127142

128143
chart.forEachAxis((a) => {
129144
a.setIntervalRestrictions(undefined);
130145
a.setThickness(0);
131146
a.setTickStrategy(AxisTickStrategies.Empty);
147+
// todo: instead of this, we need logic within Leaflet.tsx
148+
// a.setDefaultInterval((state) => ({
149+
// start: state.dataMin,
150+
// end: state.dataMax,
151+
// }));
132152
});
133153

134154
chart.setTitle("");
@@ -145,8 +165,8 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
145165

146166
const unsub1 = subscribeLatestArrays((latest) => {
147167
bgSeries.appendSamples({
148-
xValues: latest[LAT_COLNAME]!,
149-
yValues: latest[LNG_COLNAME]!,
168+
xValues: latest[LNG_COLNAME]!,
169+
yValues: latest[LAT_COLNAME]!,
150170
});
151171
visibleSeries.appendSamples({
152172
xValues: latest[LNG_COLNAME]!,
@@ -156,11 +176,12 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
156176
});
157177
});
158178
const unsub2 = subscribeViewInterval(([left, right]) => {
179+
// console.log(left, right);
180+
159181
// visibleSeries.setSamples({
160182
// xValues: viewableArraysRef.current[LAT_COLNAME]!,
161183
// yValues: viewableArraysRef.current[LONG_COLNAME]!,
162184
// });
163-
// TODO: modify `sizes` in dataset
164185
visibleSeries.fill({ lookupValue: 0 });
165186

166187
// We need +1 as left and right from dataProvider are both inclusive
@@ -172,7 +193,6 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
172193
// channel starting at the correct index
173194
visibleSeries.alterSamples(left, {
174195
// todo: this doesn't work with data cleaning
175-
// lookupValues: allOneArray.subarray(0, right - left + 1 + 1),
176196
lookupValues: gradient,
177197
});
178198
});
@@ -199,21 +219,40 @@ export default function GPSInternal({ useLeaflet, useBgSeries }: GPSInternalProp
199219
}, [lc]);
200220

201221
useEffect(() => {
202-
222+
if (bgSeriesRef.current) {
223+
bgSeriesRef.current.setStrokeStyle(
224+
useBgSeries
225+
? defaultBgSeriesStrokeStyle.setThickness(trackThickness)
226+
: emptyLine,
227+
);
228+
}
203229
}, [useBgSeries]);
204230

205-
return useLeaflet ? (
231+
useEffect(() => {
232+
if (bgSeriesRef.current) {
233+
bgSeriesRef.current.setStrokeStyle((style) => style.setThickness(trackThickness));
234+
}
235+
}, [trackThickness]);
236+
useEffect(() => {
237+
if (visibleSeriesRef.current) {
238+
visibleSeriesRef.current.setStrokeStyle((style) =>
239+
style.setThickness(carLineThickness),
240+
);
241+
}
242+
}, [carLineThickness]);
243+
244+
return (
206245
<>
207-
<div className="absolute w-[100%] h-[100%] z-0">
208-
<Leaflet chartRef={chartRef} />
209-
</div>
246+
{useLeaflet ? (
247+
<div className="absolute w-[100%] h-[100%] z-0">
248+
<Leaflet chartRef={chartRef} />
249+
</div>
250+
) : null}
210251
<div
211252
id={id}
212253
ref={containerRef}
213-
className="absolute pointer-events-none w-[100%] h-[100%] z-40,"
254+
className="absolute pointer-events-none w-[100%] h-[100%] z-40"
214255
></div>
215256
</>
216-
) : (
217-
<div id={id} ref={containerRef} className="w-[100%] h-[100%] z-40"></div>
218257
);
219258
}

0 commit comments

Comments
 (0)