Skip to content

Commit cc5c075

Browse files
authored
Merge pull request #124 from HyperloopUPV-H8/ethernet-view/charts
2 parents 1b90560 + 0b74cab commit cc5c075

18 files changed

Lines changed: 334 additions & 47 deletions

File tree

backend/pkg/logger/data/logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ func (sublogger *Logger) PushRecord(record abstraction.LoggerRecord) error {
136136
writer := csv.NewWriter(file) // TODO! use map/slice of writer
137137

138138
err := writer.Write([]string{
139-
timestamp.Format(time.RFC3339),
139+
fmt.Sprint(timestamp.UnixMilli()),
140140
dataRecord.From,
141141
dataRecord.To,
142142
val,

backend/pkg/logger/logger.go

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,7 @@ func (logger *Logger) Start() error {
6363

6464
// Create log folders
6565
for subLogger := range logger.subloggers {
66-
loggerPath := path.Join(
67-
"logger",
68-
string(subLogger),
69-
Timestamp.Format(time.RFC3339),
70-
)
66+
loggerPath := path.Join("logger", string(subLogger), Timestamp.Format(time.RFC3339))
7167
logger.trace.Debug().Str("subLogger", string(subLogger)).Str("path", loggerPath).Msg("creating folder")
7268
err := os.MkdirAll(loggerPath, os.ModePerm)
7369
if err != nil {

backend/pkg/logger/order/logger.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ func (sublogger *Logger) PushRecord(record abstraction.LoggerRecord) error {
103103
csvWriter := csv.NewWriter(sublogger.writer)
104104
defer csvWriter.Flush()
105105

106-
timestamp := orderRecord.Packet.Timestamp().Format(time.RFC3339)
106+
timestamp := orderRecord.Packet.Timestamp().UnixMilli()
107107
val := fmt.Sprint(orderRecord.Packet.GetValues())
108108
err := csvWriter.Write([]string{
109-
timestamp,
109+
fmt.Sprint(timestamp),
110110
orderRecord.From,
111111
orderRecord.To,
112112
fmt.Sprint(orderRecord.Packet.Id()),

backend/pkg/logger/protection/logger.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (sublogger *Logger) PushRecord(record abstraction.LoggerRecord) error {
119119
defer writer.Flush()
120120

121121
err := writer.Write([]string{
122-
infoRecord.Timestamp.Format(time.RFC3339),
122+
fmt.Sprint(infoRecord.Timestamp.UnixMilli()),
123123
infoRecord.From,
124124
infoRecord.To,
125125
fmt.Sprint(infoRecord.Packet.Id()),
Lines changed: 1 addition & 0 deletions
Loading

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { ChartElement } from "./ChartElement/ChartElement";
88

99
export type ChartId = string;
1010

11-
type ChartInfo = {
11+
export type ChartInfo = {
1212
chartId: ChartId;
1313
initialMeasurementId: MeasurementId;
1414
};

ethernet-view/src/components/ChartMenu/Sidebar/Sidebar.module.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@use "src/styles/styles";
2+
23
.sidebar {
34
width: auto;
45
height: 100%;
Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
import styles from "./Sidebar.module.scss";
22
import { Section } from "./Section/Section";
33
import { memo } from "react";
4+
import { Item, ItemView } from "./Section/Subsection/Subsection/Items/Item/ItemView";
45

56
type Props = {
6-
sections: Section[];
7+
sections?: Section[];
8+
items?: Item[];
79
};
810

9-
const Sidebar = ({ sections }: Props) => {
10-
return (
11+
const Sidebar = ({ sections, items }: Props) => {
12+
13+
return sections && sections.length > 0 ?
14+
(
1115
<div className={styles.sidebar}>
1216
{sections.map((section) => {
1317
return (
@@ -18,7 +22,22 @@ const Sidebar = ({ sections }: Props) => {
1822
);
1923
})}
2024
</div>
21-
);
25+
) : (items && items.length > 0 ? (
26+
<div className={styles.sidebar}>
27+
{items.map((item) => {
28+
return (
29+
// <div key={item.id} className={styles.subsection} draggable={true}>
30+
// <div className={styles.name}>{item.name}</div>
31+
// </div>
32+
<ItemView
33+
key={item.id}
34+
item={item}
35+
/>
36+
);
37+
})}
38+
</div>
39+
) : null);
40+
2241
};
2342

2443
export default memo(Sidebar);
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { ColorType, createChart, IChartApi, UTCTimestamp } from "lightweight-charts";
2+
import { ChartPoint } from "pages/LoggerPage/LogsColumn/LogLoader/LogsProcessor";
3+
import { useEffect, useRef } from "react";
4+
import { MeasurementLogger } from "./ChartElement";
5+
6+
const CHART_HEIGHT = 300;
7+
8+
interface Props {
9+
measurementsInChart: MeasurementLogger[];
10+
getDataFromLogSession: (measurement: string) => ChartPoint[];
11+
}
12+
13+
export const ChartCanvas = ({ measurementsInChart, getDataFromLogSession }: Props) => {
14+
const chart = useRef<IChartApi | null>(null);
15+
const chartContainerRef = useRef<HTMLDivElement>(null);
16+
17+
useEffect(() => {
18+
const handleResize = () => {
19+
if (chartContainerRef.current)
20+
if(chart)
21+
chart.current?.applyOptions({ width: chartContainerRef.current.clientWidth });
22+
};
23+
24+
const resizeObserver = new ResizeObserver(handleResize);
25+
if (chartContainerRef.current)
26+
resizeObserver.observe(chartContainerRef.current);
27+
28+
if (chartContainerRef.current) {
29+
if(chart)
30+
chart.current = createChart(chartContainerRef.current, {
31+
layout: {
32+
background: { type: ColorType.Solid, color: "white" },
33+
textColor: "black",
34+
},
35+
width: chartContainerRef.current.clientWidth,
36+
height: CHART_HEIGHT,
37+
timeScale: {
38+
timeVisible: true,
39+
fixLeftEdge: true,
40+
fixRightEdge: true,
41+
lockVisibleTimeRangeOnResize: true,
42+
},
43+
});
44+
}
45+
46+
for(const measurement of measurementsInChart) {
47+
const data = getDataFromLogSession(measurement.id);
48+
const series = chart.current?.addLineSeries({
49+
color: measurement.color,
50+
})
51+
console.log(data)
52+
for(const point of data) {
53+
series?.update({ time: point.time / 1000 as UTCTimestamp, value: point.value });
54+
}
55+
}
56+
57+
return () => {
58+
resizeObserver.disconnect();
59+
chart.current?.remove();
60+
}
61+
}, [measurementsInChart]);
62+
63+
return (
64+
<div ref={chartContainerRef}></div>
65+
)
66+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { ChartId } from "components/ChartMenu/ChartMenu"
2+
import { AiOutlineCloseCircle } from "react-icons/ai"
3+
import styles from "components/ChartMenu/ChartElement/ChartElement.module.scss"
4+
import { ChartCanvas } from "./ChartCanvas";
5+
import { ChartPoint } from "pages/LoggerPage/LogsColumn/LogLoader/LogsProcessor";
6+
import { useEffect, useState } from "react";
7+
import { MeasurementId, } from "common";
8+
import { ChartLegend } from "./ChartLegend";
9+
10+
interface Props {
11+
chartId: ChartId;
12+
initialMeasurementId: MeasurementId
13+
removeChart: (chartId: ChartId) => void;
14+
getDataFromLogSession: (measurement: ChartId) => ChartPoint[];
15+
}
16+
17+
export interface MeasurementLogger {
18+
id: string;
19+
color: string;
20+
}
21+
22+
export const ChartElement = ({ chartId, initialMeasurementId, removeChart, getDataFromLogSession }: Props) => {
23+
24+
const [measurementsInChart, setMeasurementsInChart] = useState<MeasurementLogger[]>([{id: initialMeasurementId, color: 'red'}]);
25+
26+
useEffect(() => {
27+
console.log(measurementsInChart)
28+
}, [measurementsInChart])
29+
30+
const addMeasurementToChart = (measurement: MeasurementLogger) => {
31+
if(!measurementsInChart.some(measurementInChart => measurementInChart.id === measurement.id)) {
32+
setMeasurementsInChart([...measurementsInChart, measurement]);
33+
}
34+
}
35+
36+
const handleDrop = (ev: React.DragEvent<HTMLDivElement>) => {
37+
ev.stopPropagation();
38+
const id = ev.dataTransfer.getData("id");
39+
addMeasurementToChart({id, color: getRandomColor()});
40+
};
41+
42+
return (
43+
<div
44+
className={styles.chartWrapper}
45+
onDrop={handleDrop}
46+
onDragEnter={(ev) => ev.preventDefault()}
47+
onDragOver={(ev) => ev.preventDefault()}
48+
>
49+
<div className={styles.chart}>
50+
<AiOutlineCloseCircle
51+
size={30}
52+
cursor="pointer"
53+
onClick={() => removeChart(chartId)}
54+
/>
55+
<ChartCanvas
56+
measurementsInChart={measurementsInChart}
57+
getDataFromLogSession={getDataFromLogSession}
58+
/>
59+
<ChartLegend
60+
chartId={chartId}
61+
measurementsInChart={measurementsInChart}
62+
removeChart={removeChart}
63+
removeMeasurementFromChart={(measurementId: MeasurementId) => setMeasurementsInChart(measurementsInChart.filter(measurement => measurement.id !== measurementId))}
64+
/>
65+
</div>
66+
</div>
67+
)
68+
}
69+
70+
function getRandomColor() {
71+
var r = Math.floor(Math.random() * 256);
72+
var g = Math.floor(Math.random() * 256);
73+
var b = Math.floor(Math.random() * 256);
74+
var hexR = r.toString(16).padStart(2, '0');
75+
var hexG = g.toString(16).padStart(2, '0');
76+
var hexB = b.toString(16).padStart(2, '0');
77+
return '#' + hexR + hexG + hexB;
78+
}

0 commit comments

Comments
 (0)