How to store and share graph data between layouts?

Hello,

I am currently working on website that shows brainwave graphs on the website.
I have two layouts - main and sub and app.layout that contains both.

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    dcc.Store(id = 'selectedGraphFigures'),
    html.Div(id='page-content',
             children = [])
])

@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/':
        return main.layout
    elif pathname == '/sub':
        return sub.layout
    else:
        return '404'

as you can see, I made dcc.Store to store data on very top layout.
What I did is I made callback that generate graph in main.layout and store that in dcc.Store(id = ‘selectedGraphFigures’).
And then, I tried to use that data to draw graph on sub.layout.

@app.callback(
    Output('selectedGraphFigures', 'data'),
    [Input('new-win-btn', 'n_clicks')],
    [State('file-input', 'filename'),
      State('selected-graphs', 'data'),
      State('row-dropdown', 'value'),
      State('col-dropdown', 'value')]
    )
def graphs_on_newWin(clicks, input_name, selected_graphs, row, col):
    if selected_graphs is not None:

        raw = mne.io.Raw(input_name, preload=True)
    
        picks = mne.pick_types(raw.info, meg='grad', exclude=[])
        start, stop = raw.time_as_index([0, 150])
        
        n_channels = row * col
        data, times = raw[picks[:n_channels], start:stop]
        ch_names = [raw.info['ch_names'][p] for p in picks[:n_channels]]
        print(*ch_names)
        print('selected_graphs : ', selected_graphs)
        
        n = []
        for i in selected_graphs:
            n.append(i)
        n.sort()
        print('n : ', *n)
        index = len(selected_graphs)
        print('index : ', index)
        
        fig = subplots.make_subplots(
            rows = index,
            cols = 1,
            shared_xaxes = True,
            subplot_titles = ch_names
            )
        
            
        for i in range(index):
            fig.append_trace(Scatter(x=times, y=data.T[:, n[i]], yaxis='y%d' % (n[i] + 1)), i+1, 1)
     
    
        for i in fig['layout']['annotations']:
            i['font'] = dict(size=12)
            
            
        fig['layout'].update(
          height= 1500,
          # width=750, 
          
          showlegend=False, 
          # plot_bgcolor='rgb(255, 0, 0)',
          xaxis=dict(
            dtick=5,
            ticklen=8,
            tickwidth=2,
            tickcolor='#000',
            showgrid=True,
            zeroline=True,
            gridwidth=2
            ),
          )
        
        # fig['layout']['plot_bgcolor'][0].update(
        #     plot_bgcolor='rgb(255, 255, 0)',
        #     )
        print('append data to storage')
        graph_output = dcc.Graph(id = 'subplot', figure = fig)
        return graph_output
    else:
        return dash.exceptions.PreventUpdate

this callback function’s Input and States take Ids’ in main.layout and output is dcc.Store(id = ‘selectedGraphFigures’). I checked whether it really stores data with callback, and it does store data in dcc.Store.

Now the problem is that when I tried to use that data in sub.layout, it said that there is no data in the storage.
sub.layout is here.

layout = html.Div([
    html.Div(id = 'sub-graphs'),
    html.Button('dsdsdsa', id = 'sub-btn')
    ])

and this is callback function

@app.callback(
    Output('sub-graphs', 'children'),
    [Input('selectedGraphFigures', 'data')]
    )
def storage_to_sub(click, data):
    print(data)
    print("storage to sub-graph")
    return data

print(data) in this code returns None and sub.layout did not show any graphs on the page.
I also tried this also, since I thought putting dcc.Store as input might generate error.

@app.callback(
    Output('sub-graphs', 'children'),
    [Input('sub-btn', 'n_clicks')],
    [State('selectedGraphFigures', 'data')]
    )
def dsdsds(click, data):
    print(data)
    print("storage to sub-graph")
    return data

but same result for this one.

Am I doing something wrong? please tell me how to fix this.
It would be great if I click a button in main.layout, it stores data and show sub.layout with that data.
If there is other way to do this work, please feel free to give me some ideas.

update:
when I used dcc.Link to sub.layout without target=’_blank’, it worked fine, but I want it to show in different window.
If I use it without target=’_blank’, when I go back to main.layout, the page was reset. I want my main page to stay same and show sub.layout in different window with graphs.

This is one year old but I just got the same problem and found the solution. So I’m leaving it here in case anyone gets the same problem.

The problem: when the app page is opened in a new browser tab (or window) the dcc.Store returns none.

Why: The default storage type of dcc.Store is storage_type='memory' which means that data are lost when the page is refreshed (the same happens when a new tab is opened). So the storage is empty when the page is opened in a new tab.

Solution: use storage_type=‘local’ for the dcc.Store