Commit c452017c authored by Paul Asmuth's avatar Paul Asmuth
Browse files

rudimentary legend rendering

parent 02fdc00f
Loading
Loading
Loading
Loading
+64 −11
Original line number Diff line number Diff line
@@ -34,15 +34,14 @@

namespace plotfx {

LegendDefinition::LegendDefinition(
    kVerticalPosition vert_pos,
    kHorizontalPosition horiz_pos,
    kPlacement placement,
    const std::string& title) :
    vert_pos_(vert_pos),
    horiz_pos_(horiz_pos),
    placement_(placement),
    title_ (title) {}
LegendDefinition::LegendDefinition() :
    padding_horiz({Unit::REM, 2.4}),
    padding_vert({Unit::REM, 1.2}),
    padding_item_horiz({Unit::REM, 2.2}),
    padding_item_vert({Unit::REM, 1.0}),
    vert_pos_(LEGEND_TOP),
    horiz_pos_(LEGEND_LEFT),
    placement_(LEGEND_INSIDE) {}

const std::string LegendDefinition::title() const {
  return title_;
@@ -64,12 +63,12 @@ LegendDefinition::kPlacement LegendDefinition::placement() const {

void LegendDefinition::addEntry(
    const std::string& name,
    const std::string& color,
    const Colour& color,
    const std::string& shape /* = "circle" */) {
  entries_.emplace_back(name, color, shape);
}

const std::vector<std::tuple<std::string, std::string, std::string>>
const std::vector<std::tuple<std::string, Colour, std::string>>
    LegendDefinition::entries() const {
  return entries_;
}
@@ -360,6 +359,60 @@ LegendDefinition* Legend::legend() const {
  }
}
*/
ReturnCode legend_draw(
    const LegendDefinition& legend,
    const Rectangle& bbox,
    Layer* layer) {
  double padding_horiz = to_px(layer->measures, legend.padding_horiz);
  double padding_vert = to_px(layer->measures, legend.padding_vert);
  double padding_item_horiz = to_px(layer->measures, legend.padding_item_horiz);
  double padding_item_vert = to_px(layer->measures, legend.padding_item_vert);
  double point_size = 5;
  double line_height = 14;
  double sx = bbox.x + padding_horiz;
  double sy = bbox.y + padding_vert + line_height / 2;

  for (const auto& e : legend.entries()) {
    const auto& label_text = std::get<0>(e);

    {
      FillStyle style;
      style.colour = std::get<1>(e);
      Path path;
      path.moveTo(sx + point_size, sy);
      path.arcTo(sx, sy, point_size, 0, M_PI * 2);
      fillPath(layer, path, style);
      sx += point_size * 2.4;
    }

    {
      TextStyle style;
      style.colour = legend.text_colour;
      style.font = legend.font;

      Rectangle label_bbox;
      auto rc = text::text_measure_span(
          label_text,
          style.font,
          style.font_size,
          layer->measures.dpi,
          layer->text_shaper.get(),
          &label_bbox);

      if (auto rc = drawTextLabel(
            label_text,
            Point(sx, sy),
            HAlign::LEFT,
            VAlign::CENTER,
            style,
            layer); rc != OK) {
        return rc;
      }

      sx += label_bbox.w + padding_item_horiz;
    }
  }
}

} // namespace plotfx
+16 −11
Original line number Diff line number Diff line
@@ -64,14 +64,7 @@ public:
    LEGEND_OUTSIDE = 1
  };

  /**
   * Create a new legend definition
   */
  LegendDefinition(
      kVerticalPosition vert_pos,
      kHorizontalPosition horiz_pos,
      kPlacement placement,
      const std::string& title);
  LegendDefinition();

  const std::string title() const;
  kVerticalPosition verticalPosition() const;
@@ -80,18 +73,26 @@ public:

  void addEntry(
      const std::string& name,
      const std::string& color,
      const Colour& color,
      const std::string& shape = "circle");

  const std::vector<std::tuple<std::string, std::string, std::string>>
  const std::vector<std::tuple<std::string, Colour, std::string>>
      entries() const;

  Colour text_colour;
  Colour border_colour;
  FontInfo font;
  Measure padding_horiz;
  Measure padding_vert;
  Measure padding_item_horiz;
  Measure padding_item_vert;

protected:
  kVerticalPosition vert_pos_;
  kHorizontalPosition horiz_pos_;
  kPlacement placement_;
  const std::string title_;
  std::vector<std::tuple<std::string, std::string, std::string>> entries_;
  std::vector<std::tuple<std::string, Colour, std::string>> entries_;
};

void renderOutsideLegends(Layer* target, const Rectangle& clip);
@@ -114,6 +115,10 @@ void renderLeftLegend(
    bool bottom,
    bool outside);

ReturnCode legend_draw(
    const LegendDefinition& legend,
    const Rectangle& bbox,
    Layer* layer);

} // namespace plotfx
+8 −0
Original line number Diff line number Diff line
@@ -87,6 +87,11 @@ ReturnCode draw(
    }
  }

  // render legend
  if (auto rc = legend_draw(config.legend, border_box, layer); !rc) {
    return rc;
  }

  return ReturnCode::success();
}

@@ -106,6 +111,9 @@ ReturnCode configure(

  // FIXME
  config.colour_scheme = doc.colour_scheme;
  config.legend.font = doc.font_sans;
  config.legend.border_colour = doc.border_colour;
  config.legend.text_colour = doc.text_colour;
  config.axis_top.font = doc.font_sans;
  config.axis_top.border_colour = doc.border_colour;
  config.axis_top.text_colour = doc.text_colour;
+2 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@
#include <common/element.h>
#include <common/document.h>
#include "plot_axis.h"
#include "legend.h"

namespace plotfx {
namespace plot {
@@ -57,6 +58,7 @@ struct PlotConfig {
  Measure margins[4];
  ColourScheme colour_scheme;
  std::vector<PlotSeries> series;
  LegendDefinition legend;
};

ReturnCode draw(const PlotConfig& config, const Rectangle& clip, Layer* frame);
+4 −2
Original line number Diff line number Diff line
@@ -108,12 +108,13 @@ ReturnCode configure(const plist::Property& prop, PlotConfig* config) {
  auto colour = config->colour_scheme.next();

  PlotLinesConfig series;
  series.line_colour.parse(colour);
  series.point_colour.parse(colour);
  series.line_colour = colour;
  series.point_colour = colour;

  static const ParserDefinitions pdefs = {
    {"xs", std::bind(&configure_series, std::placeholders::_1, &series.xs)},
    {"ys", std::bind(&configure_series, std::placeholders::_1, &series.ys)},
    {"title", std::bind(&configure_string, std::placeholders::_1, &series.title)},
    {
      "colour",
      configure_multiprop({
@@ -143,6 +144,7 @@ ReturnCode configure(const plist::Property& prop, PlotConfig* config) {
        std::placeholders::_3),
  });

  config->legend.addEntry(series.title, colour);
  return OK;
}

Loading