Skip to content

Commit 7b5c166

Browse files
committed
Merge branch 'master' of https://github.com/plotly/plotly.js into fix-choropleth-interactions-for-firefox
2 parents 56b3599 + 7588c9e commit 7b5c166

File tree

17 files changed

+330
-225
lines changed

17 files changed

+330
-225
lines changed

src/components/fx/hover.js

+37-93
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ var Drawing = require('../drawing');
1414
var Color = require('../color');
1515
var dragElement = require('../dragelement');
1616
var Axes = require('../../plots/cartesian/axes');
17-
var alignPeriod = require('../../plots/cartesian/align_period');
1817
var Registry = require('../../registry');
1918

2019
var helpers = require('./helpers');
@@ -491,6 +490,7 @@ function _hover(gd, evt, subplot, noHoverEvent) {
491490
if(hoverdistance !== 0) {
492491
if(trace._module && trace._module.hoverPoints) {
493492
var newPoints = trace._module.hoverPoints(pointData, xval, yval, _mode, {
493+
finiteRange: true,
494494
hoverLayer: fullLayout._hoverlayer
495495
});
496496

@@ -643,80 +643,51 @@ function _hover(gd, evt, subplot, noHoverEvent) {
643643
}
644644
}
645645

646-
hoverData.sort(function(d1, d2) { return d1.distance - d2.distance; });
646+
var sortHoverData = function() {
647+
hoverData.sort(function(d1, d2) { return d1.distance - d2.distance; });
647648

648-
// move period positioned points to the end of list
649-
hoverData = orderPeriod(hoverData, hovermode);
649+
// move period positioned points and box/bar-like traces to the end of the list
650+
hoverData = orderRangePoints(hoverData, hovermode);
651+
};
652+
sortHoverData();
650653

651654
// If in compare mode, select every point at position
652655
if(
653656
helpers.isXYhover(_mode) &&
654657
hoverData[0].length !== 0 &&
655658
hoverData[0].trace.type !== 'splom' // TODO: add support for splom
656659
) {
657-
var initLen = hoverData.length;
658660
var winningPoint = hoverData[0];
659661

660662
var customXVal = customVal('x', winningPoint, fullLayout);
661663
var customYVal = customVal('y', winningPoint, fullLayout);
662664

663665
findHoverPoints(customXVal, customYVal);
664666

665-
// also find start, middle and end point for period
666-
var axLetter = hovermode.charAt(0);
667-
if(winningPoint.trace[axLetter + 'period']) {
668-
var v = winningPoint[axLetter + 'LabelVal'];
669-
var ax = winningPoint[axLetter + 'a'];
670-
var T = {};
671-
T[axLetter + 'period'] = winningPoint.trace[axLetter + 'period'];
672-
T[axLetter + 'period0'] = winningPoint.trace[axLetter + 'period0'];
673-
674-
T[axLetter + 'periodalignment'] = 'start';
675-
var start = alignPeriod(T, ax, axLetter, [v])[0];
676-
677-
T[axLetter + 'periodalignment'] = 'middle';
678-
var middle = alignPeriod(T, ax, axLetter, [v])[0];
679-
680-
T[axLetter + 'periodalignment'] = 'end';
681-
var end = alignPeriod(T, ax, axLetter, [v])[0];
682-
683-
if(axLetter === 'x') {
684-
findHoverPoints(start, customYVal);
685-
findHoverPoints(middle, customYVal);
686-
findHoverPoints(end, customYVal);
687-
} else {
688-
findHoverPoints(customXVal, start);
689-
findHoverPoints(customXVal, middle);
690-
findHoverPoints(customXVal, end);
691-
}
692-
693-
var k;
694-
var seen = {};
695-
for(k = 0; k < initLen; k++) {
696-
seen[hoverData[k].trace.index] = true;
667+
var finalPoints = [];
668+
var seen = {};
669+
var insert = function(hd) {
670+
var type = hd.trace.type;
671+
var key = (
672+
type === 'box' ||
673+
type === 'violin' ||
674+
type === 'ohlc' ||
675+
type === 'candlestick'
676+
) ? hoverDataKey(hd) : hd.trace.index;
677+
if(!seen[key]) {
678+
seen[key] = true;
679+
finalPoints.push(hd);
697680
}
681+
};
698682

699-
// remove non-period aditions and traces that seen before
700-
for(k = hoverData.length - 1; k >= initLen; k--) {
701-
if(
702-
seen[hoverData[k].trace.index] ||
703-
!hoverData[k].trace[axLetter + 'period']
704-
) {
705-
hoverData.splice(k, 1);
706-
}
707-
}
683+
// insert the winnig point first
684+
insert(winningPoint);
685+
// override from the end
686+
for(var k = hoverData.length - 1; k > 0; k--) {
687+
insert(hoverData[k]);
708688
}
709-
710-
// Remove duplicated hoverData points
711-
// note that d3 also filters identical points in the rendering steps
712-
var repeated = {};
713-
hoverData = hoverData.filter(function(hd) {
714-
var key = hoverDataKey(hd);
715-
if(!repeated[key]) {
716-
repeated[key] = true;
717-
return repeated[key];
718-
}
719-
});
689+
hoverData = finalPoints;
690+
sortHoverData();
720691
}
721692

722693
// lastly, emit custom hover/unhover events
@@ -820,9 +791,7 @@ function createHoverText(hoverData, opts, gd) {
820791
var xa = c0.xa;
821792
var ya = c0.ya;
822793
var axLetter = hovermode.charAt(0);
823-
var v0 = c0[axLetter + 'LabelVal'];
824794
var t0 = c0[axLetter + 'Label'];
825-
var t00 = (String(t0) || '').split(' ')[0];
826795
var outerContainerBB = outerContainer.node().getBoundingClientRect();
827796
var outerTop = outerContainerBB.top;
828797
var outerWidth = outerContainerBB.width;
@@ -1011,44 +980,13 @@ function createHoverText(hoverData, opts, gd) {
1011980
}
1012981

1013982
label.attr('transform', strTranslate(lx, ly));
1014-
1015-
// remove the "close but not quite" points
1016-
// because of error bars, only take up to a space
1017-
hoverData = filterClosePoints(hoverData);
1018983
});
1019984

1020-
function filterClosePoints(hoverData) {
1021-
return hoverData.filter(function(d) {
1022-
if(d.zLabelVal !== undefined) return true;
1023-
if((d[axLetter + 'Label'] || '').split(' ')[0] === t00) return true;
1024-
if(d.trace[axLetter + 'period']) {
1025-
var v = d[axLetter + 'LabelVal'];
1026-
var ax = d[axLetter + 'a'];
1027-
var trace = {};
1028-
trace[axLetter + 'period'] = d.trace[axLetter + 'period'];
1029-
trace[axLetter + 'period0'] = d.trace[axLetter + 'period0'];
1030-
1031-
trace[axLetter + 'periodalignment'] = 'start';
1032-
var start = alignPeriod(trace, ax, axLetter, [v])[0];
1033-
1034-
trace[axLetter + 'periodalignment'] = 'end';
1035-
var end = alignPeriod(trace, ax, axLetter, [v])[0];
1036-
1037-
if(v0 >= start && v0 < end) return true;
1038-
}
1039-
1040-
return false;
1041-
});
1042-
}
1043-
1044985
// Show a single hover label
1045986
if(helpers.isUnifiedHover(hovermode)) {
1046987
// Delete leftover hover labels from other hovermodes
1047988
container.selectAll('g.hovertext').remove();
1048989

1049-
// similarly to compare mode, we remove the "close but not quite together" points
1050-
if((t0 !== undefined) && (c0.distance <= opts.hoverdistance)) hoverData = filterClosePoints(hoverData);
1051-
1052990
// Return early if nothing is hovered on
1053991
if(hoverData.length === 0) return;
1054992

@@ -1929,23 +1867,29 @@ function plainText(s, len) {
19291867
});
19301868
}
19311869

1932-
function orderPeriod(hoverData, hovermode) {
1870+
function orderRangePoints(hoverData, hovermode) {
19331871
var axLetter = hovermode.charAt(0);
19341872

19351873
var first = [];
1874+
var second = [];
19361875
var last = [];
19371876

19381877
for(var i = 0; i < hoverData.length; i++) {
19391878
var d = hoverData[i];
19401879

1941-
if(d.trace[axLetter + 'period']) {
1880+
if(
1881+
Registry.traceIs(d.trace, 'bar-like') ||
1882+
Registry.traceIs(d.trace, 'box-violin')
1883+
) {
19421884
last.push(d);
1885+
} else if(d.trace[axLetter + 'period']) {
1886+
second.push(d);
19431887
} else {
19441888
first.push(d);
19451889
}
19461890
}
19471891

1948-
return first.concat(last);
1892+
return first.concat(second).concat(last);
19491893
}
19501894

19511895
function customVal(axLetter, winningPoint, fullLayout) {

src/plots/cartesian/axes.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -3005,8 +3005,7 @@ axes.drawLabels = function(gd, ax, opts) {
30053005
// sync label: just position it now.
30063006
positionLabels(thisLabel, tickAngle);
30073007
}
3008-
})
3009-
.style('display', null); // visible
3008+
});
30103009

30113010
hideCounterAxisInsideTickLabels(ax, [TICK_TEXT]);
30123011

src/traces/bar/hover.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ var getLineWidth = require('./helpers').getLineWidth;
99
var hoverLabelText = require('../../plots/cartesian/axes').hoverLabelText;
1010
var BADNUM = require('../../constants/numerical').BADNUM;
1111

12-
function hoverPoints(pointData, xval, yval, hovermode) {
13-
var barPointData = hoverOnBars(pointData, xval, yval, hovermode);
12+
function hoverPoints(pointData, xval, yval, hovermode, opts) {
13+
var barPointData = hoverOnBars(pointData, xval, yval, hovermode, opts);
1414

1515
if(barPointData) {
1616
var cd = barPointData.cd;
@@ -24,7 +24,7 @@ function hoverPoints(pointData, xval, yval, hovermode) {
2424
}
2525
}
2626

27-
function hoverOnBars(pointData, xval, yval, hovermode) {
27+
function hoverOnBars(pointData, xval, yval, hovermode, opts) {
2828
var cd = pointData.cd;
2929
var trace = cd[0].trace;
3030
var t = cd[0].t;
@@ -67,6 +67,8 @@ function hoverOnBars(pointData, xval, yval, hovermode) {
6767
};
6868

6969
function inbox(_minPos, _maxPos, maxDistance) {
70+
if(opts.finiteRange) maxDistance = 0;
71+
7072
// add a little to the pseudo-distance for wider bars, so that like scatter,
7173
// if you are over two overlapping bars, the narrower one wins.
7274
return Fx.inbox(_minPos - posVal, _maxPos - posVal,

src/traces/densitymapbox/hover.js

+2-32
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
'use strict';
22

3-
var Lib = require('../../lib');
43
var Axes = require('../../plots/cartesian/axes');
5-
var scatterMapboxHoverPoints = require('../scattermapbox/hover');
4+
var scatterMapboxHoverPoints = require('../scattermapbox/hover').hoverPoints;
5+
var getExtraText = require('../scattermapbox/hover').getExtraText;
66

77
module.exports = function hoverPoints(pointData, xval, yval) {
88
var pts = scatterMapboxHoverPoints(pointData, xval, yval);
@@ -26,33 +26,3 @@ module.exports = function hoverPoints(pointData, xval, yval) {
2626

2727
return [newPointData];
2828
};
29-
30-
function getExtraText(trace, di, labels) {
31-
if(trace.hovertemplate) return;
32-
33-
var hoverinfo = di.hi || trace.hoverinfo;
34-
var parts = hoverinfo.split('+');
35-
var isAll = parts.indexOf('all') !== -1;
36-
var hasLon = parts.indexOf('lon') !== -1;
37-
var hasLat = parts.indexOf('lat') !== -1;
38-
var lonlat = di.lonlat;
39-
var text = [];
40-
41-
function format(v) {
42-
return v + '\u00B0';
43-
}
44-
45-
if(isAll || (hasLon && hasLat)) {
46-
text.push('(' + format(lonlat[0]) + ', ' + format(lonlat[1]) + ')');
47-
} else if(hasLon) {
48-
text.push(labels.lon + format(lonlat[0]));
49-
} else if(hasLat) {
50-
text.push(labels.lat + format(lonlat[1]));
51-
}
52-
53-
if(isAll || parts.indexOf('text') !== -1) {
54-
Lib.fillText(di, trace, text);
55-
}
56-
57-
return text.join('<br>');
58-
}

src/traces/funnel/hover.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ var opacity = require('../../components/color').opacity;
44
var hoverOnBars = require('../bar/hover').hoverOnBars;
55
var formatPercent = require('../../lib').formatPercent;
66

7-
module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
8-
var point = hoverOnBars(pointData, xval, yval, hovermode);
7+
module.exports = function hoverPoints(pointData, xval, yval, hovermode, opts) {
8+
var point = hoverOnBars(pointData, xval, yval, hovermode, opts);
99
if(!point) return;
1010

1111
var cd = point.cd;

src/traces/histogram/hover.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
var barHover = require('../bar/hover').hoverPoints;
44
var hoverLabelText = require('../../plots/cartesian/axes').hoverLabelText;
55

6-
module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
7-
var pts = barHover(pointData, xval, yval, hovermode);
6+
module.exports = function hoverPoints(pointData, xval, yval, hovermode, opts) {
7+
var pts = barHover(pointData, xval, yval, hovermode, opts);
88

99
if(!pts) return;
1010

src/traces/ohlc/hover.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function hoverPoints(pointData, xval, yval, hovermode) {
2323
return hoverOnPoints(pointData, xval, yval, hovermode);
2424
}
2525

26-
function getClosestPoint(pointData, xval, yval, hovermode) {
26+
function _getClosestPoint(pointData, xval, yval, hovermode) {
2727
var cd = pointData.cd;
2828
var xa = pointData.xa;
2929
var trace = cd[0].trace;
@@ -95,7 +95,7 @@ function hoverSplit(pointData, xval, yval, hovermode) {
9595
var t = cd[0].t;
9696
var closeBoxData = [];
9797

98-
var closestPoint = getClosestPoint(pointData, xval, yval, hovermode);
98+
var closestPoint = _getClosestPoint(pointData, xval, yval, hovermode);
9999
// skip the rest (for this trace) if we didn't find a close point
100100
if(!closestPoint) return [];
101101

@@ -150,7 +150,7 @@ function hoverOnPoints(pointData, xval, yval, hovermode) {
150150
var trace = cd[0].trace;
151151
var t = cd[0].t;
152152

153-
var closestPoint = getClosestPoint(pointData, xval, yval, hovermode);
153+
var closestPoint = _getClosestPoint(pointData, xval, yval, hovermode);
154154
// skip the rest (for this trace) if we didn't find a close point
155155
if(!closestPoint) return [];
156156

src/traces/scattermapbox/hover.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var getTraceColor = require('../scatter/get_trace_color');
66
var fillText = Lib.fillText;
77
var BADNUM = require('../../constants/numerical').BADNUM;
88

9-
module.exports = function hoverPoints(pointData, xval, yval) {
9+
function hoverPoints(pointData, xval, yval) {
1010
var cd = pointData.cd;
1111
var trace = cd[0].trace;
1212
var xa = pointData.xa;
@@ -66,7 +66,7 @@ module.exports = function hoverPoints(pointData, xval, yval) {
6666
pointData.hovertemplate = trace.hovertemplate;
6767

6868
return [pointData];
69-
};
69+
}
7070

7171
function getExtraText(trace, di, labels) {
7272
if(trace.hovertemplate) return;
@@ -86,7 +86,7 @@ function getExtraText(trace, di, labels) {
8686
}
8787

8888
if(isAll || (hasLon && hasLat)) {
89-
text.push('(' + format(lonlat[0]) + ', ' + format(lonlat[1]) + ')');
89+
text.push('(' + format(lonlat[1]) + ', ' + format(lonlat[0]) + ')');
9090
} else if(hasLon) {
9191
text.push(labels.lon + format(lonlat[0]));
9292
} else if(hasLat) {
@@ -99,3 +99,8 @@ function getExtraText(trace, di, labels) {
9999

100100
return text.join('<br>');
101101
}
102+
103+
module.exports = {
104+
hoverPoints: hoverPoints,
105+
getExtraText: getExtraText
106+
};

src/traces/scattermapbox/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module.exports = {
77
formatLabels: require('./format_labels'),
88
calc: require('../scattergeo/calc'),
99
plot: require('./plot'),
10-
hoverPoints: require('./hover'),
10+
hoverPoints: require('./hover').hoverPoints,
1111
eventData: require('./event_data'),
1212
selectPoints: require('./select'),
1313

0 commit comments

Comments
 (0)