Skip to content

Commit 0c5cf56

Browse files
committed
add multi-plot-type graphs mode bar button logic:
- graphs with more than one plot types get 'union buttons' which reset the view or toggle hover labels across all subplots.
1 parent fe0d8bb commit 0c5cf56

File tree

3 files changed

+140
-6
lines changed

3 files changed

+140
-6
lines changed

src/components/modebar/buttons.js

+39
Original file line numberDiff line numberDiff line change
@@ -497,3 +497,42 @@ function toggleHover(gd) {
497497

498498
Plotly.relayout(gd, 'hovermode', newHover);
499499
}
500+
501+
// buttons when more then one plot types are present
502+
503+
modeBarButtons.toggleHover = {
504+
name: 'toggleHover',
505+
title: 'Toggle show closest data on hover',
506+
attr: 'hovermode',
507+
val: null,
508+
toggle: true,
509+
icon: Icons.tooltip_basic,
510+
gravity: 'ne',
511+
click: function(gd, ev) {
512+
toggleHover(gd);
513+
514+
// the 3d hovermode update must come
515+
// last so that layout.hovermode update does not
516+
// override scene?.hovermode?.layout.
517+
handleHover3d(gd, ev);
518+
}
519+
};
520+
521+
modeBarButtons.resetViews = {
522+
name: 'resetViews',
523+
title: 'Reset views',
524+
icon: Icons.home,
525+
click: function(gd, ev) {
526+
var button = ev.currentTarget;
527+
528+
button.setAttribute('data-attr', 'zoom');
529+
button.setAttribute('data-val', 'reset');
530+
handleCartesian(gd, ev);
531+
532+
button.setAttribute('data-attr', 'resetLastSave');
533+
handleCamera3d(gd, ev);
534+
535+
// N.B handleCamera3d also triggers a replot for
536+
// geo subplots.
537+
}
538+
};

src/components/modebar/manage.js

+14-4
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,13 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
109109
// buttons common to all plot types
110110
addGroup(['toImage', 'sendDataToCloud']);
111111

112+
// graphs with more than one plot types get 'union buttons'
113+
// which reset the view or toggle hover labels across all subplots.
114+
if((hasCartesian || hasGL2D || hasPie) + hasGeo + hasGL3D > 1) {
115+
addGroup(['resetViews', 'toggleHover']);
116+
return appendButtonsToAdd(groups);
117+
}
118+
112119
if(hasGL3D) {
113120
addGroup(['zoom3d', 'pan3d', 'orbitRotation', 'tableRotation']);
114121
addGroup(['resetCameraDefault3d', 'resetCameraLastSave3d']);
@@ -136,13 +143,16 @@ function getButtonGroups(gd, buttonsToRemove, buttonsToAdd) {
136143
addGroup(['zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d']);
137144
}
138145

139-
if(hasCartesian) {
140-
addGroup(['hoverClosestCartesian', 'hoverCompareCartesian']);
146+
if(hasCartesian && hasPie) {
147+
addGroup(['toggleHover']);
141148
}
142-
if(hasGL2D) {
149+
else if(hasGL2D) {
143150
addGroup(['hoverClosestGl2d']);
144151
}
145-
if(hasPie) {
152+
else if(hasCartesian) {
153+
addGroup(['hoverClosestCartesian', 'hoverCompareCartesian']);
154+
}
155+
else if(hasPie) {
146156
addGroup(['hoverClosestPie']);
147157
}
148158

test/jasmine/tests/modebar_test.js

+87-2
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,9 @@ describe('ModeBar', function() {
202202
gd._fullLayout._hasCartesian = true;
203203
gd._fullLayout.xaxis = {fixedrange: false};
204204
gd._fullData = [{
205-
type:'scatter',
205+
type: 'scatter',
206206
visible: true,
207-
mode:'markers',
207+
mode: 'markers',
208208
_module: {selectPoints: true}
209209
}];
210210

@@ -295,6 +295,91 @@ describe('ModeBar', function() {
295295
checkButtons(modeBar, buttons, 1);
296296
});
297297

298+
it('creates mode bar (cartesian + gl3d version)', function() {
299+
var buttons = getButtons([
300+
['toImage', 'sendDataToCloud'],
301+
['resetViews', 'toggleHover']
302+
]);
303+
304+
var gd = getMockGraphInfo();
305+
gd._fullLayout._hasCartesian = true;
306+
gd._fullLayout._hasGL3D = true;
307+
gd._fullLayout._hasGeo = false;
308+
gd._fullLayout._hasGL2D = false;
309+
gd._fullLayout._hasPie = false;
310+
311+
manageModeBar(gd);
312+
var modeBar = gd._fullLayout._modeBar;
313+
314+
checkButtons(modeBar, buttons, 1);
315+
});
316+
317+
it('creates mode bar (cartesian + geo version)', function() {
318+
var buttons = getButtons([
319+
['toImage', 'sendDataToCloud'],
320+
['resetViews', 'toggleHover']
321+
]);
322+
323+
var gd = getMockGraphInfo();
324+
gd._fullLayout._hasCartesian = true;
325+
gd._fullLayout._hasGL3D = false;
326+
gd._fullLayout._hasGeo = true;
327+
gd._fullLayout._hasGL2D = false;
328+
gd._fullLayout._hasPie = false;
329+
330+
manageModeBar(gd);
331+
var modeBar = gd._fullLayout._modeBar;
332+
333+
checkButtons(modeBar, buttons, 1);
334+
});
335+
336+
it('creates mode bar (cartesian + pie version)', function() {
337+
var buttons = getButtons([
338+
['toImage', 'sendDataToCloud'],
339+
['zoom2d', 'pan2d', 'select2d', 'lasso2d'],
340+
['zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d'],
341+
['toggleHover']
342+
]);
343+
344+
var gd = getMockGraphInfo();
345+
gd._fullLayout._hasCartesian = true;
346+
gd._fullData = [{
347+
type: 'scatter',
348+
visible: true,
349+
mode: 'markers',
350+
_module: {selectPoints: true}
351+
}];
352+
gd._fullLayout.xaxis = {fixedrange: false};
353+
gd._fullLayout._hasGL3D = false;
354+
gd._fullLayout._hasGeo = false;
355+
gd._fullLayout._hasGL2D = false;
356+
gd._fullLayout._hasPie = true;
357+
358+
manageModeBar(gd);
359+
var modeBar = gd._fullLayout._modeBar;
360+
361+
checkButtons(modeBar, buttons, 1);
362+
});
363+
364+
it('creates mode bar (gl3d + geo version)', function() {
365+
var buttons = getButtons([
366+
['toImage', 'sendDataToCloud'],
367+
['resetViews', 'toggleHover']
368+
]);
369+
370+
var gd = getMockGraphInfo();
371+
gd._fullLayout._hasCartesian = false;
372+
gd._fullLayout._hasGL3D = true;
373+
gd._fullLayout._hasGeo = true;
374+
gd._fullLayout._hasGL2D = false;
375+
gd._fullLayout._hasPie = false;
376+
377+
manageModeBar(gd);
378+
var modeBar = gd._fullLayout._modeBar;
379+
380+
checkButtons(modeBar, buttons, 1);
381+
});
382+
298383
it('throws an error if modeBarButtonsToRemove isn\'t an array', function() {
299384
var gd = getMockGraphInfo();
300385
gd._context.modeBarButtonsToRemove = 'not gonna work';

0 commit comments

Comments
 (0)