-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
scrollable dropdown menus #1214
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
scrollable dropdown menus #1214
Conversation
* Don't `Lib.setTranslate` the button container and update the call to `Lib.setTranslate` for each button accordingly. * This change will let us use `Lib.setTranslate` on the button container to implement a scroll box.
Some suggestions:
|
hbarL = boxL, | ||
hbarT = (boxB + hbarH < fullHeight) ? boxB : fullHeight - hbarH; | ||
|
||
var hbar = this.container.selectAll('rect.scrollbar-horizontal').data( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this ever going to be implemented?
We made the decision to not allow horizontal scrolling legends. I doubt that dropdown buttons should scroll horizontally in any scenario.
I'd say we can get away with 🔪 this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we cut horizontal scrollbars, dropdown menus with direction: 'left' | 'right'
will be limited to fit within the plot area.
For legends, we could make Scrollbox provide the option to disable the horizontal scrollbar.
@n-riesco are you available to finish off #1214 (comment) in the short term? |
* Reduce scroll box minimum size from 44 to 25 pixels. * Allow scroll boxes to use the full width and height.
* Do not assume that only one of the scrollbars is present.
@n-riesco Looking good. This will make a bunch of users happy 🎉 I'm wondering if you noticed that menus that have a scrollbox are a little jumpy on click: I can help you debug this tomorrow if you like. |
* Changed `ScrollBox#setTranslate(translateX, translateY)` to take pixels. * Previously, invoking `ScrollBox#setTranslate(xf, yf)` would require to access `ScrollBox#_box` to compute `xf` and `yf`. * Now, it's possible to drag the buttons in the scrollbox beyond the scrollbox.
src/components/updatemenus/draw.js
Outdated
if(scrollBox._vbar) { | ||
var translateY = 0; | ||
for(i = 0; i < active; i++) { | ||
translateY += menuOpts.heights[i] + constants.gapButton; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks off for direction: 'up'
when the updatemenu y
isn't the default value:
var direction = 'up',
data = [],
layout = {
updatemenus: [{
y: 0,
direction: direction,
buttons: []
}]
};
for (var i = 0, n = 20; i < n; i++) {
data.push({
y: Array.apply(null, Array(10)).map(() => Math.random()),
line: {
shape: 'spline',
color: 'red'
},
visible: i === 0,
name: 'Data set ' + i,
});
var visible = Array.apply(null, Array(n)).map((_, j) => i === j);
layout.updatemenus[0].buttons.push({
method: 'restyle',
args: ['visible', visible],
label: 'Data set ' + i
});
}
Plotly.plot('graph', data, layout);
gives (after clicking on the header)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh! The position of the scrollbox is wrong! This happens in the up
direction, when the scrollbox doesn't fit within the chart height. Something similar may happen in the left
direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one hasn't been addressed yet, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking great now!
|
||
vbar.enter().append('rect') | ||
.classed('scrollbar-vertical', true) | ||
.call(Color.fill, ScrollBox.barColor); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be ok to chain
.attr('opacity', '0')
.transition()
.attr('opacity', '1')
here and for hbar
to make the scroll bar appear at the same time as the buttons?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working great now 👍
* | ||
* @method | ||
*/ | ||
ScrollBox.prototype.disable = function disable() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like 9e3ac1b made this method obsolete 🔪
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment ⬆️ is now obsolete
@@ -246,6 +246,8 @@ ScrollBox.prototype.enable = function enable() { | |||
.on('.drag', null) | |||
.call(onBarDrag); | |||
} | |||
|
|||
this.container.on('wheel', this._onBoxWheel.bind(this)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, the wheel handler isn't called when one tries to scroll with the cursor over the gap between the buttons (you can try increasing the gapButton
constant to make this problem easier to detect).
I think the easiest solution would be to make Scrollbox
add a background <rect>
as big as the clipped <rect>
in the container and attach the wheel
handler on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Working like a charm now. Thanks!
src/components/updatemenus/draw.js
Outdated
@@ -253,11 +254,19 @@ function drawButtons(gd, gHeader, gButton, menuOpts) { | |||
|
|||
exit.transition() | |||
.attr('opacity', '0') | |||
.remove(); | |||
.remove() | |||
.each('end', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good now 👍
src/components/updatemenus/draw.js
Outdated
var fullLayout = gd._fullLayout, | ||
scrollBoxId = 'updatemenus' + fullLayout._uid + menuOpts._index, | ||
scrollBoxPosition = { | ||
l: menuOpts.lx + menuOpts.borderwidth + x0 + menuOpts.pad.l, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job taking into account borderwidth
🎉
* Previously, the scrollbox was created every time the dropmenu was unfolded. * Now, the scrollbox is created right after creating the dropdown container. * Moved the logic to fold and unfold the dropdown menu to functions foldDropdownMenu and unfoldDropdownMenu. * Moved all the logic to compute the position and size of the scrollbox to function unfoldDropdownMenu. * Moved logic to disable the scrollbox to function foldDropdownMenu. * This refactor will help introduce a background <rect> element in the dropdown container before any dropdown buttons. * It will also help introduce a transition to show and hide the scrollbars.
* Added a <rect> background to the scrollbox, so that events on the gaps between buttons aren't dropped.
* Fixes issues caused by the relayout tests, where `updatemenus[1]` ended up without a buttons field. * A transition has been added to show and hide the scroll bars.
* Ensure scrollbox size is recomputed every time, drawButtons is called.
* Account for the direction of the scrollbox to determine to which side the scrollbox will be anchored.
Great @n-riesco looks like all the functionality is 👌 Ping me once you fixed the merge conflict and are happy with your test cases. Awesome work 👍 |
* Fixed regexp in Lib.getTranslate to accept negative values.
* Conflicts: src/components/updatemenus/draw.js src/components/updatemenus/scrollbox.js src/lib/index.js test/jasmine/tests/cartesian_test.js test/jasmine/tests/updatemenus_test.js
@etpinard Ready for review! This PR also fixes |
@@ -800,3 +801,406 @@ describe('update menus interaction with other components:', function() { | |||
.then(done); | |||
}); | |||
}); | |||
|
|||
|
|||
describe('update menus interaction with scrollbox:', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💯 / 💯 tests. Thanks!
src/lib/index.js
Outdated
@@ -453,7 +453,7 @@ lib.addStyleRule = function(selector, styleString) { | |||
|
|||
lib.getTranslate = function(element) { | |||
|
|||
var re = /.*\btranslate\((\d*\.?\d*)[^\d]*(\d*\.?\d*)[^\d].*/, | |||
var re = /.*\btranslate\((-?\d*\.?\d*)[^-\d]*(-?\d*\.?\d*)[^\d].*/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch 🔬
Would you mind adding a test case in drawing_test.js
to 🔒 this down?
(No rush on this by the way. If you don't have the time to do this by Monday night, I'll merge your PR as is and open up an issue about this).
#1214 (comment) is non-blocking. This PR will be merged and released as part of |
Merging. Thanks @n-riesco 🎉 |
Will this work for Ropensci/plotly automatically? |
This PR addresses one of the points in #810 :
provides a helper class ScrollBox (that could be reused to provide scroll boxes elsewhere)
implements scrollable dropdown menus:
dragend
)TODO
EXAMPLE
Here's an example to test the functionality: