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

simplified 'discrete' scale type

parent 66855ea3
Loading
Loading
Loading
Loading
+30 −29
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ void domain_fit_kind(const Series& data, DomainConfig* domain) {
  if (series_is_numeric(data)) {
    domain->kind = DomainKind::LINEAR;
  } else {
    domain->kind = DomainKind::CATEGORICAL;
    domain->kind = DomainKind::DISCRETE;
  }
}

@@ -83,14 +83,14 @@ void domain_fit(const Series& data, DomainConfig* domain) {
    case DomainKind::LINEAR:
    case DomainKind::LOGARITHMIC:
      return domain_fit_continuous(data, domain);
    case DomainKind::CATEGORICAL:
    case DomainKind::DISCRETE:
      return domain_fit_categorical(data, domain);
  }
}

size_t domain_cardinality(const DomainConfig& domain) {
  switch (domain.kind) {
    case DomainKind::CATEGORICAL:
    case DomainKind::DISCRETE:
      return domain.categories.size();
    default:
      return std::ceil(domain_max(domain) - domain_min(domain));
@@ -156,20 +156,14 @@ double domain_translate_log(
  return std::clamp(vt, 0.0, 1.0);
}

double domain_translate_categorical(
double domain_translate_discrete(
    const DomainConfig& domain,
    const Value& v) {
  double category_count = domain.categories.size();
  if (category_count == 0) {
    return 0;
  }

  size_t vi = 0;
  if (auto vm = domain.map.find(v); vm != domain.map.end()) {
    vi = vm->second;
  }
  double min = domain_min(domain);
  double max = domain_max(domain) + 1;

  auto vt = (vi / category_count) + (0.5 / category_count);
  auto vf = value_to_float(v);
  auto vt = (vf - min) / (max - min);

  if (domain.inverted) {
    vt = 1.0 - vt;
@@ -186,8 +180,8 @@ double domain_translate(
      return domain_translate_linear(domain, value);
    case DomainKind::LOGARITHMIC:
      return domain_translate_log(domain, value);
    case DomainKind::CATEGORICAL:
      return domain_translate_categorical(domain, value);
    case DomainKind::DISCRETE:
      return domain_translate_discrete(domain, value);
    default:
      return std::numeric_limits<double>::quiet_NaN();
  }
@@ -231,20 +225,20 @@ Value domain_untranslate_log(const DomainConfig& domain, double vt) {
  return value_from_float(min + pow(log_base, vt * range_log));
}

Value domain_untranslate_categorical(
Value domain_untranslate_discrete(
    const DomainConfig& domain,
    double vt) {
  auto min = domain_min(domain);
  auto max = domain_max(domain) + 1;
  auto range = max - min;

  vt -= 0.5 / range;

  if (domain.inverted) {
    vt = 1.0 - vt;
  }

  std::string v;
  size_t vidx = vt * domain.categories.size();
  if (vidx < domain.categories.size()) {
    v = domain.categories[vidx];
  }

  return v;
  return value_from_float(min + (max - min) * vt);
}

Value domain_untranslate(
@@ -255,8 +249,8 @@ Value domain_untranslate(
      return domain_untranslate_linear(domain, value);
    case DomainKind::LOGARITHMIC:
      return domain_untranslate_log(domain, value);
    case DomainKind::CATEGORICAL:
      return domain_untranslate_categorical(domain, value);
    case DomainKind::DISCRETE:
      return domain_untranslate_discrete(domain, value);
  }

  return {};
@@ -289,8 +283,8 @@ ReturnCode domain_configure(
      continue;
    }

    if (prop == "categorical") {
      domain->kind = DomainKind::CATEGORICAL;
    if (prop == "discrete") {
      domain->kind = DomainKind::DISCRETE;
      continue;
    }

@@ -300,7 +294,14 @@ ReturnCode domain_configure(
      continue;
    }

    return ERROR;
    return err_invalid_value(prop, {
      "linear",
      "log",
      "logarithmic",
      "discrete",
      "inverted",
      "inverted"
    });
  }

  return OK;
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@
namespace plotfx {

enum class DomainKind {
  AUTO, LINEAR, LOGARITHMIC, CATEGORICAL
  AUTO, LINEAR, LOGARITHMIC, DISCRETE
};

struct DomainConfig {
+6 −11
Original line number Diff line number Diff line
@@ -448,16 +448,16 @@ ReturnCode axis_place_labels_subdivide(
ReturnCode axis_place_labels_discrete(
    const DomainConfig& domain,
    AxisDefinition* axis) {
  auto category_count = domain_cardinality(domain);
  auto range = domain_max(domain) + 1;

  axis->labels.clear();
  axis->ticks.clear();
  axis->ticks.push_back(0.0f);

  std::vector<double> label_positions;
  for (size_t i = 0; i < category_count; ++i) {
    auto o = (1.0f / category_count) * (i + 1);
    label_positions.push_back(o - 0.5 / category_count);
  for (size_t i = 0; i < range; ++i) {
    auto o = (1.0f / range) * (i + 1);
    label_positions.push_back(o - 0.5 / range);
    axis->ticks.push_back(o);
  }

@@ -474,7 +474,7 @@ ReturnCode axis_place_labels_discrete(
ReturnCode axis_place_labels_default(
    const DomainConfig& domain,
    AxisDefinition* axis) {
  if (domain.kind == DomainKind::CATEGORICAL) {
  if (domain.kind == DomainKind::DISCRETE) {
    return axis_place_labels_discrete(domain, axis);
  }

@@ -670,13 +670,8 @@ ReturnCode configure(
  }

  if (!config->label_formatter) {
    // TODO: improved automatic formatter config
    if (domain.kind == DomainKind::CATEGORICAL) {
      config->label_formatter = format_string();
    } else {
    config->label_formatter = format_decimal_fixed(1);
  }
  }

  switch (config->tick_position) {
    case AxisLabelPosition::OUTSIDE:
+9 −0
Original line number Diff line number Diff line
width: 1200px;
height: 90px;

axis {
  scale: discrete;
  scale-min: 0;
  scale-max: 16;
  layout: discrete;
}
+5 −0
Original line number Diff line number Diff line
<svg xmlns="http://www.w3.org/2000/svg" width="1200.000000" height="90.000000" viewBox="0 0 1200.0 90.0">
  <rect width="1200.000000" height="90.000000" fill="#ffffff"/>
  <path stroke-width="1.333333" stroke="#a8a8a8" fill="none" d="M40.0 50.0 L1160.0 50.0 "/>
  <path stroke-width="1.333333" stroke="#a8a8a8" fill="none" d="M40.0 50.0 L40.0 44.666667 "/>
</svg>
 No newline at end of file