Custom Modebar Button Ordering

Hi all, I’m fairly new to Plotly, and this is my post in the community.

I’ve added a custom button to the modebar using ‘modeBarButtonsToAdd’. The button works fine, but I can’t find a way to change the ordering - as it stands, any custom added button appears at the right of the modebar. Is there any way to change this? I just want it to appear at the left of the modebar.

Example of the code:

var otherSettings = {
modeBarButtonsToAdd: [{
name: ‘Name’,
title: ‘Title’,
icon: Plotly.Icons.camera,
click: function (gd) {
console.log(‘hello’);
})
}
}]
}

Plotly.newPlot(‘container’,
data,
layout,
otherSettings
);

Thanks!

Here’s how: https://codepen.io/etpinard/pen/pLOMXR?editors=0010

Thanks for this. To confirm, the only way that buttons can be re-ordered is by manually listing each desired button in the desired order?

Yes, that’s correct.

If you want to keep up with source, as the buttons change in there, you can see the list in source by looking for:

modeBarButtons.toImage

Which begins the default button library. Internally Plotly assigns each of the default buttons to this object (modeBarButtons).

Then in manageModeBar(), it’s going to check the add, remove and modeBarButtons arrays. In the latter case, that’s a different array - the one passed in in your config object. It needs to be an array of arrays, which it will loop over in fillCustomButton (which fills all custom buttons, not just one) and if it sees a simple string like "zoom2d’, it goes and pulls that button from the default buttons and literally swaps it in for you - it loops through overwriting these string values with buttons. The rest need to be valid, custom button objects.

You can see the actual work of building buttons by looking for:
createButton = function(config)

In there you’ll learn the docs are currently incomplete. For example, instead of setting the label the user sees on mouseover with name, you can use the name property to set a code-friendly name, and set the label with another property: title. By using the name property to set a code-friendly name, you can better access your buttons from code.

Another property, attr is also available, which results in an assignment to a custom data attribute, data-attr=, so you can go in and style your icons from CSS - for example turning fill and stroke on/off, which you can’t do with the icon properties alone. An additional property val works the same way.

Here’s some sample code for reordering and styling individual buttons in the bar:

modeBarButtons: [[
	{
		name: 'download',
		attr: 'download',
		title: 'Download as Image',
		icon: {
			width: 10, height: 10,
			path: 'M5,1 L5,8 L2,5 L5,8 L8,5 M2,9 L8,9'
		},
		click: onClickDownloadImage
	}
	],['zoom2d', 'pan2d', 'select2d', 'lasso2d', 'zoomIn2d', 'zoomOut2d'
]]

So we’re swapping in a custom Download as Image button, with our own download (down arrow) icon instead of the default camera icon. The icon SVG expects strokes, not fill (the Plotly icons use fill by default), so we’re going to need to style it in a moment. And then we’ve got our own custom order and selection of the default buttons - zoom2d etc.

Then we style the download button:

div.modebar a[data-attr=download] svg.icon path {
	fill: none;
	stroke: #000;
}