creativity  v1.3.0
Agent-based model of creativity and piracy
Series.hpp
1 #pragma once
2 #include "creativity/data/graph/style.hpp"
3 #include "creativity/data/graph/Target.hpp"
4 #include <cairomm/context.h>
5 #include <pangomm/fontdescription.h>
6 #include <pangomm/font.h>
7 #include <map>
8 #include <set>
9 
10 #ifndef DOXYGEN_SHOULD_SEE_THIS
11 #if CAIROMM_MAJOR_VERSION < 1 || (CAIROMM_MAJOR_VERSION == 1 && CAIROMM_MINOR_VERSION <= 12)
12 namespace Cairo {
13 
25 class SaveGuard final {
26  public:
28  explicit SaveGuard(RefPtr<Context> context) : ctx_{context} { ctx_->save(); }
30  SaveGuard(const SaveGuard &) = delete;
32  ~SaveGuard() { ctx_->restore(); }
33  private:
34  RefPtr<Context> ctx_;
35 };
36 }
37 #endif
38 #endif
39 
40 namespace creativity { namespace data { namespace graph {
41 
43 class Series {
44  public:
46  Series() = delete;
47 
59  Series(Target &target, int tmin, int tmax, double ymin, double ymax,
60  std::string title = "", std::string x_label = "", std::string y_label = "");
61 
63  virtual ~Series();
64 
71  void finishPage();
72 
77  void newPage();
78 
81 
89  void addLine(const std::map<int, double> &points,
90  const LineStyle &style = default_line_style);
91 
96 
107  void addRegion(const std::map<int, std::pair<double, double>> &intervals,
108  const FillStyle &style = default_region_style
109  );
110 
115 
135  void addLegendItem(std::string markup,
136  const FillStyle &lower,
137  bool preserve = true,
138  const RectangleStyle &style = default_legend_box_style);
139 
141  using LegendPainterCallback_t = std::function<void(Cairo::RefPtr<Cairo::Context>, const Cairo::Matrix&)>;
142 
164  void addLegendItem(std::string name, const LegendPainterCallback_t &legend_painter, bool preserve = true);
165 
167  void addLegendItem(std::string name, LegendPainterCallback_t &&legend_painter, bool preserve = true);
168 
178  static void drawRectangle(Cairo::RefPtr<Cairo::Context> ctx, double width, double height, const RectangleStyle &style, bool clip = false);
179 
181  RGBA background_colour{White};
182 
186  LineStyle tick_style{Black, 0.5, 3};
187 
192  double tick_label_space{2.0};
193 
197  LineStyle tick_grid_style{Transparent, 0.5};
198 
202  LineStyle tick_grid_extra_style{RGBA{0.75}, 0.5};
203 
205  RGBA tick_font_colour{Black};
206 
208  Pango::FontDescription tick_font{"serif 6"};
209 
213  RectangleStyle graph_style{White, LineStyle(Black, 1)};
216  double graph_padding_left{0.0},
217  graph_padding_right{0.0},
218  graph_padding_top{2.0},
219  graph_padding_bottom{2.0};
221 
224  double margin_top{5.0},
225  margin_right{5.0},
226  margin_bottom{5.0},
227  margin_left{5.0};
229 
236  enum class LegendPosition {
237  None,
238  Inside,
239  Right,
240  Left,
241  Top,
242  Bottom
243  };
244 
250  LegendPosition legend_position{LegendPosition::Right};
251 
268  double legend_rel_x{0.5};
269 
285  double legend_rel_y{0.5};
286 
295  double legend_graph_space{5.0};
297  double legend_box_width{15.0};
299  double legend_box_height{15.0};
301  double legend_box_text_gap{5.0};
304  double legend_padding_left{3.0},
305  legend_padding_right{3.0},
306  legend_padding_top{3.0},
307  legend_padding_bottom{3.0};
311  RectangleStyle legend_style{White, Black};
317  double legend_text_max_width{60.0};
325  double legend_text_max_height{40.0};
327  double legend_spacing{3.0};
329  Pango::FontDescription legend_font{"Latin Modern, DejaVu Serif, serif oblique 6"};
330 
334  std::string title;
336  Pango::FontDescription title_font{"Latin Modern, DejaVu Serif, serif bold 12"};
340  std::string x_label;
344  std::string y_label;
348  bool y_label_rotated = true;
349 
351  Pango::FontDescription axis_label_font{"Latin Modern, DejaVu Serif, serif oblique 8"};
356  double title_padding{2.0};
357 
361  double axis_label_padding{2.0};
362 
366  double stray_thickness{1.0};
367 
371  std::set<int> t_ticks;
372 
377  std::set<double> y_ticks;
378 
382  bool y_axis_left = true;
383 
390  std::set<int> t_grid;
391 
397  std::set<int> t_grid_extra;
398 
405  std::set<double> y_grid;
406 
408  std::set<double> y_grid_extra;
409 
412  enum class TickEnds {
424  Add,
425  Replace,
426  None
427  };
428 
441  void recalcTicks(unsigned xmax = 10, unsigned ymax = 8, TickEnds end_mode = TickEnds::None);
442 
452  void recalcTicksT(unsigned max = 10, TickEnds end_mode = TickEnds::None);
453 
463  void recalcTicksY(unsigned max = 8, TickEnds end_mode = TickEnds::None);
464 
479  void setExtents(int tmin, int tmax, double ymin, double ymax, bool retick = true);
480 
488  void updateFonts(const Pango::FontDescription &new_font);
489 
494  void updateFontFamily(const std::string &new_font_family);
495 
496  private:
497  Target &target_;
498  int tmin_, tmax_;
499  double ymin_, ymax_;
500 
501  // If this is true, the current page is done.
502  bool page_finished_ = false;
503 
504  using LegendItem_t = std::tuple<bool, std::string, LegendPainterCallback_t>;
505  // Legend items to add to the page; <preserve, title, callback> tuples.
506  std::list<LegendItem_t> legend_items_;
507  // Draw callbacks for the graph items; each will be called with the ctx already clipped to
508  // the graph region, and surrounded with a save/restore pair.
509  std::list<std::function<void(Cairo::RefPtr<Cairo::Context> ctx, const Cairo::Matrix&)>> draw_;
510 
511  // Implementation callback for addLegendItem(markup, lower, preserve, bg).
512  void drawSimpleLegendItem(Cairo::RefPtr<Cairo::Context> ctx, const Cairo::Matrix &to_box, const FillStyle &lower, const RectangleStyle &bg) const;
513 
514  // Draws a legend item at the current position of the context, returning its size (width and height). If dry_run is true, just returns the size.
515  std::pair<double, double> drawLegendItem(Cairo::RefPtr<Cairo::Context> ctx, const LegendItem_t &item, bool dry_run = false) const;
516 
517  // Implementation method of addLine() that does the actual drawing
518  void drawLine(Cairo::RefPtr<Cairo::Context> ctx, const Cairo::Matrix &translate_graph, const std::map<int, double> &points, const LineStyle &style) const;
519 
520  // Implementation method of addRegion() that does the actual drawing
521  void drawRegion(Cairo::RefPtr<Cairo::Context> ctx, const Cairo::Matrix &translate_graph, const std::map<int, std::pair<double,double>> &points, const FillStyle &style) const;
522 
523  protected:
537  static void boundRegion(
538  Cairo::RefPtr<Cairo::Context> ctx,
539  std::map<int, std::pair<double, double>>::const_iterator first,
540  std::map<int, std::pair<double, double>>::const_iterator last,
541  std::map<int, std::pair<double, double>> &strays);
542 };
543 
544 }}}
Class to plot graphs of time series values and/or regions.
Definition: Series.hpp:43
Primary namespace for all Creativity library code.
Definition: config.hpp:4
Style class for a filled region.
Definition: style.hpp:145
std::set< double > y_grid_extra
Like t_grid_extra, but for y axis values.
Definition: Series.hpp:408
Style class for a filled, rectangular region.
Definition: style.hpp:173
std::set< int > t_grid
X-axis (t) grid mark locations, calculated during construction.
Definition: Series.hpp:390
Abstract base class for graph destinations.
Definition: Target.hpp:13
std::function< void(Cairo::RefPtr< Cairo::Context >, const Cairo::Matrix &)> LegendPainterCallback_t
Alias for the function callback for custom legend support.
Definition: Series.hpp:141
TickEnds
Different modes for what to do with the tmin/tmax/ymin/ymax graph end points given during constructio...
Definition: Series.hpp:412
static const LineStyle default_line_style
The default line style for addLine(): a 1-unit wide, solid black line.
Definition: Series.hpp:80
std::set< double > y_ticks
Y-axis tick mark locations, calculated during construction.
Definition: Series.hpp:377
Don&#39;t reduce the prefix/suffix: the returned prefix and suffix may overlap.
Simple class holding red, green, blue, and alpha values. Each should be a value in [0...
Definition: style.hpp:8
static const RectangleStyle default_legend_box_style
The default legend box background and/or border style: white background with a 0.5-unit wide...
Definition: Series.hpp:114
static const FillStyle default_region_style
The default fill style for a region added with addRegion(): a 1/4 opacity solid blue background...
Definition: Series.hpp:95
std::string title
The graph title text, which may contain pango markup.
Definition: Series.hpp:334
Style class for a drawn line.
Definition: style.hpp:124
std::string x_label
The x axis label, which may contain pango markup.
Definition: Series.hpp:340
Definition: GraphArea.hpp:13
std::set< int > t_ticks
X-axis (t) tick mark locations, calculated during construction.
Definition: Series.hpp:371
std::set< double > y_grid
Y-axis grid mark locations, calculated during construction.
Definition: Series.hpp:405
std::set< int > t_grid_extra
Extra x-axis grid marks to draw.
Definition: Series.hpp:397
LegendPosition
The possible general positions of the legend.
Definition: Series.hpp:236
std::string y_label
The y axis label, which may contain pango markup.
Definition: Series.hpp:344