Commit 255a2fc7 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

render basic legend

parent f5bdfc40
Loading
Loading
Loading
Loading
+83 −1
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@ void Canvas::render(RenderTarget* target) const {
  Viewport viewport(width_, height_);

  target->beginChart(width_, height_, "chart bar horizontal"); 
  renderOutsideLegends(target, &viewport);
  renderAxes(target, &viewport);
  renderInsideLegends(target, &viewport);
  renderCharts(target, &viewport);
  target->finishChart();
}
@@ -40,7 +42,7 @@ void Canvas::renderCharts(RenderTarget* target, Viewport* viewport) const {
}

void Canvas::renderAxes(RenderTarget* target, Viewport* viewport) const {
  std::tuple<int, int, int, int> padding;
  std::tuple<int, int, int, int> padding = viewport->padding();
  std::vector<std::pair<int, AxisDefinition*>> top;
  std::vector<std::pair<int, AxisDefinition*>> right;
  std::vector<std::pair<int, AxisDefinition*>> bottom;
@@ -378,6 +380,86 @@ void Canvas::renderLeftAxis(
}


void Canvas::renderOutsideLegends(
    RenderTarget* target,
    Viewport* viewport) const {
  for (const auto& legend : legends_) {
    target->beginGroup("legend");
    renderOutsideTopLegend(target, viewport, legend.get(), 25.0f);
    target->finishGroup();
  }
}

void Canvas::renderInsideLegends(
    RenderTarget* target,
    Viewport* viewport) const {
  auto orig_padding = viewport->padding();

  for (const auto& legend : legends_) {
    target->beginGroup("legend");
    viewport->setPaddingTop(viewport->paddingTop() + 10.0f);
    renderOutsideTopLegend(target, viewport, legend.get(), 15.0f);
    viewport->setPaddingTop(viewport->paddingTop() + 10.0f);
    target->finishGroup();
  }

  viewport->setPadding(orig_padding);
}

void Canvas::renderOutsideTopLegend(
    RenderTarget* target,
    Viewport* viewport,
    LegendDefinition* legend,
    double horiz_padding) const {
  double height = 0.0f;

  std::string title = "legend title";

  target->drawText(
    title,
    viewport->paddingLeft() + horiz_padding,
    viewport->paddingTop(),
    "start",
    "text-before-edge",
    "title");

  auto lx = viewport->paddingLeft() + viewport->innerWidth() - horiz_padding;
  auto lx_boundary = viewport->paddingLeft() + horiz_padding +
    estimateTextLength(title) + kLegendLabelPadding;

  for (const auto& entry : legend->entries()) {
    auto this_len = estimateTextLength(entry.first) + kLegendLabelPadding;

    /* line wrap */
    if (lx - this_len < lx_boundary) {
      lx = viewport->paddingLeft() + viewport->innerWidth() - horiz_padding;
      height += kLegendLineHeight;
      lx_boundary = viewport->paddingLeft() + horiz_padding;
    }

    target->drawPoint(
        lx,
        viewport->paddingTop() + 6 + height,
        "circle",
        4,
        entry.second,
        "circle");

    target->drawText(
      entry.first,
      lx - 8.0f,
      viewport->paddingTop() + height,
      "end",
      "text-before-edge",
      "title");

    lx -= this_len;
  }

  height += kLegendLineHeight;
  viewport->setPaddingTop(viewport->paddingTop() + height);
}

std::string Canvas::renderSVG() const {
  auto output = util::OutputStream::getStdout();
  SVGTarget target(output.get());
+23 −0
Original line number Diff line number Diff line
@@ -28,6 +28,10 @@ public:
  static const int kAxisLabelHeight = 35.0f; // FIXPAUL make configurable
  static const int kAxisLabelWidth = 50.0f; // FIXPAUL make configurable
  static const int kAxisTitleLength = 20.0f; // FIXPAUL make configurable
  static const int kCharWidth = 6.0f; // FIXPAUL make configurable
  static const int kLegendOutsideHorizPadding = 20.0f; // FIXPAUL make configurable
  static const int kLegendLabelPadding = 20.0f; // FIXPAUL make configurable
  static const int kLegendLineHeight = 20.0f; // FIXPAUL make configurable

  Canvas();

@@ -84,6 +88,9 @@ public:
   std::string renderSVG() const;

protected:
  int estimateTextLength(const std::string& str) const {
    return str.size() * kCharWidth;
  }

  /**
   * Render the charts
@@ -151,6 +158,22 @@ protected:
      AxisDefinition* axis,
      int left) const;

  /**
   * Render the legends
   */
  void renderOutsideLegends(RenderTarget* target, Viewport* viewport) const;

  /**
   * Render the legends
   */
  void renderInsideLegends(RenderTarget* target, Viewport* viewport) const;

  void renderOutsideTopLegend(
      RenderTarget* target,
      Viewport* viewport,
      LegendDefinition* legend,
      double horiz_padding) const;

  // FIXPAUL this belongs into the rendertarget
  int width_;
  int height_;
+17 −0
Original line number Diff line number Diff line
@@ -44,6 +44,23 @@ public:
      kPlacement placement,
      const std::string& title);

  const std::vector<std::pair<std::string, std::string>> entries() const {
    std::vector<std::pair<std::string, std::string>> entries;
    entries.emplace_back("fnord1", "color1");
    entries.emplace_back("fnord2", "color2");
    entries.emplace_back("iiiii", "color2");
    entries.emplace_back("iiiasdasdii", "color2");
    entries.emplace_back("iiiaasdasdasdsdasdii", "color2");
    entries.emplace_back("iiiaasdasdasdsdas  asd  asddii", "color2");
    entries.emplace_back("wwwwwwww", "color2");
    entries.emplace_back("iiiii", "color2");
    entries.emplace_back("iiiasdasdii", "color2");
    entries.emplace_back("iiiaasdasdasdsdasdii", "color2");
    entries.emplace_back("iiiaasdasdasdsdas  asd  asddii", "color2");
    entries.emplace_back("fnord3", "color3");
    return entries;
  }

protected:
  kVerticalPosition vert_pos_;
  kHorizontalPosition horiz_pos_;
+4 −0
Original line number Diff line number Diff line
@@ -43,6 +43,10 @@ static const std::string kStyleSheetDefault = R"(
    font-size: 12px;
  }

  .legend text {
    font-size: 10px;
  }

  .chart .line {
    fill: none;
    stroke: #000;
+20 −0
Original line number Diff line number Diff line
@@ -53,10 +53,30 @@ public:
    return std::get<3>(padding_);
  }

  const std::tuple<int, int, int, int>& padding() {
    return padding_;
  }

  void setPadding(const std::tuple<int, int, int, int>& padding) {
    padding_ = padding;
  }

  void setPaddingTop(int val) {
    std::get<0>(padding_) = val;
  }

  void setPaddingRight(int val) {
    std::get<1>(padding_) = val;
  }

  void setPaddingBottom(int val) {
    std::get<2>(padding_) = val;
  }

  void setPaddingLeft(int val) {
    std::get<3>(padding_) = val;
  }

protected:
  int width_;
  int height_;