New Component - Dash Dynamic Grid Layout 🎛️

Dynamic Grid Example

This ddgl component is accessible through callbacks, the data appears in a format of:

[{"i": "draggable-map-1", "x": 5, "y": 0, "w": 7, "h": 4}, {"i": "draggable-map-2", "x": 7, "y": 4, "w": 2, "h": 2}, {"i": "draggable-map-3", "x": 5, "y": 4, "w": 2, "h": 2}, {"i": "3", "x": 2, "y": 6, "w": 2, "h": 2}, {"i": "4", "x": 0, "y": 0, "w": 5, "h": 6}]

With removing components this is done through setting up a callback of:

@callback(
    Output("grid-layout", "items", allow_duplicate=True),
    Input("grid-layout", "itemToRemove"),
    State("grid-layout", "itemLayout"),
    prevent_initial_call=True,
)
def remove_component(key, layout):
    if key:
        items = Patch()
        print(key)
        for i in range(len(layout)):
            if layout[i]['i'] == key:
                del items[i]
                break
        return items
    return no_update

It basically loops through the existing list of components and deletes the one that was removed.

You can also pre define a layout on load with a ddgl setup similar to:

import dash_dynamic_grid_layout as ddgl
from dash import Dash, html, dcc
import plotly.express as px

app = Dash(__name__)

df = px.data.iris()

app.layout = html.Div([
    ddgl.DashGridLayout(
        id='grid-layout',
        items=[
            ddgl.DraggableWrapper(html.Div('Item 1', ), id='item1'),
            ddgl.DraggableWrapper(html.Div('Item 2',), id='item2')
        ],
        itemLayout=[
            {'i': 'item1', 'x': 0, 'y': 0, 'w': 2, 'h': 4},
            {'i': 'item2', 'x': 4, 'y': 0, 'w': 4, 'h': 2}
        ],
        rowHeight=150,
        cols={'lg': 12, 'md': 10, 'sm': 6, 'xs': 4, 'xxs': 2},
        style={'height': '600px'},
    )
])


if __name__ == "__main__":
    app.run_server(debug=True, port=8321)

basically you assign the Wrappers with unique id’s and connect those id’s in the itemLayout with the associated location width and size you’d like on load.

When designing the component I used a dmc.Menu to show two options for the ddgl component, which could be triggered with callbacks the add_dynamic_component and the edit_mode .

The idea was to be able to enter edit mode, move components around and save them to the layout. Once placed and exited out of edit mode the components within the wrapper take up the full size allotted to them without the possibility of accidentally closing or moving them without re-entering edit mode.

@jinnyzor Has really polished out the package, I’ve initially come up with concept and built the documentation around the component but BSDEV has put in a ton of work getting the project to an official 0.1.0 State, everything is running a lot more polished and I’ll be working on better documentation when I find the time in the near future but their should be enough references to start using it. This component shouldn’t conflict with other callbacks if you structure it properly and we have tested it on most browsers and operating systems from computers to tablets to phones.

1 Like

This is great - thx for pulling this together. I was testing it however, and found that if you have callbacks in the DraggableWrapper they where being blocked by the looks of it and not updating any components. i can see the callbacks being triggered and the callback function running but the output is not being rendered in the DraggableWrapper. I was wonderinng if you have tried somethign like this or is it something im doing wrong…cheers

@jinnyzor

  • fixed issue with allowing callbacks to re-render the layout
  • this created another issue with the max call stack
    • fixed this by reducing the circular variables created in data-grid
  • removed persistence as it is no longer supported

Basically the grid looked really nice but the components within a DraggableWrapper their callbacks wouldn’t work. The project removed the persistence for the moment and made some other changes to allow callbacks within DraggableWrappers to work. But on refresh the DashGridLayout resets to its origin layout.

Fixed a major bug, lost the cool feature of persistence.

Newest Release: dash-dynamic-grid-layout==0.1.1

2 Likes