Skip to content

Commit 5b2bdb4

Browse files
committed
Create split style parameter for axises
1 parent db8c4a4 commit 5b2bdb4

File tree

15 files changed

+118
-85
lines changed

15 files changed

+118
-85
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
- Add meaning to crossing interlacing.
3232
- Do not draw dimension axis labels when the middle of the text is off the plot.
3333

34+
### Added
35+
36+
- Add split property for plot axis style structure. Only supported the percentage value.
37+
3438
## [0.15.0] - 2024-10-28
3539

3640
### Fixed

src/apps/weblib/typeschema-api/styles.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ definitions:
452452
interlacing:
453453
$ref: Interlacing
454454
nullable: true
455+
split:
456+
$ref: Length
457+
nullable: true
455458

456459
Plot:
457460
$extends: [Padding, Box]

src/base/conv/auto_json.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct JSON
7575
else if constexpr (std::is_arithmetic_v<T>) {
7676
json += toString(val);
7777
}
78-
else if constexpr (std::is_enum_v<T>
78+
else if constexpr (Refl::is_enum<T>
7979
|| std::is_same_v<T, bool>) {
8080
json += '\"';
8181
json += toString(val);

src/base/conv/parse.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ concept Parsable = !std::is_void_v<decltype(T::fromString(
1616

1717
template <class To>
1818
constexpr inline static bool IsParsable =
19-
std::is_enum_v<To> || Parsable<To>
19+
Refl::is_enum<To> || Parsable<To>
2020
|| (Type::is_optional_v<To> && IsParsable<Type::optional_t<To>>)
2121
|| std::is_constructible_v<To, std::string>
2222
|| std::is_same_v<To, bool> || std::is_floating_point_v<To>
@@ -28,7 +28,7 @@ template <typename To>
2828
requires IsParsable<To>
2929
[[nodiscard]] decltype(auto) parse(const std::string &string)
3030
{
31-
if constexpr (std::is_enum_v<To>)
31+
if constexpr (Refl::is_enum<To>)
3232
return Refl::get_enum<To>(string);
3333
else if constexpr (Parsable<To>)
3434
return To::fromString(string);

src/base/conv/tostring.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ concept ToStringMember =
1919

2020
template <class From>
2121
constexpr inline static bool IsStringifiable =
22-
ToStringMember<From> || std::is_enum_v<From>
22+
ToStringMember<From> || Refl::is_enum<From>
2323
|| (Type::is_optional_v<From>
2424
&& IsStringifiable<Type::optional_t<From>>)
2525
|| std::is_constructible_v<std::string, From>
@@ -32,7 +32,7 @@ template <typename From>
3232
requires IsStringifiable<From>
3333
[[nodiscard]] decltype(auto) toString(const From &value)
3434
{
35-
if constexpr (std::is_enum_v<From>)
35+
if constexpr (Refl::is_enum<From>)
3636
return Refl::enum_name(value);
3737
else if constexpr (Type::is_optional_v<From>) {
3838
using T = std::remove_cvref_t<decltype(toString(*value))>;

src/base/refl/auto_enum.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,9 @@ template <class E> constexpr E get_enum(const std::string_view &data)
193193
return static_cast<E>(ix + first);
194194
}
195195

196+
template <class E>
197+
concept is_enum = std::is_enum_v<E> && Detail::count<E>() > 0;
198+
196199
template <class E> consteval auto enum_values()
197200
{
198201
constexpr auto first = Detail::from_to<E>().first;
@@ -258,9 +261,8 @@ struct EnumArray : std::array<V, std::size(enum_names<E>)>
258261
bool operator==(const EnumArray &) const = default;
259262
};
260263

261-
template <class E, class... Args>
262-
requires(std::is_enum_v<E>
263-
&& sizeof...(Args) == Detail::count<E>()
264+
template <is_enum E, class... Args>
265+
requires(sizeof...(Args) == Detail::count<E>()
264266
&& Detail::from_to<E>().first == 0)
265267
struct EnumVariant : std::variant<Args...>
266268
{

src/base/type/physicalvalue.h

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
11
#ifndef TYPE_PHYSICALVALUE
22
#define TYPE_PHYSICALVALUE
33

4-
#include <cstdint>
4+
#include "base/conv/parse.h"
5+
#include "base/conv/tostring.h"
6+
#include "base/refl/auto_enum.h"
7+
#include "base/text/valueunit.h"
58

69
namespace Type
710
{
811

9-
enum class SimpleUnit : std::uint8_t { none, relative, absolute };
10-
11-
template <typename Value, typename Unit = SimpleUnit>
12-
class PhysicalValue
12+
template <typename Value, Refl::is_enum Unit> struct PhysicalValue
1313
{
14-
public:
15-
Value value;
16-
Unit unit;
17-
18-
constexpr PhysicalValue() : value{}, unit{} {}
19-
constexpr PhysicalValue(Value value, Unit unit) :
20-
value(value),
21-
unit(unit)
22-
{}
14+
Value value{};
15+
Unit unit{};
2316

2417
constexpr bool operator==(const PhysicalValue &) const = default;
18+
19+
template <std::same_as<double> = Value>
20+
static PhysicalValue fromString(const std::string &str)
21+
{
22+
Text::ValueUnit vu{str};
23+
return {vu.getValue(), Refl::get_enum<Unit>(vu.getUnit())};
24+
}
25+
26+
std::string toString() const
27+
{
28+
return Conv::toString(value)
29+
+ std::string{Conv::toString(unit)};
30+
}
2531
};
2632

2733
}

src/chart/generator/plotbuilder.cpp

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -504,44 +504,44 @@ void PlotBuilder::addAlignment(const Buckets &subBuckets) const
504504
void PlotBuilder::addSeparation(const Buckets &subBuckets,
505505
const std::size_t &mainBucketSize) const
506506
{
507-
if (plot->getOptions()->isSplit()) {
508-
auto align = plot->getOptions()->align;
509-
510-
std::vector ranges{mainBucketSize,
511-
Math::Range<>::Raw({}, {})};
512-
std::vector<bool> anyEnabled(mainBucketSize);
513-
514-
auto &&subAxis = plot->getOptions()->subAxisType();
515-
for (auto &&bucket : subBuckets)
516-
for (std::size_t i{}, prIx{};
517-
auto &&[marker, idx] : bucket) {
518-
(i += idx.itemId - std::exchange(prIx, idx.itemId)) %=
519-
ranges.size();
520-
if (marker.enabled) {
521-
ranges[i].include(
522-
marker.getSizeBy(subAxis).size());
523-
anyEnabled[i] = true;
524-
}
525-
}
507+
if (!plot->getOptions()->isSplit()) return;
526508

527-
auto max = Math::Range<>::Raw({}, {});
528-
for (auto i = 0U; i < ranges.size(); ++i)
529-
if (anyEnabled[i]) max = max + ranges[i];
530-
531-
for (auto i = 1U; i < ranges.size(); ++i)
532-
ranges[i] = ranges[i] + ranges[i - 1].getMax()
533-
+ (anyEnabled[i - 1] ? max.getMax() / 15 : 0);
534-
535-
for (auto &&bucket : subBuckets)
536-
for (std::size_t i{}, prIx{};
537-
auto &&[marker, idx] : bucket) {
538-
(i += idx.itemId - std::exchange(prIx, idx.itemId)) %=
539-
ranges.size();
540-
marker.setSizeBy(subAxis,
541-
Base::Align{align, ranges[i]}.getAligned(
542-
marker.getSizeBy(subAxis)));
543-
}
544-
}
509+
auto align = plot->getOptions()->align;
510+
511+
std::vector ranges{mainBucketSize, Math::Range<>::Raw({}, {})};
512+
std::vector<bool> anyEnabled(mainBucketSize);
513+
514+
auto &&subAxis = plot->getOptions()->subAxisType();
515+
for (auto &&bucket : subBuckets)
516+
for (std::size_t i{}, prIx{}; auto &&[marker, idx] : bucket) {
517+
if (!marker.enabled) continue;
518+
(i += idx.itemId - std::exchange(prIx, idx.itemId)) %=
519+
ranges.size();
520+
ranges[i].include(marker.getSizeBy(subAxis).size());
521+
anyEnabled[i] = true;
522+
}
523+
524+
auto max = Math::Range<>::Raw({}, {});
525+
for (auto i = 0U; i < ranges.size(); ++i)
526+
if (anyEnabled[i]) max = max + ranges[i];
527+
528+
auto &axis = plot->getStyle().plot.getAxis(
529+
plot->getOptions()->subAxisType());
530+
auto splitSpace = axis.split->get(max.getMax(),
531+
plot->getStyle().calculatedSize());
532+
533+
for (auto i = 1U; i < ranges.size(); ++i)
534+
ranges[i] = ranges[i] + ranges[i - 1].getMax()
535+
+ (anyEnabled[i - 1] ? splitSpace : 0);
536+
537+
for (auto &&bucket : subBuckets)
538+
for (std::size_t i{}, prIx{}; auto &&[marker, idx] : bucket) {
539+
(i += idx.itemId - std::exchange(prIx, idx.itemId)) %=
540+
ranges.size();
541+
marker.setSizeBy(subAxis,
542+
Base::Align{align, ranges[i]}.getAligned(
543+
marker.getSizeBy(subAxis)));
544+
}
545545
}
546546

547547
void PlotBuilder::normalizeSizes()

src/chart/main/style.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ Chart Chart::def()
279279
},
280280
.interlacing = {
281281
.color = Gfx::Color::Gray(0.97)
282-
}
282+
},
283+
.split = Gfx::Length::Relative(1 / 15.)
283284
},
284285
.yAxis = {
285286
.color = Gfx::Color::Gray(0.8),
@@ -370,7 +371,8 @@ Chart Chart::def()
370371
},
371372
.interlacing = {
372373
.color = Gfx::Color::Gray(0.97)
373-
}
374+
},
375+
.split = Gfx::Length::Relative(1 / 15.)
374376
},
375377
.areaColor = Gfx::Color::Transparent(),
376378
.overflow = ::Anim::Interpolated<Overflow>(Overflow::hidden)

src/chart/main/style.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ struct Axis
245245
Tick ticks;
246246
Guide guides;
247247
Interlacing interlacing;
248+
Param<Gfx::Length> split;
248249
};
249250

250251
struct MarkerLabelParams

0 commit comments

Comments
 (0)