Implement interface for using web plotter from C++

It's not actually usable yet due to ODR violations created by
abseil being compiled into libwebrtc_full.a, but it does work based
on testing I've done with using websockets for data transfer.

Change-Id: I574570c7b5c85df9e53321bfb971a608d20b9803
diff --git a/frc971/analysis/in_process_plotter.h b/frc971/analysis/in_process_plotter.h
new file mode 100644
index 0000000..3d7a037
--- /dev/null
+++ b/frc971/analysis/in_process_plotter.h
@@ -0,0 +1,79 @@
+#ifndef FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_
+#define FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_
+
+#include <vector>
+
+#include "aos/events/simulated_event_loop.h"
+#include "aos/network/web_proxy.h"
+#include "frc971/analysis/plot_data_generated.h"
+
+namespace frc971 {
+namespace analysis {
+
+// This class wraps the WebProxy class to provide a convenient C++ interface to
+// dynamically generate plots.
+// Currently, the main useful interface that this provides is a matplotlib-like
+// interface--see in_process_plotter_demo.cc for sample usage. It doesn't
+// precisely follow matplotlib's conventions, but the basic style does mimic
+// matplotlib. Future iterations may ditch this in favor of a more modern
+// interface where we actually return handles for plots and lines and the such.
+//
+// Note that currently the port for the seb server is hard-coded to 8080, so
+// only one instance of the Plotter can be present at once.
+//
+// You must call Spin() for the web server to actually do anything helpful.
+class Plotter {
+ public:
+  Plotter();
+
+  // matplotlib-like interface
+  // The basic pattern is:
+  // 1) Call Figure()
+  // 2) Setup the lines, labels, etc. for the figure.
+  // 3) Repeat 1-2 however many times.
+  // 4) Call Publish().
+  // 5) Repeat 1-5 however many times.
+  //
+  // Publish() actually pushes the figures that you setup to the web-page,
+  // either with an autogenerated title or the title set by Title(). All state
+  // is cleared (or should be cleared) by the call to Publish().
+
+  // Sets the title for the current set of plots; if you
+  void Title(std::string_view title);
+  void AddFigure(std::string_view title = "", double width = 900,
+                 double height = 400);
+  void AddLine(const std::vector<double> &x, const std::vector<double> &y,
+               std::string_view label = "");
+  void ShareXAxis(bool share) { share_x_axis_ = share; }
+  void XLabel(std::string_view label);
+  void YLabel(std::string_view label);
+  void Publish();
+
+  void Spin();
+ private:
+  void MaybeFinishFigure();
+
+  aos::FlatbufferDetachedBuffer<aos::Configuration> config_;
+  aos::SimulatedEventLoopFactory event_loop_factory_;
+  std::unique_ptr<aos::EventLoop> event_loop_;
+  aos::Sender<Plot> plot_sender_;
+  aos::web_proxy::WebProxy web_proxy_;
+
+  aos::Sender<Plot>::Builder builder_;
+  flatbuffers::Offset<flatbuffers::String> title_;
+  flatbuffers::Offset<flatbuffers::String> figure_title_;
+  flatbuffers::Offset<flatbuffers::String> xlabel_;
+  flatbuffers::Offset<flatbuffers::String> ylabel_;
+  bool share_x_axis_ = false;
+  float next_top_ = 0;
+  flatbuffers::Offset<Position> position_;
+  std::vector<flatbuffers::Offset<Figure>> figures_;
+  std::vector<flatbuffers::Offset<Line>> lines_;
+
+  size_t color_wheel_position_ = 0;
+  std::vector<Color> color_wheel_;
+};
+
+}  // namespace analysis
+}  // namespace frc971
+#endif  // FRC971_ANALYSIS_IN_PROCESS_PLOTTER_H_