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

clean up the scale layout list

parent 7811a233
Loading
Loading
Loading
Loading
+233 −64
Original line number Diff line number Diff line
@@ -224,18 +224,100 @@ ReturnCode scale_configure_kind(
  return OK;
}

ReturnCode scale_layout_linear(
ReturnCode scale_layout_linear_interval(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step,
    std::optional<double> o_begin,
    std::optional<double> o_end) {
    double o_begin,
    double o_end) {
  layout->positions.clear();
  layout->labels.clear();

  auto begin = std::max(o_begin.value_or(scale_min(domain)), scale_min(domain));
  auto end = std::min(o_end.value_or(scale_max(domain)), scale_max(domain));
  auto begin = std::max(o_begin, scale_min(domain));
  auto end = std::min(o_end, scale_max(domain));

  if (((end - begin) / step) > kMaxTicks) {
    return {ERROR, "too many ticks"};
  }

  size_t idx = 0;
  for (auto v = begin; v <= end; v += step) {
    auto vp = scale_translate(domain, v);
    layout->positions.emplace_back(vp);
    layout->labels.emplace_back(label_format(idx++, std::to_string(v))); // FIXME
  }

  return OK;
}

ReturnCode scale_layout_linear_alignat(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step,
    double align) {
  auto begin = scale_min(domain);
  auto end = scale_max(domain);

  // align
  begin -= fmod(begin, step);
  begin -= fmod(align, step);

  if (((end - begin) / step) > kMaxTicks) {
    return {ERROR, "too many ticks"};
  }

  size_t idx = 0;
  for (auto v = begin; v <= end; v += step) {
    auto vp = scale_translate(domain, v);
    if (vp < 0.0) {
      continue;
    }

    layout->positions.emplace_back(vp);
    layout->labels.emplace_back(label_format(idx++, std::to_string(v))); // FIXME
  }

  return OK;
}

ReturnCode scale_layout_linear_align(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step) {
  auto begin = scale_min(domain);
  auto end = scale_max(domain);

  // align
  begin -= fmod(begin, step);

  if (((end - begin) / step) > kMaxTicks) {
    return {ERROR, "too many ticks"};
  }

  size_t idx = 0;
  for (auto v = begin; v <= end; v += step) {
    auto vp = scale_translate(domain, v);
    if (vp < 0.0) {
      continue;
    }

    layout->positions.emplace_back(vp);
    layout->labels.emplace_back(label_format(idx++, std::to_string(v))); // FIXME
  }

  return OK;
}

ReturnCode scale_layout_linear(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step) {
  auto begin = scale_min(domain);
  auto end = scale_max(domain);

  if (((end - begin) / step) > kMaxTicks) {
    return {ERROR, "too many ticks"};
@@ -269,42 +351,24 @@ ReturnCode scale_layout_subdivide(
  return OK;
}

ReturnCode scale_layout_discrete(
ReturnCode scale_layout_categorical(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout) {
  uint32_t step = 1;
  uint32_t range = scale_max(domain) - scale_min(domain);

  layout->positions.clear();
  layout->labels.clear();

  for (size_t i = 0; i <= range; i += step) {
    auto o = scale_translate(domain, i * step);
    auto o1 = scale_translate(domain, i * step - step * 0.5);
    auto o2 = scale_translate(domain, i * step + step * 0.5);
    auto v = uint32_t(scale_min(domain)) + i * step;
    auto vn = uint32_t(scale_min(domain)) + (i + 1) * step;

    if (o1 >= 0 && o2 <= 1) {
  auto n = domain.categories.size();
  for (size_t i = 0; i < n; ++i) {
    auto o =  double(i + 1) / (n + 1);
    layout->positions.emplace_back(o);
      layout->labels.emplace_back(
          label_format(i - 1, std::to_string(scale_untranslate(domain, o)))); // FIXME
    }

    //if (o1 >= 0 && o1 <= 1) {
    //  layout->ticks.push_back(o1);
    //}

    //if (o2 >= 0 && o2 <= 1) {
    //  layout->ticks.push_back(o2);
    //}
    layout->labels.emplace_back(label_format(i, domain.categories[i]));
  }

  return OK;
}

ReturnCode scale_layout_categorical(
ReturnCode scale_layout_categorical_bounds(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout) {
@@ -313,45 +377,131 @@ ReturnCode scale_layout_categorical(

  auto n = domain.categories.size();
  for (size_t i = 0; i < n; ++i) {
    auto o =  double(i + 1) / (n + 1);
    layout->positions.emplace_back(o);
    layout->labels.emplace_back(label_format(i, domain.categories[i]));
    auto o1 =  double(i + 0.5) / (n + 1);
    auto o2 =  double(i + 1.5) / (n + 1);
    layout->positions.emplace_back(o1);
    layout->positions.emplace_back(o2);
    layout->labels.emplace_back("");
    layout->labels.emplace_back("");
  }

  return OK;
}

ReturnCode scale_configure_layout_linear(
ReturnCode scale_configure_layout_linear_interval(
    const Expr* expr,
    ScaleLayoutFn* layout) {
  auto args = expr_collect(expr);

  double step = 0;
  std::optional<double> begin;
  std::optional<double> end;
  switch (args.size()) {
    case 3:
      if (auto rc = expr_to_float64_opt(args[2], &end); !rc) {
  if (args.size() != 3) {
    return errorf(
        ERROR,
        "invalid number of arguments for 'linear-interval'; expected three, got: {}",
        args.size());
  }

  double step;
  if (auto rc = expr_to_float64(args[0], &step); !rc) {
    return rc;
  }
      /* fallthrough */
    case 2:
      if (auto rc = expr_to_float64_opt(args[1], &begin); !rc) {

  double begin;
  if (auto rc = expr_to_float64(args[1], &begin); !rc) {
    return rc;
  }
      /* fallthrough */
    case 1:

  double end;
  if (auto rc = expr_to_float64(args[2], &end); !rc) {
    return rc;
  }

  *layout = bind(
      &scale_layout_linear_interval,
      _1,
      _2,
      _3,
      step,
      begin,
      end);

  return OK;
}

ReturnCode scale_configure_layout_linear_alignat(
    const Expr* expr,
    ScaleLayoutFn* layout) {
  auto args = expr_collect(expr);

  if (args.size() != 2) {
    return errorf(
        ERROR,
        "invalid number of arguments for 'linear-alignat'; expected two, got: {}",
        args.size());
  }

  double step;
  if (auto rc = expr_to_float64(args[0], &step); !rc) {
    return rc;
  }
      break;
    case 0:
      step = 1; // TODO: automatically choose a good value
      break;
    default:
      return error(

  double align;
  if (auto rc = expr_to_float64(args[1], &align); !rc) {
    return rc;
  }

  *layout = bind(
      &scale_layout_linear_alignat,
      _1,
      _2,
      _3,
      step,
      align);

  return OK;
}

ReturnCode scale_configure_layout_linear_align(
    const Expr* expr,
    ScaleLayoutFn* layout) {
  auto args = expr_collect(expr);

  if (args.size() != 1) {
    return errorf(
        ERROR,
          "invalid number of arguments for 'linear'; expected 0-3");
        "invalid number of arguments for 'linear-align'; expected one, got: {}",
        args.size());
  }

  double step;
  if (auto rc = expr_to_float64(args[0], &step); !rc) {
    return rc;
  }

  *layout = bind(
      &scale_layout_linear_align,
      _1,
      _2,
      _3,
      step);

  return OK;
}

ReturnCode scale_configure_layout_linear(
    const Expr* expr,
    ScaleLayoutFn* layout) {
  auto args = expr_collect(expr);

  if (args.size() != 1) {
    return errorf(
        ERROR,
        "invalid number of arguments for 'linear'; expected one, got: {}",
        args.size());
  }

  double step;
  if (auto rc = expr_to_float64(args[0], &step); !rc) {
    return rc;
  }

  *layout = bind(
@@ -359,9 +509,7 @@ ReturnCode scale_configure_layout_linear(
      _1,
      _2,
      _3,
      step,
      begin,
      end);
      step);

  return OK;
}
@@ -413,12 +561,29 @@ ReturnCode scale_configure_layout(
    return scale_configure_layout_linear(expr_next(expr), layout);
  }

  if (expr_is_value(expr, "linear-align")) {
    return scale_configure_layout_linear_align(expr_next(expr), layout);
  }

  if (expr_is_value(expr, "linear-alignat")) {
    return scale_configure_layout_linear_alignat(expr_next(expr), layout);
  }

  if (expr_is_value(expr, "linear-interval")) {
    return scale_configure_layout_linear_interval(expr_next(expr), layout);
  }

  if (expr_is_value(expr, "subdivide")) {
    return scale_configure_layout_subdivide(expr_next(expr), layout);
  }

  if (expr_is_value(expr, "discrete")) {
    *layout = bind(&scale_layout_discrete, _1, _2, _3);
  if (expr_is_value(expr, "categorical")) {
    *layout = bind(&scale_layout_categorical, _1, _2, _3);
    return OK;
  }

  if (expr_is_value(expr, "categorical-bounds")) {
    *layout = bind(&scale_layout_categorical_bounds, _1, _2, _3);
    return OK;
  }

@@ -426,8 +591,12 @@ ReturnCode scale_configure_layout(
      ERROR,
      "invalid argument; expected one of: \n"
      "  - linear\n"
      "  - linear-align\n"
      "  - linear-alignat\n"
      "  - linear-interval\n"
      "  - subdivide\n"
      "  - discrete\n");
      "  - categorical\n"
      "  - categorical-bounds\n");
}


+24 −5
Original line number Diff line number Diff line
@@ -82,13 +82,32 @@ ReturnCode scale_configure_kind(
    const Expr* expr,
    ScaleConfig* domain);

ReturnCode scale_layout_linear(
ReturnCode scale_layout_linear_interval(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step,
    std::optional<double> begin,
    std::optional<double> end);
    double begin,
    double end);

ReturnCode scale_layout_linear_alignat(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step,
    double align);

ReturnCode scale_layout_linear_align(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step);

ReturnCode scale_layout_linear(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout,
    double step);

ReturnCode scale_layout_subdivide(
    const ScaleConfig& domain,
@@ -96,12 +115,12 @@ ReturnCode scale_layout_subdivide(
    ScaleLayout* layout,
    uint32_t divisions);

ReturnCode scale_layout_discrete(
ReturnCode scale_layout_categorical(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout);

ReturnCode scale_layout_categorical(
ReturnCode scale_layout_categorical_bounds(
    const ScaleConfig& domain,
    const Formatter& label_format,
    ScaleLayout* layout);
+2 −2
Original line number Diff line number Diff line
@@ -296,7 +296,7 @@ static ReturnCode axis_draw_vertical(

  /* draw ticks */
  ScaleLayout ticks;
  axis_config.label_placement(
  axis_config.tick_placement(
      axis_config.scale,
      axis_config.label_formatter,
      &ticks);
@@ -438,7 +438,7 @@ static ReturnCode axis_draw_horizontal(

  /* draw ticks */
  ScaleLayout ticks;
  axis_config.label_placement(
  axis_config.tick_placement(
      axis_config.scale,
      axis_config.label_formatter,
      &ticks);
+1 −2
Original line number Diff line number Diff line
@@ -2,8 +2,7 @@
    axes (top right bottom left)
    limit-x (0.5 6.5)
    limit-y (-20 70)
    axis-x-label-placement (discrete)
    axis-y-label-placement (linear 10 -20)
    axis-y-label-placement (linear-interval 10 -20 70)
    bars (
      data-x (csv "tests/testdata/bardata.csv" var0)
      data-y (csv "tests/testdata/bardata.csv" var1)
+44 −24
Original line number Diff line number Diff line
@@ -13,18 +13,28 @@
  <path fill="#666666" d="M647.859 172.192 L647.859 269.666 L667.415 269.666 L667.415 172.192 "/>
  <path fill="#666666" d="M776.284 121.335 L776.284 396.807 L795.839 396.807 L795.839 121.335 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 49.2889 L835.274 49.2889 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M128.939 49.2889 L128.939 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M257.363 49.2889 L257.363 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M385.788 49.2889 L385.788 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M514.212 49.2889 L514.212 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M642.637 49.2889 L642.637 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M771.061 49.2889 L771.061 54.6222 "/>
  <text x="118.743345" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.0</text>
  <text x="247.167882" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.0</text>
  <text x="375.592419" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">3.0</text>
  <text x="504.016956" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.0</text>
  <text x="632.441493" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.0</text>
  <text x="760.866030" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">6.0</text>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 49.2889 L64.7264 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M141.781 49.2889 L141.781 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M218.836 49.2889 L218.836 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M295.891 49.2889 L295.891 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M372.945 49.2889 L372.945 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M450 49.2889 L450 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M527.055 49.2889 L527.055 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M604.109 49.2889 L604.109 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M681.164 49.2889 L681.164 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M758.219 49.2889 L758.219 54.6222 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M835.274 49.2889 L835.274 54.6222 "/>
  <text x="54.531076" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">0.5</text>
  <text x="131.585800" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.1</text>
  <text x="208.640523" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.7</text>
  <text x="285.695252" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.3</text>
  <text x="362.749970" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.9</text>
  <text x="439.804688" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">3.5</text>
  <text x="516.859428" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.1</text>
  <text x="593.914123" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.7</text>
  <text x="670.968863" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.3</text>
  <text x="748.023604" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.9</text>
  <text x="825.078299" y="33.555556" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">6.5</text>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M835.274 49.2889 L835.274 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M829.94 430.711 L835.274 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M829.94 388.331 L835.274 388.331 "/>
@@ -47,18 +57,28 @@
  <text x="847.006944" y="96.669136" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">60.0</text>
  <text x="847.006944" y="54.288889" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">70.0</text>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 430.711 L835.274 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M128.939 425.378 L128.939 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M257.363 425.378 L257.363 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M385.788 425.378 L385.788 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M514.212 425.378 L514.212 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M642.637 425.378 L642.637 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M771.061 425.378 L771.061 430.711 "/>
  <text x="118.743345" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.0</text>
  <text x="247.167882" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.0</text>
  <text x="375.592419" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">3.0</text>
  <text x="504.016956" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.0</text>
  <text x="632.441493" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.0</text>
  <text x="760.866030" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">6.0</text>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 425.378 L64.7264 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M141.781 425.378 L141.781 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M218.836 425.378 L218.836 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M295.891 425.378 L295.891 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M372.945 425.378 L372.945 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M450 425.378 L450 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M527.055 425.378 L527.055 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M604.109 425.378 L604.109 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M681.164 425.378 L681.164 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M758.219 425.378 L758.219 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M835.274 425.378 L835.274 430.711 "/>
  <text x="54.531076" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">0.5</text>
  <text x="131.585800" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.1</text>
  <text x="208.640523" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">1.7</text>
  <text x="285.695252" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.3</text>
  <text x="362.749970" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">2.9</text>
  <text x="439.804688" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">3.5</text>
  <text x="516.859428" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.1</text>
  <text x="593.914123" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">4.7</text>
  <text x="670.968863" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.3</text>
  <text x="748.023604" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">5.9</text>
  <text x="825.078299" y="456.444444" fill="#333333" font-size="14.666667" font-family="Arial,Helvetica,'Helvetica Neue',sans-serif">6.5</text>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 49.2889 L64.7264 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 430.711 L70.0597 430.711 "/>
  <path stroke-width="1.333333" stroke="#333333" fill="none" d="M64.7264 388.331 L70.0597 388.331 "/>
Loading