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

implement the 'scale-padding' option for categorical scales

parent f015cb75
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -236,8 +236,7 @@ ReturnCode data_to_measures(
              *v);
        }

        auto n = scale.categories.size();
        m = from_rel(double(v_iter->second + 1) / (n + 1));
        m = from_rel(scale_translate_categorical(scale, v_iter->second));
        break;
      }
      default:
+19 −7
Original line number Diff line number Diff line
@@ -98,6 +98,15 @@ double scale_translate_log(
  return vt;
}

double scale_translate_categorical(
    const ScaleConfig& scale,
    size_t index) {
  double n = scale.categories.size();
  double i = std::clamp(double(index), 0.0, n - 1);
  double p = scale.padding;
  return (i + p) / (n - 1 + p * 2);
}

double scale_translate(
    const ScaleConfig& domain,
    double value) {
@@ -106,6 +115,8 @@ double scale_translate(
      return scale_translate_linear(domain, value);
    case ScaleKind::LOGARITHMIC:
      return scale_translate_log(domain, value);
    case ScaleKind::CATEGORICAL:
      return scale_translate_categorical(domain, value);
    default:
      return std::numeric_limits<double>::quiet_NaN();
  }
@@ -198,6 +209,7 @@ ReturnCode scale_configure_kind(

    if (expr_is_value(expr, "categorical")) {
      domain->kind = ScaleKind::CATEGORICAL;
      domain->padding = 0.5;

      expr = expr_next(expr);
      if (auto rc = data_load_strings(expr, &domain->categories); !rc) {
@@ -360,7 +372,7 @@ ReturnCode scale_layout_categorical(

  auto n = domain.categories.size();
  for (size_t i = 0; i < n; ++i) {
    auto o =  double(i + 1) / (n + 1);
    auto o = scale_translate_categorical(domain, i);
    layout->positions.emplace_back(o);
    layout->labels.emplace_back(label_format(i, domain.categories[i]));
  }
@@ -376,12 +388,12 @@ ReturnCode scale_layout_categorical_bounds(
  layout->labels.clear();

  auto n = domain.categories.size();
  for (size_t i = 0; i < n; ++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("");
  double p = domain.padding;
  auto o = 0.5 / (n - 1 + p * 2);

  for (size_t i = 0; i <= n; ++i) {
    auto v = scale_translate_categorical(domain, i);
    layout->positions.emplace_back(i == n ? v + o : v - o);
    layout->labels.emplace_back("");
  }

+4 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ double scale_translate(
    const ScaleConfig& domain,
    double value);

double scale_translate_categorical(
    const ScaleConfig& domain,
    size_t index);

std::function<double (double)> scale_translate_fn(const ScaleConfig& domain);

double scale_untranslate(
+2 −0
Original line number Diff line number Diff line
@@ -728,6 +728,7 @@ ReturnCode build(const Environment& env, const Expr* expr, ElementRef* elem) {

      /* scale options */
      {"scale", bind(&scale_configure_kind, _1, &config->scale)},
      {"scale-padding", bind(&expr_to_float64, _1, &config->scale.padding)},
      {"limit", bind(&expr_to_float64_opt_pair, _1, &config->scale.min, &config->scale.max)},
      {"limit-min", bind(&expr_to_float64_opt, _1, &config->scale.min)},
      {"limit-max", bind(&expr_to_float64_opt, _1, &config->scale.max)},
@@ -754,6 +755,7 @@ ReturnCode build(const Environment& env, const Expr* expr, ElementRef* elem) {
  if (!config->label_placement) {
    if (config->scale.kind == ScaleKind::CATEGORICAL) {
      config->label_placement = bind(&scale_layout_categorical, _1, _2, _3);
      config->tick_placement = bind(&scale_layout_categorical_bounds, _1, _2, _3);
    } else {
      config->label_placement = bind(&scale_layout_subdivide, _1, _2, _3, 10);
    }
+9 −0
Original line number Diff line number Diff line
@@ -170,6 +170,15 @@ properties:

          ;; set the axis to inverted mode
          scale (invert)
      - name: scale-padding
        desc: |
          Set the scale padding. Value is clamped to [0.0, 1.0]
        desc_code: |
          scale-padding <value>
        examples: |
          ;; set the scale padding to 0.5
          scale-padding 0.5


  - title: "Title Options"
    anchor: title-options
Loading