def __init__(self, dates=None, **kwargs): # save the dates values self.dates = dates # display the dates in a text filed in a the prepend slot self.display = v.Html(tag="span", children=[""]) # create a range widget with the default params self.range = v.RangeSlider(disabled=True, v_model=[0, 1], max=1, class_="pl-5 pr-1 mt-1") # add the non conventional parameters for customization for k, val in kwargs.items(): if hasattr(self.range, k): setattr(self.range, k, val) # wrap everything in a layout super().__init__(row=True, v_model=None, xs12=True, children=[ v.Flex(xs9=True, children=[self.range]), v.Flex(xs3=True, children=[self.display]) ]) # link the v_models self.range.observe(self._on_change, 'v_model') # add the dates if existing if dates: self.set_dates(dates)
def __init__(self, widget, name="name", header="header", id_="id", **kwargs): # default self.id = id_ self.header = header self.name = name self.class_ = "ma-5" self.widget = widget self.align_center = True # creat a pencil btn self.btn = v.Icon(children=["mdi-pencil"], _metadata={"layer": id_}) # create the row super().__init__(**kwargs) self.children = [ v.Flex(align_center=True, xs1=True, children=[self.btn]), v.Flex(align_center=True, xs11=True, children=[self.widget]), ] # js behaviour self.widget.observe(self._on_change, "v_model")
def __init__(self, dates=None, **kwargs): # display the dates in a text filed in a the prepend slot self.display = v.Html(tag="span", children=[""]) # create a range widget with the default params self.slider = v.Slider(class_="pl-5 pr-1 mt-1") # add the non conventional parameters for customization for k, val in kwargs.items(): if hasattr(self.slider, k): setattr(self.slider, k, val) # wrap everything in a layout super().__init__( row=True, v_model=None, xs12=True, children=[ v.Flex(xs10=True, children=[self.slider]), v.Flex(xs2=True, children=[self.display]), ], ) # link the v_models self.slider.observe(self._on_change, "v_model") # add the real dates if existing if dates: self.set_dates(dates) else: self.disable()
def __init__(self, methods='ALL', gee=True, **kwargs): # create the map self.map = sm.SepalMap(dc=True, gee=gee) # create the view # the view include the model self.view = AoiView(methods=methods, map_=self.map, gee=gee, **kwargs) self.view.elevation = 0 # organise them in a layout layout = v.Layout(row=True, xs12=True, children=[ v.Flex(xs12=True, md6=True, class_="pa-5", children=[self.view]), v.Flex(xs12=True, md6=True, class_="pa-1", children=[self.map]) ]) # create the tile super().__init__("aoi_tile", "Select AOI", inputs=[layout], **kwargs)
def __init__(self, extentions=['.txt'], folder=os.path.expanduser('~'), label='select file', **kwargs): self.extentions = extentions self.folder = folder self.selected_file = v.TextField(label='file', v_model=self.file) self.file_list = v.List( dense=True, color='grey lighten-4', flat=True, children=[v.ListItemGroup(children=self.get_items(), v_model='')]) self.file_menu = v.Menu(min_width=300, children=[self.file_list], close_on_content_click=False, max_height='300px', v_slots=[{ 'name': 'activator', 'variable': 'x', 'children': v.Btn(v_model=False, v_on='x.on', children=[label]) }]) super().__init__(row=True, class_='pa-5', align_center=True, children=[ v.Flex(xs12=True, children=[self.selected_file]), v.Flex(xs12=True, children=[self.file_menu]) ], **kwargs) link((self.selected_file, 'v_model'), (self, 'file')) def on_file_select(change): new_value = change['new'] if new_value: if os.path.isdir(new_value): self.folder = new_value self.change_folder() elif os.path.isfile(new_value): self.file = new_value self.file_list.children[0].observe(on_file_select, 'v_model')
def __init__(self, vizapp, data=None, filename=None): self._vizapp = vizapp self.mostable = None self.mostable_dir = None self.data = data self.html = None self.current_cutout = None # Create control bar with drop down bar (OverflowBtn), back button, and next button self._back_button = v.Btn(children=["Back"], color="info") self._next_button = v.Btn(children=["Next"], color="info") self._back_button.on_event("click", self._on_back) self._next_button.on_event("click", self._on_next) self._control_bar = v.Layout(row=True, wrap=True, children=[self._back_button, self._next_button]) self._current_slit = v.OverflowBtn(label="Slit", v_model=None, items=[], width=10) self._current_slit.observe(self._on_change_current_slit, names=['v_model']) # Add to menu bar self._menu_bar = v.Layout(row=True, wrap=True, children=[ v.Flex(xs6=True, class_='px-2', children=[self._current_slit]), v.Flex(xs6=True, class_='px-2', children=[self._control_bar]) ]) # Create table and mos_widget # the table viewer must be built with the data already in. This allows the # column headers to be properly set (it's an ipysheet API constraint). For # now, the code only works when data is not None. self._table = MOSVizTable(session=self._vizapp.glue_app.session, data=data) self._mos_widget = MOSVizWidget(session=self._vizapp.glue_app.session) # Combine into main self._main_box = v.Layout(row=True, wrap=True, children=[ self._menu_bar, self._table.show(), self._mos_widget ]) if data: self.add_data(data) # not sure on how this works. Probably depends on what we # want the user interface to look at the notebook level. # It's not being exercised yet. if filename: self._vizapp.glue_app.load_data(filename)
def Tile(id_, title, inputs=[''], btn=None, output=None): """ create a customizable tile for the sepal UI framework Args: id_ (str) : the Id you want to gave to the tile. This Id will be used by the draweritems to show and hide the tile. title (str) : the title that will be display on the top of the tile btn (v.Btn, optionnal) : if the tile launch a py process, attached a btn to it. output( v.Alert, optional) : if you want to display text results of your process add an alert widget to it Returns: tile (v.Layout) : a fully functionnal tile to be display in an app """ if btn: inputs.append(btn) if output: inputs.append(output) inputs_widget = v.Layout( _metadata={'mount-id': '{}-data-input'.format(id_)}, row=True, class_="pa-5", align_center=True, children=[v.Flex(xs12=True, children=[widget]) for widget in inputs] ) tile = v.Layout( _metadata={'mount_id': id_}, row=True, xs12=True, align_center=True, class_="ma-5 d-inline", children=[ v.Card( class_="pa-5", raised=True, xs12=True, children=[ v.Html(xs12=True, tag='h2', children=[title]), v.Flex(xs12=True, children=[inputs_widget]), ] ) ] ) return tile
def set_content(self, inputs): """ Replace the current content of the tile with the provided inputs. it will keep the output and btn widget if existing. Args: inputs ([list]): the list of widget to display inside the tile Return: self """ # create the widgets content = [v.Flex(xs12=True, children=[widget]) for widget in inputs] # add the title content = [self.children[0].children[0]] + content # add the output (if existing) if self.alert: content = content + [self.alert] if self.btn: content = content + [self.btn] self.children[0].children = content return self
def __init__(self, id_, title, inputs=[''], btn=None, alert=None, **kwargs): self.btn = btn if btn: inputs.append(btn) self.alert = alert if alert: inputs.append(alert) self.title = v.Html(xs12=True, tag='h2', children=[title]) content = [v.Flex(xs12=True, children=[widget]) for widget in inputs] card = v.Card(class_="pa-5", raised=True, xs12=True, children=[self.title] + content) super().__init__(_metadata={'mount_id': id_}, row=True, align_center=True, class_="ma-5 d-inline", xs12=True, children=[card], **kwargs)
def _on_change_menu_bar_viewer(self, widget, event, data): with open("/tmp/bob.log", "a") as f: f.write(str(event) + ' ' + widget.children[0].children[0] + '\n') f.flush() if widget.children[0].children[0] == '3D Viewer': # Right now with ipyvuetify the list = list + [new] is the only # appending syntax that will update the view self._main_box.children = self._main_box.children + \ [v.Flex(xs6=True, classw='px-2', children=[ViewerND(self._vizapp).show()])] elif widget.children[0].children[0] == '1D Viewer': # Right now with ipyvuetify the list = list + [new] is the only # appending syntax that will update the view self._main_box.children = self._main_box.children + \ [v.Flex(xs6=True, classw='px-2', children=[Viewer1D(self._vizapp).show()])]
def __init__(self, label="Date", **kwargs): date_picker = v.DatePicker(no_title=True, v_model=None, scrollable=True) date_text = v.TextField(v_model=None, label=label, hint="YYYY-MM-DD format", persistent_hint=True, prepend_icon="event", readonly=True, v_on='menuData.on') menu = v.Menu(transition="scale-transition", offset_y=True, v_slots=[{ 'name': 'activator', 'variable': 'menuData', 'children': date_text, }], children=[date_picker]) super().__init__(v_model=None, row=True, class_='pa-5', align_center=True, children=[v.Flex(xs10=True, children=[menu])], **kwargs) jslink((date_picker, 'v_model'), (date_text, 'v_model')) jslink((date_picker, 'v_model'), (self, 'v_model'))
def download_tile(obj, w_selection): def bind_change(change, obj, attr): setattr(obj, attr, change['new']) w_overwrite = v.Switch(v_model=obj.overwrite, inset=True, label="Overwrite SEPAL images") w_overwrite.observe(partial(bind_change, obj=obj, attr='overwrite'), 'v_model') w_remove = v.Switch(v_model=obj.rmdrive, inset=True, label="Remove Google Drive Images") w_remove.observe(partial(bind_change, obj=obj, attr='rmdrive'), 'v_model') out = widgets.Output() btn = s.Btn(text="Download", icon='download') # Create an alert element for the process process_alert = s.Alert() on_download(obj, w_selection, btn, out, process_alert) html_header = """ <style> .widget-html span { color:black!important; } div.output_stderr{ color:none; } </style> <p>With this module you can track and download the images processed into your Google Earth Engine account by providing the 'tasks' text file, the results will be stored directly into your SEPAL account.</br> <b>Note that if you check the overwrite and remove options, the result can't be undone.</b> </p> """ download_content = v.Layout( class_="pa-5", row=True, align_center=True, children=[ v.Flex(xs12=True, children=[ v.Sheet(class_="pa-5", children=[ widgets.HTML(html_header), w_selection, w_overwrite, w_remove, btn, process_alert, out, ]) ]) ]) return download_content
def __init__(self, model, aoi_model): #gather model inputs self.model = model self.aoi_model = aoi_model # define widgets w_threshold = v.Slider(label= 'Threshold', class_="mt-5", thumb_label='always', v_model=30) # the btn and alert are created separately and linked after the call to super btn = sw.Btn('Update map', icon='mdi-check') alert = sw.Alert() # bind the widgets self.model.bind(w_threshold, 'threshold') # create a map self.m = sm.SepalMap() self.m.add_legend(legend_keys=cp.gfc_labels, legend_colors=cp.hex_palette, position='topleft') # create a layout to display the map and the inputs side by side w_inputs = v.Layout( row = True, xs12 = True, children = [ v.Flex(md6=True, children = [w_threshold, btn, alert]), v.Flex(md6=True, children = [self.m]) ] ) super().__init__( "gfc_map_tile", 'GFC visualization', inputs = [w_inputs] ) # rewire btn and alert self.btn = btn self.alert = alert # bind js events self.btn.on_event('click', self._on_click)
def __init__(self, class_path=Path("~").expanduser() / "downloads", *args, **kwargs): """Stand-alone tile composed by a select widget containing .csv reclassify files found in the class_path, and a ClassTable to edit and/or create a new classification table, Args: class_path (str) (optional): Folder path containing classification tables """ super().__init__(*args, **kwargs) self.title = v.CardTitle( children=["Edit or create new classifications"]) self.class_path = class_path self.w_class_file = v.Select( label="Select a classes file", items=self.get_items(), v_model="", dense=True, ) self.ct = ClassTable( out_path=self.class_path, schema={ "id": "number", "code": "number", "description": "string" }, ).hide() use_btn = sw.Btn("Get table") self.children = [ self.title, v.Flex( class_="ml-2 d-flex", children=[ self.w_class_file, use_btn, ], ), self.ct, ] self.get_classes_files() # Events # Listen Class table save dialog to refresh the classes widget self.ct.save_dialog.observe(self._refresh_files, "reload") # Get the corresponding table use_btn.on_event("click", self.get_class_table)
def __init__(self, html_str="", **kwargs): self.out = widgets.Output() self.update_content(html_str) super().__init__( row=True, align_center=True, class_="pa-5 ma-2", children=[v.Flex(xs12=True, children=[self.out])], **kwargs )
def draw(): return v.Layout(children=[ v.Flex(children=[ __widgets__.sel_country, __widgets__.chk_mov_ave, __widgets__.slider_mov_ave, v.Tabs(children=[ __widgets__.tab1, __widgets__.tab2, v.TabItem(children=[__plts__.fig1.fig]), v.TabItem(children=[__plts__.fig2.fig]) ]) ]) ])
def __init__(self, **kwargs): # the result widgets that will be used by the process tile self.down_btn = sw.DownloadBtn(cm.default_process.csv_btn) self.fig = Output() self.m = sm.SepalMap(['CartoDB.DarkMatter']) # you can choose in all the available basemaps of leaflet # organise them in a layout figs = v.Layout( Row = True, align_center=True, children = [ v.Flex(xs6 = True, children = [self.fig]), v.Flex(xs6 = True, children = [self.m]) ] ) # note that btn and output are not a madatory attributes super().__init__( id_ = "default_result_tile", title = cm.default_result.title, inputs = [self.down_btn, figs] )
def __init__(self, class_path=Path('~').expanduser() / 'downloads', *args, **kwargs): """Stand-alone tile composed by a select widget containing .csv reclassify files found in the class_path, and a ClassTable to edit and/or create a new classification table, Args: class_path (str) (optional): Folder path containing classification tables """ super().__init__(*args, **kwargs) self.title = v.CardTitle( children=['Edit or create new classifications']) self.class_path = class_path self.w_class_file = v.Select(label='Select a classes file', items=self.get_items(), v_model='', dense=True) self.ct = ClassTable( out_path=self.class_path, schema={ 'id': 'number', 'code': 'number', 'description': 'string' }, ).hide() use_btn = sw.Btn('Get table') self.children = [ self.title, v.Flex(class_='ml-2 d-flex', children=[ self.w_class_file, use_btn, ]), self.ct ] self.get_classes_files() # Events # Listen Class table save dialog to refresh the classes widget self.ct.save_dialog.observe(self._refresh_files, 'reload') # Get the corresponding table use_btn.on_event('click', self.get_class_table)
def shrunk(self): """when shrunked I want to display the chips int the header along the title""" # get the title title = cp.criteria_types[self.title] # get the chips chips = v.Flex(children=[ v.Chip(class_="ml-1 mr-1", small=True, children=[c.name]) for c in self.criterias if c.viz ]) # write the new header content self.header.children = [title, chips] return self
def __init__(self, mkd_str="", **kwargs): mkd = markdown(mkd_str, extensions=['fenced_code', 'sane_lists']) #need to be nested in a div to be displayed mkd = '<div>\n' + mkd + '\n</div>' #create a Html widget class MyHTML(v.VuetifyTemplate): template = traitlets.Unicode(mkd).tag(sync=True) content = MyHTML() super().__init__(row=True, class_='pa-5', align_center=True, children=[v.Flex(xs12=True, children=[content])], **kwargs)
def __init__(self, planet_key, w_state=None, *args, **kwargs): self.class_ = 'align-center mb-2' self.row = True super().__init__(*args, **kwargs) self.api_key = '' self.valid_planet = False self.client = None self.planet_key = planet_key # self.w_state = StateBar(done=True) if not w_state else w_state self.not_connected = Tooltip(widget=v.Icon(children=['mdi-circle'], color='red', x_small=True), tooltip='Not connected to Planet') self.connected = Tooltip(widget=v.Icon(children=['mdi-circle'], color='green', x_small=True), tooltip='Connected to Planet') self.w_api_key = sw.PasswordField(label='Planet API key', v_model=self.api_key) w_api_btn = sw.Btn( 'Validate ', small=True, ) w_api_key = v.Flex(class_='d-flex align-center mb-2', row=True, children=[self.w_api_key, w_api_btn]) self.children = [ self.not_connected, w_api_key, ] # Events w_api_btn.on_event('click', self._validate_api_event)
def __init__(self, bfast_tile): # create the map self.m = sm.SepalMap(gee=False) self.m.add_legend( legend_title=cm.display.legend, legend_dict={k: c for k, c in cp.legend.values()}, position="topleft", ) super().__init__( "result_tile", cm.display.title, inputs=[v.Flex(class_="mt-5 mb-5", children=[self.m])], btn=sw.Btn(cm.display.btn), alert=sw.Alert(), ) # js events bfast_tile.observe(self._change_dir, "dir_") self.btn.on_event("click", self._compute_map)
def __init__(self, mkd_str="", **kwargs): self.out = widgets.Output() mkd = markdown(mkd_str, extensions=['fenced_code','sane_lists', MathSvgExtension()]) with self.out: ipydisplay.display(ipydisplay.HTML(mkd)) #create a Html widget # class MyHTML(v.VuetifyTemplate): # template = Unicode(f'<div>{mkd}</div>').tag(sync=True) # self.content = MyHTML() super().__init__( row=True, align_center=True, class_="pa-5 ma-2", children=[v.Flex(xs12=True, children=[self.out])], **kwargs )
def __init__(self, category, criterias): # save title name self.title = category # create a header, as nothing is selected by defaul it should only display the title self.header = v.ExpansionPanelHeader( children=[cp.criteria_types[category]]) # link the criterias to the select self.criterias = [ c.disable() for c in criterias if c.header == category ] self.select = v.Select( disabled=True, # disabled until the aoi is selected class_="mt-5", small_chips=True, v_model=None, items=[c.name for c in self.criterias], label=cm.constraints.criteria_lbl, multiple=True, deletable_chips=True, persistent_hint=True, hint="select an AOI first", ) # create the content, nothing is selected by default so Select should be empty and criterias hidden criteria_flex = [ v.Flex(xs12=True, children=[c]) for c in self.criterias ] self.content = v.ExpansionPanelContent(children=[ v.Layout(row=True, children=[self.select] + criteria_flex) ]) # create the actual panel super().__init__(children=[self.header, self.content]) # link the js behaviour self.select.observe(self._show_crit, "v_model")
def __init__(self, mkd_str="", **kwargs): mkd = markdown(mkd_str, extensions=['fenced_code','sane_lists']) # need to be nested in a div to be displayed mkd = '<div>\n' + mkd + '\n</div>' # make every link to point to target black (to avoid nested iframe in sepal) mkd = mkd.replace('<a', '<a target="_blank"') # create a Html widget class MyHTML(v.VuetifyTemplate): template = Unicode(mkd).tag(sync=True) content = MyHTML() super().__init__( row=True, class_='pa-5', align_center=True, children=[v.Flex(xs12=True, children=[content])], **kwargs )
# + {"Collapsed": "false"} tab_children = [] for stage in sorted(filelist.keys()): items = filelist[stage] cards = [ v.Flex(ma_2=True, fluid=True, children=[ v.Card(hover=True, align_center=True, fluid=True, min_width='300px', max_width='300px', href=details['link'], target='_blank', children=[ v.CardTitle(children=[ v.Html(tag='div', class_='headline mb-0', children=[details['title']]), v.Spacer(), ]), v.CardText(children=[details['description']]), ]) ]) for i, details in enumerate(items) ] tab_children.append(v.Tab(children=[stage])) tab_children.append( v.TabItem(children=[v.Layout(ma_5=True, wrap=True, children=cards)]))
def __init__(self, filename, vizapp): self._vizapp = vizapp self._vizapp.glue_app.load_data(filename) # # Create File Menu # self.tile_load = v.ListTile( children=[v.ListTileTitle(children=["Load"])]) self.tile_save = v.ListTile( children=[v.ListTileTitle(children=["Save"])]) self.tile_load.on_event('click', self._on_change_menu_bar_file) self.tile_save.on_event('click', self._on_change_menu_bar_file) self.f_items = [self.tile_load, self.tile_save] self._menu_bar_file = v.Layout(children=[ v.Menu(offset_y=True, children=[ v.Btn(slot='activator', color='primary', children=[ 'File', v.Icon(right=True, children=['arrow_drop_down']) ]), v.List(children=self.f_items) ]) ]) # # Create Add Viewer Menu # self.tile_3d_viewer = v.ListTile( children=[v.ListTileTitle(children=["3D Viewer"])]) self.tile_3d_viewer.on_event('click', self._on_change_menu_bar_viewer) self.v_items = [self.tile_3d_viewer] self._menu_bar_viewer = v.Layout(children=[ v.Menu(offset_y=True, children=[ v.Btn(slot='activator', color='primary', children=[ 'Add Viewer', v.Icon(right=True, children=['arrow_drop_down']) ]), v.List(children=self.v_items) ]) ]) # Add to menu bar self._menu_bar = v.Layout(row=True, wrap=True, children=[ v.Flex(xs6=True, class_='px-2', children=[self._menu_bar_file]), v.Flex(xs6=True, class_='px-2', children=[self._menu_bar_viewer]), ]) self._menu_bar.box_style = 'success' self._v3d = ViewerND(self._vizapp) # Going to set the upper percentile rather than use the max value. self._v3d._v3d.state.layers[0].percentile = 99.5 self._main_box = v.Layout(row=True, wrap=True, children=[ v.Flex(xs12=True, class_='px-2', children=[self._menu_bar]), v.Flex(xs6=True, class_='px-2', children=[self._v3d.show()]), ])
def __init__(self): # create the different widgets # I will not use Io as the information doesn't need to be communicated to any other tile self.folder = cw.FolderSelect() self.out_dir = cw.OutDirSelect() self.tiles = cw.TilesSelect() self.poly = v.Select(label=cm.widget.harmonic.label, v_model=3, items=[i for i in range(3, 11)]) self.freq = v.Slider(label=cm.widget.freq.label, v_model=365, min=1, max=365, thumb_label="always", class_='mt-5') self.trend = v.Switch(v_model=False, label=cm.widget.trend.label) self.hfrac = v.Select(label=cm.widget.hfrac.label, v_model=.25, items=[.25, .5, 1.]) self.level = v.Slider(label=cm.widget.level.label, v_model=.95, step=.001, min=.95, max=1, thumb_label="always", class_='mt-5') self.backend = cw.BackendSelect() self.monitoring = cw.DateRangeSlider(label=cm.widget.monitoring.label) self.history = cw.DateSlider(label=cm.widget.history.label) # stack the advance parameters in a expandpanel advance_params = v.ExpansionPanels( class_='mb-5', popout=True, children=[ v.ExpansionPanel(children=[ v.ExpansionPanelHeader( children=[cm.widget.advance_params]), v.ExpansionPanelContent(children=[ v.Flex(xs12=True, children=[self.hfrac]), v.Flex(xs12=True, children=[self.level]), v.Flex(xs12=True, children=[self.backend]) ]) ]) ]) # create the tile super().__init__( "bfast_tile", cm.bfast. folder, # the title is used to describe the first section inputs=[ self.folder, self.out_dir, self.tiles, v.Html(tag="h2", children=[cm.bfast.process]), self.poly, self.freq, self.trend, advance_params, v.Html(tag="h2", children=[cm.bfast.periods]), self.history, self.monitoring ], output=cw.CustomAlert(), btn=sw.Btn(cm.bfast.btn)) # add js behaviour self.folder.observe(self._on_folder_change, 'v_model') self.btn.on_event('click', self._start_process) self.monitoring.observe(self._check_periods, 'v_model') self.history.observe(self._check_periods, 'v_model')
def date_picker_tile(Dates): import ipywidgets as widgets def bind_change(change, obj, attr): setattr(obj, attr, change['new']) # Date unique widget w_unique_date = widgets.DatePicker(description='Date', ) w_unique_cont = v.Container(class_='pa-5 d-none', children=[w_unique_date]) # Create two-way-binding with Dates object link((w_unique_date, 'value'), (Dates, 'single_date')) # Date range widget w_ini_date = widgets.DatePicker(description='Start date', ) w_ini_date_cont = v.Container(class_='pa-5 d-none', children=[w_ini_date]) link((w_ini_date, 'value'), (Dates, 'start_date')) w_end_date = widgets.DatePicker(description='End date', ) w_end_date_cont = v.Container(class_='pa-5 d-none', children=[w_end_date]) link((w_end_date, 'value'), (Dates, 'end_date')) # Season pickerr w_mmonths = v.Select( class_='d-none', multiple=True, chips=True, label='Months', deletable_chips=True, v_model=Dates.selected_months, items=Dates.months_items, ) link((w_mmonths, 'v_model'), (Dates, 'selected_months')) link((w_mmonths, 'items'), (Dates, 'months_items')) w_myears = v.Select( class_='d-none', multiple=True, chips=True, label='Years', deletable_chips=True, v_model=Dates.selected_years, items=Dates.years_items, ) link((w_myears, 'v_model'), (Dates, 'selected_years')) link((w_myears, 'items'), (Dates, 'years_items')) # Selector date method w_date_method = v.Select(v_model='', label='Specify the selection date method', items=Dates.selection_methods) # Bind the selected value to the object link((w_date_method, 'v_model'), (Dates, 'date_method')) widgets = [ w_unique_cont, w_ini_date_cont, w_end_date_cont, w_mmonths, w_myears ] # Create a behavior after change the clicked value of w_date_method wb.bind_dates(w_date_method, widgets, Dates) dates_content = v.Layout( _metadata={'mount-id': 'data-input'}, class_="pa-5", row=True, align_center=True, children=[ v.Flex(xs12=True, children=[w_date_method]), v.Flex(xs12=True, children=[w_unique_cont]), v.Flex( xs12=True, children=[ v.Layout( class_='flex-column', children=[ v.Flex(children=[w_ini_date_cont, w_end_date_cont]) ]) ]), v.Flex(xs12=True, children=[ v.Layout( class_='flex-column', children=[v.Flex(children=[ w_myears, w_mmonths, ])]) ]) ]) return dates_content
# control for linestyle line_styles = ['dashed', 'solid', 'dotted'] widget_line_styles = v.Select(items=line_styles, label='line style', v_model=line_styles[0]) widgets.link((widget_line_styles, 'v_model'), (lines, 'line_style')); display( v.Layout(pa_4=True, _metadata={'mount_id': 'content-nav'}, column=True, children=[slider, widget_line_styles]) ) # use display to support the default template fig_hist.layout.width = 'auto' fig_hist.layout.height = 'auto' fig_hist.layout.min_height = '300px' # so it still shows nicely in the notebook fig_lines.layout.width = 'auto' fig_lines.layout.height = 'auto' fig_lines.layout.min_height = '300px' # so it still shows nicely in the notebook content_main = v.Layout( _metadata={'mount_id': 'content-main'}, row=True, wrap=True, align_center=True, children=[ v.Flex(xs12=True, lg6=True, children=[ fig_hist ]), v.Flex(xs12=True, lg6=True, children=[ fig_lines ]), ]) display(content_main) # since we are not in a notebook, for default template