Skip to content
This repository has been archived by the owner on Jun 3, 2024. It is now read-only.

Omit marks that are outside of range specified by min and max. #695

Merged
merged 27 commits into from
Nov 19, 2019

Conversation

shammamah-zz
Copy link
Contributor

Closes #517.

@shammamah-zz shammamah-zz marked this pull request as ready for review November 8, 2019 19:36
@shammamah-zz
Copy link
Contributor Author

@alexcjohnson Right now I'm just omitting all labels that fall outside of the range specified for the slider, but I also agree with this comment you made:

I feel like there's a use case for "here are all the possible labels" and sometimes restricting the range to a subset of that without needing to also filter the labels.

Do you feel it would be a good idea to include some new property to "disable" the options for the ones outside of a specific range (but still show them)?

@alexcjohnson
Copy link
Collaborator

Do you feel it would be a good idea to include some new property to "disable" the options for the ones outside of a specific range (but still show them)?

No, I think what you did here is exactly what we want, no new options needed 🎉

'setProps',
'marks',
'updatemode',
],
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not for now, but just because I'm thinking about it: I'd like us to consider moving away from omit for forwarding props to 3rd-party components, and use pick instead. IMO omit makes it too hard to follow which props are being passed on, too easy to forget to remove newly added props, and makes us lazy about accepting someone else's choice of names and values even if they don't make sense in our case. (cc @Marc-Andre-Rivet )

Copy link
Contributor

Choose a reason for hiding this comment

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

@alexcjohnson Agreed for DCC! There's also a bit of this happening in the table fragments / d3-format wrappers that should be looked into. Due to its generated nature I'd say whether this makes sense on HTML components would have to be evaluated independently. Can you open an issue for follow up and tag it for Dash v1.x milestone? Thanks.

@alexcjohnson
Copy link
Collaborator

Two more questions:

  • Slider too, in addition to RangeSlider?
  • Is there anything we can do about the labels overflowing the bounding box of the <div> we draw the slider in?

@shammamah-zz
Copy link
Contributor Author

shammamah-zz commented Nov 11, 2019

Slider too, in addition to RangeSlider?

Yes, this makes sense.

Is there anything we can do about the labels overflowing the bounding box of the <div> we draw the slider in?

I'll take a look at the CSS!

Shammamah Hossain added 4 commits November 11, 2019 16:33
With the new padding values, the '0' selection is no longer at the very edge of the container div.
@shammamah-zz
Copy link
Contributor Author

@alexcjohnson Made some changes to the padding and now it looks good!

Before:
Screen Shot 2019-11-12 at 2 32 49 PM

After:
Screen Shot 2019-11-12 at 2 32 57 PM

@shammamah-zz
Copy link
Contributor Author

Some other changes made (cc @wbrgss since this affects how the slider CSS looks -- would love any suggestions you have):

  • The slider would just have a height of 0px if vertical was set to True, unless a height was specified in a stylesheet. This has now changed, as I've added a verticalHeight prop that defaults to 400px. (This won't affect any existing apps, since this prop will be overridden by a custom stylesheet.)
  • Whitespace is now preserved in the mark text, to allow for users to enter line breaks in the labels if they start to overlap each other.
  • The padding is now optional and based on tooltips.
    • If the tooltip is always visible and on the top in a horizontal slider, the padding at the top is 25px; otherwise it is 0px.
    • If the tooltip is always visible and on the left in a vertical slider, the padding for the left side is 25px; otherwise it is 0px.
    • Padding for the bottom and the right are always 25px, since this is where the labels are.

@wbrgss
Copy link
Contributor

wbrgss commented Nov 14, 2019

@shammamah These look like good changes to me. In DDK, we're "documenting around" (private docs, see "dcc.Slider best practices" section) some of these issues, including vertical height:

  • When setting the marks parameter for a dcc.Slider, ensure that min <= marks[0] and max >= marks[-1] and that your range of marks matches the min/max range. Otherwise, your marks may overflow their container.
  • Make sure your marks are spaced correctly such that they don't overlap each other.
  • On vertical sliders (dcc.Slider(vertical=True, ...)), you will probably have to use the height parameter on your control to ensure your marks and labels have enough room. In other controls and components, the height parameter should usually be avoided...

I've added a verticalHeight prop that defaults to 400px

This seems like a good idea to me, and so does

Padding for the bottom and the right are always 25px, since this is where the labels are.

I think that will be adequate to prevent this situation:

image

@wbrgss
Copy link
Contributor

wbrgss commented Nov 14, 2019

@shammamah What about labels that overlap horizontally, because there are too many of them to fit?
image

If this PR doesn't handle it, handling this robustly, by e.g. staggering the labels, might be complicated so probably out of scope for this PR. But if you think it's a good idea I can make an issue for it. Maybe we should at least document it to warn people if they are making "responsive" sliders that might have squishy labels if their screen width is too small.

Whitespace is now preserved in the mark text, to allow for users to enter line breaks in the labels if they start to overlap each other.

Oh sorry, didn't see this. I think that's good for now 👍

(k, mark) => mark >= this.props.min && mark <= this.props.max,
this.props.marks
)
: this.props.marks;
Copy link
Contributor

Choose a reason for hiding this comment

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

A matter of personal preference, but you can also make this more compact with

const truncatedMarks = this.props.marks && pickBy(...);

JS does not return a boolean for &&, ||, etc. but rather the last evaluated value.

Comment on lines 73 to 97
if (
!vertical &&
(!tooltip ||
!tooltip.always_visible ||
!contains(tooltip.placement, ['top', 'topLeft', 'topRight']))
) {
style = merge(style, {paddingTop: '0px'});
}

if (
vertical &&
(!tooltip ||
!tooltip.always_visible ||
!contains(tooltip.placement, [
'left',
'topRight',
'bottomRight',
]))
) {
style = merge(style, {paddingLeft: '0px'});
}

if (vertical) {
style = merge(style, {height: verticalHeight + 'px'});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

  • Could be simplified with shared vertical/!vertical checks.
  • Minor point, could be memoized (style, vertical, tooltip) -> style to prevent style re-evaluation below


if (vertical) {
style = merge(style, {height: verticalHeight + 'px'});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above

};

if (vertical) {
style = merge(style, {height: verticalHeight + 'px'});
Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet Nov 19, 2019

Choose a reason for hiding this comment

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

non blocking -- style is created inside the function scope, it's fine to consider it as mutable inside the function - as long as it's treated as immutable once outside

Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet left a comment

Choose a reason for hiding this comment

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

💃 🎚

@shammamah-zz shammamah-zz merged commit b098058 into dev Nov 19, 2019
@shammamah-zz shammamah-zz deleted the 517-rangeslider-labels branch November 19, 2019 17:45
rpkyle pushed a commit that referenced this pull request Dec 12, 2019
* Omit marks that are outside of range specified by min and max.

* Handle case in which marks prop is not defined.

* Add test for out-of-range numbers.

* Use pickBy.

* Add mark at point below minimum value.

* Also omit out-of-range marks for slider.

* Add test for slider.

* Add padding to Slider and RangeSlider containers.

* Update test for persistence.

With the new padding values, the '0' selection is no longer at the very edge of the container div.

* Change test for always visible rangeslider.

* Only add top padding if there are always-visible tooltips on the top.

* Preserve whitespace in marks.

* Add optional verticalHeight prop for vertical sliders.

* Update slider stylesheet.

* Update coordinates to reflect new padding.

* Remove file.

* Use fixed-width slider for rangeslider test.

* Fix persistence test.

* Memoize computation of style and move function to utils.

* Simplify style code.

* Fix eslint errors.

* Modify style object directly.

* Update CHANGELOG.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

RangeSlider: out-of-range labels
4 participants