Skip to content

Commit 6e1abbc

Browse files
authored
Merge pull request #5 from arduino/fix-plotter-max-variables
Fix plotter issues
2 parents b751586 + 0aafb86 commit 6e1abbc

7 files changed

+1593
-252
lines changed

package-lock.json

+1,506-240
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"name": "arduino-serial-plotter-webapp",
3-
"version": "0.0.15",
4-
"dependencies": {},
3+
"version": "0.0.17",
4+
"dependencies": {
5+
},
56
"license": "AGPL",
67
"scripts": {
78
"start": "react-scripts start",
@@ -32,6 +33,7 @@
3233
]
3334
},
3435
"devDependencies": {
36+
"@arduino/arc": "^0.9.1",
3537
"@testing-library/jest-dom": "^5.14.1",
3638
"@testing-library/react": "^11.2.7",
3739
"@testing-library/user-event": "^12.8.3",
@@ -52,6 +54,7 @@
5254
"node-sass": "^6.0.1",
5355
"prettier": "^2.4.1",
5456
"react": "^17.0.2",
57+
"react-aria": "^3.0.0",
5558
"react-chartjs-2": "^3.3.0",
5659
"react-custom-scrollbars": "^4.2.1",
5760
"react-dom": "^17.0.2",

src/ChartPlotter.tsx

+44-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
import React, { useState, useRef, useImperativeHandle, useEffect } from "react";
1+
import React, {
2+
useState,
3+
useRef,
4+
useImperativeHandle,
5+
useEffect,
6+
useCallback,
7+
} from "react";
28

39
import { Line } from "react-chartjs-2";
410

@@ -11,10 +17,11 @@ import ChartStreaming from "chartjs-plugin-streaming";
1117
import { ChartJSOrUndefined } from "react-chartjs-2/dist/types";
1218
import { MessageToBoard } from "./MessageToBoard";
1319

14-
Chart.register(ChartStreaming);
15-
1620
// eslint-disable-next-line
1721
import Worker from "worker-loader!./msgAggregatorWorker";
22+
import { Snackbar } from "@arduino/arc";
23+
24+
Chart.register(ChartStreaming);
1825
const worker = new Worker();
1926

2027
function _Chart(
@@ -124,9 +131,21 @@ function _Chart(
124131
},
125132
});
126133

134+
const enableTooltips = useCallback(
135+
(newState: boolean) => {
136+
(opts.plugins as any).tooltip.enabled = newState;
137+
opts.datasets!.line!.pointHoverRadius = newState ? 3 : 0;
138+
setOpts(opts);
139+
chartRef.current?.update();
140+
},
141+
[opts]
142+
);
143+
127144
useEffect(() => {
128145
if (!config.connected) {
129146
setConnected(false);
147+
// when disconnected, force tooltips to be enabled
148+
enableTooltips(true);
130149
return;
131150
}
132151

@@ -135,8 +154,11 @@ function _Chart(
135154
// cleanup buffer state
136155
worker.postMessage({ command: "cleanup" });
137156
setConnected(true);
157+
158+
// restore the tooltips state (which match the pause state when connected)
159+
enableTooltips(pause);
138160
}
139-
}, [config.connected, connected]);
161+
}, [config.connected, connected, pause, enableTooltips]);
140162

141163
const togglePause = (newState: boolean) => {
142164
if (newState === pause) {
@@ -146,9 +168,8 @@ function _Chart(
146168
(chartRef.current as any).options.scales.x.realtime.pause = pause;
147169
}
148170
setPause(newState);
149-
(opts.plugins as any).tooltip.enabled = newState;
150-
opts.datasets!.line!.pointHoverRadius = newState ? 3 : 0;
151-
setOpts(opts);
171+
worker.postMessage({ command: "cleanup" });
172+
enableTooltips(newState);
152173
};
153174

154175
const setInterpolate = (interpolate: boolean) => {
@@ -221,6 +242,22 @@ function _Chart(
221242
<Line data={initialData} ref={chartRef as any} options={opts} />
222243
</div>
223244
<MessageToBoard config={config} wsSend={wsSend} />
245+
246+
{!connected && (
247+
<Snackbar
248+
anchorOrigin={{
249+
horizontal: "center",
250+
vertical: "bottom",
251+
}}
252+
autoHideDuration={7000}
253+
className="snackbar"
254+
closeable
255+
isOpen
256+
message="Board disconnected"
257+
theme={config.darkTheme ? "dark" : "light"}
258+
turnOffAutoHide
259+
/>
260+
)}
224261
</div>
225262
</>
226263
);

src/fakeMessagsGenerators.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const genNamedVarValPair = (i: number) => {
2626
export const namedVariables = () => {
2727
const messages: string[] = [];
2828

29-
for (let i = 1; i <= 7; i++) {
29+
for (let i = 1; i <= 9; i++) {
3030
let pair = genNamedVarValPair(i);
3131
messages.push(pair);
3232
}

src/index.scss

+12
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ body {
7373
margin: 0;
7474
}
7575

76+
.snackbar {
77+
outline: none;
78+
* {
79+
outline: none;
80+
}
81+
}
82+
7683
.chart-container {
7784
display: flex;
7885
flex-direction: column;
@@ -216,6 +223,11 @@ body {
216223
}
217224
}
218225

226+
.pause-button {
227+
width: 47px;
228+
text-align: center;
229+
}
230+
219231
.clear-button {
220232
border: none;
221233
background: none;

src/msgAggregatorWorker.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ ctx.addEventListener("message", (event) => {
88

99
if (command === "cleanup") {
1010
buffer = "";
11+
discardFirstLine = true;
1112
}
1213

1314
if (data) {
@@ -16,6 +17,7 @@ ctx.addEventListener("message", (event) => {
1617
});
1718

1819
let buffer = "";
20+
let discardFirstLine = true;
1921
const separator = "\r\n";
2022
var re = new RegExp(`(${separator})`, "g");
2123

@@ -25,8 +27,26 @@ export const parseSerialMessages = (
2527
datasetNames: string[];
2628
parsedLines: { [key: string]: number }[];
2729
} => {
30+
// when the serial is real fast, the first line can be incomplete and contain incomplete messages
31+
// so we need to discard it and start aggregating from the first encountered separator
32+
let joinMessages = messages.join("");
33+
if (discardFirstLine) {
34+
const firstSeparatorIndex = joinMessages.indexOf(separator);
35+
if (firstSeparatorIndex > -1) {
36+
joinMessages = joinMessages.substring(
37+
firstSeparatorIndex + separator.length
38+
);
39+
discardFirstLine = false;
40+
} else {
41+
return {
42+
datasetNames: [],
43+
parsedLines: [],
44+
};
45+
}
46+
}
47+
2848
//add any leftover from the buffer to the first line
29-
const messagesAndBuffer = (buffer + messages.join(""))
49+
const messagesAndBuffer = ((buffer || "") + joinMessages)
3050
.split(re)
3151
.filter((message) => message.length > 0);
3252

src/utils.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ export const addDataPoints = (
8484
// add missing datasets to the chart
8585
existingDatasetNames.length < 8 &&
8686
datasetNames.forEach((datasetName) => {
87-
if (!existingDatasetNames.includes(datasetName)) {
87+
if (
88+
!existingDatasetNames.includes(datasetName) &&
89+
existingDatasetNames.length < 8
90+
) {
8891
const newDataset = {
8992
data: [],
9093
label: datasetName,

0 commit comments

Comments
 (0)