blob: 0153cdbea5c1fbe5cf07a0a325c47720918e9d53 [file] [log] [blame]
James Kuszmaul48671362020-12-24 13:54:16 -08001// Provides a plot which handles plotting the plot defined by a
Stephan Pleines9e40c8e2024-02-07 20:58:28 -08002// aos.analysis.Plot message.
Philipp Schrader548aedf2023-02-17 20:09:13 -08003import {Plot as PlotFb} from './plot_data_generated';
4import {MessageHandler, TimestampedMessage} from '../../aos/network/www/aos_plotter';
James Kuszmauldac091f2022-03-22 09:35:06 -07005import {ByteBuffer} from 'flatbuffers';
Philipp Schrader548aedf2023-02-17 20:09:13 -08006import {Plot, Point} from '../../aos/network/www/plotter';
7import {Connection} from '../../aos/network/www/proxy';
James Kuszmaul136aa2b2022-04-02 14:50:56 -07008import {Schema} from 'flatbuffers_reflection/reflection_generated';
James Kuszmaul48671362020-12-24 13:54:16 -08009
10export function plotData(conn: Connection, parentDiv: Element) {
11 // Set up a selection box to allow the user to choose between plots to show.
12 const plotSelect = document.createElement('select');
13 parentDiv.appendChild(plotSelect);
14 const plots = new Map<string, HTMLElement>();
15 const invalidSelectValue = 'null';
16 plotSelect.addEventListener('input', () => {
17 for (const plot of plots.values()) {
18 plot.style.display = 'none';
19 }
20 if (plotSelect.value == invalidSelectValue) {
21 return;
22 }
23 plots.get(plotSelect.value).style.display = 'block';
24 });
25 plotSelect.add(new Option('Select Plot', invalidSelectValue));
26
27 const plotDiv = document.createElement('div');
James Kuszmaul48671362020-12-24 13:54:16 -080028 parentDiv.appendChild(plotDiv);
29
30 conn.addReliableHandler(
Stephan Pleines9e40c8e2024-02-07 20:58:28 -080031 '/analysis', 'aos.analysis.Plot', (data: Uint8Array, time: number) => {
James Kuszmauldac091f2022-03-22 09:35:06 -070032 const plotFb = PlotFb.getRootAsPlot(new ByteBuffer(data));
James Kuszmaul48671362020-12-24 13:54:16 -080033 const name = (!plotFb.title()) ? 'Plot ' + plots.size : plotFb.title();
34 const div = document.createElement('div');
35 div.style.display = 'none';
36 plots.set(name, div);
37 plotDiv.appendChild(div);
38 plotSelect.add(new Option(name, name));
39
40 const linkedXAxes: Plot[] = [];
41
42 for (let ii = 0; ii < plotFb.figuresLength(); ++ii) {
43 const figure = plotFb.figures(ii);
44 const figureDiv = document.createElement('div');
Austin Schuh5ec17ef2022-07-15 14:37:16 -070045 if (figure.position().width() == 0) {
46 figureDiv.style.width = '100%';
47 } else {
48 figureDiv.style.width = figure.position().width().toString() + 'px';
49 }
50 if (figure.position().height() == 0) {
Austin Schuh6eb83e62022-07-19 15:40:30 -070051 figureDiv.style.height = '100%';
Austin Schuh5ec17ef2022-07-15 14:37:16 -070052 } else {
53 figureDiv.style.height =
54 figure.position().height().toString() + 'px';
55 }
Austin Schuhc2e9c502021-11-25 21:23:24 -080056 figureDiv.style.position = 'relative';
James Kuszmaul48671362020-12-24 13:54:16 -080057 div.appendChild(figureDiv);
Austin Schuhc2e9c502021-11-25 21:23:24 -080058 const plot = new Plot(figureDiv);
James Kuszmaul48671362020-12-24 13:54:16 -080059
60 if (figure.title()) {
61 plot.getAxisLabels().setTitle(figure.title());
62 }
63 if (figure.xlabel()) {
64 plot.getAxisLabels().setXLabel(figure.xlabel());
65 }
66 if (figure.ylabel()) {
James Kuszmaule32fa932021-05-11 21:38:16 -070067 plot.getAxisLabels().setYLabel(figure.ylabel());
James Kuszmaul48671362020-12-24 13:54:16 -080068 }
69 if (figure.shareXAxis()) {
70 for (const other of linkedXAxes) {
71 plot.linkXAxis(other);
72 }
73 linkedXAxes.push(plot);
74 }
75
76 for (let jj = 0; jj < figure.linesLength(); ++jj) {
77 const lineFb = figure.lines(jj);
78 const line = plot.getDrawer().addLine();
79 if (lineFb.label()) {
80 line.setLabel(lineFb.label());
81 }
James Kuszmaul0d7df892021-04-09 22:19:49 -070082 const points = [];
James Kuszmaul48671362020-12-24 13:54:16 -080083 for (let kk = 0; kk < lineFb.pointsLength(); ++kk) {
James Kuszmaul0d7df892021-04-09 22:19:49 -070084 const point = lineFb.points(kk);
85 points.push(new Point(point.x(), point.y()));
James Kuszmaul48671362020-12-24 13:54:16 -080086 }
87 if (lineFb.color()) {
88 line.setColor(
89 [lineFb.color().r(), lineFb.color().g(), lineFb.color().b()]);
90 }
James Kuszmaul19217a42022-06-17 10:54:29 -070091 if (lineFb.style()) {
92 if (lineFb.style().pointSize() !== null) {
93 line.setPointSize(lineFb.style().pointSize());
94 }
95 if (lineFb.style().drawLine() !== null) {
96 line.setDrawLine(lineFb.style().drawLine());
97 }
98 }
James Kuszmaul48671362020-12-24 13:54:16 -080099 line.setPoints(points);
100 }
101 }
Austin Schuh5ec17ef2022-07-15 14:37:16 -0700102
103 // If this is the first new element (ignoring the placeholder up top),
104 // select it by default.
105 if (plotSelect.length == 2) {
106 plotSelect.value = name;
107 plotSelect.dispatchEvent(new Event('input'));
108 }
James Kuszmaul48671362020-12-24 13:54:16 -0800109 });
110}