| /* |
| * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| #ifndef RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_PLOT_BASE_H_ |
| #define RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_PLOT_BASE_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "absl/base/attributes.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/types/optional.h" |
| #include "rtc_base/ignore_wundef.h" |
| |
| RTC_PUSH_IGNORING_WUNDEF() |
| #include "rtc_tools/rtc_event_log_visualizer/proto/chart.pb.h" |
| RTC_POP_IGNORING_WUNDEF() |
| |
| namespace webrtc { |
| |
| enum class LineStyle { |
| kNone, // No line connecting the points. Used to create scatter plots. |
| kLine, // Straight line between consecutive points. |
| kStep, // Horizontal line until the next value. Used for state changes. |
| kBar // Vertical bars from the x-axis to the point. |
| }; |
| |
| enum class PointStyle { |
| kNone, // Don't draw the points. |
| kHighlight // Draw circles or dots to highlight the points. |
| }; |
| |
| struct TimeSeriesPoint { |
| TimeSeriesPoint(float x, float y) : x(x), y(y) {} |
| float x; |
| float y; |
| }; |
| |
| struct TimeSeries { |
| TimeSeries() = default; // TODO(terelius): Remove the default constructor. |
| TimeSeries(const char* label, |
| LineStyle line_style, |
| PointStyle point_style = PointStyle::kNone) |
| : label(label), line_style(line_style), point_style(point_style) {} |
| TimeSeries(const std::string& label, |
| LineStyle line_style, |
| PointStyle point_style = PointStyle::kNone) |
| : label(label), line_style(line_style), point_style(point_style) {} |
| TimeSeries(TimeSeries&& other) |
| : label(std::move(other.label)), |
| line_style(other.line_style), |
| point_style(other.point_style), |
| points(std::move(other.points)) {} |
| TimeSeries& operator=(TimeSeries&& other) { |
| label = std::move(other.label); |
| line_style = other.line_style; |
| point_style = other.point_style; |
| points = std::move(other.points); |
| return *this; |
| } |
| |
| std::string label; |
| LineStyle line_style = LineStyle::kLine; |
| PointStyle point_style = PointStyle::kNone; |
| std::vector<TimeSeriesPoint> points; |
| }; |
| |
| struct Interval { |
| Interval() = default; |
| Interval(double begin, double end) : begin(begin), end(end) {} |
| |
| double begin; |
| double end; |
| }; |
| |
| struct IntervalSeries { |
| enum Orientation { kHorizontal, kVertical }; |
| |
| IntervalSeries() = default; |
| IntervalSeries(const std::string& label, |
| const std::string& color, |
| IntervalSeries::Orientation orientation) |
| : label(label), color(color), orientation(orientation) {} |
| |
| std::string label; |
| std::string color; |
| Orientation orientation; |
| std::vector<Interval> intervals; |
| }; |
| |
| // A container that represents a general graph, with axes, title and one or |
| // more data series. A subclass should define the output format by overriding |
| // the Draw() method. |
| class Plot { |
| public: |
| virtual ~Plot() {} |
| |
| ABSL_DEPRECATED("Use PrintPythonCode() or ExportProtobuf() instead.") |
| virtual void Draw() {} |
| |
| // Sets the lower x-axis limit to min_value (if left_margin == 0). |
| // Sets the upper x-axis limit to max_value (if right_margin == 0). |
| // The margins are measured as fractions of the interval |
| // (max_value - min_value) and are added to either side of the plot. |
| void SetXAxis(float min_value, |
| float max_value, |
| std::string label, |
| float left_margin = 0, |
| float right_margin = 0); |
| |
| // Sets the lower and upper x-axis limits based on min_value and max_value, |
| // but modified such that all points in the data series can be represented |
| // on the x-axis. The margins are measured as fractions of the range of |
| // x-values and are added to either side of the plot. |
| void SetSuggestedXAxis(float min_value, |
| float max_value, |
| std::string label, |
| float left_margin = 0, |
| float right_margin = 0); |
| |
| // Sets the lower y-axis limit to min_value (if bottom_margin == 0). |
| // Sets the upper y-axis limit to max_value (if top_margin == 0). |
| // The margins are measured as fractions of the interval |
| // (max_value - min_value) and are added to either side of the plot. |
| void SetYAxis(float min_value, |
| float max_value, |
| std::string label, |
| float bottom_margin = 0, |
| float top_margin = 0); |
| |
| // Sets the lower and upper y-axis limits based on min_value and max_value, |
| // but modified such that all points in the data series can be represented |
| // on the y-axis. The margins are measured as fractions of the range of |
| // y-values and are added to either side of the plot. |
| void SetSuggestedYAxis(float min_value, |
| float max_value, |
| std::string label, |
| float bottom_margin = 0, |
| float top_margin = 0); |
| |
| void SetYAxisTickLabels( |
| const std::vector<std::pair<float, std::string>>& labels); |
| |
| // Sets the title of the plot. |
| void SetTitle(const std::string& title); |
| |
| // Sets an unique ID for the plot. The ID is similar to the title except that |
| // the title might change in future releases whereas the ID should be stable |
| // over time. |
| void SetId(const std::string& id); |
| void SetId(absl::string_view id); |
| |
| // Add a new TimeSeries to the plot. |
| void AppendTimeSeries(TimeSeries&& time_series); |
| |
| // Add a new IntervalSeries to the plot. |
| void AppendIntervalSeries(IntervalSeries&& interval_series); |
| |
| // Add a new TimeSeries to the plot if the series contains contains data. |
| // Otherwise, the call has no effect and the timeseries is destroyed. |
| void AppendTimeSeriesIfNotEmpty(TimeSeries&& time_series); |
| |
| // Replaces PythonPlot::Draw() |
| void PrintPythonCode( |
| absl::string_view figure_output_path = absl::string_view()) const; |
| |
| // Replaces ProtobufPlot::Draw() |
| void ExportProtobuf(webrtc::analytics::Chart* chart) const; |
| |
| protected: |
| float xaxis_min_; |
| float xaxis_max_; |
| std::string xaxis_label_; |
| float yaxis_min_; |
| float yaxis_max_; |
| std::string yaxis_label_; |
| std::vector<std::pair<float, std::string>> yaxis_tick_labels_; |
| std::string title_; |
| std::string id_; |
| std::vector<TimeSeries> series_list_; |
| std::vector<IntervalSeries> interval_list_; |
| }; |
| |
| class PlotCollection { |
| public: |
| virtual ~PlotCollection() {} |
| |
| ABSL_DEPRECATED("Use PrintPythonCode() or ExportProtobuf() instead.") |
| virtual void Draw() {} |
| |
| virtual Plot* AppendNewPlot(); |
| |
| virtual Plot* AppendNewPlot(absl::string_view); |
| |
| void SetCallTimeToUtcOffsetMs(int64_t calltime_to_utc_ms) { |
| calltime_to_utc_ms_ = calltime_to_utc_ms; |
| } |
| |
| // Replaces PythonPlotCollection::Draw() |
| void PrintPythonCode( |
| bool shared_xaxis, |
| absl::string_view figure_output_path = absl::string_view()) const; |
| |
| // Replaces ProtobufPlotCollections::Draw() |
| void ExportProtobuf(webrtc::analytics::ChartCollection* collection) const; |
| |
| protected: |
| std::vector<std::unique_ptr<Plot>> plots_; |
| absl::optional<int64_t> calltime_to_utc_ms_; |
| }; |
| |
| } // namespace webrtc |
| |
| #endif // RTC_TOOLS_RTC_EVENT_LOG_VISUALIZER_PLOT_BASE_H_ |