blob: e9183794243004bf421f69f9f546389e67e87b60 [file] [log] [blame]
James Kuszmaul48671362020-12-24 13:54:16 -08001// Provides a plot which handles plotting the plot defined by a
2// frc971.analysis.Plot message.
3import * as configuration from 'org_frc971/aos/configuration_generated';
4import * as plot_data from 'org_frc971/frc971/analysis/plot_data_generated';
5import {MessageHandler, TimestampedMessage} from 'org_frc971/aos/network/www/aos_plotter';
6import {ByteBuffer} from 'org_frc971/external/com_github_google_flatbuffers/ts/byte-buffer';
James Kuszmaul0d7df892021-04-09 22:19:49 -07007import {Plot, Point} from 'org_frc971/aos/network/www/plotter';
James Kuszmaul48671362020-12-24 13:54:16 -08008import * as proxy from 'org_frc971/aos/network/www/proxy';
9
10import Connection = proxy.Connection;
11import Schema = configuration.reflection.Schema;
12import PlotFb = plot_data.frc971.analysis.Plot;
13
14export function plotData(conn: Connection, parentDiv: Element) {
15 // Set up a selection box to allow the user to choose between plots to show.
16 const plotSelect = document.createElement('select');
17 parentDiv.appendChild(plotSelect);
18 const plots = new Map<string, HTMLElement>();
19 const invalidSelectValue = 'null';
20 plotSelect.addEventListener('input', () => {
21 for (const plot of plots.values()) {
22 plot.style.display = 'none';
23 }
24 if (plotSelect.value == invalidSelectValue) {
25 return;
26 }
27 plots.get(plotSelect.value).style.display = 'block';
28 });
29 plotSelect.add(new Option('Select Plot', invalidSelectValue));
30
31 const plotDiv = document.createElement('div');
32 plotDiv.style.position = 'absolute';
33 plotDiv.style.top = '30';
34 plotDiv.style.left = '0';
35 parentDiv.appendChild(plotDiv);
36
37 conn.addReliableHandler(
38 '/analysis', 'frc971.analysis.Plot', (data: Uint8Array, time: number) => {
39 const plotFb = PlotFb.getRootAsPlot(
40 new ByteBuffer(data) as unknown as flatbuffers.ByteBuffer);
41 const name = (!plotFb.title()) ? 'Plot ' + plots.size : plotFb.title();
42 const div = document.createElement('div');
43 div.style.display = 'none';
44 plots.set(name, div);
45 plotDiv.appendChild(div);
46 plotSelect.add(new Option(name, name));
47
48 const linkedXAxes: Plot[] = [];
49
50 for (let ii = 0; ii < plotFb.figuresLength(); ++ii) {
51 const figure = plotFb.figures(ii);
52 const figureDiv = document.createElement('div');
53 figureDiv.style.top = figure.position().top().toString();
54 figureDiv.style.left = figure.position().left().toString();
55 figureDiv.style.position = 'absolute';
56 div.appendChild(figureDiv);
57 const plot = new Plot(
58 figureDiv, figure.position().width(), figure.position().height());
59
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()) {
67 plot.getAxisLabels().setYLabel(figure.xlabel());
68 }
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 }
91 line.setPoints(points);
92 }
93 }
94 });
95}