Skip to content

Commit e97a9dd

Browse files
committed
chartstore fully implemented
1 parent 6354989 commit e97a9dd

5 files changed

Lines changed: 125 additions & 34 deletions

File tree

ethernet-view/src/components/ChartMenu/ChartElement/ChartCanvas/ChartCanvas.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
1-
import { MeasurementId, NumericMeasurementInfo, UpdateFunction, useGlobalTicker } from "common";
1+
import { MeasurementId, UpdateFunction, useGlobalTicker } from "common";
2+
import { ChartId, useChartStore } from "components/ChartMenu/ChartStore";
23
import { ColorType, IChartApi, ISeriesApi, UTCTimestamp, createChart } from "lightweight-charts";
34
import { useEffect, useRef } from "react";
45

56
type DataSerieAndUpdater = Map<MeasurementId, [ISeriesApi<"Line">, UpdateFunction]>;
67

78
interface Props {
8-
measurements: NumericMeasurementInfo[];
9+
chartId: ChartId
910
}
1011

1112
const CHART_HEIGHT = 300;
1213

13-
export const ChartCanvas = ({ measurements }: Props) => {
14+
export const ChartCanvas = ({ chartId }: Props) => {
15+
16+
const measurements = useChartStore((state) => {
17+
const chart = state.charts.find((chart) => chart.chartId === chartId);
18+
return chart ? chart.measurements : [];
19+
})
1420

1521
const chartContainerRef = useRef<HTMLDivElement>(null);
1622
const chart = useRef<IChartApi | null>(null);
@@ -42,6 +48,7 @@ export const ChartCanvas = ({ measurements }: Props) => {
4248
fixLeftEdge: true,
4349
fixRightEdge: true,
4450
lockVisibleTimeRangeOnResize: true,
51+
rightBarStaysOnScroll: true,
4552
}
4653
});
4754
}
Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
import styles from "./ChartElement.module.scss";
22
import { AiOutlineCloseCircle } from 'react-icons/ai'
3-
import { MeasurementId, NumericMeasurementInfo, useMeasurementsStore } from 'common';
4-
import { ChartId } from '../ChartMenu';
3+
import { useMeasurementsStore } from 'common';
54
import { ChartCanvas } from './ChartCanvas/ChartCanvas';
65
import { ChartLegend } from './ChartLegend/ChartLegend';
7-
import { memo, useState } from "react";
6+
import { ChartId, useChartStore } from "../ChartStore";
87

98
type Props = {
109
chartId: ChartId;
11-
initialMeasurement: NumericMeasurementInfo;
12-
removeChart(chartId: ChartId): void;
1310
};
1411

1512
// React component that keeps the chart render and measurements represented on it.
16-
export const ChartElement = memo(({ chartId, initialMeasurement, removeChart }: Props) => {
17-
const [measurementsInChart, setMeasurementsInChart] = useState<NumericMeasurementInfo[]>([initialMeasurement]);
13+
export const ChartElement = ({ chartId }: Props) => {
14+
15+
const addMeasurementToChart = useChartStore(state => state.addMeasurementToChart);
16+
const removeChart = useChartStore(state => state.removeChart);
1817
const getNumericMeasurementInfo = useMeasurementsStore(state => state.getNumericMeasurementInfo);
1918

2019
const handleDrop = (ev: React.DragEvent<HTMLDivElement>) => {
2120
ev.stopPropagation();
2221
const id = ev.dataTransfer.getData("id");
2322
const measurementInfo = getNumericMeasurementInfo(id);
24-
setMeasurementsInChart([...measurementsInChart, measurementInfo]);
23+
addMeasurementToChart(chartId, measurementInfo);
2524
};
2625

2726
return (
@@ -38,15 +37,12 @@ export const ChartElement = memo(({ chartId, initialMeasurement, removeChart }:
3837
onClick={() => removeChart(chartId)}
3938
/>
4039
<ChartCanvas
41-
measurements={measurementsInChart}
40+
chartId={chartId}
4241
/>
4342
<ChartLegend
4443
chartId={chartId}
45-
measurements={measurementsInChart}
46-
removeMeasurementFromChart={(measurementId: MeasurementId) => setMeasurementsInChart(measurementsInChart.filter(measurement => measurement.id !== measurementId))}
47-
removeChart={removeChart}
4844
/>
4945
</div>
5046
</div>
5147
);
52-
});
48+
};

ethernet-view/src/components/ChartMenu/ChartElement/ChartLegend/ChartLegend.tsx

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11
import styles from "./ChartLegend.module.scss";
22
import { useEffect, useRef } from "react";
33
import { MeasurementId, NumericMeasurementInfo } from "common";
4-
import { ChartId } from "components/ChartMenu/ChartStore";
4+
import { ChartId, useChartStore } from "components/ChartMenu/ChartStore";
5+
56

67
interface Props {
78
chartId: ChartId;
8-
measurements: NumericMeasurementInfo[];
9-
removeMeasurementFromChart(measurementId: MeasurementId): void;
10-
removeChart(chartId: ChartId): void;
119
}
1210

13-
export const ChartLegend = ({ chartId, measurements, removeMeasurementFromChart, removeChart }: Props) => {
11+
export const ChartLegend = ({ chartId }: Props) => {
1412

1513
const legendRef = useRef<HTMLDivElement>(null);
14+
15+
const measurements = useChartStore((state) => {
16+
const chart = state.charts.find((chart) => chart.chartId === chartId);
17+
return chart ? chart.measurements : [];
18+
});
19+
const removeMeasurementFromChart = useChartStore((state) => state.removeMeasurementFromChart);
20+
const removeChart = useChartStore((state) => state.removeChart);
1621

1722
const onRemoveMeasurement = (measurementId: MeasurementId) => {
18-
removeMeasurementFromChart(measurementId);
23+
removeMeasurementFromChart(chartId, measurementId);
1924
};
2025

2126
useEffect(() => {

ethernet-view/src/components/ChartMenu/ChartMenu.tsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,27 @@
11
import styles from "components/ChartMenu/ChartMenu.module.scss";
2-
import { DragEvent, useState } from "react";
2+
import { DragEvent } from "react";
33
import Sidebar from "components/ChartMenu/Sidebar/Sidebar";
44
import { Section } from "./Sidebar/Section/Section";
5-
import { NumericMeasurementInfo, useMeasurementsStore } from "common";
5+
import { useMeasurementsStore } from "common";
66
import { nanoid } from "nanoid";
77
import { ChartElement } from "./ChartElement/ChartElement";
8+
import { useChartStore } from "./ChartStore";
89

910
type Props = {
1011
sidebarSections: Section[];
1112
};
1213

13-
export type ChartId = string;
14-
export type ChartInfo = {
15-
chartId: ChartId,
16-
initialMeasurement: NumericMeasurementInfo
17-
};
18-
1914
export const ChartMenu = ({ sidebarSections }: Props) => {
20-
const [charts, setCharts] = useState<ChartInfo[]>([]);
15+
16+
const charts = useChartStore((state) => state.charts);
17+
const addChart = useChartStore((state) => state.addChart);
2118
const getNumericMeasurementInfo = useMeasurementsStore((state) => state.getNumericMeasurementInfo);
2219

2320
const handleDrop = (ev: DragEvent<HTMLDivElement>) => {
2421
ev.preventDefault();
2522
const id = ev.dataTransfer.getData("id");
2623
const initialMeasurementInfo = getNumericMeasurementInfo(id);
27-
setCharts([...charts, { chartId: nanoid(), initialMeasurement: initialMeasurementInfo }]);
24+
addChart(nanoid(), initialMeasurementInfo);
2825
};
2926

3027
if (sidebarSections.length == 0) {
@@ -49,8 +46,6 @@ export const ChartMenu = ({ sidebarSections }: Props) => {
4946
<ChartElement
5047
key={chart.chartId}
5148
chartId={chart.chartId}
52-
initialMeasurement={chart.initialMeasurement}
53-
removeChart={(chartId) => setCharts(charts.filter((chart) => chart.chartId !== chartId))}
5449
/>
5550
))}
5651
</div>
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { create } from 'zustand';
2+
import { NumericMeasurementInfo, MeasurementId } from 'common';
3+
4+
export type ChartId = string;
5+
6+
export type ChartInfo = {
7+
chartId: ChartId,
8+
measurements: NumericMeasurementInfo[]
9+
};
10+
export type ChartSet = ChartInfo[];
11+
export type ChartStore = {
12+
charts: ChartSet;
13+
addChart: (chartId: ChartId, initialMeasurement: NumericMeasurementInfo) => void;
14+
removeChart: (chartId: ChartId) => void;
15+
addMeasurementToChart: (chartId: ChartId, measurement: NumericMeasurementInfo) => void;
16+
removeMeasurementFromChart: (chartId: ChartId, measurementId: MeasurementId) => void;
17+
getMeasurementsFromChart: (chartId: ChartId) => NumericMeasurementInfo[] | undefined;
18+
};
19+
20+
export const useChartStore = create<ChartStore>((set, get) => ({
21+
charts: [] as ChartSet,
22+
23+
addChart: (chartId: ChartId, initialMeasurement: NumericMeasurementInfo) => {
24+
const newChart = {
25+
chartId: chartId,
26+
measurements: [initialMeasurement]
27+
};
28+
29+
set(state => ({
30+
...state,
31+
charts: [...state.charts, newChart]
32+
}));
33+
},
34+
removeChart: (chartId: ChartId) => {
35+
const chartsDraft = get().charts;
36+
const newCharts = chartsDraft.filter(chart => chart.chartId !== chartId);
37+
38+
set(state => ({
39+
...state,
40+
charts: newCharts
41+
}));
42+
},
43+
addMeasurementToChart: (chartId: ChartId, measurement: NumericMeasurementInfo) => {
44+
const chartsDraft = get().charts;
45+
const chartIndex = chartsDraft.findIndex(chart => chart.chartId === chartId);
46+
if(chartIndex != -1) {
47+
const chart = chartsDraft[chartIndex];
48+
if(!isMeasurementInChart(measurement.id, chart)) {
49+
chart.measurements.push(measurement);
50+
51+
set(state => ({
52+
...state,
53+
charts: [
54+
...state.charts.slice(0, chartIndex),
55+
chart,
56+
...state.charts.slice(chartIndex + 1)
57+
]
58+
}));
59+
}
60+
}
61+
},
62+
removeMeasurementFromChart: (chartId: ChartId, measurementId: MeasurementId) => {
63+
const chartsDraft = get().charts;
64+
const chartIndex = chartsDraft.findIndex(chart => chart.chartId === chartId);
65+
if(chartIndex != -1) {
66+
const chart = chartsDraft[chartIndex];
67+
const newMeasurements = chart.measurements.filter(measurement => measurement.id !== measurementId);
68+
chart.measurements = newMeasurements;
69+
70+
set(state => ({
71+
...state,
72+
charts: [
73+
...state.charts.slice(0, chartIndex),
74+
chart,
75+
...state.charts.slice(chartIndex + 1)
76+
]
77+
}));
78+
}
79+
},
80+
getMeasurementsFromChart: (chartId: ChartId) => {
81+
const chart = get().charts.find(chart => chart.chartId === chartId);
82+
return chart ? chart.measurements : undefined;
83+
}
84+
}));
85+
86+
function isMeasurementInChart(measurementId: MeasurementId, chart: ChartInfo) {
87+
return chart.measurements.some(measurement => measurement.id === measurementId);
88+
}

0 commit comments

Comments
 (0)