Skip to content

Commit db44a5b

Browse files
author
John Soklaski
committed
Add support for multiple subplots to fx.hover()
1 parent 3e9288c commit db44a5b

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/plots/cartesian/graph_interact.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,15 @@ function hover(gd, evt, subplot){
313313

314314
var fullLayout = gd._fullLayout,
315315
plotinfo = fullLayout._plots[subplot],
316+
//If the user passed in an array of subplots, use those instead of finding overlayed plots
317+
subplots = (Object.prototype.toString.call(subplot) == "[object Array]") ?
318+
subplot :
319+
320+
subplots = [subplot].concat(plotinfo.overlays
321+
.map(function(pi){ return pi.id; })),
322+
316323
// list of all overlaid subplots to look at
317-
subplots = [subplot].concat(plotinfo.overlays
318-
.map(function(pi){ return pi.id; })),
324+
319325
xaArray = subplots.map(function(spId) {
320326
return Plotly.Axes.getFromId(gd, spId, 'x');
321327
}),
@@ -533,7 +539,7 @@ function hover(gd, evt, subplot){
533539
};
534540
var hoverLabels = createHoverText(hoverData, labelOpts);
535541

536-
hoverAvoidOverlaps(hoverData, rotateLabels ? xaArray[0] : yaArray[0]);
542+
hoverAvoidOverlaps(hoverData, rotateLabels ? "xa" : "ya");
537543

538544
alignHoverText(hoverLabels, rotateLabels);
539545

@@ -866,7 +872,7 @@ function createHoverText(hoverData, opts) {
866872
// first create the objects
867873
var hoverLabels = container.selectAll('g.hovertext')
868874
.data(hoverData,function(d){
869-
return [d.trace.index,d.index,d.x0,d.y0,d.name,d.attr||''].join(',');
875+
return [d.trace.index,d.index,d.x0,d.y0,d.name,d.attr,d.xa,d.ya ||''].join(',');
870876
});
871877
hoverLabels.enter().append('g')
872878
.classed('hovertext',true)
@@ -969,8 +975,8 @@ function createHoverText(hoverData, opts) {
969975
g.select('path')
970976
.style({fill:traceColor, stroke:contrastColor});
971977
var tbb = tx.node().getBoundingClientRect(),
972-
htx = xa._offset+(d.x0+d.x1)/2,
973-
hty = ya._offset+(d.y0+d.y1)/2,
978+
htx = d.xa._offset+(d.x0+d.x1)/2,
979+
hty = d.ya._offset+(d.y0+d.y1)/2,
974980
dx = Math.abs(d.x1-d.x0),
975981
dy = Math.abs(d.y1-d.y0),
976982
txTotalWidth = tbb.width+HOVERARROWSIZE+HOVERTEXTPAD+tx2width,
@@ -1033,18 +1039,19 @@ function createHoverText(hoverData, opts) {
10331039
// information then.
10341040
function hoverAvoidOverlaps(hoverData, ax) {
10351041
var nummoves = 0,
1036-
pmin = ax._offset,
1037-
pmax = ax._offset+ax._length,
10381042

10391043
// make groups of touching points
10401044
pointgroups = hoverData
10411045
.map(function(d,i){
1046+
var axis = d[ax];
10421047
return [{
10431048
i: i,
10441049
dp: 0,
10451050
pos: d.pos,
10461051
posref: d.posref,
1047-
size: d.by*(ax._id.charAt(0)==='x' ? YFACTOR : 1)/2
1052+
size: d.by*(axis._id.charAt(0)==='x' ? YFACTOR : 1)/2,
1053+
pmin: axis._offset,
1054+
pmax: axis._offset+axis._length
10481055
}];
10491056
})
10501057
.sort(function(a,b){ return a[0].posref-b[0].posref; }),
@@ -1060,10 +1067,10 @@ function hoverAvoidOverlaps(hoverData, ax) {
10601067
maxPt = grp[grp.length-1];
10611068

10621069
// overlap with the top - positive vals are overlaps
1063-
topOverlap = pmin-minPt.pos-minPt.dp+minPt.size;
1070+
topOverlap = minPt.pmin-minPt.pos-minPt.dp+minPt.size;
10641071

10651072
// overlap with the bottom - positive vals are overlaps
1066-
bottomOverlap = maxPt.pos+maxPt.dp+maxPt.size-pmax;
1073+
bottomOverlap = maxPt.pos+maxPt.dp+maxPt.size-minPt.pmax;
10671074

10681075
// check for min overlap first, so that we always
10691076
// see the largest labels
@@ -1087,7 +1094,7 @@ function hoverAvoidOverlaps(hoverData, ax) {
10871094
var deleteCount = 0;
10881095
for(i=0; i<grp.length; i++) {
10891096
pti = grp[i];
1090-
if(pti.pos+pti.dp+pti.size>pmax) deleteCount++;
1097+
if(pti.pos+pti.dp+pti.size>minPt.pmax) deleteCount++;
10911098
}
10921099

10931100
// start by deleting points whose data is off screen
@@ -1097,7 +1104,7 @@ function hoverAvoidOverlaps(hoverData, ax) {
10971104

10981105
// pos has already been constrained to [pmin,pmax]
10991106
// so look for points close to that to delete
1100-
if(pti.pos>pmax-1) {
1107+
if(pti.pos>minPt.pmax-1) {
11011108
pti.del = true;
11021109
deleteCount--;
11031110
}
@@ -1108,7 +1115,7 @@ function hoverAvoidOverlaps(hoverData, ax) {
11081115

11091116
// pos has already been constrained to [pmin,pmax]
11101117
// so look for points close to that to delete
1111-
if(pti.pos<pmin+1) {
1118+
if(pti.pos<minPt.pmin+1) {
11121119
pti.del = true;
11131120
deleteCount--;
11141121

@@ -1121,7 +1128,7 @@ function hoverAvoidOverlaps(hoverData, ax) {
11211128
for(i=grp.length-1; i>=0; i--) {
11221129
if(deleteCount<=0) break;
11231130
pti = grp[i];
1124-
if(pti.pos+pti.dp+pti.size>pmax) {
1131+
if(pti.pos+pti.dp+pti.size>minPt.pmax) {
11251132
pti.del = true;
11261133
deleteCount--;
11271134
}
@@ -1149,7 +1156,9 @@ function hoverAvoidOverlaps(hoverData, ax) {
11491156
p0 = g0[g0.length-1],
11501157
p1 = g1[0];
11511158
topOverlap = p0.pos+p0.dp+p0.size-p1.pos-p1.dp+p1.size;
1152-
if(topOverlap>0.01) {
1159+
1160+
//Only group points that lie on the same axes
1161+
if(topOverlap>0.01 && (p0.pmin == p1.pmin) && (p0.pmax == p1.pmax)) {
11531162
// push the new point(s) added to this group out of the way
11541163
for(j=g1.length-1; j>=0; j--) g1[j].dp += topOverlap;
11551164

0 commit comments

Comments
 (0)