Skip to content

Commit 6432b89

Browse files
committed
cleanup, and remove some obsolete code
1 parent a7bd686 commit 6432b89

File tree

3 files changed

+256
-340
lines changed

3 files changed

+256
-340
lines changed

src/traces/parcoords/axisbrush.js

+93-160
Original file line numberDiff line numberDiff line change
@@ -14,38 +14,6 @@ var keyFun = require('../../lib/gup').keyFun;
1414
var repeat = require('../../lib/gup').repeat;
1515
var sortAsc = require('../../lib').sorterAsc;
1616

17-
function addFilterBarDefs(defs) {
18-
var filterBarPattern = defs.selectAll('#' + c.id.filterBarPattern)
19-
.data(repeat, keyFun);
20-
21-
filterBarPattern.enter()
22-
.append('pattern')
23-
.attr('id', c.id.filterBarPattern)
24-
.attr('patternUnits', 'userSpaceOnUse');
25-
26-
filterBarPattern
27-
.attr('x', -c.bar.width)
28-
.attr('width', c.bar.captureWidth)
29-
.attr('height', function(d) {return d.model.height;});
30-
31-
var filterBarPatternGlyph = filterBarPattern.selectAll('rect')
32-
.data(repeat, keyFun);
33-
34-
filterBarPatternGlyph.enter()
35-
.append('rect')
36-
.attr('shape-rendering', 'crispEdges');
37-
38-
filterBarPatternGlyph
39-
.attr('height', function(d) {return d.model.height;})
40-
.attr('width', c.bar.width)
41-
.attr('x', c.bar.width / 2)
42-
.attr('fill', c.bar.fillColor)
43-
.attr('fill-opacity', c.bar.fillOpacity)
44-
.attr('stroke', c.bar.strokeColor)
45-
.attr('stroke-opacity', c.bar.strokeOpacity)
46-
.attr('stroke-width', c.bar.strokeWidth);
47-
}
48-
4917
var snapRatio = c.bar.snapRatio;
5018
function snapOvershoot(v, vAdjacent) { return v * (1 - snapRatio) + vAdjacent * snapRatio; }
5119

@@ -113,7 +81,7 @@ function backgroundBarHorizontalSetup(selection) {
11381
}
11482

11583
function setHighlight(d) {
116-
if(!filterActive(d.brush)) {
84+
if(!d.brush.filterSpecified) {
11785
return '0,' + d.height;
11886
}
11987
var pixelRanges = unitToPx(d.brush.filter.getConsolidated(), d.height);
@@ -144,34 +112,14 @@ function unitToPx(unitRanges, height) {
144112
});
145113
}
146114

147-
function differentInterval(int1) {
148-
// An interval is different if the extents don't match, which is a safe test only because the intervals
149-
// get consolidated anyway (ie. the identity of overlapping intervals won't be preserved; they get fused)
150-
return function(int2) {
151-
return int1[0] !== int2[0] || int1[1] !== int2[1];
152-
};
153-
}
154-
155115
// is the cursor over the north, middle, or south of a bar?
156116
// the end handles extend over the last 10% of the bar
157-
function north(fPix, y) {
158-
return north90(fPix) <= y && y <= fPix[1] + c.bar.handleHeight;
159-
}
160-
161-
function south(fPix, y) {
162-
return fPix[0] - c.bar.handleHeight <= y && y <= south90(fPix);
163-
}
164-
165-
function middle(fPix, y) {
166-
return south90(fPix) < y && y < north90(fPix);
167-
}
168-
169-
function north90(fPix) {
170-
return 0.9 * fPix[1] + 0.1 * fPix[0];
171-
}
172-
173-
function south90(fPix) {
174-
return 0.9 * fPix[0] + 0.1 * fPix[1];
117+
function getRegion(fPix, y) {
118+
var pad = c.bar.handleHeight;
119+
if(y > fPix[1] + pad || y < fPix[0] - pad) return;
120+
if(y >= 0.9 * fPix[1] + 0.1 * fPix[0]) return 'n';
121+
if(y <= 0.9 * fPix[0] + 0.1 * fPix[1]) return 's';
122+
return 'ns';
175123
}
176124

177125
function clearCursor() {
@@ -188,61 +136,67 @@ function styleHighlight(selection) {
188136
}
189137

190138
function renderHighlight(root, tweenCallback) {
191-
var bar = d3.select(root).selectAll('.highlight, .highlightShadow');
139+
var bar = d3.select(root).selectAll('.highlight, .highlight-shadow');
192140
var barToStyle = tweenCallback ? bar.transition().duration(c.bar.snapDuration).each('end', tweenCallback) : bar;
193141
styleHighlight(barToStyle);
194142
}
195143

196-
function getInterval(b, d, y) {
197-
var height = d.height;
198-
var intervals = b.filter.getConsolidated();
199-
var pixIntervals = unitToPx(intervals, height);
200-
var hoveredInterval = NaN;
201-
var previousInterval = NaN;
202-
var nextInterval = NaN;
144+
function getInterval(d, y) {
145+
var b = d.brush;
146+
var active = b.filterSpecified;
147+
var closestInterval = NaN;
148+
var out = {};
203149
var i;
204-
for(i = 0; i <= pixIntervals.length; i++) {
205-
var p = pixIntervals[i];
206-
if(p && p[0] <= y && y <= p[1]) {
207-
// over a bar
208-
hoveredInterval = i;
209-
break;
210-
} else {
211-
// between bars, or before/after the first/last bar
212-
previousInterval = i ? i - 1 : NaN;
213-
if(p && p[0] > y) {
214-
nextInterval = i;
215-
break; // no point continuing as intervals are non-overlapping and sorted; could use log search
150+
151+
if(active) {
152+
var height = d.height;
153+
var intervals = b.filter.getConsolidated();
154+
var pixIntervals = unitToPx(intervals, height);
155+
var hoveredInterval = NaN;
156+
var previousInterval = NaN;
157+
var nextInterval = NaN;
158+
for(i = 0; i <= pixIntervals.length; i++) {
159+
var p = pixIntervals[i];
160+
if(p && p[0] <= y && y <= p[1]) {
161+
// over a bar
162+
hoveredInterval = i;
163+
break;
164+
} else {
165+
// between bars, or before/after the first/last bar
166+
previousInterval = i ? i - 1 : NaN;
167+
if(p && p[0] > y) {
168+
nextInterval = i;
169+
break; // no point continuing as intervals are non-overlapping and sorted; could use log search
170+
}
216171
}
217172
}
218-
}
219173

220-
var closestInterval = hoveredInterval;
221-
if(isNaN(closestInterval)) {
222-
if(isNaN(previousInterval) || isNaN(nextInterval)) {
223-
closestInterval = isNaN(previousInterval) ? nextInterval : previousInterval;
224-
}
225-
else {
226-
closestInterval = (y - pixIntervals[previousInterval][1] < pixIntervals[nextInterval][0] - y) ?
227-
previousInterval : nextInterval;
174+
closestInterval = hoveredInterval;
175+
if(isNaN(closestInterval)) {
176+
if(isNaN(previousInterval) || isNaN(nextInterval)) {
177+
closestInterval = isNaN(previousInterval) ? nextInterval : previousInterval;
178+
}
179+
else {
180+
closestInterval = (y - pixIntervals[previousInterval][1] < pixIntervals[nextInterval][0] - y) ?
181+
previousInterval : nextInterval;
182+
}
228183
}
229-
}
230-
231-
var foundInterval = !isNaN(closestInterval);
232184

233-
var fPix = pixIntervals[closestInterval];
185+
if(!isNaN(closestInterval)) {
186+
var fPix = pixIntervals[closestInterval];
187+
var region = getRegion(fPix, y);
234188

235-
var out = {
236-
interval: foundInterval ? intervals[closestInterval] : null, // activated interval in domain terms
237-
intervalPix: foundInterval ? fPix : null, // activated interval in pixel terms
238-
n: north(fPix, y), // do we hover over the northern resize hotspot
239-
s: south(fPix, y), // do we hover over the northern resize hotspot
240-
m: middle(fPix, y) // or over the bar section itself?
241-
};
189+
if(region) {
190+
out.interval = intervals[closestInterval];
191+
out.intervalPix = fPix;
192+
out.region = region;
193+
}
194+
}
195+
}
242196

243-
if(d.ordinal && (!(out.n || out.s || out.m) || !filterActive(b))) {
244-
var a = d.ordinalScale.range().map(d.paddedUnitScale);
245-
var unitLocation = d.unitScaleInOrder.invert(y);
197+
if(d.ordinal && !out.region) {
198+
var a = d.unitTickvals;
199+
var unitLocation = d.unitToPaddedPx.invert(y);
246200
for(i = 0; i < a.length; i++) {
247201
var rangei = [
248202
a[Math.max(i - 1, 0)] * 0.25 + a[i] * 0.75,
@@ -265,71 +219,57 @@ function attachDragBehavior(selection) {
265219
selection
266220
.on('mousemove', function(d) {
267221
d3.event.preventDefault();
268-
var b = d.brush;
269-
if(d.parent.inBrushDrag) {
270-
return;
271-
}
272-
var y = d.height - d3.mouse(this)[1] - 2 * c.verticalPadding;
273-
var interval = getInterval(b, d, y);
274-
var cursor = 'crosshair';
275-
if(interval.clickableOrdinalRange) cursor = 'pointer';
276-
else if(filterActive(b)) {
277-
if(interval.n) cursor = 'n-resize';
278-
else if(interval.s) cursor = 's-resize';
279-
else if(interval.m) cursor = 'ns-resize';
222+
if(!d.parent.inBrushDrag) {
223+
var y = d.height - d3.mouse(this)[1] - 2 * c.verticalPadding;
224+
var interval = getInterval(d, y);
225+
226+
var cursor = 'crosshair';
227+
if(interval.clickableOrdinalRange) cursor = 'pointer';
228+
else if(interval.region) cursor = interval.region + '-resize';
229+
d3.select(document.body)
230+
.style('cursor', cursor);
280231
}
281-
d3.select(document.body)
282-
.style('cursor', cursor);
283232
})
284233
.on('mouseleave', function(d) {
285-
if(d.parent.inBrushDrag) {
286-
return;
287-
}
288-
clearCursor();
234+
if(!d.parent.inBrushDrag) clearCursor();
289235
})
290236
.call(d3.behavior.drag()
291237
.on('dragstart', function(d) {
292-
var e = d3.event;
293-
e.sourceEvent.stopPropagation();
238+
d3.event.sourceEvent.stopPropagation();
294239
var y = d.height - d3.mouse(this)[1] - 2 * c.verticalPadding;
295-
var unitLocation = d.unitScaleInOrder.invert(y);
240+
var unitLocation = d.unitToPaddedPx.invert(y);
296241
var b = d.brush;
297-
var intData = getInterval(b, d, y);
298-
var unitRange = intData.interval;
299-
var pixelRange = unitRange.map(d.unitScaleInOrder);
242+
var interval = getInterval(d, y);
243+
var unitRange = interval.interval;
300244
var s = b.svgBrush;
301-
var active = filterActive(b);
302-
var barInteraction = unitRange && (intData.m || intData.s || intData.n);
303245
s.wasDragged = false; // we start assuming there won't be a drag - useful for reset
304-
s.grabPoint = d.unitScaleInOrder(unitLocation) - pixelRange[0] - c.verticalPadding;
305-
s.barLength = pixelRange[1] - pixelRange[0];
306-
s.grabbingBar = active && intData.m && unitRange;
307-
s.clickableOrdinalRange = intData.clickableOrdinalRange;
308-
s.stayingIntervals = !d.multiselect ? [] :
309-
barInteraction ?
310-
b.filter.get().filter(differentInterval(unitRange)) :
311-
b.filter.get(); // keep all preexisting bars if interaction wasn't a barInteraction
312-
var grabbingBarNorth = active && intData.n;
313-
var grabbingBarSouth = active && intData.s;
314-
var newBrushing = !s.grabbingBar && !grabbingBarNorth && !grabbingBarSouth;
315-
s.startExtent = newBrushing ? unitLocation : unitRange[grabbingBarSouth ? 1 : 0];
246+
s.grabbingBar = interval.region === 'ns';
247+
if(s.grabbingBar) {
248+
var pixelRange = unitRange.map(d.unitToPaddedPx);
249+
s.grabPoint = y - pixelRange[0] - c.verticalPadding;
250+
s.barLength = pixelRange[1] - pixelRange[0];
251+
}
252+
s.clickableOrdinalRange = interval.clickableOrdinalRange;
253+
s.stayingIntervals = (d.multiselect && b.filterSpecified) ? b.filter.getConsolidated() : [];
254+
if(unitRange) {
255+
s.stayingIntervals = s.stayingIntervals.filter(function(int2) {
256+
return int2[0] !== unitRange[0] && int2[1] !== unitRange[1];
257+
});
258+
}
259+
s.startExtent = interval.region ? unitRange[interval.region === 's' ? 1 : 0] : unitLocation;
316260
d.parent.inBrushDrag = true;
317261
s.brushStartCallback();
318262
})
319263
.on('drag', function(d) {
320-
var e = d3.event;
321-
var y = d.unitScaleInOrder(d.unitScale.invert(e.y + c.verticalPadding));
264+
d3.event.sourceEvent.stopPropagation();
265+
var y = d.height - d3.mouse(this)[1] - 2 * c.verticalPadding;
322266
var s = d.brush.svgBrush;
323267
s.wasDragged = true;
324-
e.sourceEvent.stopPropagation();
325268

326269
if(s.grabbingBar) { // moving the bar
327-
s.newExtent = [y - s.grabPoint, y + s.barLength - s.grabPoint].map(d.unitScaleInOrder.invert);
270+
s.newExtent = [y - s.grabPoint, y + s.barLength - s.grabPoint].map(d.unitToPaddedPx.invert);
328271
} else { // south/north drag or new bar creation
329-
var endExtent = d.unitScaleInOrder.invert(y);
330-
s.newExtent = s.startExtent < endExtent ?
331-
[s.startExtent, endExtent] :
332-
[endExtent, s.startExtent];
272+
s.newExtent = [s.startExtent, d.unitToPaddedPx.invert(y)].sort(sortAsc);
333273
}
334274

335275
// take care of the parcoords axis height constraint: bar can't breach it
@@ -393,7 +333,7 @@ function attachDragBehavior(selection) {
393333
};
394334

395335
if(d.ordinal) {
396-
var a = d.ordinalScale.range().map(d.paddedUnitScale);
336+
var a = d.unitTickvals;
397337
if(a[a.length - 1] < a[0]) a.reverse();
398338
s.newExtent = [
399339
ordinalScaleSnapLo(a, s.newExtent[0], s.stayingIntervals),
@@ -442,19 +382,19 @@ function renderAxisBrush(axisBrush) {
442382
return d.height - c.verticalPadding;
443383
});
444384

445-
var highlightShadow = axisBrush.selectAll('.highlightShadow').data(repeat); // we have a set here, can't call it `extent`
385+
var highlightShadow = axisBrush.selectAll('.highlight-shadow').data(repeat); // we have a set here, can't call it `extent`
446386

447387
highlightShadow.enter()
448388
.append('line')
449-
.classed('highlightShadow', true)
389+
.classed('highlight-shadow', true)
450390
.attr('x', -c.bar.width / 2)
451391
.attr('stroke-width', c.bar.width + c.bar.strokeWidth)
452392
.attr('stroke', c.bar.strokeColor)
453393
.attr('opacity', c.bar.strokeOpacity)
454394
.attr('stroke-linecap', 'butt');
455395

456396
highlightShadow
457-
.attr('y1', function(d) {return d.height;})
397+
.attr('y1', function(d) { return d.height; })
458398
.call(styleHighlight);
459399

460400
var highlight = axisBrush.selectAll('.highlight').data(repeat); // we have a set here, can't call it `extent`
@@ -469,7 +409,7 @@ function renderAxisBrush(axisBrush) {
469409
.attr('stroke-linecap', 'butt');
470410

471411
highlight
472-
.attr('y1', function(d) {return d.height;})
412+
.attr('y1', function(d) { return d.height; })
473413
.call(styleHighlight);
474414
}
475415

@@ -493,11 +433,6 @@ function brushClear(brush) {
493433
brush.svgBrush.extent = [[0, 1]];
494434
}
495435

496-
497-
function filterActive(brush) {
498-
return brush.filterSpecified;
499-
}
500-
501436
function axisBrushMoved(callback) {
502437
return function axisBrushMoved(dimension) {
503438
var brush = dimension.brush;
@@ -589,9 +524,7 @@ function cleanRanges(ranges, dimension) {
589524
}
590525

591526
module.exports = {
592-
addFilterBarDefs: addFilterBarDefs,
593527
makeBrush: makeBrush,
594528
ensureAxisBrush: ensureAxisBrush,
595-
filterActive: filterActive,
596529
cleanRanges: cleanRanges
597530
};

0 commit comments

Comments
 (0)