Skip to content

Allow plotly.py to define custom modebar buttons. #6060

@CmpCtrl

Description

@CmpCtrl

First off, I don't know javascript well at all, and haven't dug into plotly.js so I don't really know how challenging this request is, but it seems simple from here.

I would like to be able to define a custom modebar button and I am using plotly.py so it appears its not currently possible, see plotly.py issue 2114. I realize I should be using plotly.js directly, but this seems like an easy enough feature to expose to plotly.py. Anyway, as far as I can tell its not possible to define the click function of a custom button from plotly.py since it dumps the config dictionary to json which of course adds double quotes around each field, ie "click": "function (gd) ...". It seems like plotly.js then interprets that as a string instead of javascript and throws an error must provide button 'click' function in button config. If i edit the html to remove the quotes around that field it works as expected, ie "click": function (gd) ....

Is it possible to edit the createButton function to also accept a string and interpret that as .js? Or, is there a better way to accomplish this? My workaround for the time being will be to edit the html after plotly.py generates it.

For reference, here is a more complete config dictionary dumped to json.

{
 "modeBarButtonsToAdd": [
  {
   "name": "Copy to Clipboard",
   "icon": {
    "path": "M102.17,29.66A3,3,0,0,0,100,26.79L73.62,1.1A3,3,0,0,0,71.31,0h-46a5.36,5.36,0,0,0-5.36,5.36V20.41H5.36A5.36,5.36,0,0,0,0,25.77v91.75a5.36,5.36,0,0,0,5.36,5.36H76.9a5.36,5.36,0,0,0,5.33-5.36v-15H96.82a5.36,5.36,0,0,0,5.33-5.36q0-33.73,0-67.45ZM25.91,20.41V6h42.4V30.24a3,3,0,0,0,3,3H96.18q0,31.62,0,63.24h-14l0-46.42a3,3,0,0,0-2.17-2.87L53.69,21.51a2.93,2.93,0,0,0-2.3-1.1ZM54.37,30.89,72.28,47.67H54.37V30.89ZM6,116.89V26.37h42.4V50.65a3,3,0,0,0,3,3H76.26q0,31.64,0,63.24ZM17.33,69.68a2.12,2.12,0,0,1,1.59-.74H54.07a2.14,2.14,0,0,1,1.6.73,2.54,2.54,0,0,1,.63,1.7,2.57,2.57,0,0,1-.64,1.7,2.16,2.16,0,0,1-1.59.74H18.92a2.15,2.15,0,0,1-1.6-.73,2.59,2.59,0,0,1,0-3.4Zm0,28.94a2.1,2.1,0,0,1,1.58-.74H63.87a2.12,2.12,0,0,1,1.59.74,2.57,2.57,0,0,1,.64,1.7,2.54,2.54,0,0,1-.63,1.7,2.14,2.14,0,0,1-1.6.73H18.94a2.13,2.13,0,0,1-1.59-.73,2.56,2.56,0,0,1,0-3.4ZM63.87,83.41a2.12,2.12,0,0,1,1.59.74,2.59,2.59,0,0,1,0,3.4,2.13,2.13,0,0,1-1.6.72H18.94a2.12,2.12,0,0,1-1.59-.72,2.55,2.55,0,0,1-.64-1.71,2.5,2.5,0,0,1,.65-1.69,2.1,2.1,0,0,1,1.58-.74ZM17.33,55.2a2.15,2.15,0,0,1,1.59-.73H39.71a2.13,2.13,0,0,1,1.6.72,2.61,2.61,0,0,1,0,3.41,2.15,2.15,0,0,1-1.59.73H18.92a2.14,2.14,0,0,1-1.6-.72,2.61,2.61,0,0,1,0-3.41Zm0-14.47A2.13,2.13,0,0,1,18.94,40H30.37a2.12,2.12,0,0,1,1.59.72,2.61,2.61,0,0,1,0,3.41,2.13,2.13,0,0,1-1.58.73H18.94a2.16,2.16,0,0,1-1.59-.72,2.57,2.57,0,0,1-.64-1.71,2.54,2.54,0,0,1,.65-1.7ZM74.3,10.48,92.21,27.26H74.3V10.48Z",
    "transform": "scale(0.12)"
   },
   "click": "function (gd) {Plotly.toImage(gd, { format: 'png', width: 2100, height: 900 }).then(async function (url) {try {const data = await fetch(url);const blob = await data.blob();await navigator.clipboard.write([new ClipboardItem({[blob.type]: blob})]);console.log('Image copied.');} catch (err) {console.error(err.name, err.message);}});}"
  }
 ]
}

Thanks for the help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions