✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
⚾️ It's finally Baseball season! Root for the home team... & Register for our Sports Analytics Webinar!

Drag and Drop Stacked Bar Chart

Hi all,

I’ve built a dash app which generates a stacked bar chart using plotly as shown for balancing processes. Currently I have an editable table, so if someone wants to move one block to a different bar, they can edit grouping in the table.

However the users would like to be to drag and drop the blocks on the graph itself (e.g. like moving postit notes on a board) in order to do the balancing - in my case clicking and dragging block “27” one to the left to balance the two bars would be an example.

Do you know if it would be possible to make such a drag and drop stacked bar chart within dash?

Thanks,

Harry

Hi @henry.k.turner, with the editable=True config option of a plotly figure, you can drag and drop shapes such as rectangles. This means that you would need to create your bar chart with shapes which is not as convenient as with px.bar or go.Bar, but markers cannot be moved in editable mode. See for example the example below adapted from https://plot.ly/python/shapes/#rectangles-positioned-relative-to-the-axes

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[1.5, 4.5],
    y=[0.75, 0.75],
    text=["Unfilled Rectangle", "Filled Rectangle"],
    mode="text",
))

# Set axes properties
fig.update_xaxes(range=[0, 7], showgrid=False)
fig.update_yaxes(range=[0, 3.5])

# Add shapes
fig.add_shape(
        # unfilled Rectangle
        go.layout.Shape(
            type="rect",
            x0=1,
            y0=1,
            x1=2,
            y1=3,
            line=dict(
                color="RoyalBlue",
            ),
        ))
fig.add_shape(
        # filled Rectangle
        go.layout.Shape(
            type="rect",
            x0=3,
            y0=1,
            x1=6,
            y1=2,
            line=dict(
                color="RoyalBlue",
                width=2,
            ),
            fillcolor="LightSkyBlue",
        ))
fig.update_shapes(dict(xref='x', yref='y'))
fig.show(config={'editable':True})

In Dash, the config is a parameter of dcc.Graph (you don’t use fig.show()). Also, you will probably want to write a callback to implement some kind of snapping to fixed positions, and move the text as well. Moving a shape will trigger a relayoutData event (see https://dash.plot.ly/interactive-graphing).

1 Like

Hi @Emmanuelle

Thanks for your help! I’ve been having a play and this may be able to work. The problem I do have currently is that I can’t make it such that the rectangles are movable, whilst stopping the use from being able to resize them.

This is because the config option:
‘edits’:{
‘shapePosition’:True,}
controls both the ability to move the rectangles, as well as the ability to resize them? Do you know if theres any way to make it such that they are movable, but not resizable?

Thanks,

Henry

2 Likes