Skip to content

Commit d25d261

Browse files
committed
tweak the parcoords constraint grabber ranges
and clean up remaining brush/brush2 cruft
1 parent 7f507c3 commit d25d261

File tree

1 file changed

+27
-49
lines changed

1 file changed

+27
-49
lines changed

src/traces/parcoords/axisbrush.js

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,26 @@ function differentInterval(int1) {
133133
};
134134
}
135135

136+
// is the cursor over the north, middle, or south of a bar?
137+
// the end handles extend over the last 10% of the bar
136138
function north(fPix, y) {
137-
return fPix[1] <= y && y <= fPix[1] + c.bar.handleHeight;
139+
return north90(fPix) <= y && y <= fPix[1] + c.bar.handleHeight;
138140
}
139141

140142
function south(fPix, y) {
141-
return fPix[0] - c.bar.handleHeight <= y && y <= fPix[0];
143+
return fPix[0] - c.bar.handleHeight <= y && y <= south90(fPix);
142144
}
143145

144146
function middle(fPix, y) {
145-
return fPix[0] < y && y < fPix[1];
147+
return south90(fPix) < y && y < north90(fPix);
148+
}
149+
150+
function north90(fPix) {
151+
return 0.9 * fPix[1] + 0.1 * fPix[0];
152+
}
153+
154+
function south90(fPix) {
155+
return 0.9 * fPix[0] + 0.1 * fPix[1];
146156
}
147157

148158
function clearCursor() {
@@ -220,7 +230,7 @@ function attachDragBehavior(selection) {
220230
if(d.parent.inBrushDrag) {
221231
return;
222232
}
223-
var y = d.unitScaleInOrder(d.unitScale.invert(d3.mouse(this)[1]));
233+
var y = d.unitScaleInOrder(d.unitScale.invert(d3.mouse(this)[1] + c.verticalPadding));
224234
var interval = getInterval(b, d.unitScaleInOrder, y);
225235
d3.select(document.body)
226236
.style('cursor', interval.n ? 'n-resize' : interval.s ? 's-resize' : !interval.m ? 'crosshair' : filterActive(b) ? 'ns-resize' : 'crosshair');
@@ -235,13 +245,13 @@ function attachDragBehavior(selection) {
235245
.on('dragstart', function(d) {
236246
var e = d3.event;
237247
e.sourceEvent.stopPropagation();
238-
var y = d.unitScaleInOrder(d.unitScale.invert(d3.mouse(this)[1]));
248+
var y = d.unitScaleInOrder(d.unitScale.invert(d3.mouse(this)[1] + c.verticalPadding));
239249
var unitLocation = d.unitScaleInOrder.invert(y);
240250
var b = d.brush;
241251
var intData = getInterval(b, d.unitScaleInOrder, y);
242252
var unitRange = intData.interval;
243253
var pixelRange = unitRange.map(d.unitScaleInOrder);
244-
var s = b.svgBrush2;
254+
var s = b.svgBrush;
245255
var active = filterActive(b);
246256
var barInteraction = unitRange && (intData.m || intData.s || intData.n);
247257
s.wasDragged = false; // we start assuming there won't be a drag - useful for reset
@@ -264,8 +274,8 @@ function attachDragBehavior(selection) {
264274
})
265275
.on('drag', function(d) {
266276
var e = d3.event;
267-
var y = d.unitScaleInOrder(d.unitScale.invert(e.y));
268-
var s = d.brush.svgBrush2;
277+
var y = d.unitScaleInOrder(d.unitScale.invert(e.y + c.verticalPadding));
278+
var s = d.brush.svgBrush;
269279
s.wasDragged = true;
270280
e.sourceEvent.stopPropagation();
271281

@@ -300,7 +310,7 @@ function attachDragBehavior(selection) {
300310
e.sourceEvent.stopPropagation();
301311
var brush = d.brush;
302312
var filter = brush.filter;
303-
var s = brush.svgBrush2;
313+
var s = brush.svgBrush;
304314
var grabbingBar = s.grabbingBar;
305315
s.grabbingBar = false;
306316
s.grabLocation = undefined;
@@ -311,10 +321,10 @@ function attachDragBehavior(selection) {
311321
if(grabbingBar) {
312322
s.extent = s.stayingIntervals;
313323
if(s.extent.length === 0) {
314-
clearBrushExtent(brush);
324+
brushClear(brush);
315325
}
316326
} else {
317-
clearBrushExtent(brush);
327+
brushClear(brush);
318328
}
319329
s.brushCallback(d);
320330
renderHighlight(this.parentElement);
@@ -403,37 +413,20 @@ function ensureAxisBrush(axisOverlays) {
403413
var axisBrush = axisOverlays.selectAll('.' + c.cn.axisBrush)
404414
.data(repeat, keyFun);
405415

406-
var axisBrushEnter = axisBrush.enter()
416+
axisBrush.enter()
407417
.append('g')
408418
.classed(c.cn.axisBrush, true);
409419

410-
var axisBrush2 = axisOverlays.selectAll('.' + c.cn.axisBrush + '2')
411-
.data(repeat, keyFun);
412-
413-
axisBrush2.enter()
414-
.append('g')
415-
.classed(c.cn.axisBrush + '2', true);
416-
417-
setAxisBrush(axisBrush, axisBrushEnter);
418-
renderAxisBrush(axisBrush2);
419-
}
420-
421-
function clearBrushExtent(brush) {
422-
brushClear(brush);
423-
}
424-
425-
function setBrushExtent(brush, range) {
426-
brush.svgBrush2.extent[0] = range[0];
427-
brush.svgBrush2.extent[1] = range[1];
420+
renderAxisBrush(axisBrush);
428421
}
429422

430423
function getBrushExtent(brush) {
431-
return brush.svgBrush2.extent.map(function(e) {return e.slice();});
424+
return brush.svgBrush.extent.map(function(e) {return e.slice();});
432425
}
433426

434427
function brushClear(brush) {
435428
brush.filterSpecified = false;
436-
brush.svgBrush2.extent = [[0, 1]];
429+
brush.svgBrush.extent = [[0, 1]];
437430
}
438431

439432

@@ -451,21 +444,6 @@ function axisBrushMoved(callback) {
451444
};
452445
}
453446

454-
function setAxisBrush(axisBrush, root) {
455-
axisBrush
456-
.each(function updateBrushExtent(d) {
457-
// Set the brush programmatically if data requires so, eg. Plotly `constraintrange` specifies a proper subset.
458-
// This is only to ensure the SVG brush is correct; WebGL lines are controlled from `d.brush.filter` directly.
459-
var b = d.brush;
460-
var f = b.filter.getBounds();
461-
if(filterActive(b)) {
462-
setBrushExtent(b, f);
463-
} else {
464-
clearBrushExtent(b, root);
465-
}
466-
});
467-
}
468-
469447
function dedupeRealRanges(intervals) {
470448
// Fuses elements of intervals if they overlap, yielding discontiguous intervals, results.length <= intervals.length
471449
// Currently uses closed intervals, ie. dedupeRealRanges([[400, 800], [300, 400]]) -> [300, 800]
@@ -503,8 +481,8 @@ function makeBrush(state, rangeSpecified, initialRange, brushStartCallback, brus
503481
return {
504482
filter: filter,
505483
filterSpecified: rangeSpecified, // there's a difference between not filtering and filtering a non-proper subset
506-
svgBrush2: {
507-
extent: [], // this is where the svgBrush2 writes contents into
484+
svgBrush: {
485+
extent: [], // this is where the svgBrush writes contents into
508486
brushStartCallback: brushStartCallback,
509487
brushCallback: axisBrushMoved(brushCallback),
510488
brushEndCallback: brushEndCallback

0 commit comments

Comments
 (0)