diff --git a/.github/workflows/docker-vizzu-dev-desktop.yml b/.github/workflows/docker-vizzu-dev-desktop.yml index 754b36495..9ce4b1fb0 100644 --- a/.github/workflows/docker-vizzu-dev-desktop.yml +++ b/.github/workflows/docker-vizzu-dev-desktop.yml @@ -24,6 +24,6 @@ jobs: - name: Build and Publish run: | IMAGE="vizzu-dev-desktop" - IMAGE_NAME="vizzu/$IMAGE:0.12" + IMAGE_NAME="vizzu/$IMAGE:0.14" docker build -t $IMAGE_NAME -f tools/ci/docker/$IMAGE . docker push $IMAGE_NAME diff --git a/.github/workflows/docker-vizzu-dev-wasm.yml b/.github/workflows/docker-vizzu-dev-wasm.yml index 5b5308e8f..4c2941f98 100644 --- a/.github/workflows/docker-vizzu-dev-wasm.yml +++ b/.github/workflows/docker-vizzu-dev-wasm.yml @@ -24,6 +24,6 @@ jobs: - name: Build and Publish run: | IMAGE="vizzu-dev-wasm" - IMAGE_NAME="vizzu/$IMAGE:0.12" + IMAGE_NAME="vizzu/$IMAGE:0.14" docker build -t $IMAGE_NAME -f tools/ci/docker/$IMAGE . docker push $IMAGE_NAME diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f64a0bf3..0705c2197 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,28 @@ ## [Unreleased] +## [0.14.0] - 2024-10-03 + +### Fixed + +- Fix again measure axis labels when the axis range and step set too. +- Fix drilldown regroup strategy on fake-split charts. +- From now vertical line connections are curved lines. +- Remove duplicated circles on line-circle transition. +- Fix area-circle polar connection transition. +- Fix line-rectangle polar connection linearity. +- Fix all polar connection interpolation (except fading). +- Remove unwanted line connections from line-circle + orientation changed anim. +- Move axis to the center on align: center charts. + +### Changed + +- Removed the 'align: max' property from the API. That function can be achieved + by setting the axis range to: {min: '100%', max: '0%'}. + + +## [0.13.0] - 2024-09-13 + ### Fixed - Legend title bottomPadding extended. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6ee27633a..1275cb24f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,7 @@ docker run -i -t -v .:/workspace vizzu/vizzu-dev-desktop bash or you can use a specific version of the prebuilt image: ```sh -docker run -i -t -v .:/workspace vizzu/vizzu-dev-desktop:0.12 bash +docker run -i -t -v .:/workspace vizzu/vizzu-dev-desktop:0.14 bash ``` Run the following commands to build and run the `WASM` version's development @@ -84,7 +84,7 @@ docker run -i -t -v .:/workspace vizzu/vizzu-dev-wasm bash or you can use a specific version of the prebuilt image: ```sh -docker run -i -t -v .:/workspace vizzu/vizzu-dev-wasm:0.12 bash +docker run -i -t -v .:/workspace vizzu/vizzu-dev-wasm:0.14 bash ``` ### Building the project diff --git a/docs/tutorial/chart_layout.md b/docs/tutorial/chart_layout.md index 5aa4a3458..529f5ad04 100644 --- a/docs/tutorial/chart_layout.md +++ b/docs/tutorial/chart_layout.md @@ -23,9 +23,7 @@ are aligned. ```javascript chart.animate({ style: { - title: { - backgroundColor: '#A0A0A0' - }, + backgroundColor: '#A0A0A0', plot: { backgroundColor: '#D2D2D2' }, diff --git a/docs/tutorial/shorthands_store.js b/docs/tutorial/shorthands_store.js index 3840a3fc2..d8e7514d5 100644 --- a/docs/tutorial/shorthands_store.js +++ b/docs/tutorial/shorthands_store.js @@ -140,7 +140,7 @@ Promise.all([dataLoaded, mdChartLoaded]).then((results) => { return chart.animate({ style: { 'plot.xAxis.label.fontSize': '150%', - 'title.backgroundColor': '#A0A0A0' + 'plot.backgroundColor': '#A0A0A0' } }) } diff --git a/docs/tutorial/shorthands_store.md b/docs/tutorial/shorthands_store.md index 4981e6bbd..300345b04 100644 --- a/docs/tutorial/shorthands_store.md +++ b/docs/tutorial/shorthands_store.md @@ -122,7 +122,7 @@ chart.animate({ style: { // plot: { xAxis: { label: { fontSize: '150%' } } } 'plot.xAxis.label.fontSize': '150%', - 'title.backgroundColor': '#A0A0A0' + 'plot.backgroundColor': '#A0A0A0' } }) ``` diff --git a/src/apps/weblib/typeschema-api/config.yaml b/src/apps/weblib/typeschema-api/config.yaml index 6e6e65022..6c48f2839 100644 --- a/src/apps/weblib/typeschema-api/config.yaml +++ b/src/apps/weblib/typeschema-api/config.yaml @@ -223,7 +223,7 @@ definitions: on where the measure is. In case both axes have measures on them, this is determined by the `orientation` of the chart. type: string - enum: [none, min, center, max, stretch] + enum: [none, min, center, stretch] split: description: | If set to true, markers will be split by the dimension(s) along the axis. diff --git a/src/base/anim/interpolated.h b/src/base/anim/interpolated.h index 339fa78cb..185bf3680 100644 --- a/src/base/anim/interpolated.h +++ b/src/base/anim/interpolated.h @@ -132,6 +132,14 @@ template class Interpolated return values[has_second && static_cast(index)]; } + [[nodiscard]] std::optional get_index( + const Type &type) const + { + if (values[0].value == type) return first; + if (has_second && values[1].value == type) return second; + return {}; + } + template // NOLINTNEXTLINE(cppcoreguidelines-missing-std-forward) [[nodiscard]] auto get(T &&) const = delete; diff --git a/src/base/refl/auto_enum.h b/src/base/refl/auto_enum.h index b4d09eee4..671529878 100644 --- a/src/base/refl/auto_enum.h +++ b/src/base/refl/auto_enum.h @@ -34,8 +34,29 @@ namespace Detail { template using real_t = std::underlying_type_t; -template From, real_t To> - requires(!std::same_as>) +template +concept UniqueNames = requires { + static_cast(unique_enum_names(E{})); +}; + +template +concept UniqueRange = requires { + static_cast, real_t>>(unique_from_to(E{})); +}; + +template + requires(UniqueRange) +consteval std::pair, real_t> from_to() +{ + constexpr auto res = unique_from_to(E{}); + static_assert(res.first <= res.second, "Invalid range"); + return res; +} + +template From = real_t{}, + real_t To = real_t{}> + requires(!UniqueRange && !std::same_as>) consteval std::pair, real_t> from_to() { if constexpr (std::is_signed_v> @@ -44,39 +65,40 @@ consteval std::pair, real_t> from_to() return from_to(); else if constexpr (!Name::name(To)>().empty()) return from_to(); - else - return {From, To}; + else { + static_assert(From != To, "Not found any enum string"); + return {From, To - 1}; + } } template - requires(std::same_as>) + requires(!UniqueRange && std::same_as>) consteval std::pair, real_t> from_to() { - return {false, false}; + constexpr auto has_false = + !Name::name(false)>().empty(); + constexpr auto has_true = + !Name::name(true)>().empty(); + static_assert(has_false || has_true, "Not found any enum string"); + return {!has_false, has_true}; } template requires(!std::same_as>) consteval real_t count() { - auto [from, to] = from_to(); - return static_cast>(to - from); + auto [from, to] = from_to(); + return static_cast>(to - from + 1); } template requires(std::same_as>) consteval int count() { - return Name::name(false)>().empty() - ? 0 - : 1 + !Name::name(true)>().empty(); + auto [from, to] = from_to(); + return to - from + 1; } -template -concept UniqueNames = requires { - static_cast(unique_enum_names(E{})); -}; - template , F... Ix> consteval auto whole_array(std::integer_sequence = {}) { @@ -87,7 +109,7 @@ consteval auto whole_array(std::integer_sequence = {}) return res; } else { - constexpr auto first = Detail::from_to().first; + constexpr auto first = Detail::from_to().first; std::array(Ix + first)>().size() + ... + (sizeof...(Ix) - 1))> @@ -109,7 +131,7 @@ constexpr std::array enum_name_holder = Detail::whole_array( Detail::count()>{}); template -constexpr std::array enum_name_holder = +constinit const std::array enum_name_holder = Detail::whole_array( std::make_integer_sequence()>{}); @@ -143,7 +165,7 @@ template constexpr std::array enum_names = get_names(); template Type enum_name(E name) { - constexpr auto first = Detail::from_to().first; + constexpr auto first = Detail::from_to().first; constexpr auto n = std::size(enum_names); if (static_cast( static_cast>(name) - first) @@ -159,7 +181,7 @@ Type enum_name(E name) template constexpr E get_enum(const std::string_view &data) { - constexpr auto first = Detail::from_to().first; + constexpr auto first = Detail::from_to().first; Detail::real_t ix{}; for (auto v : enum_names) { if (v == data) break; @@ -204,7 +226,7 @@ struct EnumArray : std::array)> template requires(std::is_enum_v && sizeof...(Args) == Detail::count() - && Detail::from_to().first == 0) + && Detail::from_to().first == 0) struct EnumVariant : std::variant { using base_variant = std::variant; diff --git a/src/chart/animator/planner.cpp b/src/chart/animator/planner.cpp index d3cdf4ea5..9aa646b88 100644 --- a/src/chart/animator/planner.cpp +++ b/src/chart/animator/planner.cpp @@ -383,7 +383,7 @@ bool Planner::needColor() const } size_t Planner::dimensionCount(const Gen::Plot *plot, - Gen::ChannelId type) + Gen::AxisId type) { return plot->getOptions() ->getChannels() @@ -401,15 +401,15 @@ bool Planner::verticalBeforeHorizontal() const || !srcOpt->getChannels().anyAxisSet() || !trgOpt->getChannels().anyAxisSet()) { if (srcOpt->getChannels().anyAxisSet()) - return srcOpt->subAxisType() == Gen::ChannelId::y; + return srcOpt->subAxisType() == Gen::AxisId::y; if (trgOpt->getChannels().anyAxisSet()) - return trgOpt->mainAxisType() == Gen::ChannelId::y; + return trgOpt->mainAxisType() == Gen::AxisId::y; } - auto srcXcnt = dimensionCount(source, Gen::ChannelId::x); - auto srcYcnt = dimensionCount(source, Gen::ChannelId::y); - auto trgXcnt = dimensionCount(target, Gen::ChannelId::x); - auto trgYcnt = dimensionCount(target, Gen::ChannelId::y); + auto srcXcnt = dimensionCount(source, Gen::AxisId::x); + auto srcYcnt = dimensionCount(source, Gen::AxisId::y); + auto trgXcnt = dimensionCount(target, Gen::AxisId::x); + auto trgYcnt = dimensionCount(target, Gen::AxisId::y); if ((trgYcnt != srcYcnt) || (trgXcnt != srcXcnt)) { return (trgYcnt > srcYcnt) || (trgXcnt < srcXcnt); @@ -425,8 +425,8 @@ bool Planner::needVertical() const != target->axises.at(Gen::ChannelId::y).measure || source->axises.at(Gen::ChannelId::y).dimension != target->axises.at(Gen::ChannelId::y).dimension - || source->guides.at(Gen::ChannelId::y) - != target->guides.at(Gen::ChannelId::y) + || source->guides.at(Gen::AxisId::y) + != target->guides.at(Gen::AxisId::y) || (isAnyLegend(Gen::ChannelId::size) && (source->axises.at(Gen::ChannelId::size).common != target->axises.at(Gen::ChannelId::size).common @@ -472,8 +472,8 @@ bool Planner::needHorizontal() const != target->axises.at(Gen::ChannelId::x).measure || source->axises.at(Gen::ChannelId::x).dimension != target->axises.at(Gen::ChannelId::x).dimension - || source->guides.at(Gen::ChannelId::x) - != target->guides.at(Gen::ChannelId::x) + || source->guides.at(Gen::AxisId::x) + != target->guides.at(Gen::AxisId::x) || source->anyAxisSet != target->anyAxisSet || source->keepAspectRatio != target->keepAspectRatio || (source->markerConnectionOrientation diff --git a/src/chart/animator/planner.h b/src/chart/animator/planner.h index b0cae3561..28bb4d61b 100644 --- a/src/chart/animator/planner.h +++ b/src/chart/animator/planner.h @@ -50,7 +50,7 @@ class Planner : public ::Anim::Group [[nodiscard]] bool positionMorphNeeded() const; [[nodiscard]] bool verticalBeforeHorizontal() const; static size_t dimensionCount(const Gen::Plot *plot, - Gen::ChannelId type); + Gen::AxisId type); [[nodiscard]] bool isAnyLegend(Gen::ChannelId type) const; diff --git a/src/chart/generator/axis.h b/src/chart/generator/axis.h index 719334b72..1e07318c0 100644 --- a/src/chart/generator/axis.h +++ b/src/chart/generator/axis.h @@ -154,12 +154,22 @@ struct Axises return axises.at(channelType); } - [[nodiscard]] const Axis &other(ChannelId channelType) const + [[nodiscard]] const Axis &at(AxisId axisType) const { - switch (channelType) { - case ChannelId::x: return axises.at(ChannelId::y); - case ChannelId::y: return axises.at(ChannelId::x); - default: throw std::logic_error("not an axis channel"); + return axises.at(asChannel(axisType)); + } + + [[nodiscard]] Axis &at(AxisId axisType) + { + return axises.at(asChannel(axisType)); + } + + [[nodiscard]] const Axis &other(AxisId axisType) const + { + switch (axisType) { + default: + case AxisId::x: return at(AxisId::y); + case AxisId::y: return at(AxisId::x); } } diff --git a/src/chart/generator/guides.cpp b/src/chart/generator/guides.cpp index c86a52b2a..0d0657c40 100644 --- a/src/chart/generator/guides.cpp +++ b/src/chart/generator/guides.cpp @@ -1,7 +1,5 @@ #include "guides.h" -#include - #include "base/math/interpolation.h" #include "chart/options/align.h" #include "chart/options/channel.h" @@ -92,18 +90,22 @@ Guides::Guides(const Options &options) || (!yIsMeasure && !yOpt.isEmpty()))); } -GuidesByAxis &Guides::at(ChannelId channel) +GuidesByAxis &Guides::at(AxisId channel) { - if (channel == ChannelId::x) return x; - if (channel == ChannelId::y) return y; - throw std::out_of_range("guides index out of range"); + switch (channel) { + default: + case AxisId::x: return x; + case AxisId::y: return y; + } } -const GuidesByAxis &Guides::at(ChannelId channel) const +const GuidesByAxis &Guides::at(AxisId channel) const { - if (channel == ChannelId::x) return x; - if (channel == ChannelId::y) return y; - throw std::out_of_range("guides index out of range"); + switch (channel) { + default: + case AxisId::x: return x; + case AxisId::y: return y; + } } bool Guides::hasAnyGuides() const diff --git a/src/chart/generator/guides.h b/src/chart/generator/guides.h index 6f3738560..4c8fd731b 100644 --- a/src/chart/generator/guides.h +++ b/src/chart/generator/guides.h @@ -32,8 +32,8 @@ struct Guides GuidesByAxis y; explicit Guides(const Options &options); - [[nodiscard]] const GuidesByAxis &at(ChannelId channel) const; - GuidesByAxis &at(ChannelId channel); + [[nodiscard]] const GuidesByAxis &at(AxisId channel) const; + GuidesByAxis &at(AxisId channel); [[nodiscard]] bool hasAnyGuides() const; }; diff --git a/src/chart/generator/plotbuilder.cpp b/src/chart/generator/plotbuilder.cpp index c3233b8ec..5a5beba16 100644 --- a/src/chart/generator/plotbuilder.cpp +++ b/src/chart/generator/plotbuilder.cpp @@ -185,9 +185,7 @@ PlotBuilder::sortedBuckets(const Buckets &buckets, bool main) const void PlotBuilder::addSpecLayout(Buckets &buckets) { - auto geometry = plot->getOptions() - ->geometry.get_or_first(::Anim::first) - .value; + auto geometry = plot->getOptions()->geometry.values[0].value; if (auto &markers = plot->markers; isConnecting(geometry)) { Charts::TableChart::setupVector(markers, true); } @@ -434,7 +432,7 @@ void PlotBuilder::calcDimensionAxis(ChannelId type) if (scale.isMeasure() || !scale.hasDimension()) return; - auto &&isTypeAxis = isAxis(type); + auto &&isTypeAxis = asAxis(type).has_value(); if (auto merge = scale.labelLevel == 0; isTypeAxis) { for (const auto &marker : plot->markers) { if (!marker.enabled) continue; @@ -480,16 +478,23 @@ void PlotBuilder::addAlignment(const Buckets &subBuckets) const { if (static_cast(plot->getOptions()->split)) return; - if (std::signbit( - plot->axises.at(plot->getOptions()->subAxisType()) - .measure.range.getMin()) - || std::signbit( - plot->axises.at(plot->getOptions()->subAxisType()) - .measure.range.getMax())) + auto &subAxisRange = + plot->axises.at(plot->getOptions()->subAxisType()) + .measure.range; + if (std::signbit(subAxisRange.getMin()) + || std::signbit(subAxisRange.getMax())) return; if (plot->getOptions()->align == Base::Align::Type::none) return; + if (plot->getOptions()->align == Base::Align::Type::center) { + auto &&halfSize = subAxisRange.size() / 2.0; + if (!Math::Floating::is_zero(halfSize)) + subAxisRange = Math::Range::Raw( + subAxisRange.getMin() - halfSize, + subAxisRange.getMax() - halfSize); + } + auto &&vectical = !plot->getOptions()->isHorizontal(); const Base::Align align{plot->getOptions()->align, Math::Range(0.0, 1.0)}; diff --git a/src/chart/main/style.h b/src/chart/main/style.h index 24ef6cd79..879e0caa1 100644 --- a/src/chart/main/style.h +++ b/src/chart/main/style.h @@ -106,9 +106,7 @@ struct Font [[nodiscard]] std::string calculatedFamily() const { if (fontFamily.has_value()) - if (auto &&ff = - fontFamily->get_or_first(::Anim::first).value; - !ff.empty()) + if (auto &&ff = fontFamily->values[0].value; !ff.empty()) return ff; if (fontParent) return fontParent->calculatedFamily(); @@ -363,9 +361,9 @@ struct PlotParams struct Plot : Padding, Box, PlotParams { - [[nodiscard]] const Axis &getAxis(Gen::ChannelId id) const + [[nodiscard]] const Axis &getAxis(Gen::AxisId id) const { - return id == Gen::ChannelId::x ? xAxis : yAxis; + return id == Gen::AxisId::x ? xAxis : yAxis; } }; diff --git a/src/chart/main/version.cpp b/src/chart/main/version.cpp index de7c3492d..7760ef6f0 100644 --- a/src/chart/main/version.cpp +++ b/src/chart/main/version.cpp @@ -2,6 +2,6 @@ #include "base/app/version.h" -const App::Version Vizzu::Main::version(0, 12, 1); +const App::Version Vizzu::Main::version(0, 14, 0); const char *const Vizzu::Main::siteUrl = "https://vizzu.io/"; diff --git a/src/chart/options/advancedoptions.cpp b/src/chart/options/advancedoptions.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/chart/options/advancedoptions.h b/src/chart/options/advancedoptions.h deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/chart/options/align.h b/src/chart/options/align.h index 390cfa54c..5edd71dde 100644 --- a/src/chart/options/align.h +++ b/src/chart/options/align.h @@ -10,30 +10,17 @@ namespace Vizzu::Base struct Align : private Math::Range { -public: - enum class Type : std::uint8_t { - none, - min, - center, - max, - stretch - }; - - Align(Type type, const Range &range) : - Range(range), - type(type) - {} - - [[nodiscard]] Range getAligned( - const Range &range) const + enum class Type : std::uint8_t { none, min, center, stretch }; + + Align(Type type, const Range &range) : Range(range), type(type) {} + + [[nodiscard]] Range getAligned(const Range &range) const { switch (type) { case Type::none: return range; case Type::min: return range + min - range.getMin(); case Type::center: return range - range.middle() + middle(); - case Type::max: return range + max - range.getMax(); - case Type::stretch: - return static_cast &>(*this); + case Type::stretch: return static_cast(*this); } throw std::logic_error("invalid align type"); } diff --git a/src/chart/options/channel.cpp b/src/chart/options/channel.cpp index 5b839ebec..46cc995ab 100644 --- a/src/chart/options/channel.cpp +++ b/src/chart/options/channel.cpp @@ -16,9 +16,22 @@ namespace Vizzu::Gen { -bool isAxis(ChannelId type) +std::optional asAxis(ChannelId type) { - return type == ChannelId::x || type == ChannelId::y; + return type == ChannelId::x || type == ChannelId::y + ? std::make_optional(static_cast( + static_cast(type))) + : std::nullopt; +} + +ChannelId asChannel(AxisId type) +{ + return static_cast(static_cast(type)); +} + +bool operator==(const AxisId &axis, const ChannelId &channel) +{ + return asChannel(axis) == channel; } Channel Channel::makeChannel(Type id) diff --git a/src/chart/options/channel.h b/src/chart/options/channel.h index 5d048e51d..cc1020c68 100644 --- a/src/chart/options/channel.h +++ b/src/chart/options/channel.h @@ -23,6 +23,28 @@ enum class ChannelId : std::uint8_t { y, noop }; +using ChannelIdType = std::underlying_type_t; + +enum class AxisId : ChannelIdType { + x = static_cast(ChannelId::x), + y = static_cast(ChannelId::y) +}; + +consteval auto unique_from_to(AxisId) +{ + return std::pair{static_cast(AxisId::x), + static_cast(AxisId::y)}; +} + +static_assert(Refl::enum_names.size() == 2); +static_assert(std::ranges::all_of(Refl::enum_names, + [](std::string_view name) + { + return static_cast( + Refl::get_enum(name)) + == static_cast( + Refl::get_enum(name)); + })); class Channel { @@ -69,7 +91,11 @@ class Channel Base::AutoParam step{}; }; -bool isAxis(ChannelId type); +std::optional asAxis(ChannelId type); +ChannelId asChannel(AxisId type); + +[[nodiscard]] bool operator==(const AxisId &axis, + const ChannelId &channel); } diff --git a/src/chart/options/channels.h b/src/chart/options/channels.h index 57c929839..d5fa83a13 100644 --- a/src/chart/options/channels.h +++ b/src/chart/options/channels.h @@ -31,7 +31,16 @@ class Channels const std::span &channelTypes) const; [[nodiscard]] const Channel &at(const ChannelId &id) const; - Channel &at(const ChannelId &id); + [[nodiscard]] Channel &at(const ChannelId &id); + + [[nodiscard]] const Channel &at(const AxisId &id) const + { + return at(asChannel(id)); + } + [[nodiscard]] Channel &at(const AxisId &id) + { + return at(asChannel(id)); + } void removeSeries(const Data::SeriesIndex &index); diff --git a/src/chart/options/options.cpp b/src/chart/options/options.cpp index af751cce1..5a73ba17b 100644 --- a/src/chart/options/options.cpp +++ b/src/chart/options/options.cpp @@ -66,7 +66,7 @@ const Channel *Options::subAxisOf(ChannelId id) const if (id == ChannelId::size && channels.anyAxisSet()) { return &channels.at(ChannelId::size); } - if (isAxis(id)) { + if (asAxis(id)) { if (channels.at(id).isDimension() && id == mainAxisType()) return &subAxis(); return &channels.at(ChannelId::size); @@ -81,7 +81,7 @@ ChannelId Options::stackChannelType() const if (channels.anyAxisSet()) { switch (geometry.get()) { case ShapeType::area: - case ShapeType::rectangle: return subAxisType(); + case ShapeType::rectangle: return asChannel(subAxisType()); default: case ShapeType::circle: case ShapeType::line: return ChannelId::size; @@ -93,11 +93,18 @@ ChannelId Options::stackChannelType() const std::optional Options::secondaryStackType() const { if (channels.anyAxisSet() && geometry == ShapeType::line) - return subAxisType(); + return asChannel(subAxisType()); return std::nullopt; } +bool Options::isStacked() const +{ + auto dims = stackChannel().dimensions(); + dims.split_by(mainAxis().dimensions()); + return !dims.empty(); +} + Channels Options::shadowChannels() const { auto shadow = channels.shadow(); @@ -122,12 +129,11 @@ void Options::drilldownTo(const Options &other) { auto &stackChannel = this->stackChannel(); + if (this->split && !isSplit()) this->split = false; + for (auto &&dim : other.getChannels().getDimensions()) if (!getChannels().isSeriesUsed(dim)) stackChannel.addSeries(dim); - if (stackChannel.isDimension() - && geometry == ShapeType::rectangle) - this->align = Base::Align::Type::stretch; } void Options::intersection(const Options &other) @@ -192,9 +198,9 @@ bool Options::sameShadowAttribs(const Options &other) const return shape == shapeOther && coordSystem == other.coordSystem && angle == other.angle && orientation == other.orientation - && split == other.split && dataFilter == other.dataFilter - && align == other.align && sort == other.sort - && reverse == other.reverse; + && isSplit() == other.isSplit() + && dataFilter == other.dataFilter && align == other.align + && sort == other.sort && reverse == other.reverse; } bool Options::sameAttributes(const Options &other) const diff --git a/src/chart/options/options.h b/src/chart/options/options.h index 55194bef3..2fda34cbc 100644 --- a/src/chart/options/options.h +++ b/src/chart/options/options.h @@ -26,8 +26,6 @@ namespace Vizzu::Gen class Options { - using ChannelIdType = std::underlying_type_t; - public: enum class LegendId : ChannelIdType { color = static_cast(ChannelId::color), @@ -68,9 +66,9 @@ class Options void reset(); - [[nodiscard]] ChannelId mainAxisType() const + [[nodiscard]] AxisId mainAxisType() const { - return isHorizontal() ? ChannelId::x : ChannelId::y; + return isHorizontal() ? AxisId::x : AxisId::y; } [[nodiscard]] bool isHorizontal() const @@ -81,9 +79,9 @@ class Options == Gen::Orientation::horizontal; } - [[nodiscard]] ChannelId subAxisType() const + [[nodiscard]] AxisId subAxisType() const { - return isHorizontal() ? ChannelId::y : ChannelId::x; + return isHorizontal() ? AxisId::y : AxisId::x; } [[nodiscard]] const Channel &mainAxis() const @@ -109,6 +107,18 @@ class Options return channels.at(stackChannelType()); } + [[nodiscard]] const Channel &stackChannel() const + { + return channels.at(stackChannelType()); + } + + [[nodiscard]] bool isStacked() const; + [[nodiscard]] bool isSplit() const + { + return split + && (subAxisType() != stackChannelType() || isStacked()); + } + Heading title{std::nullopt}; Heading subtitle{std::nullopt}; Heading caption{std::nullopt}; diff --git a/src/chart/rendering/colorbuilder.cpp b/src/chart/rendering/colorbuilder.cpp index 3a726de60..446fc0f99 100644 --- a/src/chart/rendering/colorbuilder.cpp +++ b/src/chart/rendering/colorbuilder.cpp @@ -24,7 +24,7 @@ ColorBuilder::ColorBuilder(const LightnessRange &lightnessRange, Gfx::Color ColorBuilder::render( const Anim::Interpolated &colorBase) const { - if (!colorBase.get_or_first(::Anim::first).value.isDiscrete() + if (!colorBase.values[0].value.isDiscrete() && !colorBase.get_or_first(::Anim::second) .value.isDiscrete()) { auto pos = colorBase.combine( diff --git a/src/chart/rendering/drawaxes.cpp b/src/chart/rendering/drawaxes.cpp index 2f3935afb..4b11ff546 100644 --- a/src/chart/rendering/drawaxes.cpp +++ b/src/chart/rendering/drawaxes.cpp @@ -31,8 +31,8 @@ void DrawAxes::drawGeometries() const { interlacing.drawGeometries(); - drawAxis(Gen::ChannelId::x); - drawAxis(Gen::ChannelId::y); + drawAxis(Gen::AxisId::x); + drawAxis(Gen::AxisId::y); DrawGuides{{ctx()}, canvas, painter}.draw(); } @@ -44,13 +44,13 @@ void DrawAxes::drawLabels() const drawDimensionLabels(true); drawDimensionLabels(false); - drawTitle(Gen::ChannelId::x); - drawTitle(Gen::ChannelId::y); + drawTitle(Gen::AxisId::x); + drawTitle(Gen::AxisId::y); } -Geom::Line DrawAxes::getAxis(Gen::ChannelId axisIndex) const +Geom::Line DrawAxes::getAxis(Gen::AxisId axisIndex) const { - auto horizontal = axisIndex == Gen::ChannelId::x; + auto horizontal = axisIndex == Gen::AxisId::x; auto offset = plot->axises.other(axisIndex).measure.origo(); @@ -63,10 +63,10 @@ Geom::Line DrawAxes::getAxis(Gen::ChannelId axisIndex) const return {}; } -void DrawAxes::drawAxis(Gen::ChannelId axisIndex) const +void DrawAxes::drawAxis(Gen::AxisId axisIndex) const { auto eventTarget = - Events::Targets::axis(axisIndex == Gen::ChannelId::x); + Events::Targets::axis(axisIndex == Gen::AxisId::x); auto lineBaseColor = *rootStyle.plot.getAxis(axisIndex).color; @@ -97,7 +97,7 @@ void DrawAxes::drawAxis(Gen::ChannelId axisIndex) const } } -Geom::Point DrawAxes::getTitleBasePos(Gen::ChannelId axisIndex, +Geom::Point DrawAxes::getTitleBasePos(Gen::AxisId axisIndex, ::Anim::InterpolateIndex index) const { typedef Styles::AxisTitle::Position Pos; @@ -125,12 +125,12 @@ Geom::Point DrawAxes::getTitleBasePos(Gen::ChannelId axisIndex, case VPos::begin: break; } - return axisIndex == Gen::ChannelId::x + return axisIndex == Gen::AxisId::x ? Geom::Point{parallel, orthogonal} : Geom::Point{orthogonal, parallel}; } -Geom::Point DrawAxes::getTitleOffset(Gen::ChannelId axisIndex, +Geom::Point DrawAxes::getTitleOffset(Gen::AxisId axisIndex, ::Anim::InterpolateIndex index, bool fades) const { @@ -166,12 +166,12 @@ Geom::Point DrawAxes::getTitleOffset(Gen::ChannelId axisIndex, fades ? calcVSide(titleStyle.vside->get_or_first(index).value) : titleStyle.vside->combine(calcVSide); - return axisIndex == Gen::ChannelId::x + return axisIndex == Gen::AxisId::x ? Geom::Point{parallel, -orthogonal} : Geom::Point{orthogonal, -parallel}; } -void DrawAxes::drawTitle(Gen::ChannelId axisIndex) const +void DrawAxes::drawTitle(Gen::AxisId axisIndex) const { const auto &titleString = plot->axises.at(axisIndex).common.title; @@ -252,7 +252,7 @@ void DrawAxes::drawTitle(Gen::ChannelId axisIndex) const titleStyle, *rootEvents.draw.plot.axis.title, Events::Targets::axisTitle(title.value, - axisIndex == Gen::ChannelId::x), + axisIndex == Gen::AxisId::x), {.colorTransform = Gfx::ColorTransform::Opacity(weight), .flip = upsideDown}); @@ -262,8 +262,7 @@ void DrawAxes::drawTitle(Gen::ChannelId axisIndex) const void DrawAxes::drawDimensionLabels(bool horizontal) const { - auto axisIndex = - horizontal ? Gen::ChannelId::x : Gen::ChannelId::y; + auto axisIndex = horizontal ? Gen::AxisId::x : Gen::AxisId::y; const auto &labelStyle = rootStyle.plot.getAxis(axisIndex).label; @@ -295,8 +294,7 @@ void DrawAxes::drawDimensionLabel(bool horizontal, enabled.labels); if (weight == 0) return; - auto axisIndex = - horizontal ? Gen::ChannelId::x : Gen::ChannelId::y; + auto axisIndex = horizontal ? Gen::AxisId::x : Gen::AxisId::y; const auto &labelStyle = rootStyle.plot.getAxis(axisIndex).label; auto drawLabel = OrientedLabel{{ctx()}}; @@ -370,12 +368,11 @@ void DrawAxes::drawDimensionLabel(bool horizontal, draw(text.get_or_first(index), position.weight); if (!labelStyle.position->interpolates() && !text.interpolates()) - draw(text.get_or_first(::Anim::first)); + draw(text.values[0]); else if (labelStyle.position->interpolates()) - draw(text.get_or_first(::Anim::first), - position.weight); + draw(text.values[0], position.weight); else if (text.interpolates()) { - draw(text.get_or_first(::Anim::first)); + draw(text.values[0]); draw(text.get_or_first(::Anim::second)); } }); diff --git a/src/chart/rendering/drawaxes.h b/src/chart/rendering/drawaxes.h index 588fa7135..8b84ffa7c 100644 --- a/src/chart/rendering/drawaxes.h +++ b/src/chart/rendering/drawaxes.h @@ -21,15 +21,14 @@ class DrawAxes : public DrawingContext DrawInterlacing interlacing; private: - [[nodiscard]] Geom::Line getAxis(Gen::ChannelId axisIndex) const; - [[nodiscard]] Geom::Point getTitleBasePos( - Gen::ChannelId axisIndex, + [[nodiscard]] Geom::Line getAxis(Gen::AxisId axisIndex) const; + [[nodiscard]] Geom::Point getTitleBasePos(Gen::AxisId axisIndex, ::Anim::InterpolateIndex index) const; - [[nodiscard]] Geom::Point getTitleOffset(Gen::ChannelId axisIndex, + [[nodiscard]] Geom::Point getTitleOffset(Gen::AxisId axisIndex, ::Anim::InterpolateIndex index, bool fades) const; - void drawAxis(Gen::ChannelId axisIndex) const; - void drawTitle(Gen::ChannelId axisIndex) const; + void drawAxis(Gen::AxisId axisIndex) const; + void drawTitle(Gen::AxisId axisIndex) const; void drawDimensionLabels(bool horizontal) const; void drawDimensionLabel(bool horizontal, const Geom::Point &origo, diff --git a/src/chart/rendering/drawguides.cpp b/src/chart/rendering/drawguides.cpp index bd272755a..a1be45a78 100644 --- a/src/chart/rendering/drawguides.cpp +++ b/src/chart/rendering/drawguides.cpp @@ -23,7 +23,7 @@ void DrawGuides::draw() void DrawGuides::draw(bool horizontal) { - auto axisId = horizontal ? Gen::ChannelId::x : Gen::ChannelId::y; + auto axisId = horizontal ? Gen::AxisId::x : Gen::AxisId::y; const auto &guideStyle = rootStyle.plot.getAxis(axisId).guides; diff --git a/src/chart/rendering/drawinterlacing.cpp b/src/chart/rendering/drawinterlacing.cpp index 99f92fe5b..a848831be 100644 --- a/src/chart/rendering/drawinterlacing.cpp +++ b/src/chart/rendering/drawinterlacing.cpp @@ -39,8 +39,7 @@ void DrawInterlacing::drawTexts() const void DrawInterlacing::draw(bool horizontal, bool text) const { - auto axisIndex = - horizontal ? Gen::ChannelId::y : Gen::ChannelId::x; + auto axisIndex = horizontal ? Gen::AxisId::y : Gen::AxisId::x; auto interlacingColor = *rootStyle.plot.getAxis(axisIndex).interlacing.color; @@ -111,8 +110,7 @@ void DrawInterlacing::draw( const auto &enabled = horizontal ? plot->guides.y : plot->guides.x; - auto axisIndex = - horizontal ? Gen::ChannelId::y : Gen::ChannelId::x; + auto axisIndex = horizontal ? Gen::AxisId::y : Gen::AxisId::x; const auto &axisStyle = rootStyle.plot.getAxis(axisIndex); @@ -148,7 +146,8 @@ void DrawInterlacing::draw( auto iMin = axisBottom > 0 ? std::floor(-axis.origo() / (2 * stripWidth)) * 2 - : std::round(axis.range.getMin() - stepSize); + : std::round( + (axis.range.getMin() - stepSize) / stepSize); auto interlaceCount = 0U; const auto maxInterlaceCount = 1000U; @@ -251,8 +250,7 @@ void DrawInterlacing::drawDataLabel( const ::Anim::String &unit, double alpha) const { - auto axisIndex = - horizontal ? Gen::ChannelId::y : Gen::ChannelId::x; + auto axisIndex = horizontal ? Gen::AxisId::y : Gen::AxisId::x; const auto &labelStyle = rootStyle.plot.getAxis(axisIndex).label; auto drawLabel = OrientedLabel{{ctx()}}; @@ -308,8 +306,7 @@ void DrawInterlacing::drawSticks(double tickIntensity, bool horizontal, const Geom::Point &tickPos) const { - auto axisIndex = - horizontal ? Gen::ChannelId::y : Gen::ChannelId::x; + auto axisIndex = horizontal ? Gen::AxisId::y : Gen::AxisId::x; const auto &axisStyle = rootStyle.plot.getAxis(axisIndex); const auto &tickStyle = axisStyle.ticks; diff --git a/src/chart/rendering/drawmarkerinfo.cpp b/src/chart/rendering/drawmarkerinfo.cpp index 4b1193794..fa3d931d7 100644 --- a/src/chart/rendering/drawmarkerinfo.cpp +++ b/src/chart/rendering/drawmarkerinfo.cpp @@ -195,8 +195,7 @@ void DrawMarkerInfo::draw(Gfx::ICanvas &canvas, const Geom::Rect &boundary) const { for (const auto &info : plot->getMarkersInfo()) { - auto &&[cnt1, weight1] = - info.second.get_or_first(::Anim::first); + auto &&[cnt1, weight1] = info.second.values[0]; if (!info.second.interpolates() && cnt1) { MarkerDC dc(*this, canvas, boundary, cnt1); dc.draw(weight1); diff --git a/src/chart/rendering/markerrenderer.cpp b/src/chart/rendering/markerrenderer.cpp index a963e9acd..6a167dca1 100644 --- a/src/chart/rendering/markerrenderer.cpp +++ b/src/chart/rendering/markerrenderer.cpp @@ -110,20 +110,31 @@ void MarkerRenderer::drawMarkers(Gfx::ICanvas &canvas, draw(canvas, painter, circle, 1, false); - blended.marker.prevMainMarker.visit( - [this, &blended, &canvas, &painter]( - ::Anim::InterpolateIndex index, - const auto &value) - { - draw(canvas, - painter, - ConnectingMarker{ctx(), - blended.marker, - index, - Gen::ShapeType::line}, - value.weight, - true); - }); + auto drawMarker = [this, &blended, &canvas, &painter]( + ::Anim::InterpolateIndex index, + const auto &value) + { + draw(canvas, + painter, + ConnectingMarker{ctx(), + blended.marker, + index, + Gen::ShapeType::line}, + value.weight, + true); + }; + + if (blended.marker.prevMainMarker.interpolates()) + blended.marker.prevMainMarker.visit(drawMarker); + else { + auto index = + getOptions() + .geometry.get_index(Gen::ShapeType::line) + .value(); + drawMarker(index, + blended.marker.prevMainMarker.get_or_first( + index)); + } } else { std::optional other; @@ -178,9 +189,7 @@ void MarkerRenderer::drawMarkers(Gfx::ICanvas &canvas, if (containsSingle) { auto lineIndex = isConnecting( - getOptions() - .geometry.get_or_first(::Anim::first) - .value) + getOptions().geometry.values[0].value) ? ::Anim::first : ::Anim::second; @@ -195,9 +204,8 @@ void MarkerRenderer::drawMarkers(Gfx::ICanvas &canvas, } else drawMarker(::Anim::first, - ::Anim::Weighted{blended.marker.prevMainMarker - .get_or_first(::Anim::first) - .value, + ::Anim::Weighted{ + blended.marker.prevMainMarker.values[0].value, sum_weight}); } } @@ -211,7 +219,7 @@ void MarkerRenderer::drawLabels(Gfx::ICanvas &canvas) const if (blended.marker.enabled == false) continue; drawLabel(canvas, blended, - axis.unit.get_or_first(::Anim::first).value, + axis.unit.values[0].value, keepMeasure, ::Anim::first); drawLabel(canvas, @@ -270,7 +278,11 @@ void MarkerRenderer::draw(Gfx::ICanvas &canvas, {Geom::Line(p0, p1), false}))) { painter.drawStraightLine(line, abstractMarker.lineWidth, - static_cast(abstractMarker.linear)); + getOptions().coordSystem.factor( + Gen::CoordSystem::cartesian) + == 1.0 + ? 1.0 + : static_cast(abstractMarker.linear)); renderedChart.emplace( Draw::Marker{abstractMarker.marker.enabled != false, diff --git a/src/chart/rendering/markers/abstractmarker.cpp b/src/chart/rendering/markers/abstractmarker.cpp index 090f5b69a..b4b929eaa 100644 --- a/src/chart/rendering/markers/abstractmarker.cpp +++ b/src/chart/rendering/markers/abstractmarker.cpp @@ -67,8 +67,7 @@ AbstractMarker AbstractMarker::createInterpolated( { const auto &options = ctx.getOptions(); - auto fromShapeType = - options.geometry.get_or_first(::Anim::first).value; + auto fromShapeType = options.geometry.values[0].value; auto fromMarker = create(ctx, marker, fromShapeType, lineIndex); @@ -84,13 +83,25 @@ AbstractMarker AbstractMarker::createInterpolated( aMarker.labelEnabled = fromMarker.labelEnabled + toMarker.labelEnabled; - auto sum = - static_cast(fromMarker.enabled + toMarker.enabled); + auto enableFactorBase = static_cast(toMarker.enabled); + auto labelEnableFactorBase = + static_cast(toMarker.labelEnabled); + auto enableSum = static_cast(aMarker.enabled); + auto labelEnableSum = static_cast(aMarker.labelEnabled); + + if (marker.polarConnection.interpolates()) { + auto firstWeight = options.geometry.values[0].weight; + auto secondWeight = options.geometry.values[1].weight; + enableSum = firstWeight + secondWeight; + enableFactorBase = secondWeight; + labelEnableSum = firstWeight + secondWeight; + labelEnableFactorBase = secondWeight; + } using Math::interpolate; using Vizzu::Draw::interpolate; - if (sum > 0.0) { - auto factor = static_cast(toMarker.enabled) / sum; + if (!Math::Floating::is_zero(enableSum)) { + auto factor = enableFactorBase / enableSum; aMarker.morphToCircle = interpolate(fromMarker.morphToCircle, toMarker.morphToCircle, factor); @@ -109,11 +120,8 @@ AbstractMarker AbstractMarker::createInterpolated( aMarker.center = interpolate(fromMarker.center, toMarker.center, factor); } - sum = static_cast( - fromMarker.labelEnabled + toMarker.labelEnabled); - if (sum > 0.0) { - auto factor = - static_cast(toMarker.labelEnabled) / sum; + if (!Math::Floating::is_zero(labelEnableSum)) { + auto factor = labelEnableFactorBase / labelEnableSum; aMarker.dataRect = interpolate(fromMarker.dataRect, toMarker.dataRect, factor); diff --git a/src/chart/rendering/markers/connectingmarker.cpp b/src/chart/rendering/markers/connectingmarker.cpp index 5459f10fe..abc730e45 100644 --- a/src/chart/rendering/markers/connectingmarker.cpp +++ b/src/chart/rendering/markers/connectingmarker.cpp @@ -29,13 +29,36 @@ ConnectingMarker::ConnectingMarker(const DrawingContext &ctx, auto isLine = type == Gen::ShapeType::line; auto isArea = type == Gen::ShapeType::area; + auto needConnection = + !ctx.getOptions().geometry.interpolates() + || isConnecting( + ctx.getOptions().geometry.get_or_first(lineIndex).value); + + auto otherNeedConnection = isConnecting( + ctx.getOptions() + .geometry + .get_or_first(lineIndex == ::Anim::first ? ::Anim::second + : ::Anim::first) + .value); + auto polar = ctx.getOptions().coordSystem.factor( Gen::CoordSystem::polar); auto horizontal = ctx.getOptions().orientation.factor( Gen::Orientation::horizontal); - linear = !polar || horizontal; + auto &&isHorizontal = + ctx.getOptions().orientation.get_or_first(lineIndex).value + == Gen::Orientation::horizontal; + + linear = !polar || horizontal + || Math::FuzzyBool::And( + !isHorizontal + && ctx.plot->axises.at(Gen::Channel::Type::x) + .dimension.enabled, + ctx.plot->axises.at(Gen::Channel::Type::x) + .measure.enabled.factor(false), + !horizontal); lineWidth[0] = lineWidth[1] = 0; @@ -49,7 +72,8 @@ ConnectingMarker::ConnectingMarker(const DrawingContext &ctx, if (prev) { enabled = labelEnabled && prev->enabled; connected = Math::FuzzyBool::And(enabled, - marker.prevMainMarker.get_or_first(lineIndex).weight); + marker.prevMainMarker.get_or_first(lineIndex).weight, + needConnection); if (auto &&pc = marker.polarConnection.get_or_first(lineIndex); pc.value) { @@ -59,6 +83,9 @@ ConnectingMarker::ConnectingMarker(const DrawingContext &ctx, || Math::FuzzyBool::Or(polar, pc.weight).more(); connected = connected && newPolar && horizontal; enabled = enabled && newPolar && horizontal; + + if (polar != false && prev != &marker) + linear = linear || Math::FuzzyBool{isHorizontal}; } } else { @@ -92,13 +119,13 @@ ConnectingMarker::ConnectingMarker(const DrawingContext &ctx, auto prevSpacing = prev->spacing * prev->size / 2; auto prevPos = prev->position; - if (polar != false - && ctx.getOptions() - .orientation.get_or_first(lineIndex) - .value - == Gen::Orientation::horizontal - && prev != &marker && prevPos.x >= 1) { - prevPos.x -= 1; + if (polar != false && isHorizontal && prev != &marker) { + if (!otherNeedConnection + && marker.polarConnection.get_or_first(lineIndex) + .value) + prevPos.x = 0; + else if (prevPos.x >= 1) + prevPos.x -= 1; } points[3] = prevPos - prevSpacing; diff --git a/src/chart/rendering/markers/rectanglemarker.cpp b/src/chart/rendering/markers/rectanglemarker.cpp index c0866ed28..32bc81a36 100644 --- a/src/chart/rendering/markers/rectanglemarker.cpp +++ b/src/chart/rendering/markers/rectanglemarker.cpp @@ -21,6 +21,14 @@ RectangleMarker::RectangleMarker(const Gen::Marker &marker, SingleDrawMarker(marker, options, Gen::ShapeType::rectangle) { linear = options.coordSystem.factor(Gen::CoordSystem::polar) == 0; + + if (marker.polarConnection.interpolates() + && options.geometry.contains(Gen::ShapeType::line)) { + linear = linear + || !marker.polarConnection.factor(true) + .less(); + } + border = Math::FuzzyBool(true); auto spacing = Geom::Size{ diff --git a/src/chart/rendering/painter/drawline.cpp b/src/chart/rendering/painter/drawline.cpp index 97c7dcf23..f78d1bf39 100644 --- a/src/chart/rendering/painter/drawline.cpp +++ b/src/chart/rendering/painter/drawline.cpp @@ -8,6 +8,7 @@ #include "base/math/interpolation.h" #include "coordinatesystem.h" +#include "drawpolygon.h" #include "pathsampler.h" namespace Vizzu::Draw @@ -22,15 +23,14 @@ DrawLine::DrawLine(const Geom::Line &line, DrawLine::DrawLine(const Geom::Line &line, std::array widths, - [[maybe_unused]] double straightFactor, - CoordinateSystem &coordSys, + const Options &options, Gfx::ICanvas &canvas) { - auto pBeg = coordSys.convert(line.begin); - auto pEnd = coordSys.convert(line.end); + auto pBeg = options.coordSys.convert(line.begin); + auto pEnd = options.coordSys.convert(line.end); - auto wBeg = widths[0] * coordSys.getRect().size.minSize(); - auto wEnd = widths[1] * coordSys.getRect().size.minSize(); + auto wBeg = widths[0] * options.coordSys.getRect().size.minSize(); + auto wEnd = widths[1] * options.coordSys.getRect().size.minSize(); const auto &[p0, p1, p2, p3] = Geom::ConvexQuad::Isosceles(pBeg, pEnd, wBeg * 2, wEnd * 2) @@ -41,12 +41,25 @@ DrawLine::DrawLine(const Geom::Line &line, if (pBeg != pEnd) { canvas.circle(Geom::Circle(pEnd, wEnd)); - canvas.beginPolygon(); - canvas.addPoint(p0); - canvas.addPoint(p1); - canvas.addPoint(p2); - canvas.addPoint(p3); - canvas.endPolygon(); + if (options.straightFactor == 1.0) { + canvas.beginPolygon(); + canvas.addPoint(p0); + canvas.addPoint(p1); + canvas.addPoint(p2); + canvas.addPoint(p3); + canvas.endPolygon(); + } + else { + DrawPolygon({options.coordSys.getOriginal(p0), + options.coordSys.getOriginal(p1), + options.coordSys.getOriginal(p2), + options.coordSys.getOriginal(p3)}, + {static_cast(options), + {.toCircleFactor = 0, + .straightFactor = options.straightFactor}}, + canvas, + false); + } } } diff --git a/src/chart/rendering/painter/drawline.h b/src/chart/rendering/painter/drawline.h index 3acaf5bcd..2d14c5379 100644 --- a/src/chart/rendering/painter/drawline.h +++ b/src/chart/rendering/painter/drawline.h @@ -14,14 +14,21 @@ namespace Vizzu::Draw class DrawLine { public: + struct LineOptions + { + double straightFactor; + }; + + struct Options : PathSampler::Options, LineOptions + {}; + DrawLine(const Geom::Line &line, const PathSampler::Options &options, Gfx::ICanvas &canvas); DrawLine(const Geom::Line &line, std::array widths, - double straightFactor, - CoordinateSystem &coordSys, + const Options &options, Gfx::ICanvas &canvas); private: diff --git a/src/chart/rendering/painter/painter.cpp b/src/chart/rendering/painter/painter.cpp index c08fe01fa..c3dd324c2 100644 --- a/src/chart/rendering/painter/painter.cpp +++ b/src/chart/rendering/painter/painter.cpp @@ -20,7 +20,10 @@ void Painter::drawStraightLine(const Geom::Line &line, std::array widths, double straightFactor) { - Draw::DrawLine(line, widths, straightFactor, system, getCanvas()); + DrawLine(line, + widths, + {{pathSamplerOptions, system}, {straightFactor}}, + getCanvas()); } void Painter::drawPolygon(const std::array &ps, diff --git a/test/e2e/test_cases/test_cases.json b/test/e2e/test_cases/test_cases.json index 1572c9033..41a495267 100644 --- a/test/e2e/test_cases/test_cases.json +++ b/test/e2e/test_cases/test_cases.json @@ -113,7 +113,7 @@ "refs": ["69db5d4"] }, "basic_animations/someOtherTests/merge_split_area_stream_2dis_1con": { - "refs": ["f2b76ef"] + "refs": ["e4d1b13"] }, "basic_animations/someOtherTests/total_time_area_bar": { "refs": ["d908ab5"] @@ -506,7 +506,7 @@ "refs": ["592c356"] }, "web_content/analytical_operations/compare/stream_stacked": { - "refs": ["e6a3d8e"] + "refs": ["18519bf"] }, "web_content/analytical_operations/compare/waterfall": { "refs": ["6c43732"] @@ -620,10 +620,10 @@ "refs": ["dcff220"] }, "web_content/analytical_operations/filter/stream_1": { - "refs": ["8f1411b"] + "refs": ["6f09295"] }, "web_content/analytical_operations/filter/stream_2": { - "refs": ["e0754e3"] + "refs": ["4032552"] }, "web_content/analytical_operations/misc/donut_to_coxcomb": { "refs": ["76f76c6"] @@ -770,7 +770,7 @@ "refs": ["4e1f1e8"] }, "web_content/analytical_operations/sum/stream_stacked": { - "refs": ["f10a963"] + "refs": ["def9ca7"] }, "web_content/analytical_operations/sum/treemap": { "refs": ["bfa16c8"] @@ -800,7 +800,7 @@ "refs": ["8a45f1d"] }, "web_content_removed/animated/merge_split_area_stream_3dis_1con": { - "refs": ["33ef953"] + "refs": ["44510ac"] }, "web_content_removed/animated/merge_split_bar": { "refs": ["99a64ed"] @@ -923,10 +923,10 @@ "refs": ["4bebc47"] }, "web_content/presets/graph/stream": { - "refs": ["b8b49d2"] + "refs": ["24b7673"] }, "web_content/presets/graph/stream_vertical": { - "refs": ["4bc1f73"] + "refs": ["f675019"] }, "web_content/presets/graph/violin": { "refs": ["683b150"] @@ -1037,7 +1037,7 @@ "refs": ["ac87631"] }, "web_content/static/graph/stream_stacked": { - "refs": ["f035f3d"] + "refs": ["08265f8"] }, "web_content/static/chart/waterfall": { "refs": ["2aeab23"] @@ -1088,7 +1088,7 @@ "refs": ["f51d29b"] }, "ww_animTiming/descartes-polar/04_d-p_l-r-l": { - "refs": ["6167247"] + "refs": ["7b0a74f"] }, "ww_animTiming/descartes-polar/05_d-p_r-c-r": { "refs": ["e88e386"] @@ -1103,7 +1103,7 @@ "refs": ["ff41d1b"] }, "ww_animTiming/descartes-polar/09_d-p_r-a-r": { - "refs": ["885e837"] + "refs": ["6ae914e"] }, "ww_animTiming/descartes-polar/10_d-p_c-a-c": { "refs": ["e0c5690"] @@ -1115,13 +1115,13 @@ "refs": ["9b044b7"] }, "ww_animTiming/descartes-polar/13_d-p_r-l-r": { - "refs": ["2aeba50"] + "refs": ["1d1ce35"] }, "ww_animTiming/descartes-polar/14_d-p_c-l-c": { - "refs": ["cc23605"] + "refs": ["0d6764a"] }, "ww_animTiming/descartes-polar/15_d-p_a-l-a": { - "refs": ["a0bc772"] + "refs": ["6344cdb"] }, "ww_animTiming/descartes-polar/16_d-p_l-l-l": { "refs": ["ed8f0d3"] @@ -1136,7 +1136,7 @@ "refs": ["055beac"] }, "ww_animTiming/descartes-polar_orient/04_d-p_o_l-r-l": { - "refs": ["8d171ed"] + "refs": ["8ea29c3"] }, "ww_animTiming/descartes-polar_orient/05_d-p_o_r-c-r": { "refs": ["6b8bec2"] @@ -1148,31 +1148,31 @@ "refs": ["85fa481"] }, "ww_animTiming/descartes-polar_orient/08_d-p_o_l-c-l": { - "refs": ["313f14d"] + "refs": ["bc44721"] }, "ww_animTiming/descartes-polar_orient/09_d-p_o_r-a-r": { - "refs": ["7ac3539"] + "refs": ["92347cf"] }, "ww_animTiming/descartes-polar_orient/10_d-p_o_c-a-c": { "refs": ["c3da357"] }, "ww_animTiming/descartes-polar_orient/11_d-p_o_a-a-a": { - "refs": ["e39f80e"] + "refs": ["7f929c2"] }, "ww_animTiming/descartes-polar_orient/12_d-p_o_l-a-l": { - "refs": ["4cc65b5"] + "refs": ["d6cd7fa"] }, "ww_animTiming/descartes-polar_orient/13_d-p_o_r-l-r": { - "refs": ["9b5018c"] + "refs": ["79cdab9"] }, "ww_animTiming/descartes-polar_orient/14_d-p_o_c-l-c": { - "refs": ["9efa494"] + "refs": ["307d013"] }, "ww_animTiming/descartes-polar_orient/15_d-p_o_a-l-a": { - "refs": ["b52a112"] + "refs": ["f0ef870"] }, "ww_animTiming/descartes-polar_orient/16_d-p_o_l-l-l": { - "refs": ["8d69b8a"] + "refs": ["9ac7b04"] }, "ww_animTiming/descartes/02_d-d_c-r-c": { "refs": ["6b41e5c"] @@ -1223,7 +1223,7 @@ "refs": ["e5b8fb4"] }, "ww_animTiming/descartes_orientation/08_d-d_o_l-c-l": { - "refs": ["f1f6788"] + "refs": ["f8bc2c3"] }, "ww_animTiming/descartes_orientation/09_d-d_o_r-a-r": { "refs": ["1aba15d"] @@ -1241,7 +1241,7 @@ "refs": ["c8df19a"] }, "ww_animTiming/descartes_orientation/14_d-d_o_c-l-c": { - "refs": ["42a8c02"] + "refs": ["34c771f"] }, "ww_animTiming/descartes_orientation/15_d-d_o_a-l-a": { "refs": ["66b0ce9"] @@ -1253,16 +1253,16 @@ "refs": ["809202b"] }, "ww_animTiming/polar/03_p-p_a-r-a": { - "refs": ["372d996"] + "refs": ["475d32c"] }, "ww_animTiming/polar/04_p-p_l-r-l": { - "refs": ["0ee8b01"] + "refs": ["601e976"] }, "ww_animTiming/polar/07_p-p_a-c-a": { - "refs": ["6312909"] + "refs": ["11024d1"] }, "ww_animTiming/polar/08_p-p_l-c-l": { - "refs": ["5636001"] + "refs": ["7980351"] }, "ww_animTiming/polar/12_p-p_l-a-l": { "refs": ["4d931d3"] @@ -1274,10 +1274,10 @@ "refs": ["6838848"] }, "ww_animTiming/polar_orientation/03_p-p_o_a-r-a": { - "refs": ["f55871f"] + "refs": ["afcec38"] }, "ww_animTiming/polar_orientation/04_p-p_o_l-r-l": { - "refs": ["9f1810c"] + "refs": ["5a8dc56"] }, "ww_animTiming/polar_orientation/05_p-p_o_r-c-r": { "refs": ["194a1ba"] @@ -1286,34 +1286,34 @@ "refs": ["e8610b7"] }, "ww_animTiming/polar_orientation/07_p-p_o_a-c-a": { - "refs": ["63f6bda"] + "refs": ["263570a"] }, "ww_animTiming/polar_orientation/08_p-p_o_l-c-l": { - "refs": ["4f6c55e"] + "refs": ["fa4d1b4"] }, "ww_animTiming/polar_orientation/09_p-p_o_r-a-r": { - "refs": ["97ba516"] + "refs": ["f4d745b"] }, "ww_animTiming/polar_orientation/10_p-p_o_c-a-c": { - "refs": ["8235eaa"] + "refs": ["26551fc"] }, "ww_animTiming/polar_orientation/11_p-p_o_a-a-a": { - "refs": ["26881ce"] + "refs": ["0b73432"] }, "ww_animTiming/polar_orientation/12_p-p_o_l-a-l": { - "refs": ["8b783ab"] + "refs": ["80363cf"] }, "ww_animTiming/polar_orientation/13_p-p_o_r-l-r": { - "refs": ["2923272"] + "refs": ["22c2e94"] }, "ww_animTiming/polar_orientation/14_p-p_o_c-l-c": { - "refs": ["72b4c2f"] + "refs": ["dc004c2"] }, "ww_animTiming/polar_orientation/15_p-p_o_a-l-a": { - "refs": ["e524c29"] + "refs": ["28de082"] }, "ww_animTiming/polar_orientation/16_p-p_o_l-l-l": { - "refs": ["48cf189"] + "refs": ["d13f10e"] }, "ww_animTiming/without-descartes/01_w-d_r-r-r": { "refs": ["e38d661"] @@ -1337,7 +1337,7 @@ "refs": ["9476a9e"] }, "ww_animTiming/without-descartes/14_w-d_c-l-c": { - "refs": ["1c4d882"] + "refs": ["4d42242"] }, "ww_animTiming/without-descartes_orientation/01_w-d_o_r-r-r": { "refs": ["dd2956b"] @@ -1361,7 +1361,7 @@ "refs": ["12843e9"] }, "ww_animTiming/without-descartes_orientation/14_w-d_o_c-l-c": { - "refs": ["edb0256"] + "refs": ["37b2c36"] }, "ww_animTiming/without-polar/01_w-p_r-r-r": { "refs": ["0093ba5"] @@ -1376,16 +1376,16 @@ "refs": ["de13c5b"] }, "ww_animTiming/without-polar/09_w-p_r-a-r": { - "refs": ["35a776b"] + "refs": ["9d80ca3"] }, "ww_animTiming/without-polar/10_w-p_c-a-c": { "refs": ["8e2fa00"] }, "ww_animTiming/without-polar/13_w-p_r-l-r": { - "refs": ["95fca69"] + "refs": ["f2e07b9"] }, "ww_animTiming/without-polar/14_w-p_c-l-c": { - "refs": ["2610145"] + "refs": ["071349d"] }, "ww_animTiming/without-polar_orientation/01_w-p_o_r-r-r": { "refs": ["230025c"] @@ -1406,10 +1406,10 @@ "refs": ["b6454bf"] }, "ww_animTiming/without-polar_orientation/13_w-p_o_r-l-r": { - "refs": ["facbfc3"] + "refs": ["b1879d3"] }, "ww_animTiming/without-polar_orientation/14_w-p_o_c-l-c": { - "refs": ["a11b5c2"] + "refs": ["9aa7e5e"] }, "ww_animTiming/without/02_w-w_c-r-c": { "refs": ["8a6ff6f"] @@ -1421,7 +1421,7 @@ "refs": ["502c2d5"] }, "ww_animTiming_TESTS/descartes-polar/04_d-p_l-r-l": { - "refs": ["ac9ec08"] + "refs": ["7680514"] }, "ww_animTiming_TESTS/descartes-polar/05_d-p_r-c-r": { "refs": ["4267970"] @@ -1436,25 +1436,25 @@ "refs": ["6bc3ae9"] }, "ww_animTiming_TESTS/descartes-polar/09_d-p_r-a-r": { - "refs": ["eca31a6"] + "refs": ["76566a4"] }, "ww_animTiming_TESTS/descartes-polar/10_d-p_c-a-c": { - "refs": ["233d04d"] + "refs": ["9e850b4"] }, "ww_animTiming_TESTS/descartes-polar/11_d-p_a-a-a": { "refs": ["d41e2e7"] }, "ww_animTiming_TESTS/descartes-polar/12_d-p_l-a-l": { - "refs": ["884fc37"] + "refs": ["3dd8622"] }, "ww_animTiming_TESTS/descartes-polar/13_d-p_r-l-r": { - "refs": ["214f7df"] + "refs": ["be21d7f"] }, "ww_animTiming_TESTS/descartes-polar/14_d-p_c-l-c": { - "refs": ["511a167"] + "refs": ["e0eb2ab"] }, "ww_animTiming_TESTS/descartes-polar/15_d-p_a-l-a": { - "refs": ["4b41033"] + "refs": ["46d46de"] }, "ww_animTiming_TESTS/descartes-polar/16_d-p_l-l-l": { "refs": ["bf46c48"] @@ -1469,7 +1469,7 @@ "refs": ["6f3b332"] }, "ww_animTiming_TESTS/descartes-polar_orient/04_d-p_o_l-r-l": { - "refs": ["c0892c5"] + "refs": ["0cd0d8a"] }, "ww_animTiming_TESTS/descartes-polar_orient/05_d-p_o_r-c-r": { "refs": ["4c56078"] @@ -1481,10 +1481,10 @@ "refs": ["4804203"] }, "ww_animTiming_TESTS/descartes-polar_orient/08_d-p_o_l-c-l": { - "refs": ["60e1f19"] + "refs": ["c97e1b5"] }, "ww_animTiming_TESTS/descartes-polar_orient/09_d-p_o_r-a-r": { - "refs": ["7fd047f"] + "refs": ["a2c55d5"] }, "ww_animTiming_TESTS/descartes-polar_orient/10_d-p_o_c-a-c": { "refs": ["9e91c47"] @@ -1493,19 +1493,19 @@ "refs": ["fdf551a"] }, "ww_animTiming_TESTS/descartes-polar_orient/12_d-p_o_l-a-l": { - "refs": ["a25fcdc"] + "refs": ["6c0e5d8"] }, "ww_animTiming_TESTS/descartes-polar_orient/13_d-p_o_r-l-r": { - "refs": ["a21a05b"] + "refs": ["dc0ede2"] }, "ww_animTiming_TESTS/descartes-polar_orient/14_d-p_o_c-l-c": { - "refs": ["0087e57"] + "refs": ["5bd7de5"] }, "ww_animTiming_TESTS/descartes-polar_orient/15_d-p_o_a-l-a": { - "refs": ["8aaae63"] + "refs": ["c1ccdd6"] }, "ww_animTiming_TESTS/descartes-polar_orient/16_d-p_o_l-l-l": { - "refs": ["d1c92f3"] + "refs": ["9cc461d"] }, "ww_animTiming_TESTS/descartes/02_d-d_c-r-c": { "refs": ["24a02ce"] @@ -1556,7 +1556,7 @@ "refs": ["3dfc970"] }, "ww_animTiming_TESTS/descartes_orientation/08_d-d_o_l-c-l": { - "refs": ["eb72661"] + "refs": ["31698e2"] }, "ww_animTiming_TESTS/descartes_orientation/09_d-d_o_r-a-r": { "refs": ["553ae01"] @@ -1574,7 +1574,7 @@ "refs": ["3d3592b"] }, "ww_animTiming_TESTS/descartes_orientation/14_d-d_o_c-l-c": { - "refs": ["d1a36ed"] + "refs": ["f99a273"] }, "ww_animTiming_TESTS/descartes_orientation/15_d-d_o_a-l-a": { "refs": ["8e81a70"] @@ -1586,16 +1586,16 @@ "refs": ["3e25139"] }, "ww_animTiming_TESTS/polar/03_p-p_a-r-a": { - "refs": ["c4bb893"] + "refs": ["ea73407"] }, "ww_animTiming_TESTS/polar/04_p-p_l-r-l": { - "refs": ["f3f57f3"] + "refs": ["73a417f"] }, "ww_animTiming_TESTS/polar/07_p-p_a-c-a": { - "refs": ["9fbce5b"] + "refs": ["e66651e"] }, "ww_animTiming_TESTS/polar/08_p-p_l-c-l": { - "refs": ["91c7b15"] + "refs": ["3a0e61b"] }, "ww_animTiming_TESTS/polar/12_p-p_l-a-l": { "refs": ["a19415c"] @@ -1607,10 +1607,10 @@ "refs": ["381f355"] }, "ww_animTiming_TESTS/polar_orientation/03_p-p_o_a-r-a": { - "refs": ["b152c6c"] + "refs": ["156e730"] }, "ww_animTiming_TESTS/polar_orientation/04_p-p_o_l-r-l": { - "refs": ["5068b63"] + "refs": ["ff4c947"] }, "ww_animTiming_TESTS/polar_orientation/05_p-p_o_r-c-r": { "refs": ["cfcddbc"] @@ -1619,34 +1619,34 @@ "refs": ["dc0dd32"] }, "ww_animTiming_TESTS/polar_orientation/07_p-p_o_a-c-a": { - "refs": ["4cb9cda"] + "refs": ["9a18083"] }, "ww_animTiming_TESTS/polar_orientation/08_p-p_o_l-c-l": { - "refs": ["6c7d10e"] + "refs": ["154df25"] }, "ww_animTiming_TESTS/polar_orientation/09_p-p_o_r-a-r": { - "refs": ["c667ccb"] + "refs": ["a7959f7"] }, "ww_animTiming_TESTS/polar_orientation/10_p-p_o_c-a-c": { - "refs": ["ed1fc0e"] + "refs": ["1678161"] }, "ww_animTiming_TESTS/polar_orientation/11_p-p_o_a-a-a": { "refs": ["e3b8771"] }, "ww_animTiming_TESTS/polar_orientation/12_p-p_o_l-a-l": { - "refs": ["82d2c47"] + "refs": ["dd4ab8a"] }, "ww_animTiming_TESTS/polar_orientation/13_p-p_o_r-l-r": { - "refs": ["1d74287"] + "refs": ["7b3999a"] }, "ww_animTiming_TESTS/polar_orientation/14_p-p_o_c-l-c": { - "refs": ["0814a0b"] + "refs": ["b9a6c91"] }, "ww_animTiming_TESTS/polar_orientation/15_p-p_o_a-l-a": { - "refs": ["a40eebc"] + "refs": ["825c108"] }, "ww_animTiming_TESTS/polar_orientation/16_p-p_o_l-l-l": { - "refs": ["b7a2622"] + "refs": ["f3b4e3e"] }, "ww_animTiming_TESTS/without-descartes/01_w-d_r-r-r": { "refs": ["f7cdb5e"] @@ -1670,7 +1670,7 @@ "refs": ["fd971f8"] }, "ww_animTiming_TESTS/without-descartes/14_w-d_c-l-c": { - "refs": ["631f180"] + "refs": ["e955812"] }, "ww_animTiming_TESTS/without-descartes_orientation/01_w-d_o_r-r-r": { "refs": ["cdf5fa6"] @@ -1694,7 +1694,7 @@ "refs": ["42f1324"] }, "ww_animTiming_TESTS/without-descartes_orientation/14_w-d_o_c-l-c": { - "refs": ["21090ba"] + "refs": ["fa9e4f7"] }, "ww_animTiming_TESTS/without-polar/01_w-p_r-r-r": { "refs": ["0a5d425"] @@ -1709,16 +1709,16 @@ "refs": ["595d4d2"] }, "ww_animTiming_TESTS/without-polar/09_w-p_r-a-r": { - "refs": ["49d5709"] + "refs": ["5be3f29"] }, "ww_animTiming_TESTS/without-polar/10_w-p_c-a-c": { - "refs": ["02254c6"] + "refs": ["d0fb7f1"] }, "ww_animTiming_TESTS/without-polar/13_w-p_r-l-r": { - "refs": ["415b996"] + "refs": ["72ae20d"] }, "ww_animTiming_TESTS/without-polar/14_w-p_c-l-c": { - "refs": ["97df1a9"] + "refs": ["5354fd6"] }, "ww_animTiming_TESTS/without-polar_orientation/01_w-p_o_r-r-r": { "refs": ["dd0a8a7"] @@ -1739,10 +1739,10 @@ "refs": ["fc3ab2f"] }, "ww_animTiming_TESTS/without-polar_orientation/13_w-p_o_r-l-r": { - "refs": ["ea1e18b"] + "refs": ["0166671"] }, "ww_animTiming_TESTS/without-polar_orientation/14_w-p_o_c-l-c": { - "refs": ["c048e2a"] + "refs": ["9807b66"] }, "ww_animTiming_TESTS/without/02_w-w_c-r-c": { "refs": ["0a179a2"] @@ -2072,7 +2072,7 @@ "refs": ["5c375dd"] }, "ww_next_steps/next_steps_byOperations/wREGIEKBOL/03_d-w_lin": { - "refs": ["556ceb3"] + "refs": ["b187a26"] }, "ww_next_steps/next_steps_byOperations/wREGIEKBOL/03_d-w_rec": { "refs": ["957ce26"] @@ -2375,28 +2375,28 @@ "refs": ["0fa780b"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/02_d-w_lin": { - "refs": ["a45d447"] + "refs": ["b7fb39c"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/03_d-w_lin": { - "refs": ["65eb3e6"] + "refs": ["b8d14ad"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/04a_d-w_lin": { "refs": ["505049f"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/04b_d-w_lin": { - "refs": ["2e096bf"] + "refs": ["c30cd88"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/05a_d-w_lin": { "refs": ["da98786"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/05b_d-w_lin": { - "refs": ["ed0e9a1"] + "refs": ["ed6eeee"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/06a_d-w_lin": { "refs": ["4d5e7d8"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/line/06b_d-w_lin": { - "refs": ["b3ad102"] + "refs": ["c380464"] }, "ww_noFade/wNoFade_Tests/2_des_pol-without/rectangle/02_d-w_rec": { "refs": ["80e2a13"] @@ -2447,7 +2447,7 @@ "refs": ["295cd11"] }, "ww_noFade/wNoFade_Tests/Marker_transition_problem/Bubble_Stacked_Bubble_to_Line": { - "refs": ["fc2c6f5"] + "refs": ["3a3e32f"] }, "ww_noFade/wNoFade_Tests/Marker_transition_problem/Treemap_Stacked_Treemap_to_Area": { "refs": ["e5678fa"] @@ -2738,7 +2738,7 @@ "refs": ["899b393"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/circle/08_d-w_cir_2c": { - "refs": ["7f77f0d"] + "refs": ["0b47ef8"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/03_d-w_cir_V1": { "refs": ["56a1e9b"] @@ -2765,7 +2765,7 @@ "refs": ["9a3ff21"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/08_d-w_cir_V1_2c": { - "refs": ["b618687"] + "refs": ["33f365d"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line-rectangle/02_d-d_lin": { "refs": ["6eefc98"] @@ -2795,52 +2795,52 @@ "refs": ["c6a04b0"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/02_d-w_lin": { - "refs": ["3c77802"] + "refs": ["1e0bb82"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/03_d-w_lin": { - "refs": ["13c3122"] + "refs": ["ec968a0"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/04a_d-w_lin": { - "refs": ["5a7c1ca"] + "refs": ["6cccc69"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/04b_d-w_lin": { - "refs": ["1ce9a5c"] + "refs": ["1a434cd"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/05a_d-w_lin": { - "refs": ["179dd5c"] + "refs": ["55c2090"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/05b_d-w_lin": { - "refs": ["5d92ecc"] + "refs": ["0fe11dd"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/06a_d-w_lin": { - "refs": ["0eec891"] + "refs": ["9f026a4"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line/06b_d-w_lin": { - "refs": ["9eec8e6"] + "refs": ["748d599"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/02_d-w_lin_V1": { - "refs": ["da22d36"] + "refs": ["3dfd65f"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/03_d-w_lin_V1": { - "refs": ["6f746a6"] + "refs": ["52c251e"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/04a_d-w_lin_V1": { - "refs": ["c62e561"] + "refs": ["4838b72"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/04b_d-w_lin_V1": { - "refs": ["520a21c"] + "refs": ["1e1175c"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/05a_d-w_lin_V1": { - "refs": ["00bc232"] + "refs": ["bcbbb71"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/05b_d-w_lin_V1": { - "refs": ["62a0bee"] + "refs": ["6788f87"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/06a_d-w_lin_V1": { - "refs": ["4471f7f"] + "refs": ["f9998fb"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/line_V1/06b_d-w_lin_V1": { - "refs": ["93e79eb"] + "refs": ["74b8546"] }, "ww_noFade/wNoFade_cases/2_des_pol-without/rectangle/02_d-w_rec": { "refs": ["f7fce9b"] @@ -3065,10 +3065,10 @@ "refs": ["52a2da9"] }, "ww_samples_for_presets/cartesian_coo_sys/32_C_A_stream_graph": { - "refs": ["ed823d3"] + "refs": ["f4d215c"] }, "ww_samples_for_presets/cartesian_coo_sys/33_C_A_stream_graph_vert": { - "refs": ["98ce42b"] + "refs": ["f128560"] }, "ww_samples_for_presets/cartesian_coo_sys/34_C_A_violin_graph": { "refs": ["0cddf74"] @@ -3188,13 +3188,13 @@ "refs": ["aa768ea"] }, "www_new_analytical_operations/operations/07_distribute/Bubble_Stacked_Bubble_to_Line": { - "refs": ["3880e09"] + "refs": ["8098657"] }, "www_new_analytical_operations/operations/07_distribute/Treemap_Stacked_Treemap_to_Area": { "refs": ["62ce1aa"] }, "basic_animations/markers_morph/marker_trans_polar": { - "refs": ["e0b4253"] + "refs": ["3360eb3"] }, "web_content/cookbook/chart_types/exploded_pie_chart": { "refs": ["f1a2f41"] @@ -3236,7 +3236,7 @@ "refs": ["bd104b0"] }, "web_content/cookbook/style/dark_theme": { - "refs": ["709d924"] + "refs": ["e8be03d"] }, "web_content/cookbook/style/highligh_markers": { "refs": ["54fc3d3"] diff --git a/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle/08_d-w_cir_2c.mjs b/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle/08_d-w_cir_2c.mjs index 14434d78c..9d2b2637e 100755 --- a/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle/08_d-w_cir_2c.mjs +++ b/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle/08_d-w_cir_2c.mjs @@ -42,8 +42,7 @@ const testSteps = [ noop: null, size: { set: ['Year', 'Country'] } }, - title: 'Stack Discs', - align: 'center' + title: 'Stack Discs' } }), diff --git a/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/08_d-w_cir_V1_2c.mjs b/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/08_d-w_cir_V1_2c.mjs index 431819f10..285d75774 100755 --- a/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/08_d-w_cir_V1_2c.mjs +++ b/test/e2e/test_cases/ww_noFade/wNoFade_cases/2_des_pol-without/circle_V1/08_d-w_cir_V1_2c.mjs @@ -42,8 +42,7 @@ const testSteps = [ noop: null, size: { set: ['Year', 'Country'] } }, - title: 'Stack Discs', - align: 'center' + title: 'Stack Discs' } }), diff --git a/test/e2e/tests/features.json b/test/e2e/tests/features.json index db6d13e54..1d8ec5d1a 100644 --- a/test/e2e/tests/features.json +++ b/test/e2e/tests/features.json @@ -11,7 +11,7 @@ "refs": ["ffc403c"] }, "data_input/object_records": { - "refs": ["ba17dad"] + "refs": ["7c8b0bb"] }, "events/drawing_events": { "refs": ["6496e1d"] @@ -26,7 +26,7 @@ "refs": ["b6c8e6a"] }, "presets": { - "refs": ["84541ff"] + "refs": ["d530bbd"] }, "detach": { "refs": ["e3b0c44"] diff --git a/test/e2e/tests/fixes.json b/test/e2e/tests/fixes.json index b81cd75fe..fc7c76252 100644 --- a/test/e2e/tests/fixes.json +++ b/test/e2e/tests/fixes.json @@ -7,6 +7,9 @@ "91": { "refs": ["1732a49"] }, + "143": { + "refs": ["fb8a740"] + }, "144": { "refs": ["fde02e4"] }, @@ -16,11 +19,14 @@ "163": { "refs": ["a82431f"] }, + "252": { + "refs": ["00f01d9"] + }, "320": { "refs": ["e4b8a2f"] }, "327": { - "refs": ["47ed740"] + "refs": ["8eb7c5d"] }, "333": { "refs": ["6a5536c"] @@ -32,7 +38,7 @@ "refs": ["1467e41"] }, "536": { - "refs": ["1eb5a0b"] + "refs": ["5b502cd"] }, "540": { "refs": ["13feb5d"] diff --git a/test/e2e/tests/fixes/143.mjs b/test/e2e/tests/fixes/143.mjs new file mode 100644 index 000000000..db662e8ba --- /dev/null +++ b/test/e2e/tests/fixes/143.mjs @@ -0,0 +1,42 @@ +const testSteps = [ + (chart) => { + const data = { + series: [ + { + name: 'Colors', + type: 'dimension', + values: ['red', 'green', 'blue', 'red', 'green', 'blue', 'red', 'green', 'blue'] + }, + { + name: 'Letters', + type: 'dimension', + values: ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'] + }, + { + name: 'Val', + type: 'measure', + values: [3, 5, 4, 3 + 1, 5 + 1, 4 + 1, 3 + 2, 5 + 2, 4 + 2] + } + ] + } + + return chart.animate({ + data, + config: { + y: 'Colors', + x: 'Val' + } + }) + }, + (chart) => + chart.animate( + { + y: 'Val', + x: 'Letters', + split: true + }, + { regroupStrategy: 'drilldown' } + ) +] + +export default testSteps diff --git a/test/e2e/tests/fixes/252.mjs b/test/e2e/tests/fixes/252.mjs new file mode 100644 index 000000000..41ec5d116 --- /dev/null +++ b/test/e2e/tests/fixes/252.mjs @@ -0,0 +1,102 @@ +function time(y, m, d) { + return y + (m - 1) / 12 + (d - 1) / 31 / 12 +} + +const testSteps = [ + (chart) => + chart.animate({ + data: { + series: [ + { + name: 'Name', + type: 'dimension', + values: [ + 'Apple Pie', + 'Banana Bread', + 'Cupcake', + 'Donut', + 'Eclair', + 'Froyo', + 'Gingerbread', + 'Honeycomb', + 'Ice Cream Sandwich', + 'Jelly Bean', + 'KitKat', + 'Lollipop', + 'Marshmallow', + 'Nougat', + 'Orea' + ] + }, + { + name: 'Time', + type: 'measure', + values: [ + time(2008, 9, 23), + time(2009, 4, 9), + time(2009, 4, 27), + time(2009, 9, 15), + time(2009, 10, 26), + time(2010, 4, 29), + time(2010, 12, 6), + time(2011, 2, 22), + time(2011, 10, 12), + time(2012, 4, 12), + time(2013, 10, 31), + time(2014, 11, 3), + time(2015, 10, 5), + time(2016, 8, 22), + time(2017, 8, 21) + ] + }, + { + name: 'Placement', + type: 'measure', + values: [1, -1, 1.5, -1.5, 1, -2, 1.5, -1.5, 1, -1, 1, -1, 1, -1, 1] + } + ] + } + }), + (chart) => + chart.animate({ + config: { + x: { + set: 'Time', + range: { min: 2008.5, max: 2018.1 }, + step: 1, + ticks: true, + title: null + }, + y: { + set: 'Placement', + interlacing: false, + labels: false, + markerGuides: false, + title: null + }, + label: 'Name', + geometry: 'circle' + }, + style: { + plot: { + xAxis: { + label: { + numberFormat: 'none', + position: 'axis' + } + }, + marker: { + guides: { + color: '#666666' + } + } + } + } + }), + (chart) => + chart.animate({ + x: { step: 2 } + }) +] + +export default testSteps diff --git a/test/e2e/tests/style_tests.json b/test/e2e/tests/style_tests.json index 15b2111aa..ab70e60d8 100644 --- a/test/e2e/tests/style_tests.json +++ b/test/e2e/tests/style_tests.json @@ -1013,7 +1013,7 @@ "refs": ["9edbce5"] }, "legend/offsetY": { - "refs": ["b326287"] + "refs": ["e065914"] } } } diff --git a/tools/ci/gcp/cloudbuild/cloudbuild.yaml b/tools/ci/gcp/cloudbuild/cloudbuild.yaml index bee298903..ab967791e 100644 --- a/tools/ci/gcp/cloudbuild/cloudbuild.yaml +++ b/tools/ci/gcp/cloudbuild/cloudbuild.yaml @@ -3,15 +3,15 @@ steps: id: pull_wasm waitFor: - '-' - args: ['pull', 'vizzu/vizzu-dev-wasm:0.12'] + args: ['pull', 'vizzu/vizzu-dev-wasm:0.14'] - name: 'gcr.io/cloud-builders/docker' id: pull_desktop waitFor: - '-' - args: ['pull', 'vizzu/vizzu-dev-desktop:0.12'] + args: ['pull', 'vizzu/vizzu-dev-desktop:0.14'] - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: init waitFor: - pull_wasm @@ -24,7 +24,7 @@ steps: ./tools/ci/run/init-py.sh dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: check_src waitFor: - init @@ -41,7 +41,7 @@ steps: npm run lint:src fi dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: check_docs waitFor: - init @@ -58,7 +58,7 @@ steps: npm run lint:docs fi dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: check_tools waitFor: - init @@ -77,7 +77,7 @@ steps: fi dir: /workspace - - name: vizzu/vizzu-dev-desktop:0.12 + - name: vizzu/vizzu-dev-desktop:0.14 id: build_desktop_clangformat waitFor: - pull_desktop @@ -97,7 +97,7 @@ steps: fi dir: /workspace - - name: vizzu/vizzu-dev-desktop:0.12 + - name: vizzu/vizzu-dev-desktop:0.14 id: build_desktop_clangtidy waitFor: - build_desktop_clangformat @@ -113,7 +113,7 @@ steps: ./tools/ci/run/pkg-build-desktop-clangtidy.sh fi dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: build_wasm waitFor: - build_desktop_clangformat @@ -134,7 +134,7 @@ steps: ./tools/ci/run/pkg-build-js.sh dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: lib_sha waitFor: - build_wasm @@ -157,7 +157,7 @@ steps: fi dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: test waitFor: - lib_sha @@ -172,7 +172,7 @@ steps: fi dir: /workspace - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: docs waitFor: - test @@ -215,7 +215,7 @@ steps: - VIZZUHQ_GITHUB_USER - VIZZUHQ_GITHUB_EMAIL - - name: vizzu/vizzu-dev-wasm:0.12 + - name: vizzu/vizzu-dev-wasm:0.14 id: publish waitFor: - docs