Skip to content

Commit 20e8318

Browse files
committed
restructure chart menu component
1 parent ce80d3d commit 20e8318

9 files changed

Lines changed: 153 additions & 171 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
export const ChartCanvas = () => {
3+
return (
4+
<div>ChartCanvas</div>
5+
)
6+
}

ethernet-view/src/components/ChartMenu/ChartList/ChartElement/ChartElement.module.scss renamed to ethernet-view/src/components/ChartMenu/ChartElement/ChartElement.module.scss

File renamed without changes.

ethernet-view/src/components/ChartMenu/ChartList/ChartElement/ChartElement.tsx renamed to ethernet-view/src/components/ChartMenu/ChartElement/ChartElement.tsx

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@ import CanvasJSReact from '@canvasjs/react-charts';
33
import styles from "./ChartElement.module.scss";
44
import { AiOutlineCloseCircle } from 'react-icons/ai'
55
import { memo, useRef, useEffect, useCallback } from "react";
6-
import { ChartId, MeasurementId, MeasurementInfo, UpdateFunction, } from '../ChartList';
7-
import { createChart, ColorType, IChartApi, ISeriesApi, UTCTimestamp } from 'lightweight-charts';
8-
import { useGlobalTicker } from 'common';
6+
import { IChartApi, ISeriesApi, UTCTimestamp } from 'lightweight-charts';
7+
import { MeasurementId, NumericMeasurementInfo, UpdateFunction, useGlobalTicker } from 'common';
8+
import { ChartId, useChartStore } from '../ChartStore';
99

1010
type MeasurementToSerieAndUpdater = Map<MeasurementId, { DataSerie: ISeriesApi<"Line">, Updater: UpdateFunction }>;
1111

1212
type Props = {
1313
chartId: ChartId;
14-
measurementId: MeasurementId;
1514
chartHeight: number;
16-
removeChart: (id: ChartId) => void;
17-
getMeasurementInfo: (id: MeasurementId) => MeasurementInfo;
1815
};
1916

2017
// React component that keeps the chart render and measurements represented on it.
21-
export const ChartElement = memo(({ chartId, measurementId, chartHeight, removeChart, getMeasurementInfo }: Props) => {
18+
export const ChartElement = memo(({ chartId, chartHeight }: Props) => {
2219

2320
// Ref to the CanvasJS chart render
2421
const chartContainerRef = useRef<HTMLDivElement>(null);
@@ -27,60 +24,61 @@ export const ChartElement = memo(({ chartId, measurementId, chartHeight, removeC
2724
let chartLegend = useRef<HTMLDivElement>(null);
2825
// Ref to chart's data series
2926
const chartDataSeries = useRef<MeasurementToSerieAndUpdater>(new Map());
27+
const removeChart = useChartStore((state) => state.removeChart);
3028

3129
// INITIALIZE ALL THE CHART INITIAL SETTINGS.
3230
useEffect(() => {
33-
const measurement = getMeasurementInfo(measurementId);
34-
const chartLegendItem = createChartLegendItem(measurement);
35-
chartLegendItem.onclick = (ev) => removeSeriesFromChart(ev, measurementId);
36-
if (chartLegend) chartLegend.current?.appendChild(chartLegendItem);
37-
38-
const handleResize = () => {
39-
if (chartContainerRef.current)
40-
chart.applyOptions({ width: chartContainerRef.current.clientWidth });
41-
};
42-
43-
const resizeObserver = new ResizeObserver(handleResize);
44-
if (chartContainerRef.current)
45-
resizeObserver.observe(chartContainerRef.current);
46-
47-
if (!chartContainerRef.current) return;
48-
chart = createChart(chartContainerRef.current, {
49-
layout: {
50-
background: { type: ColorType.Solid, color: "white" },
51-
textColor: "black",
52-
},
53-
width: chartContainerRef.current.clientWidth,
54-
height: chartHeight,
55-
timeScale: {
56-
timeVisible: true,
57-
secondsVisible: true,
58-
fixLeftEdge: true,
59-
fixRightEdge: true,
60-
lockVisibleTimeRangeOnResize: true,
61-
}
62-
});
63-
64-
chartDataSeries.current.set(measurementId, {DataSerie: chart.addLineSeries({ color: measurement.color }), Updater: measurement.getUpdate});
65-
66-
return () => {
67-
resizeObserver.disconnect();
68-
chart.remove();
69-
};
31+
// const measurement = getNumericMeasurementInfo(measurementId);
32+
// const chartLegendItem = createChartLegendItem(measurement);
33+
// chartLegendItem.onclick = (ev) => removeSeriesFromChart(ev, measurementId);
34+
// if (chartLegend) chartLegend.current?.appendChild(chartLegendItem);
35+
36+
// const handleResize = () => {
37+
// if (chartContainerRef.current)
38+
// chart.applyOptions({ width: chartContainerRef.current.clientWidth });
39+
// };
40+
41+
// const resizeObserver = new ResizeObserver(handleResize);
42+
// if (chartContainerRef.current)
43+
// resizeObserver.observe(chartContainerRef.current);
44+
45+
// if (!chartContainerRef.current) return;
46+
// chart = createChart(chartContainerRef.current, {
47+
// layout: {
48+
// background: { type: ColorType.Solid, color: "white" },
49+
// textColor: "black",
50+
// },
51+
// width: chartContainerRef.current.clientWidth,
52+
// height: chartHeight,
53+
// timeScale: {
54+
// timeVisible: true,
55+
// secondsVisible: true,
56+
// fixLeftEdge: true,
57+
// fixRightEdge: true,
58+
// lockVisibleTimeRangeOnResize: true,
59+
// }
60+
// });
61+
62+
// chartDataSeries.current.set(measurementId, {DataSerie: chart.addLineSeries({ color: measurement.color }), Updater: measurement.getUpdate});
63+
64+
// return () => {
65+
// resizeObserver.disconnect();
66+
// chart.remove();
67+
// };
7068
});
7169

7270
useEffect(() => {
73-
if(chartContainerRef.current)
74-
chartContainerRef.current.ondrop = (ev) => {
75-
ev.stopPropagation();
76-
const measurementId = ev.dataTransfer?.getData("id");
77-
if (measurementId === undefined || chartDataSeries.current.get(measurementId)) return;
78-
const measurement = getMeasurementInfo(measurementId);
79-
chartDataSeries.current.set(measurementId, {DataSerie: chart.addLineSeries({ color: measurement.color }), Updater: measurement.getUpdate});
80-
const chartLegendItem = createChartLegendItem(measurement);
81-
chartLegendItem.onclick = (ev) => removeSeriesFromChart(ev, measurementId);
82-
if (chartLegend) chartLegend.current?.appendChild(chartLegendItem);
83-
};
71+
// if(chartContainerRef.current)
72+
// chartContainerRef.current.ondrop = (ev) => {
73+
// ev.stopPropagation();
74+
// const measurementId = ev.dataTransfer?.getData("id");
75+
// if (measurementId === undefined || chartDataSeries.current.get(measurementId)) return;
76+
// const measurement = getMeasurementInfo(measurementId);
77+
// chartDataSeries.current.set(measurementId, {DataSerie: chart.addLineSeries({ color: measurement.color }), Updater: measurement.getUpdate});
78+
// const chartLegendItem = createChartLegendItem(measurement);
79+
// chartLegendItem.onclick = (ev) => removeSeriesFromChart(ev, measurementId);
80+
// if (chartLegend) chartLegend.current?.appendChild(chartLegendItem);
81+
// };
8482
});
8583

8684
// Update the chart with the new measurements values.
@@ -122,7 +120,7 @@ export const ChartElement = memo(({ chartId, measurementId, chartHeight, removeC
122120
);
123121
});
124122

125-
function createChartLegendItem(measurement: MeasurementInfo) {
123+
function createChartLegendItem(measurement: NumericMeasurementInfo) {
126124
const legendItem = document.createElement("div");
127125
legendItem.setAttribute("data-id", measurement.id);
128126
legendItem.className = styles.chartLegendItem;

ethernet-view/src/components/ChartMenu/ChartElement/ChartLegend/ChartLegend.module.scss

Whitespace-only changes.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import styles from './ChartLegend.module.scss';
2+
import { MeasurementInfo } from '../../ChartList/ChartList';
3+
4+
export const ChartLegend = () => {
5+
return (
6+
<div>ChartLegend</div>
7+
)
8+
}
9+
10+
function createChartLegendItem(measurement: MeasurementInfo) {
11+
const legendItem = document.createElement("div");
12+
legendItem.setAttribute("data-id", measurement.id);
13+
legendItem.className = styles.chartLegendItem;
14+
const seriesColor = document.createElement("div");
15+
seriesColor.className = styles.chartLegendItemColor;
16+
seriesColor.style.backgroundColor = measurement.color;
17+
const seriesName = document.createElement("p");
18+
seriesName.innerText = measurement.name;
19+
legendItem.appendChild(seriesColor);
20+
legendItem.appendChild(seriesName);
21+
return legendItem;
22+
}
Lines changed: 32 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,42 @@
11
import styles from "./ChartList.module.scss";
22
import { DragEvent, useCallback, useState } from "react";
3-
import { ChartElement } from "./ChartElement/ChartElement";
3+
import { ChartElement } from "../ChartElement/ChartElement";
44
import { nanoid } from "nanoid";
5-
6-
export type ChartId = string;
7-
export type MeasurementId = string;
8-
9-
export type MeasurementName = string;
10-
export type MeasurementColor = string;
11-
export type MeasurementUnits = string;
12-
export type UpdateFunction = () => number;
13-
14-
export type ChartInfo = {
15-
chartId: ChartId;
16-
measurementId: MeasurementId;
17-
};
18-
19-
export type MeasurementInfo = {
20-
readonly id: MeasurementId;
21-
readonly name: MeasurementName;
22-
readonly range: [number | null, number | null];
23-
readonly color: MeasurementColor;
24-
readonly units: MeasurementUnits;
25-
readonly getUpdate: UpdateFunction;
26-
};
5+
import { MeasurementId, NumericMeasurementInfo } from "common";
6+
import { ChartId, useChartStore } from "../ChartStore";
277

288
type Props = {
29-
getMeasurementInfo: (id: MeasurementId) => MeasurementInfo;
9+
getMeasurementInfo: (id: MeasurementId) => NumericMeasurementInfo;
3010
};
3111

3212
export const ChartList = ({ getMeasurementInfo }: Props) => {
33-
const [charts, setCharts] = useState<ChartInfo[]>([]);
34-
35-
const addChart = (chartId: ChartId, measurementId: MeasurementId) => {
36-
setCharts((prev) => [
37-
...prev,
38-
{
39-
chartId: chartId,
40-
measurementId: measurementId,
41-
},
42-
]);
43-
};
44-
45-
const removeChart = useCallback((id: ChartId) => {
46-
setCharts((prev) => prev.filter((chart) => chart.chartId !== id));
47-
}, []);
48-
49-
const handleDrop = (ev: DragEvent<HTMLDivElement>) => {
50-
const id = ev.dataTransfer.getData("id");
51-
const measurementId = getMeasurementInfo(id).id;
52-
addChart(nanoid(), measurementId);
53-
};
5413

55-
return (
56-
<div
57-
className={styles.chartListWrapper}
58-
onDrop={handleDrop}
59-
onDragEnter={(ev) => ev.preventDefault()}
60-
onDragOver={(ev) => ev.preventDefault()}
61-
>
62-
{charts.map((chart) => (
63-
<ChartElement
64-
key={chart.chartId}
65-
chartId={chart.chartId}
66-
measurementId={chart.measurementId}
67-
chartHeight={300}
68-
getMeasurementInfo={getMeasurementInfo}
69-
removeChart={removeChart}
70-
/>
71-
))}
72-
</div>
73-
);
14+
const charts = useChartStore((state) => state.charts);
15+
const createChart = useChartStore((state) => state.addChart);
16+
17+
const handleDrop = (ev: DragEvent<HTMLDivElement>) => {
18+
const id = ev.dataTransfer.getData("id");
19+
const measurementId = getNumericMeasurementInfo(id).id;
20+
addChart(nanoid(), measurementId);
21+
};
22+
23+
return (
24+
<div
25+
className={styles.chartListWrapper}
26+
onDrop={handleDrop}
27+
onDragEnter={(ev) => ev.preventDefault()}
28+
onDragOver={(ev) => ev.preventDefault()}
29+
>
30+
{charts.map((chart) => (
31+
<ChartElement
32+
key={chart.chartId}
33+
chartId={chart.chartId}
34+
measurementId={chart.measurementId}
35+
chartHeight={300}
36+
getMeasurementInfo={getMeasurementInfo}
37+
removeChart={removeChart}
38+
/>
39+
))}
40+
</div>
41+
);
7442
};
Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
import styles from "components/ChartMenu/ChartMenu.module.scss";
2+
import { DragEvent } from "react";
23
import Sidebar from "components/ChartMenu/Sidebar/Sidebar";
3-
import { ChartList } from "components/ChartMenu/ChartList/ChartList";
44
import { Section } from "./Sidebar/Section/Section";
5-
import { NumericMeasurement, getMeasurement, useMeasurementsStore } from "common";
6-
7-
function getRandomColor() {
8-
const r = Math.floor(Math.random() * 256);
9-
const g = Math.floor(Math.random() * 256);
10-
const b = Math.floor(Math.random() * 256);
11-
12-
return `rgb(${r}, ${g}, ${b})`;
13-
}
5+
import { useMeasurementsStore } from "common";
6+
import { useChartStore } from "./ChartStore";
7+
import { nanoid } from "nanoid";
8+
import { ChartElement } from "./ChartElement/ChartElement";
149

1510
type Props = {
1611
sidebarSections: Section[];
1712
};
1813

1914
export const ChartMenu = ({ sidebarSections }: Props) => {
15+
const getNumericMeasurementInfo = useMeasurementsStore((state) => state.getNumericMeasurementInfo);
16+
17+
const charts = useChartStore((state) => state.charts);
18+
const addChart = useChartStore((state) => state.addChart);
2019

21-
const measurements = useMeasurementsStore((state) => state.measurements);
20+
const handleDrop = (ev: DragEvent<HTMLDivElement>) => {
21+
const id = ev.dataTransfer.getData("id");
22+
const initialMeasurementInfo = getNumericMeasurementInfo(id);
23+
addChart(nanoid(), initialMeasurementInfo);
24+
};
2225

2326
if (sidebarSections.length == 0) {
2427
return (
@@ -32,24 +35,23 @@ export const ChartMenu = ({ sidebarSections }: Props) => {
3235
return (
3336
<div className={styles.chartMenuWrapper}>
3437
<Sidebar sections={sidebarSections} />
35-
<ChartList
36-
getMeasurementInfo={(id) => {
37-
const meas = getMeasurement(measurements, id) as NumericMeasurement;
38-
return {
39-
id: id,
40-
name: meas.name,
41-
units: meas.units,
42-
range: meas.safeRange,
43-
getUpdate: () => {
44-
const meas = getMeasurement(measurements, id) as NumericMeasurement;
45-
if (meas == undefined) return 0
46-
return meas.value.last;
47-
},
48-
color: getRandomColor(),
49-
};
50-
}}
51-
/>
38+
<div
39+
className={styles.chartListWrapper}
40+
onDrop={handleDrop}
41+
onDragEnter={(ev) => ev.preventDefault()}
42+
onDragOver={(ev) => ev.preventDefault()}
43+
>
44+
{Object.keys(charts).map((chartId) => {
45+
return (
46+
<ChartElement
47+
key={chartId}
48+
chartId={chartId}
49+
chartHeight={300}
50+
/>
51+
);
52+
})}
53+
</div>
5254
</div>
5355
);
5456
}
55-
};
57+
};

0 commit comments

Comments
 (0)