Skip to content

Commit 74649d0

Browse files
committed
enable hover modebars using simplified strings
1 parent f7d5a3a commit 74649d0

File tree

3 files changed

+63
-29
lines changed

3 files changed

+63
-29
lines changed

src/components/modebar/manage.js

+57-23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
var axisIds = require('../../plots/cartesian/axis_ids');
44
var scatterSubTypes = require('../../traces/scatter/subtypes');
55
var Registry = require('../../registry');
6+
var isUnifiedHover = require('../fx/helpers').isUnifiedHover;
67

78
var createModeBar = require('./modebar');
89
var modeBarButtons = require('./buttons');
@@ -66,25 +67,6 @@ var DRAW_MODES = [
6667
'eraseshape'
6768
];
6869

69-
var HOVER_MODES = [
70-
'hoverCompareCartesian',
71-
'hoverClosestCartesian',
72-
'hoverClosestGl2d',
73-
'hoverClosest3d',
74-
'hoverClosestGeo',
75-
'hoverClosestPie',
76-
'toggleHover'
77-
];
78-
79-
var SPIKE_MODES = [
80-
'toggleSpikelines'
81-
];
82-
83-
var EXTRA_MODES = []
84-
.concat(DRAW_MODES)
85-
.concat(HOVER_MODES)
86-
.concat(SPIKE_MODES);
87-
8870
// logic behind which buttons are displayed by default
8971
function getButtonGroups(gd) {
9072
var fullLayout = gd._fullLayout;
@@ -104,6 +86,7 @@ function getButtonGroups(gd) {
10486
var hasPolar = fullLayout._has('polar');
10587
var hasSankey = fullLayout._has('sankey');
10688
var allAxesFixed = areAllAxesFixed(fullLayout);
89+
var hasUnifiedHoverLabel = isUnifiedHover(fullLayout.hovermode);
10790

10891
var groups = [];
10992

@@ -128,23 +111,45 @@ function getButtonGroups(gd) {
128111
addGroup(commonGroup);
129112

130113
var zoomGroup = [];
114+
var hoverGroup = [];
131115
var resetGroup = [];
132116
var dragModeGroup = [];
133117

134118
if((hasCartesian || hasGL2D || hasPie || hasFunnelarea || hasTernary) + hasGeo + hasGL3D + hasMapbox + hasPolar > 1) {
135119
// graphs with more than one plot types get 'union buttons'
136-
// which reset the view across all subplots.
120+
// which reset the view or toggle hover labels across all subplots.
121+
hoverGroup = ['toggleHover'];
137122
resetGroup = ['resetViews'];
138123
} else if(hasGeo) {
139124
zoomGroup = ['zoomInGeo', 'zoomOutGeo'];
125+
hoverGroup = ['hoverClosestGeo'];
140126
resetGroup = ['resetGeo'];
141127
} else if(hasGL3D) {
128+
hoverGroup = ['hoverClosest3d'];
142129
resetGroup = ['resetCameraDefault3d', 'resetCameraLastSave3d'];
143130
} else if(hasMapbox) {
144131
zoomGroup = ['zoomInMapbox', 'zoomOutMapbox'];
132+
hoverGroup = ['toggleHover'];
145133
resetGroup = ['resetViewMapbox'];
134+
} else if(hasGL2D) {
135+
hoverGroup = ['hoverClosestGl2d'];
136+
} else if(hasPie) {
137+
hoverGroup = ['hoverClosestPie'];
146138
} else if(hasSankey) {
139+
hoverGroup = ['hoverClosestCartesian', 'hoverCompareCartesian'];
147140
resetGroup = ['resetViewSankey'];
141+
} else { // hasPolar, hasTernary
142+
// always show at least one hover icon.
143+
hoverGroup = ['toggleHover'];
144+
}
145+
// if we have cartesian, allow switching between closest and compare
146+
// regardless of what other types are on the plot, since they'll all
147+
// just treat any truthy hovermode as 'closest'
148+
if(hasCartesian) {
149+
hoverGroup = ['toggleSpikelines', 'hoverClosestCartesian', 'hoverCompareCartesian'];
150+
}
151+
if(hasNoHover(fullData) || hasUnifiedHoverLabel) {
152+
hoverGroup = [];
148153
}
149154

150155
if((hasCartesian || hasGL2D) && !allAxesFixed) {
@@ -165,20 +170,40 @@ function getButtonGroups(gd) {
165170
dragModeGroup.push('select2d', 'lasso2d');
166171
}
167172

168-
// accept pre-defined buttons as string
173+
var enabledHoverGroup = [];
174+
var enableHover = function(a) {
175+
// return if already added
176+
if(enabledHoverGroup.indexOf(a) !== -1) return;
177+
// should be in hoverGroup
178+
if(hoverGroup.indexOf(a) !== -1) {
179+
enabledHoverGroup.push(a);
180+
}
181+
};
169182
if(Array.isArray(buttonsToAdd)) {
170183
var newList = [];
171184
for(var i = 0; i < buttonsToAdd.length; i++) {
172185
var b = buttonsToAdd[i];
173186
if(typeof b === 'string') {
174-
if(EXTRA_MODES.indexOf(b) !== -1) {
187+
if(DRAW_MODES.indexOf(b) !== -1) {
188+
// accept pre-defined drag modes i.e. shape drawing features as string
175189
if(
176-
DRAW_MODES.indexOf(b) === -1 ||
177190
fullLayout._has('mapbox') || // draw shapes in paper coordinate (could be improved in future to support data coordinate, when there is no pitch)
178191
fullLayout._has('cartesian') // draw shapes in data coordinate
179192
) {
180193
dragModeGroup.push(b);
181194
}
195+
} else if(b === 'toggleSpikelines') {
196+
enableHover('toggleSpikelines');
197+
} else if(b === 'toggleHover') {
198+
enableHover('toggleHover');
199+
} else if(b === 'hoverCompare') {
200+
enableHover('hoverCompareCartesian');
201+
} else if(b === 'hoverClosest') {
202+
enableHover('hoverClosestCartesian');
203+
enableHover('hoverClosestGeo');
204+
enableHover('hoverClosest3d');
205+
enableHover('hoverClosestGl2d');
206+
enableHover('hoverClosestPie');
182207
}
183208
} else newList.push(b);
184209
}
@@ -187,6 +212,7 @@ function getButtonGroups(gd) {
187212

188213
addGroup(dragModeGroup);
189214
addGroup(zoomGroup.concat(resetGroup));
215+
addGroup(enabledHoverGroup);
190216

191217
return appendButtonsToGroups(groups, buttonsToAdd);
192218
}
@@ -235,6 +261,14 @@ function isSelectable(fullData) {
235261
return selectable;
236262
}
237263

264+
// check whether all trace are 'noHover'
265+
function hasNoHover(fullData) {
266+
for(var i = 0; i < fullData.length; i++) {
267+
if(!Registry.traceIs(fullData[i], 'noHover')) return false;
268+
}
269+
return true;
270+
}
271+
238272
function appendButtonsToGroups(groups, buttons) {
239273
if(buttons.length) {
240274
if(Array.isArray(buttons[0])) {

test/jasmine/tests/gl3d_plot_interact_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ describe('Test gl3d modebar handlers - perspective case', function() {
457457
}
458458
},
459459
config: {
460-
modeBarButtonsToAdd: ['hoverClosest3d']
460+
modeBarButtonsToAdd: ['hoverClosest']
461461
}
462462
};
463463

@@ -537,7 +537,7 @@ describe('Test gl3d modebar handlers - perspective case', function() {
537537
expect(buttonOrbit.isActive()).toBe(false);
538538
});
539539

540-
it('@gl button hoverClosest3d should update the scene hovermode and spikes', function() {
540+
it('@gl button hoverClosest should update the scene hovermode and spikes', function() {
541541
var buttonHover = selectButton(modeBar, 'hoverClosest3d');
542542

543543
assertScenes(gd._fullLayout, 'hovermode', 'closest');

test/jasmine/tests/modebar_test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,8 @@ describe('ModeBar', function() {
10681068
Plotly.newPlot(gd, mockData, mockLayout, {
10691069
modeBarButtonsToAdd: [
10701070
'toggleSpikelines',
1071-
'hoverCompareCartesian',
1072-
'hoverClosestCartesian'
1071+
'hoverCompare',
1072+
'hoverClosest'
10731073
]
10741074
}).then(function() {
10751075
modeBar = gd._fullLayout._modeBar;
@@ -1246,7 +1246,7 @@ describe('ModeBar', function() {
12461246

12471247
gd = createGraphDiv();
12481248
Plotly.newPlot(gd, mockData, {}, {
1249-
modeBarButtonsToAdd: ['hoverClosestPie']
1249+
modeBarButtonsToAdd: ['hoverClosest']
12501250
}).then(function() {
12511251
modeBar = gd._fullLayout._modeBar;
12521252
done();
@@ -1281,7 +1281,7 @@ describe('ModeBar', function() {
12811281

12821282
gd = createGraphDiv();
12831283
Plotly.newPlot(gd, mockData, {}, {
1284-
modeBarButtonsToAdd: ['hoverClosestGeo']
1284+
modeBarButtonsToAdd: ['hoverClosest']
12851285
}).then(function() {
12861286
modeBar = gd._fullLayout._modeBar;
12871287
done();

0 commit comments

Comments
 (0)