Commit 8be03b76 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

improved automatic scale configuration, convert PlotLayers into normal Elements

parent 8cbffa3e
Loading
Loading
Loading
Loading
+93 −0
Original line number Diff line number Diff line
@@ -80,6 +80,13 @@ ReturnCode configure_color(
  return ReturnCode::error("EARG", "invalid color");
}

ParserFn configure_color_var(Color* var) {
  return configure_var(
      static_cast<ScalarParseFn<Color>>(
          std::bind(&configure_color, std::placeholders::_1, std::placeholders::_2)),
      var);
}

ReturnCode configure_float(
    const plist::Property& prop,
    double* value) {
@@ -203,5 +210,91 @@ ParserFn configure_key(std::string* key) {
  };
}

ReturnCode parse_data_series_csv(
    const plist::Property& prop ,
    SeriesRef* data_ref) {
  if (!plist::is_enum(prop, "csv")) {
    return ERROR_INVALID_ARGUMENT;
  }

  if (prop.size() < 2) {
    return ERROR_INVALID_ARGUMENT; // FIXME
  }

  const auto& csv_path = prop[0].value;
  const auto& csv_column = prop[1].value;

  size_t csv_column_idx = 0;
  try {
    csv_column_idx = std::stoul(csv_column);
  } catch (... ) {
    return ERROR_INVALID_ARGUMENT; // FIXME
  }

  auto csv_data_str = FileUtil::read(csv_path).toString();
  auto csv_data = CSVData{};
  auto csv_opts = CSVParserConfig{};

  for (size_t i = 2; i < prop.size(); ++i) {
    if (prop[i].value == "noheaders") {
      csv_opts.headers = false;
      continue;
    }
  }

  if (auto rc = parseCSV(csv_data_str, csv_opts, &csv_data); !rc) {
    return rc;
  }

  auto data = std::make_shared<Series>();
  for (const auto& row : csv_data) {
    if (row.size() > csv_column_idx) {
      const auto& value = row[csv_column_idx];
      data->emplace_back(value);
    }
  }

  *data_ref = data;
  return OK;
}


ReturnCode parse_data_series_inline(
    const plist::Property& prop,
    SeriesRef* data_ref) {
  if (!plist::is_list(prop)) {
    return ERROR_INVALID_ARGUMENT;
  }

  auto data = std::make_shared<Series>();
  for (const auto& value : *prop.next) {
    data->emplace_back(value);
  }

  *data_ref = data;
  return OK;
}

ReturnCode configure_series(
    const plist::Property& prop,
    SeriesRef* data) {
  if (plist::is_enum(prop, "csv")) {
    return parse_data_series_csv(prop, data);
  }

  if (plist::is_list(prop)) {
    return parse_data_series_inline(prop, data);
  }

  return ERROR_INVALID_ARGUMENT;
}

ParserFn configure_series_var(SeriesRef* series) {
  return configure_var(
      static_cast<ScalarParseFn<SeriesRef>>(
          std::bind(&configure_series, std::placeholders::_1, std::placeholders::_2)),
      series);
}

} // namespace plotfx
+25 −0
Original line number Diff line number Diff line
@@ -100,6 +100,18 @@ ReturnCode resolve_slot(
    size_t data_idx,
    T* val);

template <typename T>
struct VariableSlot {
  std::string variable;
  std::vector<T> values;
};

template <typename T>
using ScalarParseFn = std::function<ReturnCode (const plist::Property&, T*)>;

template <typename T>
using ListParseFn = std::function<ReturnCode (const plist::Property&, std::vector<T>*)>;

template <typename T>
ParserFn configure_slot(Slot<T>* slot);

@@ -117,6 +129,8 @@ ReturnCode configure_color(
    const plist::Property& prop,
    Color* value);

ParserFn configure_color_var(Color* var);

ReturnCode configure_float(
    const plist::Property& prop,
    double* value);
@@ -133,6 +147,17 @@ ReturnCode configure_data_frame(
    const plist::Property& prop,
    DataFrame* data);

ReturnCode configure_series(
    const plist::Property& prop,
    SeriesRef* data);

ParserFn configure_series_var(SeriesRef* data);

template <typename T>
ParserFn configure_var(
    ScalarParseFn<T> parser,
    T* value);

} // namespace plotfx

#include "config_helpers_impl.h"
+21 −0
Original line number Diff line number Diff line
@@ -75,5 +75,26 @@ ParserFn configure_slot(Slot<T>* slot) {
  };
}

template <typename T>
ReturnCode configure_var(
    const plist::Property& prop,
    ScalarParseFn<T> parser,
    T* value) {
  if (auto rc = parser(prop, value); !rc) {
    return rc;
  }

  return OK;
}

template <typename T>
ParserFn configure_var(
    ScalarParseFn<T> parser,
    T* value) {
  return [parser, value] (const plist::Property& prop) {
    return configure_var(prop, parser, value);
  };
}

} // namespace plotfx
+19 −0
Original line number Diff line number Diff line
@@ -126,5 +126,24 @@ std::vector<DataGroup> column_group(const DataColumn& col) {
  return groups;
}

std::vector<DataGroup> series_group(const Series& data) {
  std::vector<DataGroup> groups;

  for (size_t idx = 0; idx < data.size(); ) {
    DataGroup g;
    g.key = data[idx];
    g.begin = idx;
    g.end = idx;

    while (g.end < data.size() && data[g.end] == data[g.begin]) {
      g.end = ++idx;
    }

    groups.emplace_back(g);
  }

  return groups;
}

} // namespace plotfx
+3 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ namespace plotfx {

using Value = std::string;
using Series = std::vector<Value>;
using SeriesRef = std::shared_ptr<Series>;

// FIXME: rename to column?
struct DataColumn {
@@ -65,6 +66,8 @@ Value data_lookup(

std::vector<DataGroup> column_group(const DataColumn& col);

std::vector<DataGroup> series_group(const Series& data);

size_t series_len(const Series& s);

bool series_is_numeric(const Series& s);
Loading