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 __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, label="Thresholds"): # hidden textfield to save the v_model # the v_model will be stored as json self.save = v.TextField(v_model=None) # create the inputs self.text_fields = [ v.TextField(placeholder=cm.frag.window_lbl.format(i + 1), v_model=None, type="number", class_='ml-1 mr-1', hint=cm.frag.invalid_window) for i in range(10) ] # title title = v.Html(tag='h4', children=[label]) # add js behaviour for w in self.text_fields: w.observe(self._on_change, 'v_model') w.on_event('focusout', self._on_focusout) super().__init__( class_="ma-5", row=True, children=[title, v.Layout(row=True, children=self.text_fields)])
def __init__(self, label="Thresholds"): # hidden textfield to save the v_model # the v_model will be stored as json self.save = v.TextField(v_model=None) # create the inputs self.text_fields = [ v.TextField(placeholder=f'threshold {i+1}', v_model=None, type="number", class_='ml-1 mr-1', hint=cm.acc.res_hint) for i in range(5) ] # title title = v.Html(tag='h4', children=[label]) for w in self.text_fields: w.observe(self._on_change, 'v_model') w.on_event('focusout', self._on_focus_out) super().__init__( class_="ma-5", row=True, children=[title, v.Layout(row=True, children=self.text_fields)])
def __init__(self, aoi_model, model, **kwargs): # gather the model self.aoi_model = aoi_model self.model = model self.scale = v.TextField(label=cm.export.scale, v_model=30) # create buttons self.asset_btn = sw.Btn( cm.export.asset_btn, "mdi-download", disabled=True, class_="ma-5" ) self.sepal_btn = sw.Btn( cm.export.sepal_btn, "mdi-download", disabled=True, class_="ma-5" ) # bindings self.model.bind(self.scale, "scale") # note that btn and alert are not a madatory attributes super().__init__( id_="export_widget", title=cm.export.title, inputs=[self.scale], alert=sw.Alert(), btn=v.Layout(row=True, children=[self.asset_btn, self.sepal_btn]), ) # link the btn self.asset_btn.on_event("click", self._on_asset_click) self.sepal_btn.on_event("click", self._on_sepal_click)
def __init__(self, statebar=None, **kwargs): super().__init__(**kwargs) self.gdf = None # Parameters self.out_path = Path('') self.json_path = None # Widgets self.shape_input = sw.FileInput(['.shp'], os.getcwd()) self.w_state_bar = sw.StateBar( loading=True) if not statebar else statebar # Link behaviours link((self.shape_input, 'file'), (self, 'shapefile')) # View self.children = [v.Layout(row=True, children=[ self.shape_input, ])] # Add a statebar if there is not provided an external one if not statebar: self.children = self.children + [self.w_state_bar]
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, aoi_model, model, viz_tile, export_tile, **kwargs): # gather the model self.aoi_model = aoi_model self.model = model self.viz_tile = viz_tile self.export_tile = export_tile # widgets w_time_title = v.Html(tag="H3", class_="mt-3", children=[ms.selection.time_range]) self.start_picker = sw.DatePicker(label=ms.selection.start) self.end_picker = sw.DatePicker(label=ms.selection.end) w_time_range = v.Layout(row=True, children=[self.start_picker, self.end_picker]) w_collection_title = v.Html(tag="H3", class_="mt-3", children=[ms.selection.collection]) self.sensors = v.Select( label=ms.selection.sensor, items=pm.sensors, v_model=None, chips=True, multiple=True, ) self.t2 = v.Switch(class_="ml-5", label=ms.selection.t2, v_model=False) self.sr = v.Switch(class_="ml-5", label=ms.selection.sr, v_model=False) self.model.bind(self.start_picker, "start").bind(self.end_picker, "end").bind( self.sensors, "sensors").bind(self.t2, "t2").bind(self.sr, "sr") # construct the Tile with the widget we have initialized super().__init__( id_= "selection_widget", # the id will be used to make the Tile appear and disapear title=ms.selection. title, # the Title will be displayed on the top of the tile inputs=[ w_time_title, w_time_range, w_collection_title, self.sensors, self.t2, self.sr, ], btn=sw.Btn(ms.selection.btn), alert=sw.Alert(), ) # now that the Tile is created we can link it to a specific function self.btn.on_event("click", self._on_run)
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, model): # create the widgets baseline_title = v.Html(tag="h4", children=[cm.input_lbl.baseline], class_="mb-0 mt-5") baseline_start_picker = sw.DatePicker(label=cm.input_lbl.start) baseline_end_picker = sw.DatePicker(label=cm.input_lbl.end) baseline_picker_line = v.Layout( xs12=True, row=True, children=[baseline_start_picker, baseline_end_picker]) analysis_title = v.Html(tag="h4", children=[cm.input_lbl.analysis], class_="mb-0 mt-5") analysis_start_picker = sw.DatePicker(label=cm.input_lbl.start) analysis_end_picker = sw.DatePicker(label=cm.input_lbl.end) analysis_picker_line = v.Layout( xs12=True, row=True, children=[analysis_start_picker, analysis_end_picker]) # bind the widgets model.bind(baseline_start_picker, "reference_start").bind( baseline_end_picker, "reference_end").bind(analysis_start_picker, "analysis_start").bind( analysis_end_picker, "analysis_end") super().__init__( "nested_widget", cm.tile.time, inputs=[ baseline_title, baseline_picker_line, analysis_title, analysis_picker_line, ], )
def close_filter_tile(w_selector): def on_click(widget, event, data, out, obj, alert): # Get the current path process_path = obj.get_current_path() # Clear output if there is something printed before out.clear_output() # Once the button is clicked, disable it btn.disable() # Clear old alert messages alert.clear() @out.capture() def run_process(obj): run_filter( process_path, alert, ) run_process(obj) btn.activate() out = Output() btn = s.Btn(text="Start") # Create an alert element for the process alert = s.Alert() content = v.Layout(xs12=True, row=True, class_="ma-5 d-block", children=[ filter_text, w_selector, btn, alert, out, ]) btn.on_event('click', partial( on_click, obj=w_selector, out=out, alert=alert, )) return content
def __init__(self, test_case_widget, lb_scheme_widget, discret_widget, **kwargs): self.test_case_widget = test_case_widget self.lb_scheme_widget = lb_scheme_widget self.discret_widget = discret_widget self.params, self.relax_params = None, None self.select_param = v.Select(label='Parameters', v_model=None, items=[]) self.select_relax = v.Select(label='relaxation rates', v_model=[], items=[], multiple=True, class_='d-none') self.srt_relax = v.Switch(label='Single relaxation time', v_model=True, class_='d-none') self.sigma = v.Switch(label='Using sigma', v_model=False, class_='d-none') self.in_log = v.Switch(label='Using log10', v_model=False, class_='d-none') self.minmax = v.Layout() self.update_select_fields(None) test_case_widget.select_case.observe(self.update_select_fields, 'v_model') lb_scheme_widget.select_case.observe(self.update_select_fields, 'v_model') discret_widget['dx'].observe(self.update_select_fields, 'v_model') self.fields = [ self.select_param, self.select_relax, self.srt_relax, self.sigma, self.in_log, self.minmax ] super().__init__(v_model='valid', children=self.fields) self.select_param.observe(self.select_param_changed, 'v_model') self.select_relax.observe(self.select_relax_all, 'v_model') self.select_relax.observe(self.check_changes, 'v_model') self.in_log.observe(self.check_changes, 'v_model') self.sigma.observe(self.check_changes, 'v_model')
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, 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, **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 run_process_tile(aoi, dates): """ Display the given input values and start de process """ # Instantiate an Output() widget to capture the module outputs. # such as stderr or stdout out = widgets.Output() btn = s.Btn(text="Start") # Create an alert element for the process process_alert = s.Alert() content = v.Layout(xs12=True, row=True, class_="ma-5 d-block", children=[ btn, process_alert, out, ]) wb.bin_pysmm_process(aoi, dates, btn, out, process_alert) return content
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
def update_range(*ignore): if selector.selected is not None and len(selector.selected) == 2: xmin, xmax = selector.selected mask = (x > xmin) & (x < xmax) hist.sample = y[mask] selector.observe(update_range, 'selected') # 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'},
def create_tools(self): self.tools = [] tool_actions = [] self.tool_actions_map = tool_actions_map = {u"pan/zoom": self.panzoom} tool_actions.append(u"pan/zoom") # self.control_widget.set_title(0, "Main") self._main_widget = widgets.VBox() self._main_widget_1 = widgets.HBox() self._main_widget_2 = widgets.HBox() if 1: # tool_select: self.brush = bqplot.interacts.BrushSelector(x_scale=self.scale_x, y_scale=self.scale_y, color="green") tool_actions_map["select"] = self.brush tool_actions.append("select") self.brush.observe(self.update_brush, ["selected", "selected_x"]) # fig.interaction = brush # callback = self.dataset.signal_selection_changed.connect(lambda dataset: update_image()) # callback = self.dataset.signal_selection_changed.connect(lambda *x: self.update_grid()) # def cleanup(callback=callback): # self.dataset.signal_selection_changed.disconnect(callback=callback) # self._cleanups.append(cleanup) self.button_select_nothing = v.Btn( icon=True, v_on='tooltip.on', children=[v.Icon(children=['delete'])]) self.widget_select_nothing = v.Tooltip( bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': self.button_select_nothing }], children=["Delete selection"]) self.button_reset = widgets.Button(description="", icon="refresh") import copy self.start_limits = copy.deepcopy(self.limits) def reset(*args): self.limits = copy.deepcopy(self.start_limits) with self.scale_y.hold_trait_notifications(): self.scale_y.min, self.scale_y.max = self.limits[1] with self.scale_x.hold_trait_notifications(): self.scale_x.min, self.scale_x.max = self.limits[0] self.plot.update_grid() self.button_reset.on_click(reset) self.button_select_nothing.on_event( 'click', lambda *ignore: self.plot.select_nothing()) self.tools.append(self.button_select_nothing) self.modes_names = "replace and or xor subtract".split() self.modes_labels = "replace and or xor subtract".split() self.button_selection_mode = widgets.Dropdown( description='select', options=self.modes_labels) self.tools.append(self.button_selection_mode) def change_interact(*args): with self.output: # print "change", args name = tool_actions[self.button_action.v_model] self.figure.interaction = tool_actions_map[name] tool_actions = ["pan/zoom", "select"] # tool_actions = [("m", "m"), ("b", "b")] self.button_action = \ v.BtnToggle(v_model=0, mandatory=True, multiple=False, children=[ v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['pan_tool']) ]) }], children=[ "Pan & zoom" ]), v.Tooltip(bottom=True, v_slots=[{ 'name': 'activator', 'variable': 'tooltip', 'children': v.Btn(v_on='tooltip.on', children=[ v.Icon(children=['crop_free']) ]) }], children=[ "Square selection" ]), ]) self.widget_tool_basic = v.Layout(children=[ v.Layout( pa_1=True, column=False, align_center=True, children=[self.button_action, self.widget_select_nothing]) ]) self.plot.add_control_widget(self.widget_tool_basic) self.button_action.observe(change_interact, "v_model") self.tools.insert(0, self.button_action) self.button_action.value = "pan/zoom" # tool_actions[-1] if len(self.tools) == 1: tools = [] # self._main_widget_1.children += (self.button_reset,) self._main_widget_1.children += (self.button_action, ) self._main_widget_1.children += (self.button_select_nothing, ) # self._main_widget_2.children += (self.button_selection_mode,) self._main_widget.children = [self._main_widget_1, self._main_widget_2] self.control_widget.children += (self._main_widget, ) self._update_grid_counter = 0 # keep track of t self._update_grid_counter_scheduled = 0 # keep track of t
def __init__(self, questionnaire_tile, aoi_model, area_tile, theme_tile): # add the explanation mkd = sw.Markdown(" \n".join(cm.map.txt)) # create a save widget self.save = cw.ExportMap() # create the map self.m = sm.SepalMap(dc=True).hide_dc() self.m.add_control(WidgetControl(widget=self.save, position="topleft")) self.m.add_colorbar(colors=cp.red_to_green, vmin=1, vmax=5) # create a window to display AOI information self.html = HTML() self.html.layout.margin = "0em 2em 0em 20em" control = WidgetControl(widget=self.html, position="bottomright") self.m.add_control(control) # drawing managment self.draw_features = deepcopy(self.EMPTY_FEATURES) self.colors = [] self.name_dialog = cw.CustomAoiDialog() # create a layout with 2 btn self.map_btn = sw.Btn(cm.compute.btn, class_="ma-2") self.compute_dashboard = sw.Btn(cm.map.compute_dashboard, class_="ma-2", disabled=True) # models self.layer_model = questionnaire_tile.layer_model self.question_model = questionnaire_tile.question_model self.aoi_model = aoi_model # create the shape loader self.load_shape = cw.LoadShapes() # get the dashboard tile self.area_tile = area_tile self.theme_tile = theme_tile # init the final layers self.wlc_outputs = None self.area_dashboard = None self.theme_dashboard = None # create the tile super().__init__( id_="map_widget", title=cm.map.title, inputs=[mkd, self.load_shape, self.m, self.name_dialog], alert=sw.Alert(), btn=v.Layout(children=[self.map_btn, self.compute_dashboard]), ) # decorate the function self._compute = su.loading_button(self.alert, self.map_btn, debug=True)(self._compute) self._dashboard = su.loading_button(self.alert, self.compute_dashboard, debug=True)(self._dashboard) # add js behaviour self.compute_dashboard.on_event("click", self._dashboard) self.m.dc.on_draw(self._handle_draw) self.map_btn.on_event("click", self._compute) self.load_shape.btn.on_event("click", self._load_shapes) self.name_dialog.observe(self.save_draw, "value")
def __init__(self, filename, vizapp, process_data=None): self._vizapp = vizapp self._vizapp.glue_app.load_data(filename) if process_data is not None: process_data(self) # # 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_1d_viewer = v.ListTile( children=[v.ListTileTitle(children=["1D Viewer"])]) self.tile_3d_viewer.on_event('click', self._on_change_menu_bar_viewer) self.tile_1d_viewer.on_event('click', self._on_change_menu_bar_viewer) self.v_items = [self.tile_3d_viewer, self.tile_1d_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._v1d = Viewer1D(self._vizapp) self._v3d = ViewerND(self._vizapp) 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()]), v.Flex(xs6=True, class_='px-2', children=[self._v1d.show()]), ])
def __init__(self, test_case, known_cases): """ Widget definition for lattice Boltzmann schemes. Parameters ========== - test_case: the selected test case. - known_cases: dict A dictionary of all known cases the keys are an instance of a test case the values are a list of available lattice Boltzmann schemes for this test case This widget is composed by a menu where you can Choose the lb scheme and modify its default parameters. If you change any of the parameters, you will see a reset button to revover the default parameters of this scheme. This widget is also composed by a main widget where we have 3 tabs - the description of the lb scheme, - the properties of the lb scheme, - the equivalent equations of the lb scheme. """ self.test_case = test_case self.known_cases = known_cases self.default_cases = {c.name: c for c in known_cases[test_case.get_case()]} self.cases = {c.name: copy.copy(c) for c in known_cases[test_case.get_case()]} self.parameters = {} ## ## The menu ## default_case = list(self.cases.keys())[0] self.select_case = v.Select(items=list(self.cases.keys()), v_model=default_case, label='LBM schemes') self.panels = v.ExpansionPanels(v_model=None, children=[ParametersPanel('Show parameters')]) self.reset = v.Btn(children=['reset to default'], class_='d-none') self.menu = [self.select_case, self.panels, self.reset] ## ## The main ## self.description = Markdown() self.properties = v.Layout() self.eq_pde = v.Layout() self.tabs = v.Tabs( v_model=0, children= [ v.Tab(children=['Description']), v.Tab(children=['Properties']), v.Tab(children=['Equivalent equations']), v.TabItem(children=[self.description]), v.TabItem(children=[self.properties]), v.TabItem(children=[self.eq_pde]), ] ) self.main = [self.tabs] # populate the parameters and the description of the selected # lb scheme self.change_case(None) ## ## Widget events ## self.select_case.observe(self.change_case, 'v_model') # Allow to go back to the default parameters self.reset.on_event('click', self.reset_btn) # Check the tab id to activate the computation # of the equivalent equations or the scheme properties # since it can take time. self.tabs.observe(self.change_tab, 'v_model') # If the test case is changed, we need to list the available # lb schemes for this test. self.test_case.select_case.observe(self.change_test_case, 'v_model') # Bind each parameter to change_param # to make the reset button available if needed. self.panels.children[0].bind(self.change_param)
def statistics_tile(w_selector, statistics_io): def on_click(widget, event, data, path_selector, date_selector, statistic, alert, out): # Clear output if there is something printed before out.clear_output() # Once the button is clicked, disable it btn.disable() # Clear old alert messages alert.clear() @out.capture() def run_process(path_selector, date_selector, statistic, alert): stack_composed(path_selector, date_selector, statistic, alert) run_process(path_selector, date_selector, statistic, alert) # Reactivate button btn.activate() def field_change(change, date_selector, alert): alert.clear() months_and_years = get_months_years(w_selector.get_current_path(), alert) if months_and_years: years, months = months_and_years else: # Stop the excecution return date_selector.clear_season() parsed_months = date_selector.numbers_to_months(months) date_selector.months_items = parsed_months date_selector.years_items = years alert = s.Alert() btn = s.Btn(text="Calculate statistics") out = Output() date_selector = DateSelector(season=True, remove_method=['Single date']) field_widget = w_selector.widget_field() field_widget.observe( partial(field_change, date_selector=date_selector, alert=alert), 'v_model') date_tile = date_picker_tile(date_selector) w_stats = v.Select( label='Statistic', items=statistics_io.items, v_model=statistics_io.selected, ) link((w_stats, 'items'), (statistics_io, 'items')) link((w_stats, 'v_model'), (statistics_io, 'selected')) w_cores = v.Slider(v_model=statistics_io.cores, thumb_label='Always', step=1, label='Processors', min=1, max=statistics_io.cores) link((w_cores, 'v_model'), (statistics_io, 'cores')) w_chunk = v.Slider(v_model=200, thumb_label='Always', step=20, label='Chunk size', max=1000, min=20) link((w_chunk, 'v_model'), (statistics_io, 'chunks')) advanced_settings = v.ExpansionPanels( flat=False, children=[ v.ExpansionPanel(children=[ v.ExpansionPanelHeader(children=['Advanced settings']), v.ExpansionPanelContent(children=[w_cores, w_chunk]) ], ), ]) btn.on_event( 'click', partial( on_click, path_selector=w_selector, date_selector=date_selector, statistic=statistics_io, alert=alert, out=out, )) content = v.Layout(dark=True, _metadata={'mount-id': 'data-input'}, class_="pa-5", row=True, align_center=True, children=[ v.Flex(xs12=True, children=[ statistics_text, v.Subheader(children=['Area selection']), v.Divider(), w_selector, v.Subheader(children=['Date selection']), v.Divider(), date_tile, v.Divider(), w_stats, advanced_settings, btn, alert, out ]), ]) return content
def __init__(self, viz_model, tb_model): # gather model self.viz_model = viz_model self.tb_model = tb_model # Create alert self.alert = sw.Alert() # create the widgets self.driver = v.RadioGroup( label = cm.viz.driver, row= True, v_model = self.viz_model.driver, children = [ v.Radio(key=i, label=n, value=n) for i, n in enumerate(cp.drivers) ] ) self.sources = v.Select( items=cp.sources, label=cm.viz.sources, v_model=self.viz_model.sources, multiple=True, chips=True ) self.planet_key = sw.PasswordField( label = cm.planet.key_label ).hide() self.semester = v.RadioGroup( label = cm.viz.semester, row= True, v_model = None, children = [ v.Radio(label=cp.planet_semesters[n], value=n) for n in [*cp.planet_date_ranges[cp.planet_min_start_year]] ] ) su.hide_component(self.semester) self.bands = v.Select( items=[*cp.getAvailableBands()], label=cm.viz.bands, v_model=self.viz_model.bands ) self.start = v.Select( class_='mr-5 ml-5', items=[ y for y in range(cp.gee_min_start_year, cp.gee_max_end_year+1) ], label=cm.viz.start_year, v_model=self.viz_model.start_year ) self.end = v.Select( class_='ml-5 mr-5', items=[y for y in range(cp.gee_min_start_year, cp.gee_max_end_year+1) ], label=cm.viz.end_year, v_model=self.viz_model.end_year ) years = v.Layout( xs=12, row=True, children=[self.start, self.end] ) image_size = v.Slider( step=500, min=cp.min_image, max=cp.max_image, label=cm.viz.image_size, v_model=self.viz_model.image_size, thumb_label='always', class_='mt-5' ) square_size = v.Slider( step=10, min=cp.min_square, max=cp.max_square, label=cm.viz.square_size, v_model=self.viz_model.square_size, thumb_label='always', class_='mt-5' ) # bind the inputs self.viz_model.bind(self.sources, 'sources') \ .bind(self.planet_key, 'planet_key') \ .bind(self.bands, 'bands') \ .bind(self.start, 'start_year') \ .bind(self.end, 'end_year') \ .bind(self.driver, 'driver') \ .bind(image_size, 'image_size') \ .bind(square_size, 'square_size') \ .bind(self.semester, 'semester') # create the tile super().__init__( id_ = "viz_widget", title = cm.viz.title, btn = sw.Btn(cm.viz.btn), inputs = [ self.driver, self.sources, self.planet_key, self.bands, years, self.semester, image_size, square_size ], alert = self.alert ) # js behaviour self.btn.on_event('click', self._display_data) self.driver.observe(self._on_driver_change, 'v_model')
def __init__(self, backend, dataset, x, y=None, z=None, w=None, grid=None, limits=None, shape=128, what="count(*)", f=None, vshape=16, selection=None, grid_limits=None, normalize=None, colormap="afmhot", figure_key=None, fig=None, what_kwargs={}, grid_before=None, vcount_limits=None, show_drawer=False, controls_selection=True, **kwargs): super(PlotBase, self).__init__(x=x, y=y, z=z, w=w, what=what, vcount_limits=vcount_limits, grid_limits=grid_limits, f=f, **kwargs) self.backend = backend self.vgrids = [None, None, None] self.vcount = None self.dataset = dataset self.limits = self.get_limits(limits) self.shape = shape self.selection = selection #self.grid_limits = grid_limits self.grid_limits_visible = None self.normalize = normalize self.colormap = colormap self.what_kwargs = what_kwargs self.grid_before = grid_before self.figure_key = figure_key self.fig = fig self.vshape = vshape self._new_progressbar() self.output = widgets.Output() def output_changed(*ignore): self.widget.new_output = True self.output.observe(output_changed, 'outputs') # with self.output: if 1: self._cleanups = [] self.progress = widgets.FloatProgress(value=0.0, min=0.0, max=1.0, step=0.01) self.progress.layout.width = "95%" self.progress.layout.max_width = '500px' self.progress.description = "progress" self.control_widget = v.Layout(pa_1=True, column=True, children=[]) self.backend.create_widget(self.output, self, self.dataset, self.limits) # self.create_tools() # self.widget = widgets.VBox([widgets.HBox([self.backend.widget, self.control_widget]), self.progress, self.output]) self.widget = PlotTemplate(components={ 'main-widget': widgets.VBox([self.backend.widget, self.progress, self.output]), 'control-widget': self.control_widget, 'output-widget': self.output }, model=show_drawer) if grid is None: self.update_grid() else: self.grid = grid self.widget_f = v.Select( items=['identity', 'log', 'log10', 'log1p', 'log1p'], v_model='log', label='Transform') widgets.link((self, 'f'), (self.widget_f, 'v_model')) self.observe(lambda *__: self.update_image(), 'f') self.add_control_widget(self.widget_f) self.widget_grid_limits_min = widgets.FloatSlider( value=0, min=0, max=100, step=0.1, description='vmin%') self.widget_grid_limits_max = widgets.FloatSlider( value=100, min=0, max=100, step=0.1, description='vmax%') widgets.link((self.widget_grid_limits_min, 'value'), (self, 'grid_limits_min')) widgets.link((self.widget_grid_limits_max, 'value'), (self, 'grid_limits_max')) #widgets.link((self.widget_grid_limits_min, 'f'), (self.widget_f, 'value')) self.observe(lambda *__: self.update_image(), ['grid_limits_min', 'grid_limits_max']) self.add_control_widget(self.widget_grid_limits_min) self.add_control_widget(self.widget_grid_limits_max) self.widget_grid_limits = None selections = _ensure_list(self.selection) selections = [_translate_selection(k) for k in selections] selections = [k for k in selections if k] self.widget_selection_active = widgets.ToggleButtons( options=list(zip(selections, selections)), description='selection') self.controls_selection = controls_selection modes = ['replace', 'and', 'or', 'xor', 'subtract'] self.widget_selection_mode = widgets.ToggleButtons(options=modes, description='mode') if self.controls_selection: self.add_control_widget(self.widget_selection_active) self.add_control_widget(self.widget_selection_mode) self.widget_selection_undo = widgets.Button(options=modes, description='undo', icon='arrow-left') self.widget_selection_redo = widgets.Button(options=modes, description='redo', icon='arrow-right') self.add_control_widget( widgets.HBox([ widgets.Label('history', layout={'width': '80px'}), self.widget_selection_undo, self.widget_selection_redo ])) def redo(*ignore): selection = _translate_selection( self.widget_selection_active.value) self.dataset.selection_redo(name=selection) check_undo_redo() self.widget_selection_redo.on_click(redo) def undo(*ignore): selection = _translate_selection( self.widget_selection_active.value) self.dataset.selection_undo(name=selection) check_undo_redo() self.widget_selection_undo.on_click(undo) def check_undo_redo(*ignore): selection = _translate_selection( self.widget_selection_active.value) self.widget_selection_undo.disabled = not self.dataset.selection_can_undo( selection) self.widget_selection_redo.disabled = not self.dataset.selection_can_redo( selection) self.widget_selection_active.observe(check_undo_redo, 'value') check_undo_redo() callback = self.dataset.signal_selection_changed.connect( check_undo_redo) callback = self.dataset.signal_selection_changed.connect( lambda *x: self.update_grid()) def _on_limits_change(*args): self._progressbar.cancel() self.update_grid() self.backend.observe(_on_limits_change, "limits") for attrname in "x y z vx vy vz".split(): def _on_change(change, attrname=attrname): limits_index = {'x': 0, 'y': 1, 'z': 2}.get(attrname) if limits_index is not None: self.backend.limits[limits_index] = None self.update_grid() self.observe(_on_change, attrname) self.observe(lambda *args: self.update_grid(), "what") self.observe(lambda *args: self.update_image(), "vcount_limits")
def __init__(self, aoi_model, model, **kwargs): # gather the model self.aoi_model = aoi_model self.model = model # create an output alert self.output = sw.Alert() # self.backscatter = v.Switch(class_="ml-5", label=ms.export.backscatter, v_model=True) self.rfdi = v.Switch(class_="ml-5", label=ms.export.rfdi, v_model=True) self.texture = v.Switch(class_="ml-5", label=ms.export.texture, v_model=False) self.aux = v.Switch(class_="ml-5", label=ms.export.aux, v_model=False) self.fnf = v.Switch(class_="ml-5", label=ms.export.fnf, v_model=False) self.scale = v.TextField(label=ms.export.scale, v_model=25) # create buttons self.asset_btn = sw.Btn(ms.export.asset_btn, "mdi-download", disabled=True, class_="ma-5") self.sepal_btn = sw.Btn(ms.export.sepal_btn, "mdi-download", disabled=True, class_="ma-5") # bindings self.model.bind(self.backscatter, "backscatter").bind( self.rfdi, "rfdi").bind(self.texture, "texture").bind( self.aux, "aux").bind(self.fnf, "fnf").bind(self.scale, "scale") # note that btn and output are not a madatory attributes super().__init__( id_="export_widget", title=ms.export.title, inputs=[ self.backscatter, self.rfdi, self.texture, self.aux, self.fnf, self.scale, ], alert=sw.Alert(), btn=v.Layout(row=True, children=[self.asset_btn, self.sepal_btn]), ) # decorate each function as we are using multiple btns self._on_asset_click = su.loading_button(self.alert, self.asset_btn, debug=False)( self._on_asset_click) self._on_sepal_click = su.loading_button(self.alert, self.sepal_btn, debug=False)( self._on_sepal_click) # link the btn self.asset_btn.on_event("click", self._on_asset_click) self.sepal_btn.on_event("click", self._on_sepal_click)
def set_inputs(self): root_dir = os.path.expanduser('~') # select type self.select_type = v.Select(items=available_drivers, label=ms.SELECT_TYPE, v_model=None) # start/end line self.start_picker = sw.DatePicker('Start', xs6=True) self.output.bind(self.start_picker, self.io, 'start') self.end_picker = sw.DatePicker('End', xs6=True) self.output.bind(self.end_picker, self.io, 'end') self.picker_line = v.Layout( xs=12, row=True, children=[self.start_picker, self.end_picker]) # local text self.local_txt = sw.Markdown(ms.LOCAL_TXT) # date file self.select_date_file = sw.FileInput(['.tif', '.tiff'], label=ms.SELECT_DATE_FILE) self.output.bind(self.select_date_file, self.io, 'date_file') # alert file self.select_alerts_file = sw.FileInput(['.tif', '.tiff'], label=ms.SELECT_ALERTS_FILE) self.output.bind(self.select_alerts_file, self.io, 'alert_file') def update_asset_bands(widget, event, data, dropdown, obj, variable): setattr(obj.io, variable, widget.v_model) obj.output.add_msg(f"You selected: {widget.v_model}") # read and add the bands to the dropdown try: ee_image = ee.ImageCollection(widget.v_model).first() dropdown.items = [ band['id'] for band in ee_image.getInfo()['bands'] ] except Exception as e: obj.output.add_msg(str(e), 'error') return # gee text self.gee_txt = sw.Markdown(ms.GEE_TXT) # date asset self.select_date_asset = v.TextField( xs8=True, label=ms.SELECT_DATE_ASSET, placeholder='users/[username]/[asset_name]', v_model=None) self.select_date_asset_band = v.Select(xs4=True, class_='pl-5', label='band', items=None, v_model=None) self.output.bind(self.select_date_asset_band, self.io, 'asset_date_band') self.select_date_asset.on_event( 'change', partial(update_asset_bands, dropdown=self.select_date_asset_band, obj=self, variable='date_asset')) self.asset_date_line = v.Layout( class_='pa-5', xs12=True, row=True, children=[self.select_date_asset, self.select_date_asset_band]) # alert asset self.select_alerts_asset = v.TextField( label=ms.SELECT_ALERTS_ASSET, placeholder='users/[username]/[asset_name]', v_model=None) self.select_alerts_asset_band = v.Select(xs4=True, class_='pl-5', label='band', items=None, v_model=None) self.output.bind(self.select_alerts_asset_band, self.io, 'asset_alerts_band') self.select_alerts_asset.on_event( 'change', partial(update_asset_bands, dropdown=self.select_alerts_asset_band, obj=self, variable='alert_asset')) self.asset_alerts_line = v.Layout( class_='pa-5', xs12=True, row=True, children=[self.select_alerts_asset, self.select_alerts_asset_band]) return self
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)])) # + {"Collapsed": "false"} tabs = v.Tabs(v_model='tab', color='grey lighten-5', fixed_tabs=True, children=tab_children) app = v.App(style_="background: white", children=[ toolbar, v.Container( fluid=True, mt_3=True, children=[v.Layout(children=[v.Flex(children=[tabs])])]) ])
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()]), ])