Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/main' into axis_ref…
Browse files Browse the repository at this point in the history
…actor_v12
  • Loading branch information
schaumb committed Nov 27, 2024
2 parents c4173b0 + 717d4ef commit d3ce44d
Show file tree
Hide file tree
Showing 42 changed files with 580 additions and 260 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@
- Enable dimension axis ticks and interlacing.
- Enable measure axis guides.
- Fix dimension axis guides on sorted chart.
- Fix NaN handling on axes and size measures other aggregators than sum.
- Add meaning to crossing interlacing.
- Do not draw dimension axis labels when the middle of the text is off the plot.

### Added

- Add spacing property for plot axis style structure.

### Changed

Expand Down
4 changes: 4 additions & 0 deletions src/apps/weblib/typeschema-api/styles.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ definitions:
interlacing:
$ref: Interlacing
nullable: true
spacing:
type: string
mask: /:number:%/
nullable: true

Plot:
$extends: [Padding, Box]
Expand Down
2 changes: 1 addition & 1 deletion src/base/conv/auto_json.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ struct JSON
else if constexpr (std::is_arithmetic_v<T>) {
json += toString(val);
}
else if constexpr (std::is_enum_v<T>
else if constexpr (Refl::is_enum<T>
|| std::is_same_v<T, bool>) {
json += '\"';
json += toString(val);
Expand Down
4 changes: 2 additions & 2 deletions src/base/conv/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ concept Parsable = !std::is_void_v<decltype(T::fromString(

template <class To>
constexpr inline static bool IsParsable =
std::is_enum_v<To> || Parsable<To>
Refl::is_enum<To> || Parsable<To>
|| (Type::is_optional_v<To> && IsParsable<Type::optional_t<To>>)
|| std::is_constructible_v<To, std::string>
|| std::is_same_v<To, bool> || std::is_floating_point_v<To>
Expand All @@ -28,7 +28,7 @@ template <typename To>
requires IsParsable<To>
[[nodiscard]] decltype(auto) parse(const std::string &string)
{
if constexpr (std::is_enum_v<To>)
if constexpr (Refl::is_enum<To>)
return Refl::get_enum<To>(string);
else if constexpr (Parsable<To>)
return To::fromString(string);
Expand Down
4 changes: 2 additions & 2 deletions src/base/conv/tostring.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ concept ToStringMember =

template <class From>
constexpr inline static bool IsStringifiable =
ToStringMember<From> || std::is_enum_v<From>
ToStringMember<From> || Refl::is_enum<From>
|| (Type::is_optional_v<From>
&& IsStringifiable<Type::optional_t<From>>)
|| std::is_constructible_v<std::string, From>
Expand All @@ -32,7 +32,7 @@ template <typename From>
requires IsStringifiable<From>
[[nodiscard]] decltype(auto) toString(const From &value)
{
if constexpr (std::is_enum_v<From>)
if constexpr (Refl::is_enum<From>)
return Refl::enum_name(value);
else if constexpr (Type::is_optional_v<From>) {
using T = std::remove_cvref_t<decltype(toString(*value))>;
Expand Down
9 changes: 6 additions & 3 deletions src/base/refl/auto_enum.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,12 +193,16 @@ template <class E> constexpr E get_enum(const std::string_view &data)
return static_cast<E>(ix + first);
}

template <class E>
concept is_enum = std::is_enum_v<E> && Detail::count<E>() > 0;

template <class E> consteval auto enum_values()
{
constexpr auto first = Detail::from_to<E>().first;
constexpr auto n = std::size(enum_names<E>);
std::array<E, n> res{};
for (std::size_t i = 0; i < n; ++i)
// NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
res[i] = static_cast<E>(i + first);
return res;
}
Expand Down Expand Up @@ -258,9 +262,8 @@ struct EnumArray : std::array<V, std::size(enum_names<E>)>
bool operator==(const EnumArray &) const = default;
};

template <class E, class... Args>
requires(std::is_enum_v<E>
&& sizeof...(Args) == Detail::count<E>()
template <is_enum E, class... Args>
requires(sizeof...(Args) == Detail::count<E>()
&& Detail::from_to<E>().first == 0)
struct EnumVariant : std::variant<Args...>
{
Expand Down
35 changes: 21 additions & 14 deletions src/base/type/physicalvalue.h
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
#ifndef TYPE_PHYSICALVALUE
#define TYPE_PHYSICALVALUE

#include <cstdint>
#include "base/conv/parse.h"
#include "base/conv/tostring.h"
#include "base/refl/auto_enum.h"
#include "base/text/valueunit.h"

namespace Type
{

enum class SimpleUnit : std::uint8_t { none, relative, absolute };

template <typename Value, typename Unit = SimpleUnit>
class PhysicalValue
template <typename Value, Refl::is_enum Unit> struct PhysicalValue
{
public:
Value value;
Unit unit;

constexpr PhysicalValue() : value{}, unit{} {}
constexpr PhysicalValue(Value value, Unit unit) :
value(value),
unit(unit)
{}
Value value{};
Unit unit{};

constexpr bool operator==(const PhysicalValue &) const = default;

template <std::same_as<double> = Value>
[[nodiscard]] static PhysicalValue fromString(
const std::string &str)
{
const Text::ValueUnit vu{str};
return {vu.getValue(), Refl::get_enum<Unit>(vu.getUnit())};
}

[[nodiscard]] std::string toString() const
{
return Conv::toString(value)
+ std::string{Conv::toString(unit)};
}
};

}
Expand Down
2 changes: 1 addition & 1 deletion src/base/type/uniquelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ template <class T> class UniqueList
struct CommonIterateVal
{
const T &value;
const std::size_t *othIx;
const std::size_t *otherIx;
};

struct common_iterator
Expand Down
5 changes: 3 additions & 2 deletions src/chart/generator/axis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include <iterator>
#include <limits>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <tuple>
Expand Down Expand Up @@ -287,7 +286,9 @@ bool DimensionAxis::setLabels(double step)
auto currStep = 0.0;

for (auto curr = int{}; auto &&item : sortedItems()) {
if (++curr <= currStep) continue;
if (auto mid = item.get().range.middle();
std::signbit(mid) || mid > 1.0 || ++curr <= currStep)
continue;
currStep += step;
item.get().label = true;
hasLabel = true;
Expand Down
7 changes: 4 additions & 3 deletions src/chart/generator/axis.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ struct ChannelStats
template <ChannelIdLike T>
[[nodiscard]] const TrackType &at(const T &id) const
{
return tracked[-id];
return tracked[+id];
}

void track(ChannelId at, const Data::MarkerId &id)
Expand All @@ -40,13 +40,14 @@ struct ChannelStats

void track(ChannelId at, const double &value)
{
std::get<0>(tracked[at]).include(value);
if (std::isfinite(value))
std::get<0>(tracked[at]).include(value);
}

template <ChannelIdLike Id>
void setIfRange(Id at, const Math::Range<> &range)
{
if (auto *r = std::get_if<0>(&tracked[-at])) *r = range;
if (auto *r = std::get_if<0>(&tracked[+at])) *r = range;
}
};

Expand Down
5 changes: 3 additions & 2 deletions src/chart/generator/buckets.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ struct Buckets
});
}

[[nodiscard]] bool operator!=(const const_iterator &oth) const
[[nodiscard]] bool operator!=(
const const_iterator &other) const
{
return data.data() != oth.data.data();
return data.data() != other.data.data();
}

const_iterator &operator++();
Expand Down
16 changes: 10 additions & 6 deletions src/chart/generator/marker.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "marker.h"

#include <cmath>
#include <cstdint>
#include <optional>
#include <utility>
Expand Down Expand Up @@ -31,10 +32,10 @@ Marker::Marker(const Options &options,
bool needMarkerInfo) :
cellInfo(data.cellInfo(index, needMarkerInfo)),
mainId(data.getId(mainAxisList,
options.dimLabelIndex(-options.mainAxisType()),
options.dimLabelIndex(+options.mainAxisType()),
index)),
subId(data.getId(subAxisList,
options.dimLabelIndex(-options.subAxisType()),
options.dimLabelIndex(+options.subAxisType()),
index)),
sizeId(data.getId(
options.getChannels().at(ChannelId::size).dimensions(),
Expand Down Expand Up @@ -76,7 +77,7 @@ Marker::Marker(const Options &options,
if (subAxisList != options.subAxis().dimensions())
subId.label =
data.getId(options.subAxis().dimensions(),
options.dimLabelIndex(-options.subAxisType()),
options.dimLabelIndex(+options.subAxisType()),
index)
.label;

Expand Down Expand Up @@ -140,6 +141,9 @@ Marker::Marker(const Options &options,
data.joinDimensionValues(labelChannel.dimensions(),
index)};
}

if (!std::isfinite(position.x) || !std::isfinite(position.y))
enabled = false;
}

bool Marker::connectMarkers(bool first,
Expand Down Expand Up @@ -220,14 +224,14 @@ void Marker::fromRectangle(const Geom::Rect &rect)

Math::Range<> Marker::getSizeBy(AxisId axisId) const
{
return isHorizontal(+axisId) ? toRectangle().hSize()
: toRectangle().vSize();
return isHorizontal(orientation(axisId)) ? toRectangle().hSize()
: toRectangle().vSize();
}

void Marker::setSizeBy(AxisId axisId, const Math::Range<> range)
{
auto rect = toRectangle();
if (isHorizontal(+axisId))
if (isHorizontal(orientation(axisId)))
rect.setHSize(range);
else
rect.setVSize(range);
Expand Down
Loading

0 comments on commit d3ce44d

Please sign in to comment.