Stephan Pleines | 9e40c8e | 2024-02-07 20:58:28 -0800 | [diff] [blame] | 1 | #ifndef AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_ |
| 2 | #define AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_ |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 3 | |
Stephan Pleines | 31f98da | 2024-05-22 17:31:23 -0700 | [diff] [blame] | 4 | #include <stddef.h> |
| 5 | |
| 6 | #include <memory> |
| 7 | #include <string> |
| 8 | #include <string_view> |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 9 | #include <vector> |
| 10 | |
Stephan Pleines | 31f98da | 2024-05-22 17:31:23 -0700 | [diff] [blame] | 11 | #include "flatbuffers/buffer.h" |
| 12 | #include "flatbuffers/string.h" |
| 13 | |
Stephan Pleines | 85b295c | 2024-02-04 17:50:26 -0800 | [diff] [blame] | 14 | #include "aos/analysis/plot_data_generated.h" |
Stephan Pleines | 31f98da | 2024-05-22 17:31:23 -0700 | [diff] [blame] | 15 | #include "aos/configuration_generated.h" |
| 16 | #include "aos/events/event_loop.h" |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 17 | #include "aos/events/simulated_event_loop.h" |
Stephan Pleines | 31f98da | 2024-05-22 17:31:23 -0700 | [diff] [blame] | 18 | #include "aos/flatbuffers.h" |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 19 | #include "aos/network/web_proxy.h" |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 20 | |
Stephan Pleines | 9e40c8e | 2024-02-07 20:58:28 -0800 | [diff] [blame] | 21 | namespace aos::analysis { |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 22 | |
| 23 | // This class wraps the WebProxy class to provide a convenient C++ interface to |
| 24 | // dynamically generate plots. |
| 25 | // Currently, the main useful interface that this provides is a matplotlib-like |
| 26 | // interface--see in_process_plotter_demo.cc for sample usage. It doesn't |
| 27 | // precisely follow matplotlib's conventions, but the basic style does mimic |
| 28 | // matplotlib. Future iterations may ditch this in favor of a more modern |
| 29 | // interface where we actually return handles for plots and lines and the such. |
| 30 | // |
| 31 | // Note that currently the port for the seb server is hard-coded to 8080, so |
| 32 | // only one instance of the Plotter can be present at once. |
| 33 | // |
| 34 | // You must call Spin() for the web server to actually do anything helpful. |
| 35 | class Plotter { |
| 36 | public: |
| 37 | Plotter(); |
| 38 | |
| 39 | // matplotlib-like interface |
| 40 | // The basic pattern is: |
| 41 | // 1) Call Figure() |
Philipp Schrader | a671252 | 2023-07-05 20:25:11 -0700 | [diff] [blame] | 42 | // 2) Set up the lines, labels, etc. for the figure. |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 43 | // 3) Repeat 1-2 however many times. |
| 44 | // 4) Call Publish(). |
| 45 | // 5) Repeat 1-5 however many times. |
| 46 | // |
| 47 | // Publish() actually pushes the figures that you setup to the web-page, |
| 48 | // either with an autogenerated title or the title set by Title(). All state |
| 49 | // is cleared (or should be cleared) by the call to Publish(). |
| 50 | |
| 51 | // Sets the title for the current set of plots; if you |
| 52 | void Title(std::string_view title); |
Austin Schuh | 5ec17ef | 2022-07-15 14:37:16 -0700 | [diff] [blame] | 53 | void AddFigure(std::string_view title = "", double width = 0, |
| 54 | double height = 0); |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 55 | struct LineOptions { |
| 56 | std::string_view label = ""; |
| 57 | std::string_view line_style = "*-"; |
| 58 | std::string_view color = ""; |
Austin Schuh | 69d0b73 | 2022-07-20 21:19:32 -0700 | [diff] [blame] | 59 | double point_size = 3.0; |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 60 | }; |
| 61 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 62 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 63 | std::string_view label) { |
| 64 | AddLine(x, y, LineOptions{.label = label}); |
| 65 | } |
| 66 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
| 67 | std::string_view label, std::string_view line_style) { |
| 68 | AddLine(x, y, LineOptions{.label = label, .line_style = line_style}); |
| 69 | } |
| 70 | void AddLine(const std::vector<double> &x, const std::vector<double> &y, |
| 71 | LineOptions options); |
| 72 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 73 | void ShareXAxis(bool share) { share_x_axis_ = share; } |
| 74 | void XLabel(std::string_view label); |
| 75 | void YLabel(std::string_view label); |
| 76 | void Publish(); |
| 77 | |
| 78 | void Spin(); |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 79 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 80 | private: |
| 81 | void MaybeFinishFigure(); |
| 82 | |
| 83 | aos::FlatbufferDetachedBuffer<aos::Configuration> config_; |
| 84 | aos::SimulatedEventLoopFactory event_loop_factory_; |
| 85 | std::unique_ptr<aos::EventLoop> event_loop_; |
| 86 | aos::Sender<Plot> plot_sender_; |
| 87 | aos::web_proxy::WebProxy web_proxy_; |
| 88 | |
| 89 | aos::Sender<Plot>::Builder builder_; |
| 90 | flatbuffers::Offset<flatbuffers::String> title_; |
| 91 | flatbuffers::Offset<flatbuffers::String> figure_title_; |
| 92 | flatbuffers::Offset<flatbuffers::String> xlabel_; |
| 93 | flatbuffers::Offset<flatbuffers::String> ylabel_; |
| 94 | bool share_x_axis_ = false; |
| 95 | float next_top_ = 0; |
| 96 | flatbuffers::Offset<Position> position_; |
| 97 | std::vector<flatbuffers::Offset<Figure>> figures_; |
| 98 | std::vector<flatbuffers::Offset<Line>> lines_; |
| 99 | |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 100 | struct ColorWheelColor { |
| 101 | std::string name; |
| 102 | Color color; |
| 103 | }; |
| 104 | |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 105 | size_t color_wheel_position_ = 0; |
Austin Schuh | ea62f60 | 2022-07-18 16:53:04 -0700 | [diff] [blame] | 106 | std::vector<ColorWheelColor> color_wheel_; |
James Kuszmaul | 4867136 | 2020-12-24 13:54:16 -0800 | [diff] [blame] | 107 | }; |
| 108 | |
Stephan Pleines | 9e40c8e | 2024-02-07 20:58:28 -0800 | [diff] [blame] | 109 | } // namespace aos::analysis |
| 110 | #endif // AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_ |