blob: 8c000964d12c121c7446d0cf9aa9b781b8f9b694 [file] [log] [blame]
#ifndef AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_
#define AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_
#include <stddef.h>
#include <memory>
#include <string>
#include <string_view>
#include <vector>
#include "flatbuffers/buffer.h"
#include "flatbuffers/string.h"
#include "aos/analysis/plot_data_generated.h"
#include "aos/configuration_generated.h"
#include "aos/events/event_loop.h"
#include "aos/events/simulated_event_loop.h"
#include "aos/flatbuffers.h"
#include "aos/network/web_proxy.h"
namespace aos::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) Set up 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 = 0,
double height = 0);
struct LineOptions {
std::string_view label = "";
std::string_view line_style = "*-";
std::string_view color = "";
double point_size = 3.0;
};
void AddLine(const std::vector<double> &x, const std::vector<double> &y,
std::string_view label) {
AddLine(x, y, LineOptions{.label = label});
}
void AddLine(const std::vector<double> &x, const std::vector<double> &y,
std::string_view label, std::string_view line_style) {
AddLine(x, y, LineOptions{.label = label, .line_style = line_style});
}
void AddLine(const std::vector<double> &x, const std::vector<double> &y,
LineOptions options);
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_;
struct ColorWheelColor {
std::string name;
Color color;
};
size_t color_wheel_position_ = 0;
std::vector<ColorWheelColor> color_wheel_;
};
} // namespace aos::analysis
#endif // AOS_ANALYSIS_IN_PROCESS_PLOTTER_H_