Embedding nested widget options

Hello,

I have a parameter based app with two selector widgets where the options in the second widget depend on the selected value in the first widget. This works great when using a server, but I need to save this as a static html. When I use the embed=True the options for the second selector do not change when the first selector is changed.

Using embed_json, or setting the max_opts value does not change the outcome.

Is what I am trying to do possible with Panel? If so, does anyone have any suggestions for getting it to work?

Here is a reproducible example. And the two screenshots show the difference between the served version and the embedded version

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource
import param
import numpy as np
import panel as pn

class NestedEmbed(param.Parameterized):

    selector1 = param.Selector(objects=[1, 2, 3])
    selector2 = param.ObjectSelector(default=None, objects=None)
    selector2_options = param.List()

    def __init__(self, data_dict, **params):
        super().__init__(**params)
        self.data_dict = data_dict
        self.load_data()

    @param.depends('selector1', watch=True)
    def load_data(self):
        data = self.data_dict[self.selector1]
        self.hist_data = data['hist']
        self.timeseries = data['timeseries']

        self.selector2_options = list(self.timeseries.keys())

    @param.depends('selector2_options', watch=True)
    def update_select(self):
        self.param['selector2'].objects = self.selector2_options
        self.selector2 = self.selector2_options[0]
    
    @param.depends('selector1')
    def counts_view(self):
        source = ColumnDataSource(self.hist_data)
        p = figure(x_range=self.hist_data['x'], plot_height=250, title="Counts",
           toolbar_location=None, tools="")

        p.vbar(x='x', top='y', source=source, width=0.9)

        p.xgrid.grid_line_color = None
        p.y_range.start = 0

        return pn.Column(p)

    @param.depends('selector2')
    def time_view(self):
        source = ColumnDataSource(self.timeseries[self.selector2])
        p = figure(plot_height=250,
           toolbar_location=None, tools="")

        p.line(x='x', y='y', source=source)

        return pn.Column(p)

def main():

    kiwi = {'x':np.arange(0,15,1),
            'y': np.cos(np.arange(0,15,1))}
    kakapo = {'x':np.arange(0,15,1),
            'y': np.sin(np.arange(0,15,1))}
    tui = {'x':np.arange(0,15,1),
            'y': np.arange(0,15,1)**2}
    kaka = {'x':np.arange(0,15,1),
            'y': np.arange(0,15,1)**0.5}
    kereru = {'x':np.arange(0,15,1),
            'y': np.arange(0,15,1)**3}

    data = {1:{'hist': {'x':['kiwi', 'kakapo','tui'], 'y':[5, 10, 20]},
            'timeseries':{'kiwi':kiwi, 'kakapo':kakapo,'tui':tui}},
            2:{'hist': {'x':['kiwi', 'kakapo','tui', 'kaka'], 'y':[5, 10, 20, 10]},
            'timeseries':{'kiwi':kiwi, 'kakapo':kakapo,'tui':tui, 'kaka':kaka}},
            3:{'hist': {'x':['kiwi', 'kakapo','tui', 'kaka', 'kereru'], 'y':[5, 10, 20, 10, 50]},
            'timeseries':{'kiwi':kiwi, 'kakapo':kakapo,'tui':tui, 'kaka':kaka, 'kereru':kereru}}}
    
    birds = NestedEmbed(data)

    birds_view = pn.Column(birds.param['selector1'], 
                            birds.counts_view,
                            birds.param['selector2'],
                            birds.time_view)

    # birds_view.show()
    birds_view.save('nested_embed.html', embed=True, max_opts=100)

if __name__=="__main__":
    main()

Served

Here is the screenshot of the embedded version (apologies - could only include 1 image in the original post)

Embedded

Similar to this … can we nest 3 selectors?? for example

Select #1: Continent
Select #2: Country
Select #3: City

Regards
Chris

1 Like