Commit 9c46a61a authored by Paul Asmuth's avatar Paul Asmuth
Browse files

move data configuration into the plot element

parent 4efbf3aa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ add_library(plotfxlib STATIC
    elements/plot_lines.cc
    elements/legend.cc
    common/config_helpers.cc
    common/data_frame.cc
    common/domain.cc
    common/format.cc
    common/plist/plist.cc
@@ -48,7 +49,6 @@ add_library(plotfxlib STATIC
    common/graphics/font_lookup.cc
    common/element_factory.cc
    common/document.cc
    common/series.cc
    common/utils/random.cc
    common/utils/csv.cc
    common/utils/bufferutil.cc
+57 −74
Original line number Diff line number Diff line
@@ -34,80 +34,6 @@

namespace plotfx {

ReturnCode parse_data_series_csv(
    const plist::Property& prop ,
    Series* data) {
  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;
  }

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

  return OK;
}

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

  for (const auto& value : *prop.next) {
    data->emplace_back(value);
  }

  return OK;
}

ReturnCode configure_series(
    const plist::Property& prop,
    Series* 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;
}

ReturnCode configure_measure_rel(
    const plist::Property& prop,
    double dpi,
@@ -206,5 +132,62 @@ ReturnCode configure_string(
  return OK;
}

ReturnCode parse_data_frame_csv(
    const plist::Property& prop ,
    DataFrame* data) {
  if (!plist::is_enum(prop, "csv")) {
    return ERROR_INVALID_ARGUMENT;
  }

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

  const auto& csv_path = prop[0].value;
  auto csv_data_str = FileUtil::read(csv_path).toString();
  auto csv_data = CSVData{};
  auto csv_opts = CSVParserConfig{};

  for (size_t i = 1; 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;
  }

  std::optional<size_t> column_count;
  for (const auto& row : csv_data) {
    if (!column_count || row.size() < column_count) {
      column_count = row.size();
    }
  }

  for (size_t i = 0; i < column_count; ++i) {
    DataColumn column;
    column.name = std::to_string(i);
    for (const auto& row : csv_data) {
      column.data.push_back(row[i]);
    }

    data->columns.emplace_back(column);
  }

  return OK;
}

ReturnCode configure_data_frame(
    const plist::Property& prop,
    DataFrame* data) {
  if (plist::is_enum(prop, "csv")) {
    return parse_data_frame_csv(prop, data);
  }

  return ERROR_INVALID_ARGUMENT;
}

} // namespace plotfx
+5 −5
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
#include <graphics/measure.h>
#include <graphics/color.h>
#include "utils/return_code.h"
#include "common/series.h"
#include "common/data_frame.h"

namespace plotfx {

@@ -87,10 +87,6 @@ ReturnCode parse_classlike(

ParserFn configure_multiprop(const std::vector<ParserFn>& parsers);

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

ReturnCode configure_measure_rel(
    const plist::Property& prop,
    double dpi,
@@ -113,5 +109,9 @@ ReturnCode configure_float_opt(
    const plist::Property& prop,
    std::optional<double>* value);

ReturnCode configure_data_frame(
    const plist::Property& prop,
    DataFrame* data);

} // namespace plotfx
+14 −2
Original line number Diff line number Diff line
@@ -27,11 +27,23 @@
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "series.h"
#include "data_frame.h"

namespace plotfx {

using Series = std::vector<std::string>;
ReturnCode column_find(
    const DataFrame& frame,
    const std::string& column_name,
    const DataColumn** column) {
  for (const auto& c : frame.columns) {
    if (c.name == column_name) {
      *column = &c;
      return OK;
    }
  }

  return ReturnCode::errorf("EARG", "column not found: $0", column_name);
}

size_t series_len(const Series& s) {
  return s.size();
+17 −8
Original line number Diff line number Diff line
@@ -28,21 +28,30 @@
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once
#include <algorithm>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <optional>
#include <variant>
#include "utils/return_code.h"
#include "plist/plist.h"
#include <vector>
#include "common/utils/return_code.h"

namespace plotfx {

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

// FIXME: rename to column?
struct DataColumn {
  std::string name;
  Series data;
};

struct DataFrame {
  std::vector<DataColumn> columns;
};

ReturnCode column_find(
    const DataFrame& frame,
    const std::string& column_name,
    const DataColumn** column);

size_t series_len(const Series& s);

std::vector<double> series_to_float(const Series& s);
Loading