Skip to content

Fix plotter issues #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 13, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,746 changes: 1,506 additions & 240 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"name": "arduino-serial-plotter-webapp",
"version": "0.0.15",
"dependencies": {},
"version": "0.0.17",
"dependencies": {
},
"license": "AGPL",
"scripts": {
"start": "react-scripts start",
@@ -32,6 +33,7 @@
]
},
"devDependencies": {
"@arduino/arc": "^0.9.1",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
@@ -52,6 +54,7 @@
"node-sass": "^6.0.1",
"prettier": "^2.4.1",
"react": "^17.0.2",
"react-aria": "^3.0.0",
"react-chartjs-2": "^3.3.0",
"react-custom-scrollbars": "^4.2.1",
"react-dom": "^17.0.2",
51 changes: 44 additions & 7 deletions src/ChartPlotter.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import React, { useState, useRef, useImperativeHandle, useEffect } from "react";
import React, {
useState,
useRef,
useImperativeHandle,
useEffect,
useCallback,
} from "react";

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

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

Chart.register(ChartStreaming);

// eslint-disable-next-line
import Worker from "worker-loader!./msgAggregatorWorker";
import { Snackbar } from "@arduino/arc";

Chart.register(ChartStreaming);
const worker = new Worker();

function _Chart(
@@ -124,9 +131,21 @@ function _Chart(
},
});

const enableTooltips = useCallback(
(newState: boolean) => {
(opts.plugins as any).tooltip.enabled = newState;
opts.datasets!.line!.pointHoverRadius = newState ? 3 : 0;
setOpts(opts);
chartRef.current?.update();
},
[opts]
);

useEffect(() => {
if (!config.connected) {
setConnected(false);
// when disconnected, force tooltips to be enabled
enableTooltips(true);
return;
}

@@ -135,8 +154,11 @@ function _Chart(
// cleanup buffer state
worker.postMessage({ command: "cleanup" });
setConnected(true);

// restore the tooltips state (which match the pause state when connected)
enableTooltips(pause);
}
}, [config.connected, connected]);
}, [config.connected, connected, pause, enableTooltips]);

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

const setInterpolate = (interpolate: boolean) => {
@@ -221,6 +242,22 @@ function _Chart(
<Line data={initialData} ref={chartRef as any} options={opts} />
</div>
<MessageToBoard config={config} wsSend={wsSend} />

{!connected && (
<Snackbar
anchorOrigin={{
horizontal: "center",
vertical: "bottom",
}}
autoHideDuration={7000}
className="snackbar"
closeable
isOpen
message="Board disconnected"
theme={config.darkTheme ? "dark" : "light"}
turnOffAutoHide
/>
)}
</div>
</>
);
2 changes: 1 addition & 1 deletion src/fakeMessagsGenerators.ts
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ const genNamedVarValPair = (i: number) => {
export const namedVariables = () => {
const messages: string[] = [];

for (let i = 1; i <= 7; i++) {
for (let i = 1; i <= 9; i++) {
let pair = genNamedVarValPair(i);
messages.push(pair);
}
12 changes: 12 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
@@ -73,6 +73,13 @@ body {
margin: 0;
}

.snackbar {
outline: none;
* {
outline: none;
}
}

.chart-container {
display: flex;
flex-direction: column;
@@ -216,6 +223,11 @@ body {
}
}

.pause-button {
width: 47px;
text-align: center;
}

.clear-button {
border: none;
background: none;
22 changes: 21 additions & 1 deletion src/msgAggregatorWorker.ts
Original file line number Diff line number Diff line change
@@ -8,6 +8,7 @@ ctx.addEventListener("message", (event) => {

if (command === "cleanup") {
buffer = "";
discardFirstLine = true;
}

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

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

@@ -25,8 +27,26 @@ export const parseSerialMessages = (
datasetNames: string[];
parsedLines: { [key: string]: number }[];
} => {
// when the serial is real fast, the first line can be incomplete and contain incomplete messages
// so we need to discard it and start aggregating from the first encountered separator
let joinMessages = messages.join("");
if (discardFirstLine) {
const firstSeparatorIndex = joinMessages.indexOf(separator);
if (firstSeparatorIndex > -1) {
joinMessages = joinMessages.substring(
firstSeparatorIndex + separator.length
);
discardFirstLine = false;
} else {
return {
datasetNames: [],
parsedLines: [],
};
}
}

//add any leftover from the buffer to the first line
const messagesAndBuffer = (buffer + messages.join(""))
const messagesAndBuffer = ((buffer || "") + joinMessages)
.split(re)
.filter((message) => message.length > 0);

5 changes: 4 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -84,7 +84,10 @@ export const addDataPoints = (
// add missing datasets to the chart
existingDatasetNames.length < 8 &&
datasetNames.forEach((datasetName) => {
if (!existingDatasetNames.includes(datasetName)) {
if (
!existingDatasetNames.includes(datasetName) &&
existingDatasetNames.length < 8
) {
const newDataset = {
data: [],
label: datasetName,