-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
Changes from all commits
f247698
84a7c06
387e7da
079f747
189e313
a320f29
22a6f3b
18e09dc
9a3e45b
10d591b
40e3021
a79aba3
aac197e
b826ddf
b3fdb5d
74350d6
da787d7
bb3fb10
933603c
543fe14
166da3b
5c74610
ef3c734
7cd5b30
2934f11
eff56fc
ed90f81
9972341
313da5c
de960ab
897e309
08843ef
4e4afc6
3dd0c15
71033b9
26936aa
eadd7fb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
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; | ||
out.push(modeBarButtons[button]); | ||
} | ||
|
||
groups.push(out); | ||
} | ||
|
||
// buttons common to all plot types | ||
addGroup(['toImage', 'sendDataToCloud']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'); | ||
|
@@ -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) { | ||
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need for this catch anymore. |
||
context.plotGlPixelRatio = context.plot3dPixelRatio; | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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; | ||
|
@@ -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); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if users want to use our icons for their custom buttons? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah right - I forgot we had both of these... 👍 |
||
|
||
// configuration | ||
|
There was a problem hiding this comment.
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 themodebarButtonToRemove
plot config list, do not pass it the Modebar constructor.