Skip to content
This repository has been archived by the owner on Jul 13, 2021. It is now read-only.

Commit

Permalink
add IntervalSlider (#675)
Browse files Browse the repository at this point in the history
* add basic rangeslider

* add snap

* add center shift to rangeslider

* fix crossover logic

* make sliderrange dynamically changeable

* fix dynamic sliderrange

* comment

* rename to intervalslider

* fix duplicated functions

* return real values from `set_close_to!`

* update docs

* update docs

* add intervalslider page

* add IntervalSlider to basic MakieLayout test

* resolution fixed
  • Loading branch information
jkrumbiegel authored Mar 27, 2021
1 parent fb04c2a commit 5573064
Show file tree
Hide file tree
Showing 9 changed files with 423 additions and 23 deletions.
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ makedocs(
"makielayout/button.md",
"makielayout/colorbar.md",
"makielayout/gridlayout.md",
"makielayout/intervalslider.md",
"makielayout/label.md",
"makielayout/legend.md",
"makielayout/lscene.md",
Expand Down
52 changes: 52 additions & 0 deletions docs/src/makielayout/intervalslider.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# IntervalSlider

The interval slider selects an interval (low, high) from the supplied attribute `range`.
The (approximate) start values can be set with `startvalues`.

The currently selected interval is in the attribute `interval` and is a Tuple of `(low, high)`.
Don't change this value manually, but use the function `set_close_to!(intslider, v1, v2)`.
This is necessary to ensure the values are actually present in the `range` attribute.

You can click anywhere outside of the currently selected range and the closer interval edge will jump to the point.
You can then drag the edge around.
When hovering over the slider, the larger button indicates the edge that will react.

If the mouse hovers over the central area of the interval and both buttons are enlarged, clicking and dragging shifts the interval around as a whole.

You can double-click the slider to reset it to the values present in `startvalues`.
If `startvalues === AbstractPlotting.automatic`, the full interval will be selected (this is the default).

If you set the attribute `snap = false`, the slider will move continously while dragging and only jump to the closest available values when releasing the mouse.


```@example
using CairoMakie
AbstractPlotting.inline!(true) # hide
CairoMakie.activate!() # hide
f = Figure(resolution = (800, 800))
Axis(f[1, 1], limits = (0, 1, 0, 1))
rs_h = IntervalSlider(f[2, 1], range = LinRange(0, 1, 1000),
startvalues = (0.2, 0.8))
rs_v = IntervalSlider(f[1, 2], range = LinRange(0, 1, 1000),
startvalues = (0.4, 0.9), horizontal = false)
Label(f[3, 1], @lift(string(round.($(rs_h.interval), digits = 2))),
tellwidth = false)
Label(f[1, 3], @lift(string(round.($(rs_v.interval), digits = 2))),
tellheight = false, rotation = pi/2)
points = rand(Point2f0, 300)
# color points differently if they are within the two intervals
colors = lift(rs_h.interval, rs_v.interval) do h_int, v_int
map(points) do p
(h_int[1] < p[1] < h_int[2]) && (v_int[1] < p[2] < v_int[2])
end
end
scatter!(points, color = colors, colormap = [:black, :orange], strokewidth = 0)
f
```
18 changes: 11 additions & 7 deletions docs/src/makielayout/slider.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ CairoMakie.activate!()

A simple slider without a label. You can create a label using a `Label` object,
for example. You need to specify a range that constrains the slider's possible values.
You can then lift the `value` observable to make interactive plots.

The currently selected value is in the attribute `value`.
Don't change this value manually, but use the function `set_close_to!(slider, value)`.
This is necessary to ensure the value is actually present in the `range` attribute.

You can double-click the slider to reset it (approximately) to the value present in `startvalue`.

If you set the attribute `snap = false`, the slider will move continously while dragging and only jump to the closest available value when releasing the mouse.


```@example
using CairoMakie
Expand All @@ -30,6 +38,8 @@ limits!(ax, 0, 10, 0, 10)
fig
```

## Labelled slider convenience functions

To create a horizontal layout containing a label, a slider, and a value label, use the convenience function [`AbstractPlotting.MakieLayout.labelslider!`](@ref), or, if you need multiple aligned rows of sliders, use [`AbstractPlotting.MakieLayout.labelslidergrid!`](@ref).

```@example
Expand Down Expand Up @@ -62,9 +72,3 @@ set_close_to!(lsgrid.sliders[3], 15.9)
fig
```

If you want to programmatically move the slider, use the function [`AbstractPlotting.MakieLayout.set_close_to!`](@ref).
Don't manipulate the `value` attribute directly, as there is no guarantee that
this value exists in the range underlying the slider, and the slider's displayed value would
not change anyway by changing the slider's output.

2 changes: 2 additions & 0 deletions src/makielayout/MakieLayout.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ include("layoutables/axis.jl")
include("layoutables/colorbar.jl")
include("layoutables/label.jl")
include("layoutables/slider.jl")
include("layoutables/intervalslider.jl")
include("layoutables/button.jl")
include("layoutables/box.jl")
include("layoutables/toggle.jl")
Expand All @@ -66,6 +67,7 @@ include("layoutables/textbox.jl")

export Axis
export Slider
export IntervalSlider
export Button
export Colorbar
export Label
Expand Down
55 changes: 53 additions & 2 deletions src/makielayout/defaultattributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -577,14 +577,14 @@ function default_attributes(::Type{Slider}, scene)
"The height setting of the slider."
height = Auto()
"The range of values that the slider can pick from."
range = 0:10
range = 0:0.01:10
"Controls if the parent layout can adjust to this element's width"
tellwidth = true
"Controls if the parent layout can adjust to this element's height"
tellheight = true
"The start value of the slider or the value that is closest in the slider range."
startvalue = 0
"The current value of the slider."
"The current value of the slider. Don't set this manually, use the function `set_close_to!`."
value = 0
"The width of the slider line"
linewidth = 15
Expand All @@ -598,6 +598,8 @@ function default_attributes(::Type{Slider}, scene)
horizontal = true
"The align mode of the slider in its parent GridLayout."
alignmode = Inside()
"Controls if the button snaps to valid positions or moves freely"
snap = true
end
(attributes = attrs, documentation = docdict, defaults = defaultdict)
end
Expand All @@ -612,6 +614,55 @@ end)
"""
Slider

function default_attributes(::Type{IntervalSlider}, scene)
attrs, docdict, defaultdict = @documented_attributes begin
"The horizontal alignment of the slider in its suggested bounding box."
halign = :center
"The vertical alignment of the slider in its suggested bounding box."
valign = :center
"The width setting of the slider."
width = Auto()
"The height setting of the slider."
height = Auto()
"The range of values that the slider can pick from."
range = 0:0.01:10
"Controls if the parent layout can adjust to this element's width"
tellwidth = true
"Controls if the parent layout can adjust to this element's height"
tellheight = true
"The start values of the slider or the values that are closest in the slider range."
startvalues = AbstractPlotting.automatic
"The current interval of the slider. Don't set this manually, use the function `set_close_to!`."
interval = (0, 0)
"The width of the slider line"
linewidth = 15
"The color of the slider when the mouse hovers over it."
color_active_dimmed = COLOR_ACCENT_DIMMED[]
"The color of the slider when the mouse clicks and drags the slider."
color_active = COLOR_ACCENT[]
"The color of the slider when it is not interacted with."
color_inactive = RGBf0(0.94, 0.94, 0.94)
"Controls if the slider has a horizontal orientation or not."
horizontal = true
"The align mode of the slider in its parent GridLayout."
alignmode = Inside()
"Controls if the buttons snap to valid positions or move freely"
snap = true
end
(attributes = attrs, documentation = docdict, defaults = defaultdict)
end

@doc """
IntervalSlider has the following attributes:
$(let
_, docs, defaults = default_attributes(IntervalSlider, nothing)
docvarstring(docs, defaults)
end)
"""
IntervalSlider


function default_attributes(::Type{Toggle}, scene)
attrs, docdict, defaultdict = @documented_attributes begin
"The horizontal alignment of the toggle in its suggested bounding box."
Expand Down
Loading

0 comments on commit 5573064

Please sign in to comment.