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

update the 'chart/bars' element

parent bd7748a5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ include_directories(${CAIRO_INCLUDE_DIRS} ${FREETYPE_INCLUDE_DIRS} ${HARFBUZZ_IN

# Build: fviz Library
# -----------------------------------------------------------------------------
file(GLOB source_files "core/**/*.cc" "core/*.cc" "elements/*.cc"  "elements/layout/*.cc" "elements/chart/axis.cc" "elements/chart/layout.cc" "elements/chart/points.cc" "elements/chart/lines.cc" "elements/chart/areas.cc" "elements/chart/labels.cc")
file(GLOB source_files "core/**/*.cc" "core/*.cc" "elements/*.cc"  "elements/layout/*.cc" "elements/chart/axis.cc" "elements/chart/layout.cc" "elements/chart/points.cc" "elements/chart/lines.cc" "elements/chart/areas.cc" "elements/chart/labels.cc" "elements/chart/bars.cc")
list(REMOVE_ITEM source_files "core/cli.cc")
add_library(fviz STATIC ${source_files})
set_target_properties(fviz PROPERTIES PUBLIC_HEADER "source/fviz.h;source/fviz_sdl.h")
+3 −1
Original line number Diff line number Diff line
@@ -21,9 +21,10 @@
#include "utils/fileutil.h"
#include "core/environment.h"
#include "elements/text.h"
#include "elements/chart/axis.h"
#include "elements/chart/layout.h"
#include "elements/chart/areas.h"
#include "elements/chart/axis.h"
#include "elements/chart/bars.h"
#include "elements/chart/labels.h"
#include "elements/chart/lines.h"
#include "elements/chart/points.h"
@@ -52,6 +53,7 @@ fviz_t* fviz_init() {
  element_bind(elems, "chart/axis-left", bind(elements::chart::axis::build, _1, _2, _3));
  element_bind(elems, "chart/layout", bind(elements::chart::layout::build, _1, _2, _3));
  element_bind(elems, "chart/areas", bind(elements::chart::areas::build, _1, _2, _3));
  element_bind(elems, "chart/bars", bind(elements::chart::bars::build, _1, _2, _3));
  element_bind(elems, "chart/labels", bind(elements::chart::labels::build, _1, _2, _3));
  element_bind(elems, "chart/lines", bind(elements::chart::lines::build, _1, _2, _3));
  element_bind(elems, "chart/points", bind(elements::chart::points::build, _1, _2, _3));
+80 −63
Original line number Diff line number Diff line
@@ -12,22 +12,41 @@
 * limitations under the License.
 */
#include "bars.h"

#include "environment.h"
#include "layout.h"
#include "graphics/path.h"
#include "graphics/brush.h"
#include "graphics/text.h"
#include "graphics/layout.h"
#include "scale.h"
#include "sexpr_conv.h"
#include "sexpr_util.h"

#include <numeric>
#include <fviz.h>
#include <graphics/path.h>
#include <graphics/brush.h>
#include <graphics/text.h>
#include <graphics/layout.h>
#include <source/utils/algo.h>
#include "source/config_helpers.h"
#include "core/environment.h"
#include "core/layout.h"

using namespace std::placeholders;

namespace fviz {
namespace plot {
namespace bars {
namespace fviz::elements::chart::bars {

struct PlotBarsConfig {
  PlotBarsConfig();
  Direction direction;
  std::vector<Measure> x;
  std::vector<Measure> xoffset;
  std::vector<Measure> y;
  std::vector<Measure> yoffset;
  ScaleConfig scale_x;
  ScaleConfig scale_y;
  std::vector<Color> colors;
  std::vector<Measure> sizes;
  std::vector<Measure> offsets;
  std::vector<std::string> labels;
  FontInfo label_font;
  Measure label_padding;
  Measure label_font_size;
  Color label_color;
};

static const double kDefaultBarSizePT = 10;
static const double kDefaultLabelPaddingHorizEM = 0.6;
@@ -46,7 +65,7 @@ ReturnCode draw_horizontal(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_x), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_x), _1),
        bind(&convert_unit_relative, clip.w, _1)
      },
      &*config.x.begin(),
@@ -55,7 +74,7 @@ ReturnCode draw_horizontal(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_x), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_x), _1),
        bind(&convert_unit_relative, clip.w, _1)
      },
      &*config.xoffset.begin(),
@@ -64,7 +83,7 @@ ReturnCode draw_horizontal(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_y), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_y), _1),
        bind(&convert_unit_relative, clip.h, _1)
      },
      &*config.y.begin(),
@@ -73,7 +92,7 @@ ReturnCode draw_horizontal(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_y), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_y), _1),
        bind(&convert_unit_relative, clip.h, _1)
      },
      &*config.yoffset.begin(),
@@ -94,7 +113,7 @@ ReturnCode draw_horizontal(
      &*config.offsets.end());

  /* draw bars */
  auto x0 = std::clamp(clip.h * domain_translate(config.scale_x, 0), 0.0, 1.0);
  auto x0 = std::clamp(clip.h * scale_translate(config.scale_x, 0), 0.0, 1.0);
  for (size_t i = 0; i < config.x.size(); ++i) {
    auto sy = clip.y + clip.h - config.y[i];
    auto sx1 = clip.x + (config.xoffset.empty() ? x0 : config.xoffset[i]);
@@ -167,7 +186,7 @@ ReturnCode draw_vertical(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_x), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_x), _1),
        bind(&convert_unit_relative, clip.w, _1)
      },
      &*config.x.begin(),
@@ -176,7 +195,7 @@ ReturnCode draw_vertical(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_x), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_x), _1),
        bind(&convert_unit_relative, clip.w, _1)
      },
      &*config.xoffset.begin(),
@@ -185,7 +204,7 @@ ReturnCode draw_vertical(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_y), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_y), _1),
        bind(&convert_unit_relative, clip.h, _1)
      },
      &*config.y.begin(),
@@ -194,7 +213,7 @@ ReturnCode draw_vertical(
  convert_units(
      {
        bind(&convert_unit_typographic, layer->dpi, layer->font_size.value, _1),
        bind(&convert_unit_user, domain_translate_fn(config.scale_y), _1),
        bind(&convert_unit_user, scale_translate_fn(config.scale_y), _1),
        bind(&convert_unit_relative, clip.h, _1)
      },
      &*config.yoffset.begin(),
@@ -215,7 +234,7 @@ ReturnCode draw_vertical(
      &*config.offsets.end());

  /* draw bars */
  auto y0 = clip.h * std::clamp(domain_translate(config.scale_y, 0), 0.0, 1.0);
  auto y0 = clip.h * std::clamp(scale_translate(config.scale_y, 0), 0.0, 1.0);
  for (size_t i = 0; i < config.x.size(); ++i) {
    auto sx = clip.x + config.x[i];
    auto sy1 = clip.y + clip.h - (config.yoffset.empty() ? y0 : config.yoffset[i]);
@@ -278,54 +297,52 @@ ReturnCode draw_vertical(
}

ReturnCode draw(
    const PlotBarsConfig& config,
    std::shared_ptr<PlotBarsConfig> config,
    const LayoutInfo& layout,
    Layer* layer) {
  switch (config.direction) {
  switch (config->direction) {
    case Direction::HORIZONTAL:
      return draw_horizontal(config, layout, layer);
      return draw_horizontal(*config, layout, layer);
    case Direction::VERTICAL:
      return draw_vertical(config, layout, layer);
      return draw_vertical(*config, layout, layer);
    default:
      return ERROR;
  }
}

ReturnCode configure(
    const plist::PropertyList& plist,
ReturnCode build(
    const Environment& env,
    PlotBarsConfig* config) {
    const Expr* expr,
    ElementRef* elem) {
  /* set defaults from environment */
  config->scale_x = env.scale_x;
  config->scale_y = env.scale_y;
  auto config = std::make_shared<PlotBarsConfig>();
  config->label_font = env.font;
  config->label_font_size = env.font_size;

  ParserDefinitions pdefs = {
    {"xs", bind(&configure_measures, _1, &config->x)},
    {"ys", bind(&configure_measures, _1, &config->y)},
    {"x-offsets", bind(&configure_measures, _1, &config->xoffset)},
    {"y-offsets", bind(&configure_measures, _1, &config->yoffset)},
    {"scale-x", bind(&domain_configure, _1, &config->scale_x)},
    {"scale-x-min", bind(&configure_float_opt, _1, &config->scale_x.min)},
    {"scale-x-max", bind(&configure_float_opt, _1, &config->scale_x.max)},
    {"scale-x-padding", bind(&configure_float, _1, &config->scale_x.padding)},
    {"scale-y", bind(&domain_configure, _1, &config->scale_y)},
    {"scale-y-min", bind(&configure_float_opt, _1, &config->scale_y.min)},
    {"scale-y-max", bind(&configure_float_opt, _1, &config->scale_y.max)},
    {"scale-y-padding", bind(&configure_float, _1, &config->scale_y.padding)},
    {"size", bind(&configure_measures, _1, &config->sizes)},
    {"sizes", bind(&configure_measures, _1, &config->sizes)},
    {"offset", bind(&configure_measures, _1, &config->offsets)},
    {"offsets", bind(&configure_measures, _1, &config->offsets)},
    {"direction", bind(&configure_direction, _1, &config->direction)},
    {"color", configure_vec<Color>(bind(&configure_color, _1, _2), &config->colors)},
    {"colors", configure_vec<Color>(bind(&configure_color, _1, _2), &config->colors)},
    {"labels", bind(&configure_strings, _1, &config->labels)},
  };

  if (auto rc = parseAll(plist, pdefs); !rc) {
    return rc;
  /* parse properties */
  auto config_rc = expr_walk_map(expr_next(expr), {
    {"xdata", bind(&expr_to_measures, _1, &config->x)},
    {"ydata", bind(&expr_to_measures, _1, &config->y)},
    {"xoffsetdata", bind(&expr_to_measures, _1, &config->xoffset)},
    {"yoffsetdata", bind(&expr_to_measures, _1, &config->yoffset)},
    {"xmin", bind(&expr_to_float64_opt, _1, &config->scale_x.min)},
    {"xmax", bind(&expr_to_float64_opt, _1, &config->scale_x.max)},
    {"xscale", bind(&scale_configure_kind, _1, &config->scale_x)},
    {"xscale-padding", bind(&expr_to_float64, _1, &config->scale_x.padding)},
    {"ymin", bind(&expr_to_float64_opt, _1, &config->scale_y.min)},
    {"ymax", bind(&expr_to_float64_opt, _1, &config->scale_y.max)},
    {"yscale", bind(&scale_configure_kind, _1, &config->scale_y)},
    {"yscale-padding", bind(&expr_to_float64, _1, &config->scale_y.padding)},
    {"size", bind(&expr_to_measures, _1, &config->sizes)},
    {"sizes", bind(&expr_to_measures, _1, &config->sizes)},
    //{"direction", bind(&expr_to_direction, _1, &config->direction)},
    {"color", expr_tov_fn<Color>(bind(&expr_to_color, _1, _2), &config->colors)},
    {"colors", expr_tov_fn<Color>(bind(&expr_to_color, _1, _2), &config->colors)},
    {"labels", bind(&expr_to_strings, _1, &config->labels)},
  });

  if (!config_rc) {
    return config_rc;
  }

  /* check configuraton */
@@ -352,32 +369,32 @@ ReturnCode configure(
  /* scale autoconfig */
  for (const auto& v : config->x) {
    if (v.unit == Unit::USER) {
      domain_fit(v.value, &config->scale_x);
      scale_fit(v.value, &config->scale_x);
    }
  }

  for (const auto& v : config->xoffset) {
    if (v.unit == Unit::USER) {
      domain_fit(v.value, &config->scale_x);
      scale_fit(v.value, &config->scale_x);
    }
  }

  for (const auto& v : config->y) {
    if (v.unit == Unit::USER) {
      domain_fit(v.value, &config->scale_y);
      scale_fit(v.value, &config->scale_y);
    }
  }

  for (const auto& v : config->yoffset) {
    if (v.unit == Unit::USER) {
      domain_fit(v.value, &config->scale_y);
      scale_fit(v.value, &config->scale_y);
    }
  }

  *elem = std::make_shared<Element>();
  (*elem)->draw = bind(&draw, config, _1, _2);
  return OK;
}

} // namespace bars
} // namespace plot
} // namespace fviz
} // namespace fviz::elements::chart::bars
+6 −40
Original line number Diff line number Diff line
@@ -12,48 +12,14 @@
 * limitations under the License.
 */
#pragma once
#include <stdlib.h>
#include <sexpr.h>
#include <graphics/layer.h>
#include <source/core/scale.h>
#include <source/element.h>
#include <source/config_helpers.h>
#include "element.h"

namespace fviz {
namespace plot {
namespace bars {
namespace fviz::elements::chart::bars {

struct PlotBarsConfig {
  PlotBarsConfig();
  Direction direction;
  std::vector<Measure> x;
  std::vector<Measure> xoffset;
  std::vector<Measure> y;
  std::vector<Measure> yoffset;
  DomainConfig scale_x;
  DomainConfig scale_y;
  std::vector<Color> colors;
  std::vector<Measure> sizes;
  std::vector<Measure> offsets;
  std::vector<std::string> labels;
  FontInfo label_font;
  Measure label_padding;
  Measure label_font_size;
  Color label_color;
  LayoutSettings layout;
};

ReturnCode draw(
    const PlotBarsConfig& config,
    const LayoutInfo& layout,
    Layer* layer);

ReturnCode configure(
    const plist::PropertyList& plist,
ReturnCode build(
    const Environment& env,
    PlotBarsConfig* config);
    const Expr* expr,
    ElementRef* elem);

} // namespace bars
} // namespace plot
} // namespace fviz
} // namespace fviz::elements::chart::bars
+4 −0
Original line number Diff line number Diff line
(chart/bars
    xdata (100px 300px 500px 700px 900px)
    ydata (200px 300px 200px 300px 100px)
    colors (#06c))
Loading