"Duplicate Page" functionality for multi-tab work

Hello everyone,

I am exploring features in Dash and would like to know if there is an existing capability similar to the “duplicate page” functionality found in Power BI or Tableau, which allows users to work with multiple tabs. Is this a built-in feature in Dash Enterprise? Could anyone provide examples or documentation on how to implement this in Dash?

Additionally, I am interested in an efficient method for transferring data series between charts or tabs. For instance, if I have a line chart with multiple series, how could I select a specific series and send it to another plot area within the application? Are there built-in mechanisms or best practices for this type of data interaction in Dash? I can imagine I could send virtualRowData which is already a basis for plots in my app but would still need easy way to define relevant rows based on data series selection (possibly in plot area).

Hello @davzup89,

Yes, this is possible in Dash.

app.py

import dash
from dash import Dash, Input, Output, State, html, dcc, no_update, Patch

app = Dash(__name__)

import dash_mantine_components as dmc

app.layout = html.Div([
    html.Button('Duplicate', id='dup', n_clicks=0),
    dmc.Tabs(
        [
            dmc.TabsList(
                [
                    dmc.Tab("Gallery", value="gallery"),
                    dmc.Tab("Messages", value="messages"),
                    dmc.Tab("Settings", value="settings"),
                ],
                id='tabsList'
            ),
            dmc.TabsPanel("Gallery tab content", value="gallery", pb="xs"),
            dmc.TabsPanel("Messages tab content", value="messages", pb="xs"),
            dmc.TabsPanel("Settings tab content", value="settings", pb="xs"),
        ],
        value="gallery",
        id='tabs'
    )
    ]
)

@app.callback(
    Output('tabs', 'children'), Output('tabs', 'value'), Output('tabsList', 'children'),
    Input('dup', 'n_clicks'), State('tabs', 'value'), State('tabs', 'children')
)
def dupTab(n, v, s):
    if n:
        newChildren = Patch()
        newList = Patch()
        newInt = '1'
        try:
            newInt = str(int(v.split('-')[1])+1)
        except:
            pass
        newValue = v.split('-')[0] + '-' + newInt
        for children in s[1:]:
            if children['props']['value'] == v:
                newChild = children
                newChild['props']['value'] = newValue
                newChildren.append(newChild)
        for children in s[0]['props']['children']:
            if children['props']['value'] == v:
                newChild = children
                newChild['props']['value'] = newValue
                newChild['props']['children'] = newValue
                newList.append(newChild)
        return newChildren, newValue, newList
    return [no_update]*3

app.run(debug=True)

As far as pulling data from a figure to go to another chart, yes, this is possible, you’d just need to select it from the ‘data’ that corresponds to the selected plot in the figure.

4 Likes

Hi @davzup89

If the content is dynamic, you can also use pattern matching callbacks. Here are a couple examples:

3 Likes

Thank you both! Very useful, will try to implement it in my app.

1 Like

@jinnyzor and @AnnMarieW in formation flight. Topic solved. :joy: :hugs:

2 Likes