Skip to content

Add config options to remove specific modebar buttons #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Nov 25, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f247698
put modebar configuration into seperate modebar_config file:
etpinard Nov 19, 2015
84a7c06
clean up ModeBar API:
etpinard Nov 19, 2015
387e7da
require Icons in modebar index directly,
etpinard Nov 19, 2015
079f747
rename modebar_config -> buttons_config
etpinard Nov 20, 2015
189e313
mv create/update Modebar wrapper in modebar/ :
etpinard Nov 20, 2015
a320f29
make main modebar module export a creator function
etpinard Nov 20, 2015
22a6f3b
add update method to Modebar:
etpinard Nov 20, 2015
18e09dc
replace Modebar.cleanup with removeAllButtons:
etpinard Nov 20, 2015
9a3e45b
update Modebar.hasButtons for cases where buttons haven't been drawn yet
etpinard Nov 20, 2015
10d591b
add Modebar.destroy method
etpinard Nov 20, 2015
40e3021
add 'modebarButtonsToRemove' config argument:
etpinard Nov 20, 2015
a79aba3
generalize findButtons helper to look for buttons by category and group
etpinard Nov 20, 2015
aac197e
lint
etpinard Nov 20, 2015
b826ddf
update / add modebar jasmine tests
etpinard Nov 20, 2015
b3fdb5d
add click handler definition in modebar button config:
etpinard Nov 23, 2015
74350d6
make Modebar constructor not rely on button config in scope:
etpinard Nov 23, 2015
da787d7
update modebar manager:
etpinard Nov 23, 2015
bb3fb10
add check for button 'name':
etpinard Nov 23, 2015
933603c
robustify button config API:
etpinard Nov 23, 2015
543fe14
update modebar tests
etpinard Nov 23, 2015
166da3b
modif modebar click handler call signature:
etpinard Nov 24, 2015
5c74610
merge doSceneDragmode and domodebar relayout checks,
etpinard Nov 24, 2015
ef3c734
add full svg Icons to modebar button config
etpinard Nov 24, 2015
7cd5b30
make svg 'ascent' and 'descent' props part of every plotly icons
etpinard Nov 24, 2015
2934f11
rename 'graphInfo' --> 'gd' for consistency in modebar buttons defs
etpinard Nov 24, 2015
eff56fc
improve fallback for button 'title':
etpinard Nov 24, 2015
ed90f81
sub 'modebar' --> 'modeBar'
etpinard Nov 24, 2015
9972341
export Icons,
etpinard Nov 24, 2015
313da5c
add 'modeBarButtonsToAdd' config arg:
etpinard Nov 24, 2015
de960ab
add 'modeBarButtons' config arg:
etpinard Nov 24, 2015
897e309
Merge branch 'master' into custom-modebar
etpinard Nov 24, 2015
08843ef
make Icons.question the fall back icon
etpinard Nov 24, 2015
4e4afc6
fix condition on custom buttons
etpinard Nov 24, 2015
3dd0c15
add test for modeBar 'add' and 'fully custom' modebar buttons
etpinard Nov 24, 2015
71033b9
improve logic around button title and name
etpinard Nov 24, 2015
26936aa
add ability to multiple mode bar button groups via 'modeBarButtonToAdd'
etpinard Nov 25, 2015
eadd7fb
add comments
etpinard Nov 25, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
474 changes: 474 additions & 0 deletions src/components/modebar/buttons.js

Large diffs are not rendered by default.

626 changes: 119 additions & 507 deletions src/components/modebar/index.js

Large diffs are not rendered by default.

166 changes: 166 additions & 0 deletions src/components/modebar/manage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/**
* Copyright 2012-2015, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/


'use strict';

var Plotly = require('../../plotly');

var createModeBar = require('./');
var modeBarButtons = require('./buttons');

/**
* ModeBar wrapper around 'create' and 'update',
* chooses buttons to pass to ModeBar constructor based on
* plot type and plot config.
*
* @param {object} gd main plot object
*
*/
module.exports = function manageModeBar(gd) {
var fullLayout = gd._fullLayout,
context = gd._context,
modeBar = fullLayout._modeBar;

if(!context.displayModeBar && modeBar) {
modeBar.destroy();
delete fullLayout._modeBar;
return;
}

if(!Array.isArray(context.modeBarButtonsToRemove)) {
throw new Error([
'*modeBarButtonsToRemove* configuration options',
'must be an array.'
].join(' '));
}

if(!Array.isArray(context.modeBarButtonsToAdd)) {
throw new Error([
'*modeBarButtonsToAdd* configuration options',
'must be an array.'
].join(' '));
}

var customButtons = context.modeBarButtons;
var buttonGroups;

if(Array.isArray(customButtons) && customButtons.length) {
buttonGroups = fillCustomButton(customButtons);
}
else {
buttonGroups = getButtonGroups(
fullLayout,
context.modeBarButtonsToRemove,
context.modeBarButtonsToAdd
);
}

if(modeBar) modeBar.update(gd, buttonGroups);
else fullLayout._modeBar = createModeBar(gd, buttonGroups);
};

// logic behind which buttons are displayed by default
function getButtonGroups(fullLayout, buttonsToRemove, buttonsToAdd) {
var groups = [];

function addGroup(newGroup) {
var out = [];

for(var i = 0; i < newGroup.length; i++) {
var button = newGroup[i];
if(buttonsToRemove.indexOf(button) !== -1) continue;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if button name is part of the modebarButtonToRemove plot config list, do not pass it the Modebar constructor.

out.push(modeBarButtons[button]);
}

groups.push(out);
}

// buttons common to all plot types
addGroup(['toImage', 'sendDataToCloud']);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the modebar manager selects which buttons config objects to passed to the Modebar constructor based on the plot type.


if(fullLayout._hasGL3D) {
addGroup(['zoom3d', 'pan3d', 'orbitRotation', 'tableRotation']);
addGroup(['resetCameraDefault3d', 'resetCameraLastSave3d']);
addGroup(['hoverClosest3d']);
}

if(fullLayout._hasGeo) {
addGroup(['zoomInGeo', 'zoomOutGeo', 'resetGeo']);
addGroup(['hoverClosestGeo']);
}

var hasCartesian = fullLayout._hasCartesian,
hasGL2D = fullLayout._hasGL2D,
allAxesFixed = areAllAxesFixed(fullLayout);

if((hasCartesian || hasGL2D) && !allAxesFixed) {
addGroup(['zoom2d', 'pan2d']);
addGroup(['zoomIn2d', 'zoomOut2d', 'autoScale2d', 'resetScale2d']);
}

if(hasCartesian) {
addGroup(['hoverClosestCartesian', 'hoverCompareCartesian']);
}
if(hasGL2D) {
addGroup(['hoverClosestGl2d']);
}
if(fullLayout._hasPie) {
addGroup(['hoverClosestPie']);
}

// append buttonsToAdd to the groups
if(buttonsToAdd.length) {
if(Array.isArray(buttonsToAdd[0])) {
for(var i = 0; i < buttonsToAdd.length; i++) {
groups.push(buttonsToAdd[i]);
}
}
else groups.push(buttonsToAdd);
}

return groups;
}

function areAllAxesFixed(fullLayout) {
var axList = Plotly.Axes.list({_fullLayout: fullLayout}, null, true);
var allFixed = true;

for(var i = 0; i < axList.length; i++) {
if(!axList[i].fixedrange) {
allFixed = false;
break;
}
}

return allFixed;
}

// fill in custom buttons referring to default mode bar buttons
function fillCustomButton(customButtons) {
for(var i = 0; i < customButtons.length; i++) {
var buttonGroup = customButtons[i];

for(var j = 0; j < buttonGroup.length; j++) {
var button = buttonGroup[j];

if(typeof button === 'string')
if(modeBarButtons[button] !== undefined) {
customButtons[i][j] = modeBarButtons[button];
}
else {
throw new Error([
'*modeBarButtons* configuration options',
'invalid button name'
].join(' '));
}
}
}

return customButtons;
}
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ exports.deleteTraces = Plotly.deleteTraces;
exports.moveTraces = Plotly.moveTraces;
exports.setPlotConfig = require('./plot_api/set_plot_config');

// plot icons
exports.Icons = require('../build/ploticon');

// unofficial 'beta' plot methods, use at your own risk
exports.Plots = Plotly.Plots;
exports.Fx = Plotly.Fx;
Expand Down
21 changes: 8 additions & 13 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

var Plotly = require('../plotly');
var Events = require('../lib/events');
var manageModeBar = require('../components/modebar/manage');

var d3 = require('d3');
var m4FromQuat = require('gl-mat4/fromQuat');
Expand All @@ -31,7 +32,7 @@ var plots = Plotly.Plots;
* object describing the overall display of the plot,
* all the stuff that doesn't pertain to any individual trace
* @param {object} config
* configuration options
* configuration options (see ./plot_config.js for more info)
*
*/
Plotly.plot = function(gd, data, layout, config) {
Expand Down Expand Up @@ -399,11 +400,6 @@ function setPlotContext(gd, config) {
}
});

// cause a remake of the modebar any time we change context
if(gd._fullLayout && gd._fullLayout._modebar) {
delete gd._fullLayout._modebar;
}

// map plot3dPixelRatio to plotGlPixelRatio for backward compatibility
if(config.plot3dPixelRatio && !context.plotGlPixelRatio) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need for this catch anymore. manageModebar and Modebar.update take care of this.

context.plotGlPixelRatio = context.plot3dPixelRatio;
Expand Down Expand Up @@ -2176,7 +2172,6 @@ Plotly.relayout = function relayout(gd, astr, val) {
doplot = false,
docalc = false,
domodebar = false,
doSceneDragmode = false,
newkey, axes, keys, xyref, scene, axisAttr;

if(typeof astr === 'string') aobj[astr] = val;
Expand Down Expand Up @@ -2410,8 +2405,7 @@ Plotly.relayout = function relayout(gd, astr, val) {
* height, width, autosize get dealt with below. Except for the case of
* of subplots - scenes - which require scene.handleDragmode to be called.
*/
else if(ai==='hovermode') domodebar = true;
else if (ai === 'dragmode') doSceneDragmode = true;
else if(['hovermode', 'dragmode'].indexOf(ai) !== -1) domodebar = true;
else if(['hovermode','dragmode','height',
'width','autosize'].indexOf(ai)===-1) {
doplot = true;
Expand Down Expand Up @@ -2468,11 +2462,12 @@ Plotly.relayout = function relayout(gd, astr, val) {
return plots.previousPromises(gd);
});
}

// this is decoupled enough it doesn't need async regardless
if(domodebar) Plotly.Fx.modeBar(gd);
if(domodebar) {
manageModeBar(gd);

var subplotIds;
if(doSceneDragmode || domodebar) {
var subplotIds;
subplotIds = plots.getSubplotIds(fullLayout, 'gl3d');
for(i = 0; i < subplotIds.length; i++) {
scene = fullLayout[subplotIds[i]]._scene;
Expand Down Expand Up @@ -3006,7 +3001,7 @@ function lsInner(gd) {

Plotly.Titles.draw(gd, 'gtitle');

Plotly.Fx.modeBar(gd);
manageModeBar(gd);

return gd._promises.length && Promise.all(gd._promises);
}
18 changes: 16 additions & 2 deletions src/plot_api/plot_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,24 @@ module.exports = {
// false or function adding source(s) to linkText <text>
showSources: false,

// display the modebar (true, false, or 'hover')
// display the mode bar (true, false, or 'hover')
displayModeBar: 'hover',

// add the plotly logo on the end of the modebar
// remove mode bar button by name
// (see ./components/modebar/buttons.js for the list of names)
modeBarButtonsToRemove: [],

// add mode bar button using config objects
// (see ./components/modebar/buttons.js for list of arguments)
modeBarButtonsToAdd: [],

// fully custom mode bar buttons as nested array,
// where the outer arrays represents button groups, and
// the inner arrays have buttons config objects or names of default buttons
// (see ./components/modebar/buttons.js for more info)
modeBarButtons: false,

// add the plotly logo on the end of the mode bar
displaylogo: true,

// increase the pixel ratio for Gl plot images
Expand Down
3 changes: 1 addition & 2 deletions src/plotly.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ exports.Lib = require('./lib');
exports.util = require('./lib/svg_text_utils');
exports.Queue = require('./lib/queue');

// plot icons svg and plot css
exports.Icons = require('../build/ploticon');
// plot css
require('../build/plotcss');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if users want to use our icons for their custom buttons?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right - I forgot we had both of these... 👍


// configuration
Expand Down
2 changes: 1 addition & 1 deletion src/plots/cartesian/axes.js
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,7 @@ axes.doAutoRange = function(ax) {
};

// save a copy of the initial axis ranges in fullLayout
// use them in modebar and dblclick events
// use them in mode bar and dblclick events
axes.saveRangeInitial = function(gd, overwrite) {
var axList = axes.list(gd, '', true),
hasOneAxisChanged = false;
Expand Down
Loading