Commit 6d2a341c authored by Paul Asmuth's avatar Paul Asmuth
Browse files

improved scale auto-configuration

parent f4da8129
Loading
Loading
Loading
Loading
+2 −8
Original line number Diff line number Diff line
width: 1200px;
height: 480px;

scale-x-min: 1404270100;
scale-x-max: 1404320100;
scale-y-min: 0;
scale-y-max: 150;
scale-y-min: -1;
scale-y-max: 200;

points {
  xs: csv('tests/testdata/measurement.csv', time);
@@ -15,13 +13,9 @@ points {

axis {
  position: bottom;
  scale-min: 1404270100;
  scale-max: 1404280100;
  format: datetime("%H:%M:%S");
}

axis {
  position: left;
  scale-min: 0;
  scale-max: 100;
}
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ std::vector<Color> series_to_colors(
  }

  auto domain = domain_config;
  domain_fit(*series, &domain);
  //domain_fit(*series, &domain);

  std::vector<Color> colors;
  //for (const auto& v : *series) {
+4 −4
Original line number Diff line number Diff line
@@ -149,10 +149,10 @@ ReturnCode document_render_to(

  auto bbox_elem = layout_margin_box(
      bbox_layer,
      40,
      40,
      40,
      40);
      60,
      60,
      60,
      60);
  //if (!tree.roots.empty()) {
  //  return {ERROR, "document has no root - empty configuration?"};
  //}
+15 −39
Original line number Diff line number Diff line
@@ -40,31 +40,8 @@ DomainConfig::DomainConfig() :
    kind(DomainKind::LINEAR),
    min_auto_snap_zero(false),
    inverted(false),
    padding(0.1f) {}

void domain_fit_continuous(const Series& data_raw, DomainConfig* domain) {
  auto data = series_to_float(data_raw);

  for (const auto& d : data) {
    if (!domain->min_auto || *domain->min_auto > d) {
      domain->min_auto = std::optional<double>(d);
    }
    if (!domain->max_auto || *domain->max_auto < d) {
      domain->max_auto = std::optional<double>(d);
    }
  }
}

void domain_fit_categorical(const Series& data, DomainConfig* domain) {
  for (const auto& d : data) {
    if (domain->map.count(d) > 0) {
      continue;
    }

    domain->map.emplace(d, domain->categories.size());
    domain->categories.emplace_back(d);
  }
}
    padding(0.1f),
    limit_hints(std::make_shared<DomainLimitHints>()) {}

void domain_fit_kind(const Series& data, DomainConfig* domain) {
  if (series_is_numeric(data)) {
@@ -74,17 +51,16 @@ void domain_fit_kind(const Series& data, DomainConfig* domain) {
  }
}

void domain_fit(const Series& data, DomainConfig* domain) {
  if (domain->kind == DomainKind::AUTO) {
    domain_fit_kind(data, domain);
  }
void domain_fit(double value, DomainConfig* domain) {
  //if (domain->kind == DomainKind::AUTO) {
  //  domain_fit_kind(data, domain);
  //}

  switch (domain->kind) {
    case DomainKind::LINEAR:
    case DomainKind::LOGARITHMIC:
      return domain_fit_continuous(data, domain);
    case DomainKind::DISCRETE:
      return domain_fit_categorical(data, domain);
  if (!domain->limit_hints->min_value || *domain->limit_hints->min_value > value) {
    domain->limit_hints->min_value = std::optional<double>(value);
  }
  if (!domain->limit_hints->max_value || *domain->limit_hints->max_value < value) {
    domain->limit_hints->max_value = std::optional<double>(value);
  }
}

@@ -98,8 +74,8 @@ size_t domain_cardinality(const DomainConfig& domain) {
}

double domain_min(const DomainConfig& domain) {
  auto min = domain.min.value_or(domain.min_auto.value_or(0));
  auto max = domain.max.value_or(domain.max_auto.value_or(0));
  auto min = domain.min.value_or(domain.limit_hints->min_value.value_or(0));
  auto max = domain.max.value_or(domain.limit_hints->max_value.value_or(0));

  double min_auto = 0;
  if (!domain.min_auto_snap_zero || min < 0) {
@@ -110,8 +86,8 @@ double domain_min(const DomainConfig& domain) {
}

double domain_max(const DomainConfig& domain) {
  auto min = domain.min.value_or(domain.min_auto.value_or(0));
  auto max = domain.max.value_or(domain.max_auto.value_or(0));
  auto min = domain.min.value_or(domain.limit_hints->min_value.value_or(0));
  auto max = domain.max.value_or(domain.limit_hints->max_value.value_or(0));
  double max_auto = max + (max - min) * domain.padding;
  return domain.max.value_or(max_auto);
}
+8 −3
Original line number Diff line number Diff line
@@ -44,6 +44,12 @@ namespace plotfx {

enum class DomainKind {
  AUTO, LINEAR, LOGARITHMIC, DISCRETE

};

struct DomainLimitHints {
  std::optional<double> min_value;
  std::optional<double> max_value;
};

struct DomainConfig {
@@ -51,14 +57,13 @@ struct DomainConfig {
  DomainKind kind;
  bool inverted;
  std::optional<double> min;
  std::optional<double> min_auto;
  bool min_auto_snap_zero;
  std::optional<double> max;
  std::optional<double> max_auto;
  std::optional<double> log_base;
  std::vector<std::string> categories;
  std::unordered_map<std::string, double> map;
  double padding;
  std::shared_ptr<DomainLimitHints> limit_hints;
};

using DomainMap = std::unordered_map<std::string, DomainConfig>;
@@ -66,7 +71,7 @@ using DomainMap = std::unordered_map<std::string, DomainConfig>;
static const std::string SCALE_DEFAULT_X = "x";
static const std::string SCALE_DEFAULT_Y = "y";

void domain_fit(const Series& data, DomainConfig* domain);
void domain_fit(double value, DomainConfig* domain);

size_t domain_cardinality(const DomainConfig& domain);
double domain_min(const DomainConfig& domain);
Loading