diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e26aa3f..38e2efbb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Support `Waterfall` plot type [#583](https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/583). + ## v0.8.13 - 2024-10-21 - Added aesthetics for `Stairs` [#573](https://github.com/MakieOrg/AlgebraOfGraphics.jl/pull/573). @@ -120,4 +122,4 @@ - **Breaking**: Analyses now require parentheses (i.e. `linear()` instead of `linear`). - **Breaking**: Rename `layout_x` and `layout_y` to `col` and `row`. - **Breaking**: Rename `wts` keyword argument to `weights`. -- **Breaking**: `categorical` has been replaced by `nonnumeric`. \ No newline at end of file +- **Breaking**: `categorical` has been replaced by `nonnumeric`. diff --git a/src/aesthetics.jl b/src/aesthetics.jl index 8a2f69707..f8e88c7b5 100644 --- a/src/aesthetics.jl +++ b/src/aesthetics.jl @@ -118,6 +118,23 @@ function aesthetic_mapping(::Type{BarPlot}, N::Int) ]) end +aesthetic_mapping(::Type{Waterfall}, ::Normal) = aesthetic_mapping(Waterfall, 1) +aesthetic_mapping(::Type{Waterfall}, ::Normal, ::Normal) = aesthetic_mapping(Waterfall, 2) +function aesthetic_mapping(::Type{Waterfall}, N::Int) + @assert 1 <= N <= 2 + positionals = if N == 1 + [1 => AesY] + elseif N == 2 + [1 => AesX, 2 => AesY] + end + dictionary([ + positionals..., + :color => AesColor, + :width => AesDeltaX, + :dodge => AesDodgeX, + ]) +end + function aesthetic_mapping(::Type{Violin}, ::Normal, ::Normal) dictionary([ 1 => :orientation => dictionary([ @@ -461,4 +478,4 @@ function aesthetic_mapping(::Type{Stairs}, N::Int) :color => AesColor, :linestyle => AesLineStyle, ]) -end \ No newline at end of file +end diff --git a/src/guides/legend.jl b/src/guides/legend.jl index 9f1929a17..4ffb3733a 100644 --- a/src/guides/legend.jl +++ b/src/guides/legend.jl @@ -372,6 +372,12 @@ function legend_elements(T::Type{<:Union{BarPlot,Violin,BoxPlot,Choropleth,Poly, )] end +function legend_elements(T::Type{Waterfall}, attributes, scale_args::MixedArguments) + [PolyElement( + color = _get(T, scale_args, attributes, :color), + )] +end + function legend_elements(T::Type{RainClouds}, attributes, scale_args::MixedArguments) [PolyElement( color = _get(T, scale_args, attributes, :color), diff --git a/test/reference_tests.jl b/test/reference_tests.jl index 994fae500..5c24347ac 100644 --- a/test/reference_tests.jl +++ b/test/reference_tests.jl @@ -1018,3 +1018,17 @@ reftest("stairs") do visual(Stairs) draw(spec) end + +reftest("waterfall") do + df = ( + x=repeat(1:2, inner=5), + y=[6, 4, 2, -8, 3, 5, 1, -2, -3, 7], + group=repeat('A':'E', outer=2), + ) + f = Figure() + fg = draw!(f[1, 1], data(df) * visual(Waterfall, show_final=true) * mapping(:x, :y, color=:group, dodge=:group)) + legend!(f[1, 2], fg) + draw!(f[2, 1:2], data(df) * visual(Waterfall, show_direction=true) * mapping(:y)) + f +end + diff --git a/test/reference_tests/waterfall ref.png b/test/reference_tests/waterfall ref.png new file mode 100644 index 000000000..a9939d0df Binary files /dev/null and b/test/reference_tests/waterfall ref.png differ