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

Range slider second iteration (part 1) #962

Merged
merged 14 commits into from
Oct 6, 2016
Merged

Range slider second iteration (part 1) #962

merged 14 commits into from
Oct 6, 2016

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Sep 21, 2016

fixes #686

In this first instalment of the range slider second iteration push:

  • the draw routine has been rewritten using d3 enter/exit/update
    • so creation / deletion / update are governed by the same code paths!
    • this make the setRangeSliderRange relayout hook obsolete. The range slider simply updates according to the current xaxis.range and xaxis.rangeslider.range
  • the mousedown handler now creates a cover slip to avoid selecting text (e.g. axis labels) while dragging
  • range sliders now span the correct axis width (using xaxis.domain)
  • range sliders stay coherent after relayout calls!
  • all features coming from Feature range slider #336 / Rangeslider data conversion #441 and /Initial rangeslider ranges #473 are intact (I think)

@mdtusz

- so that computed rangeslider range can be copied
  into input container, ensuring that the autorange routine
  isn't called on updates.
- use d3 enter/exit/update pattern to handle drawing step
  for creation / deletion and update paths
  -> no longer need a relayout hook !!!
- fix: range slider span depends on axis range
- fix: range slider option now update on relayout
- use coverslip to avoid select axis title
- with proper class name and full 'translate' values
@etpinard etpinard added bug something broken type: maintenance labels Sep 21, 2016
@etpinard etpinard added this to the v1.18.0 milestone Sep 21, 2016
minVal = opts.d2p(axisOpts.range[0]),
maxVal = opts.d2p(axisOpts.range[1]);

var dragCover = dragElement.coverSlip();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: I didn't use the full dragElement routine because it slowed down the requestAnimationFrame calls considerably.


var rangeSliders = fullLayout._infolayer
.selectAll('g.' + constants.containerClassName)
.data(rangeSliderData, keyFunction);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As before, there can only be one range slider on a graph at once.

But, the drawing code is now general enough that adding multiple range sliders as a feature would be pretty easy.

}

function drawRangePlot(rangeSlider, gd, axisOpts, opts) {
var rangePlots = rangePlot(gd, opts._width, opts._height);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mdtusz 's rangePlot wrapper is (still) is use here.

After #946, I hope to make obsolete.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Commits in https://github.com/plotly/plotly.js/compare/range-slider-range-plot indeed make the current rangePlot() obsolete. Those commits deserve a PR of their own - coming after this PR is merged.

Copy link
Contributor

@mdtusz mdtusz left a comment

Choose a reason for hiding this comment

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

I guess there's still not quite enough tolerance in those tests still for CI :/

Looks great though! Will hopefully make refactoring more to allow for vertical and multiple sliders much easier.

💃 once addressing the one comment, and tests ✅

@@ -48,4 +52,7 @@ module.exports = function handleDefaults(layoutIn, layoutOut, axName, counterAxe
layoutOut[ax] = opposing;
});
}

// to map back range slider (auto) range
containerOut._input = containerIn;
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to delete containerIn._input before this to avoid a loop?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

what kind of loop are you referring to here?

Copy link
Contributor

Choose a reason for hiding this comment

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

containerOut._input = { 
  /* the containerIn */, 
  _input: { 
    /* the previous containerIn */, 
    _input: { 
      /* the previous conta...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_input is always linked to the layout as passed to Plotly.plot(gd, data, layout) - which doesn't know anything about containerOut.

.call(drawRangePlot, gd, axisOpts, opts)
.call(drawMasks, gd, axisOpts, opts)
.call(drawSlideBox, gd, axisOpts, opts)
.call(drawGrabbers, gd, axisOpts, opts);
Copy link
Contributor

Choose a reason for hiding this comment

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

My favourite method name.

var dataMin = clamp(opts.p2d(opts._pixelMin)),
dataMax = clamp(opts.p2d(opts._pixelMax));

window.requestAnimationFrame(function() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sure it's valid, but I'm curious what effect requestAnimationFrame has here. I'm not sure I've ever really used it without calling is pseudo-recursively. Is the goal to get it bumped down in priority below user interactions so that relayout doesn't block the UI?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yep. It has a similar effect to setTimeout(something, 0)

Copy link
Contributor

Choose a reason for hiding this comment

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

Cool. I hadn't noticed it affecting interactions that way, but I believe it. I'm usually after the pause-while-backgrounded nature of the calls.


toBeWithin: function() {
return {
compare: function(actual, expected, tolerance, msgExtra) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ping @rreusser @monfera for future test cases

Copy link
Contributor

Choose a reason for hiding this comment

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

Nice. I found toBeCloseTo a bit unpleasant in the way it uses digits of precision instead of just a tolerance.

@mdtusz
Copy link
Contributor

mdtusz commented Oct 6, 2016

Lookin gooood.

💃

@etpinard etpinard merged commit bedb673 into master Oct 6, 2016
@etpinard etpinard deleted the range-slider-v2 branch October 6, 2016 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

Successfully merging this pull request may close these issues.

range slider width does not update on relayout
3 participants