Update "min" and "max" of Ranged Slider via "relayoutData" of Figure not working

Hi ,

i am quite new to Julia and especially Dash. So maybe there is an easy fix to my problems.

I want to plot a heatmap and then add via callback vlines to the heatmap. That is working quite well.
In another callback i want to be able to change the position of the vlines with a ranged slider. This is not working quite well, since we cant just add a trace to an existing figure. I tried a workaround with using the figure as Input in a callback and then just use addtraces! from the PlotlyJS package. This works, but the updates are quite slow, due the complexity of the origninal heatmap. There is no Dash function for just adding traces to an existing figure without recomputing the whole original figure, right?

Now to my Issue thats not working:

I want to use the slider for the visualisation of the slider values in my heatmap. Therefore i want to be able to zoom into my heatmap to increase the accuracy of my vline position. With the “relayoutData” attribute of my Heatmap i can access the current xlim and ylim positions of my Heatmap. I want to use these to update the “min” and “max” attribute of the ranged slider corresponding to my “zoom” in my Heatmap.

This should work right?

I am currently using Julia 1.5.3:

(@v1.5) pkg> st
Status `~\.julia\environments\v1.5\Project.toml`
  [1b08a953] Dash v0.1.3
  [1b08a953] DashCoreComponents v1.12.0
  [1b08a953] DashHtmlComponents v1.1.1
  [7073ff75] IJulia v1.23.0
  [f0f68f2c] PlotlyJS v0.14.0

I tried to make an easy example that illustrates my Issue.

Thank you!

    using Dash, DashHtmlComponents, DashCoreComponents,PlotlyJS
    
    app = dash(external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"])
    
    xdata= rand(1:10,3)
    ydata= rand(1:10,3)
    matrix= rand(1:10,3,3)
    
    
    
    function vline(xposition,ydata)
    
        scatter(Dict(
                    :mode => "lines",  
                    :x => fill(xposition,2), 
                    :y => [minimum(ydata),maximum(ydata)],
                
                ),
                showlegend=false,
                marker_line_width = 0.5,
                marker_opacity = 0.8,
                line_color= "#da0a72b6"
        ) 
    end
    
                                            #Main layout
    
    app.layout =    html_div() do
        html_div(
            children=[
                dcc_graph(  
                    id="Hidden-Heatmap",
                    figure = (
                        Plot(
                            heatmap(
                                Dict( 
                                    :type => "heatmap", 
                                    :x => xdata, 
                                    :y => ydata,
                                    :z => [matrix[i,:] for i in 1:size(matrix)[1]]
                                ),
                                zmax= 10,
                                zmin= 0 ,
                                colorscale= "Viridis"
                            ),
                            Layout(
                                uirevision = "zoom"
                            )
                        )
                    ),style= Dict(
                        :display => "none"
                    )
                 ),
                html_div(
                    children =[
                        dcc_graph(id="Heatmap",
                        ),
                        html_div(
                            id="Slider Div",
                            dcc_rangeslider(
                                id = "Ranged Slider",
                                step = 0.01,
                                min=0,
                                max=10,
                                value=[3,5],
                                persistence=true ,
                                allowCross=false,          
                            )
                        )
                    ]
                )
            ],
            className ="twelve columns"
        ) 
    end
    
    # Vline into Graph from Hidden Graph figure
    callback!(app,
    Output("Heatmap","figure"),
    Input("Ranged Slider","value"),
    State("Hidden-Heatmap","figure")) do value,current_fig
        @show length(value)
        
            type = current_fig[:data][1][:type]
            zmax = current_fig[:data][1][:zmax]
            zmin = current_fig[:data][1][:zmin]
            
            xdata = current_fig[:data][1][:x]
            ydata = current_fig[:data][1][:y]
            zdata = current_fig[:data][1][:z]
        
            cur_plot =  Plot(
                            heatmap(
                                Dict( 
                                    :type => type, 
                                    :x    => xdata, 
                                    :y    => ydata,
                                    :z    => zdata
                                ),
                                zmax = 10,
                                zmin = 1,
                                colorscale= "Viridis",
                                uirevision = "zoom"
                            ),
                            Layout(uirevision = "zoom"
                            )
                        )  
                for i in 1:length(value)     
                    addtraces!(cur_plot,vline(value[i],ydata))
                end
            return figure=(cur_plot)
        
    end
    
    
    # Autosize range of ranged sliders to Zoom of Heatmap
    callback!(app,
    Output("Ranged Slider","min"),
    Output("Ranged Slider","max"),
    Input("Heatmap","relayoutData"),
    State("Heatmap","figure"))  do   range,figure 
    
        # Set ranges of RangedSliders 
        ## if relayoutData is at default
        if  (try range[:autosize]  catch end !== nothing)
            xdata_fig = figure[:data][1][:x]
            min = minimum(xdata_fig)
            max = maximum(xdata_fig)
    
                return min,max
        ## changed the zoom
        elseif  try range[:autosize]  catch end === nothing && typeof(range) == (NamedTuple{(Symbol("xaxis.range[0]"), Symbol("xaxis.range[1]"), Symbol("yaxis.range[0]"), Symbol("yaxis.range[1]")),NTuple{4,Float64}})
            min = range[1]
            max = range[2]
        
                return min,max
        ## set back to autosize
        elseif  try range[:autosize]  catch end === nothing && typeof(range) == (NamedTuple{(Symbol("xaxis.autorange"), Symbol("yaxis.autorange")),Tuple{Bool,Bool}})
            xdata_fig = figure[:data][1][:x]
            min = minimum(xdata_fig)
            max = maximum(xdata_fig)    
    
                return min,max
        else 
            return Dash.no_update(), Dash.no_update()
        end
    end
    
    
    run_server(app, "0.0.0.0", debug=true)