Skip to content

Commit

Permalink
Merge pull request #518 from vizzuhq/iterate_on_dataframe
Browse files Browse the repository at this point in the history
Dataframe implementation fixes
  • Loading branch information
schaumb authored Apr 23, 2024
2 parents b4a8d70 + 65dd633 commit f742b18
Show file tree
Hide file tree
Showing 18 changed files with 459 additions and 468 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
- next() can be called multiple times from Plugin hooks
- Line and circle chats with only dimensions on x, and y axes the markers were off the axis labels.
- Crash on TreeMap only with negative values
- On dimension axis where no marker, print the dimension name as default title.
- On measure axis with specified channel min-max where no marker, print the labels.
- Legend markers are not flickering on same data.
- From now legend appears/disappears linear time.
- Axis labels are not animated to a different axis label.
- Dimension axis density on sorted values was wrongly calculated.

### Added

Expand Down
12 changes: 10 additions & 2 deletions src/chart/generator/axis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,18 +93,26 @@ bool DimensionAxis::operator==(const DimensionAxis &other) const
return enabled == other.enabled && values == other.values;
}

void DimensionAxis::setLabels(double step)
bool DimensionAxis::setLabels(double step)
{
bool hasLabel{};
step = std::max(step, 1.0);
double currStep = 0.0;

for (int curr{}; auto &[slice, item] : values) {
std::multimap<double, Values::pointer> reorder;
for (auto &ref : values)
reorder.emplace(ref.second.range.getMin(), &ref);

for (int curr{}; auto &[v, pp] : reorder) {
auto &[slice, item] = *pp;
item.categoryValue = Data::DataCube::getValue(slice);

if (++curr <= currStep) continue;
currStep += step;
item.label = item.categoryValue;
hasLabel = true;
}
return hasLabel;
}

DimensionAxis interpolate(const DimensionAxis &op0,
Expand Down
2 changes: 1 addition & 1 deletion src/chart/generator/axis.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ struct DimensionAxis
{
return values.cend();
}
void setLabels(double step);
bool setLabels(double step);

private:
Values values;
Expand Down
30 changes: 16 additions & 14 deletions src/chart/generator/plot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,11 +256,14 @@ bool Plot::linkMarkers(const Buckets &buckets, bool main)

void Plot::normalizeXY()
{
const auto &xrange = options->getHorizontalAxis().range;
const auto &yrange = options->getVeritalAxis().range;

if (markers.empty()) {
stats.channels[ChannelId::x].range =
Math::Range<double>(0.0, 0.0);
xrange.getRange({0.0, 0.0});
stats.channels[ChannelId::y].range =
Math::Range<double>(0.0, 0.0);
yrange.getRange({0.0, 0.0});
return;
}

Expand All @@ -274,9 +277,6 @@ void Plot::normalizeXY()
options->setAutoRange(boundRect.positive().hSize().getMin() >= 0,
boundRect.positive().vSize().getMin() >= 0);

auto xrange = options->getHorizontalAxis().range;
auto yrange = options->getVeritalAxis().range;

boundRect.setHSize(xrange.getRange(boundRect.hSize()));
boundRect.setVSize(yrange.getRange(boundRect.vSize()));

Expand Down Expand Up @@ -304,10 +304,10 @@ void Plot::calcMeasureAxis(ChannelId type)
auto &axis = measureAxises.at(type);
const auto &scale = options->getChannels().at(type);
if (!scale.isEmpty() && scale.measureId) {
commonAxises.at(type).title =
scale.title == "auto" ? scale.measureName(dataCube)
: scale.title == "null" ? std::string()
: scale.title;
commonAxises.at(type).title = scale.title.isAuto()
? scale.measureName(dataCube)
: scale.title ? *scale.title
: std::string{};

if (type == options->subAxisType()
&& options->align == Base::Align::Type::stretch) {
Expand Down Expand Up @@ -343,10 +343,6 @@ void Plot::calcDimensionAxis(ChannelId type)

if (scale.dimensionIds.empty() || !scale.isDimension()) return;

commonAxises.at(type).title =
scale.title == "auto" || scale.title == "null" ? std::string()
: scale.title;

auto dim = scale.labelLevel;

auto &&isTypeAxis = isAxis(type);
Expand Down Expand Up @@ -380,7 +376,13 @@ void Plot::calcDimensionAxis(ChannelId type)
dim == 0))
count += 1;
}
axis.setLabels(isTypeAxis ? scale.step.getValue(1.0) : 1.0);
auto hasLabel =
axis.setLabels(isTypeAxis ? scale.step.getValue(1.0) : 1.0);

commonAxises.at(type).title = scale.title.isAuto() && !hasLabel
? scale.labelDimensionName()
: scale.title ? *scale.title
: std::string{};

if (auto &&series = scale.labelSeries())
axis.category = series.value().getColIndex();
Expand Down
5 changes: 4 additions & 1 deletion src/chart/options/autoparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ template <typename Type, bool nullable = false> struct AutoParam
public:
AutoParam() : autoSet(true) {}

explicit AutoParam(const Type &value) : value(value) {}
explicit AutoParam(const Type &value)
requires(!std::is_same_v<Type, std::string>)
: value(value)
{}

explicit AutoParam(std::optional<Type> value) :
value(std::move(value))
Expand Down
8 changes: 7 additions & 1 deletion src/chart/options/channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void Channel::reset()
{
measureId = std::nullopt;
dimensionIds.clear();
title = "auto";
title = Base::AutoParam<std::string, true>{};
axisLine = Base::AutoBool();
axisLabels = Base::AutoBool();
ticks = Base::AutoBool();
Expand Down Expand Up @@ -124,6 +124,12 @@ std::string Channel::measureName(
return {};
}

std::string Channel::labelDimensionName() const
{
auto &&ser = labelSeries();
return ser ? ser->getOrigName() : "";
}

std::list<std::string_view> Channel::dimensionNames() const
{
std::list<std::string_view> res;
Expand Down
9 changes: 5 additions & 4 deletions src/chart/options/channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,19 @@ class Channel
Data::DataCubeOptions::IndexSet &series) const;
[[nodiscard]] std::string measureName(
const std::optional<Data::DataCube> &cube = {}) const;
[[nodiscard]] std::string labelDimensionName() const;
[[nodiscard]] std::list<std::string_view> dimensionNames() const;
[[nodiscard]] OptionalIndex labelSeries() const;
bool operator==(const Channel &other) const;

Type type;
double defaultValue;
bool stackable;
Type type{};
double defaultValue{};
bool stackable{};
OptionalIndex measureId{};
DimensionIndices dimensionIds{};
ChannelRange range{};
std::size_t labelLevel{};
std::string title = "auto";
Base::AutoParam<std::string, true> title{};
Base::AutoBool axisLine{};
Base::AutoBool axisLabels{};
Base::AutoBool ticks{};
Expand Down
4 changes: 2 additions & 2 deletions src/chart/rendering/drawlegend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void DrawLegend::drawDimension(const Info &info) const
if (itemRect.y().getMax() >= info.contentRect.y().getMax())
continue;

auto alpha = value.second.weight * info.weight;
auto alpha = std::min(value.second.weight, info.weight);

drawMarker(info,
value.second.categoryValue,
Expand All @@ -104,7 +104,7 @@ void DrawLegend::drawDimension(const Info &info) const
value.second.categoryValue,
value.second.categoryValue,
info.type),
{.alpha = alpha * weighted.weight});
{.alpha = std::min(alpha, weighted.weight)});
});
}
}
Expand Down
17 changes: 3 additions & 14 deletions src/dataframe/impl/dataframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,23 +710,12 @@ std::string dataframe::get_record_id_by_dims(std::size_t my_record,
dataframe::series_meta_t dataframe::get_series_meta(
const std::string &id) const
{
using enum state_type;
const auto *state = get_if<modifying>(&state_data);
if (!state || state->empty()) error();

auto it = std::find(state->begin(), state->end(), id);

if (it == state->end()) error();

auto ix = static_cast<std::size_t>(it - state->begin());

switch (auto &&ser = get_data_source().get_series(id)) {
using enum series_type;
default: return {{}, ix, ser};
case measure:
return {unsafe_get<measure>(ser).first, ix, measure};
default: return {{}, ser};
case measure: return {unsafe_get<measure>(ser).first, measure};
case dimension:
return {unsafe_get<dimension>(ser).first, ix, dimension};
return {unsafe_get<dimension>(ser).first, dimension};
}
}

Expand Down
1 change: 0 additions & 1 deletion src/dataframe/impl/dataframe.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ class dataframe
struct series_meta_t
{
std::string_view name;
std::size_t ix;
series_type type;
};

Expand Down
Loading

0 comments on commit f742b18

Please sign in to comment.