Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Slider and IntervalSlider for dragging logic #3231

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

jkrumbiegel
Copy link
Member

Description

Supersedes #2228

I thought about it some more and now settled on the idea that the user can use the dragging status to decide what they want to do with a changed slider value. This is a bit more flexible than having a second output observable, and allows further custom logic depending on the slider drag state change. This approach also showed some smaller problems with the implementation which I therefore refactored a bit.

Delete options that do not apply:

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist

  • Added an entry in NEWS.md (for new features and breaking changes)
  • Added or changed relevant sections in the documentation
  • Added unit tests for new algorithms, conversion methods, etc.
  • Added reference image tests for new plotting functions, recipes, visual options, etc.

@MakieBot
Copy link
Collaborator

MakieBot commented Sep 14, 2023

Compile Times benchmark

Note, that these numbers may fluctuate on the CI servers, so take them with a grain of salt. All benchmark results are based on the mean time and negative percent mean faster than the base branch. Note, that GLMakie + WGLMakie run on an emulated GPU, so the runtime benchmark is much slower. Results are from running:

using_time = @ctime using Backend
# Compile time
create_time = @ctime fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @ctime Makie.colorbuffer(display(fig))
# Runtime
create_time = @benchmark fig = scatter(1:4; color=1:4, colormap=:turbo, markersize=20, visible=true)
display_time = @benchmark Makie.colorbuffer(display(fig))
using create display create display
GLMakie 12.38s (12.01, 12.65) 0.23+- 1.19s (1.14, 1.29) 0.05+- 817.81ms (789.77, 874.22) 30.25+- 11.16ms (10.99, 11.57) 0.19+- 143.64ms (140.67, 145.13) 1.41+-
master 12.29s (12.09, 12.41) 0.10+- 1.17s (1.15, 1.20) 0.02+- 795.84ms (778.12, 818.95) 12.19+- 10.99ms (10.83, 11.12) 0.11+- 144.93ms (142.04, 152.25) 4.51+-
evaluation +0.72%, 0.09s invariant (0.51d, 0.37p, 0.16std) +1.00%, 0.01s invariant (0.29d, 0.60p, 0.04std) +2.69%, 21.97ms invariant (0.95d, 0.11p, 21.22std) +1.54%, 0.17ms invariant (1.11d, 0.07p, 0.15std) -0.89%, -1.29ms invariant (-0.38d, 0.49p, 2.96std)
CairoMakie 11.07s (10.81, 11.19) 0.13+- 1.15s (1.12, 1.17) 0.02+- 222.28ms (218.15, 226.91) 3.35+- 10.95ms (10.71, 11.15) 0.15+- 6.52ms (6.37, 6.65) 0.10+-
master 11.04s (10.92, 11.15) 0.09+- 1.16s (1.14, 1.17) 0.01+- 225.89ms (219.79, 230.78) 3.97+- 10.86ms (10.59, 11.06) 0.16+- 6.49ms (6.39, 6.59) 0.09+-
evaluation +0.28%, 0.03s invariant (0.28d, 0.61p, 0.11std) -0.40%, -0.0s invariant (-0.27d, 0.63p, 0.02std) -1.62%, -3.61ms invariant (-0.98d, 0.09p, 3.66std) +0.85%, 0.09ms invariant (0.60d, 0.28p, 0.15std) +0.48%, 0.03ms invariant (0.34d, 0.54p, 0.09std)
WGLMakie 15.37s (14.97, 16.03) 0.35+- 1.61s (1.43, 1.76) 0.10+- 14.92s (14.10, 16.21) 0.74+- 22.73ms (20.35, 28.49) 2.77+- 1.28s (1.15, 1.42) 0.10+-
master 15.27s (14.76, 16.08) 0.45+- 1.56s (1.48, 1.73) 0.08+- 14.31s (13.66, 15.54) 0.66+- 22.28ms (21.22, 24.26) 1.19+- 1.36s (1.24, 1.48) 0.08+-
evaluation +0.63%, 0.1s invariant (0.24d, 0.66p, 0.40std) +3.18%, 0.05s invariant (0.55d, 0.33p, 0.09std) +4.05%, 0.6s invariant (0.86d, 0.13p, 0.70std) +1.95%, 0.44ms invariant (0.21d, 0.71p, 1.98std) -5.84%, -0.07s noisy🤷‍♀️ (-0.82d, 0.15p, 0.09std)

@jkrumbiegel jkrumbiegel requested review from SimonDanisch and ffreyer and removed request for SimonDanisch September 16, 2023 11:34
Comment on lines 215 to +216
onmouseleftdoubleclick(mouseevents) do event
isl.dragging[] = false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes an update like this:

IntervalSlider drag true
IntervalSlider drag false
IntervalSlider interval (0.0, 10.0)

So if you react to dragging you won't catch the new interval here. It would be better if you did. Maybe in general the dragging = false update should happen after the interval update?

Comment on lines 191 to +192
sliderfractions[] = sliderfractions[]
notify(isl.selected_indices)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just duplicates updates

IntervalSlider interval (1.18, 10.0)
IntervalSlider indices (119, 1001)
IntervalSlider drag false
IntervalSlider interval (1.18, 10.0)
IntervalSlider indices (119, 1001)

so I think we should just skip the notify here.

Comment on lines +209 to 213
onmouseleftclick(mouseevents) do event
isl.dragging[] = false
notify(isl.selected_indices)
return Consume(true)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clicks also trigger a drag start so you end up with a duplicate update here too:

IntervalSlider drag true
IntervalSlider interval (0.43, 10.0)
IntervalSlider indices (44, 1001)
[ Info: click start
IntervalSlider drag false
IntervalSlider interval (0.43, 10.0)
IntervalSlider indices (44, 1001)
[ Info: click end

There is an exception to this her though: If you do not move the slider through a click you do not get an interval update through the drag start. So then you only get the click update, which however does not change the values. I'm not sure if that's an update worth pushing out.

Comment on lines 116 to 138
onmouseleftdragstop(mouseevents) do event
dragging[] = false
sl.dragging[] = false
# adjust slider to closest legal value
sliderfraction[] = sliderfraction[]
fraction = get_fraction(event)
newindex = closest_fractionindex(sliderrange[], fraction)
selected_index[] = newindex

linecolors[] = [sl.color_active_dimmed[], sl.color_inactive[]]
return Consume(true)
end

onmouseleftclick(mouseevents) do event
sl.dragging[] = false
# adjust slider to closest legal value
sliderfraction[] = sliderfraction[]
fraction = get_fraction(event)
newindex = closest_fractionindex(sliderrange[], fraction)
selected_index[] = newindex

linecolors[] = [sl.color_active_dimmed[], sl.color_inactive[]]
return Consume(true)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the same update duplication as IntervalSlider

Comment on lines 154 to 158
onmouseleftdoubleclick(mouseevents) do event
sl.dragging[] = false
selected_index[] = closest_index(sliderrange[], sl.startvalue[])
return Consume(true)
end
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same update order problem as IntervalSlider

@Sagnac
Copy link
Contributor

Sagnac commented Oct 24, 2024

@jkrumbiegel I've tried this specific slider dragging feature in a dev build before and found that it works quite well in its current state. Is there still a plan to continue working on this and eventually merge it or has it been abandoned?

@jkrumbiegel
Copy link
Member Author

I never took the time to follow up on @ffreyer's review comments, but in principle I'd still like to get equivalent changes in.

@maxfreu
Copy link

maxfreu commented Nov 5, 2024

Hi! Thanks for your efforts already! I just wanted to express interest in this; it would be really cool to have for uses when you don't want to trigger countless calls of a long-running function as you drag. In my use case I'd use the slider to flip through satellite images taken at different times and only want to read the target images from disk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants