-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Context
We want to display interactive SVG elements on a plotly plot in data coordinates. In order to do this, we currently use the _fullLayout
"private" API in order to get a handle to
- subplots
clipId
- top shape layer.
We then add a new layer for positioning interactive elements right above _fullLayout._shapeUpperLayer
, as seen here:
import { select as d3_select } from 'd3-selection';
export function getInteractorLayer(plotlyPlot, plot='xy') {
// plotlyPlot is a plotly plot object, e.g. from Plotly.newPlot() or Plotly.react()
// plot is the subplot name, e.g. 'xy', 'x2y2'
const subplot = plotlyPlot._fullLayout._plots[plot];
const shapelayer = plotlyPlot._fullLayout._shapeUpperLayer;
const layer_above = d3_select(shapelayer.node().parentNode);
// create interactor layer, if not exists:
layer_above.selectAll("g.interactorlayer")
.data(["interactors"])
.enter().append("g")
.classed("interactorlayer", true);
const interactorlayer = layer_above.selectAll("g.interactorlayer");
const clipid = subplot.clipId.replace(/plot$/, '');
return { interactorlayer, subplot, clipid };
}
Request
A public interface for getting handles to subplots, the clipId, and the top shape layer (or a simple API function for creating a new top layer!)
Once we have the items above, we can create interactors on top of a plotly plot and re-render them as needed with e.g.
plotlyPlot.on('plotly_relayout', relayout);
plotlyPlot.on('plotly_afterplot', relayout);
plotlyPlot.on('plotly_relayouting', relayout);
as seen in this demo: https://bmaranville.github.io/plotly-interactors/demo.html (drag the interactors around and look at the console to see the callbacks being called with the updated state of the interactor)
