def well_points_tab_layout(self) -> html.Div: return html.Div([ dbc.Button("Table Settings", id=self.ids("button-open-table-settings")), dbc.Modal( children=[ dbc.ModalHeader("Table Settings"), dbc.ModalBody(children=[ html.Label( style={ "font-weight": "bold", "textAlign": "Left", }, children="Select Table Columns", ), dcc.Checklist( id=self.ids("columns-checklist"), options=[{ "label": name, "value": column_name } for name, column_name in zip( self.df_well_target_points.get_wellpoints_df(). keys().values, self.df_well_target_points.get_wellpoints_df( ).keys().values, )], value=[ "Surface", "Well", "TVD", "MD", "Outlier", "Deleted", "Residual", ], persistence=True, persistence_type="session", ), ], ), dbc.ModalFooter(children=[ dbc.Button( "Close", id=self.ids("button-close-table-settings"), className="ml-auto", ), dbc.Button( "Apply", id=self.ids("button-apply-columnlist"), className="ml-auto", ), ]), ], id=self.ids("modal-table-settings"), size="sm", centered=True, backdrop=False, fade=False, ), html.Div(id=self.ids("well-points-table-container")), ])
def check_list(): return dcc.Checklist( options=[ {'label': 'Aggregate (hist/stats)', 'value': 'agg'}, ], # value=['NYC', 'MTL'] )
def streetViewFeatDash(): return dcc.Checklist( ['трасса', 'автомобильный мост', 'памятники архитектуры', 'памятники культуры', 'пешеходные бульвары' ], value=[], id='streetViewBox' )
def check_list(): return dcc.Checklist(id='aggregate', options=[ { 'label': 'Aggregate (hist/stats)', 'value': 'agg' }, ], value=[''])
def LabeledChecklist(label, id, help_text='', max_width=400, **kwargs): """'max_width' specifies the maximum width of the Div containing all of these components. """ return html.Div(className='labeled-comp', id=f'div-{id}', style={'maxWidth': max_width}, children=[ make_label(label, id, help_text), dcc.Checklist(id=id, **kwargs) ])
def intersection_option(self) -> html.Div: options = [ { "label": "Keep zoom state", "value": "keep_zoom_state" }, { "label": "Show surface fill", "value": "show_surface_fill" }, ] value = ["show_surface_fill"] if self.segyfiles: options.append({"label": "Show seismic", "value": "show_seismic"}) if self.zonelog is not None: options.append({"label": "Show zonelog", "value": "show_zonelog"}) value.append("show_zonelog") return html.Div( style=self.set_style(marginTop="20px"), children=[ html.Label("Intersection settings", style={"font-weight": "bold"}), html.Label("Sampling"), dcc.Input( id=self.ids("sampling"), debounce=True, type="number", required=True, value=self.sampling, persistence=True, persistence_type="session", ), html.Label("Extension"), dcc.Input( id=self.ids("nextend"), debounce=True, type="number", required=True, value=self.nextend, persistence=True, persistence_type="session", ), dcc.Checklist( id=self.ids("options"), options=options, value=value, persistence=True, persistence_type="session", ), ], )
def makeCheckList(id, itemList, defaultItem=None): options = [{'label': x, 'value': x} for x in itemList] ret = dcc.Checklist( id=id, persistence=True, options=options, value=[itemList[0]], #labelStyle={'display': 'inline-block'} labelStyle={"margin-right": "15px"}, # adds space between options list inputStyle={"margin-right": "5px"}, # adds space between check and its label ), # Checklist return ret
def edit_list(add, add2, clear, new_item, items, items_done): app.list_calls.value += 1 triggered = [t["prop_id"] for t in dash.callback_context.triggered] adding = len([ 1 for i in triggered if i in ("add.n_clicks", "new-item.n_submit") ]) clearing = len([1 for i in triggered if i == "clear-done.n_clicks"]) new_spec = [(text, done) for text, done in zip(items, items_done) if not (clearing and done)] if adding: new_spec.append((new_item, [])) # Check callback context use of grouping assert not dash.callback_context.using_args_grouping assert not dash.callback_context.using_outputs_grouping new_list = [ html.Div( [ dcc.Checklist( id={ "item": i, "action": "done" }, options=[{ "label": "", "value": "done" }], value=done, style={"display": "inline"}, ), html.Div(text, id={"item": i}, style=style_done if done else style_todo), html.Div(id={ "item": i, "preceding": True }, style=style_todo), ], style={"clear": "both"}, ) for i, (text, done) in enumerate(new_spec) ] return [new_list, "" if adding else new_item]
def viz_options_layout(self) -> dcc.Checklist: options = [{ "label": "Show surface fill", "value": "show_surface_fill" }] value = ["show_surface_fill"] if self.segyfiles: options.append({"label": "Show seismic", "value": "show_seismic"}) if self.zonelog: options.append({"label": "Show zonelog", "value": "show_zonelog"}) value.append("show_zonelog") return dcc.Checklist( id=self.ids("options"), options=options, value=value, persistence=True, persistence_type="session", )
def edit_list(items, triggers): app.list_calls.value += 1 triggered = [t["prop_id"] for t in dash.callback_context.triggered] adding = len([ 1 for i in triggered if i in ("add.n_clicks", "new-item.n_submit") ]) new_spec = items["all"] if adding: new_spec.append(items["new"]) # Check callback context use of grouping assert dash.callback_context.using_args_grouping assert dash.callback_context.using_outputs_grouping new_list = [ html.Div( [ dcc.Checklist( id={ "id": i, "property": "done" }, options=[{ "label": "", "value": "done" }], style={"display": "inline"}, ), html.Div(text, id={"id": i}, style=style_todo), ], style={"clear": "both"}, ) for i, text in enumerate(new_spec) ] return { "list_container": new_list, "new_item": "", "totals": f"{len(new_list)} total item(s)", "cc_args_grouping": repr(dash.callback_context.args_grouping), "cc_outputs_grouping": repr(dash.callback_context.outputs_grouping), }
def __init__(self, label: str = None, vertical: bool = True, className: str = "", wrapper_id: str = None, persistence: bool = True, persistence_type: str = "session", **kwargs: Any) -> None: super().__init__() if wrapper_id is not None: self.id = wrapper_id children = [html.Label(label)] if label else [] children.append( dcc.Checklist( persistence=persistence, persistence_type=persistence_type, className=className + " webviz-block-options" if vertical else className, **kwargs, )) self.children = html.Div(style={"fontSize": "15px"}, children=children)
def test_mdcap001_dcc_components_as_props(dash_dcc): app = Dash(__name__) app.layout = html.Div( [ dcc.Checklist( [ {"label": html.H2("H2 label"), "value": "h2"}, {"label": html.A("Link in checklist", href="#"), "value": "a"}, ], id="checklist", ), dcc.RadioItems( [ {"label": html.H3("on"), "value": "on"}, {"label": html.P("off"), "value": "off"}, ], id="radio-items", ), dcc.Dropdown( [ {"label": html.H4("h4"), "value": "h4"}, {"label": html.H6("h6"), "value": "h6"}, ], id="dropdown", ), ] ) dash_dcc.start_server(app) dash_dcc.wait_for_text_to_equal("#checklist h2", "H2 label") dash_dcc.wait_for_text_to_equal("#checklist a", "Link in checklist") dash_dcc.wait_for_text_to_equal("#radio-items h3", "on") dash_dcc.wait_for_text_to_equal("#radio-items p", "off") dash_dcc.find_element("#dropdown").click() dash_dcc.wait_for_text_to_equal("#dropdown h4", "h4") dash_dcc.wait_for_text_to_equal("#dropdown h6", "h6")
"label": "San Francisco", "value": "SF" }, ], value="MTL", ), html.Label("Checkboxes"), dcc.Checklist( options=[ { "label": "New York City", "value": "NYC" }, { "label": u"Montréal", "value": "MTL" }, { "label": "San Francisco", "value": "SF" }, ], value=["MTL", "SF"], ), html.Label("Text Input"), dcc.Input(value="MTL", type="text"), html.Label("Slider"), dcc.Slider( min=0, max=9, marks={
def layout(): return html.Div( id='variantmap-body', className='app-body', children=[ html.Div( id='variantmap-control-tabs', className='control-tabs', children=[ dcc.Tabs( id='variantmap-tabs', value='what-is', children=[ # "What is" tab dcc.Tab( label='About', value='what-is', children=html.Div( className='control-tab', children=[ html.H4( className='what-is', children='What is VariantMap?'), html. P('VariantMap is a genomic structural variant (SV) visualization ' 'technique that displays variants across multiple samples in a ' 'single heatmap. Each row represents a sample and each column ' 'represents an SV breakend in the sample cohort. The colors ' 'indicate the class of an SV present in a sample. The ' 'heatmap can be customized interactively to suit your analysis ' 'by changing various components in the "Customize" tab.' ), html. P('VariantMap requires a dataframe object that is generated by ' 'VariantBreak. Do note that only NanoVar VCF ' 'files are currently compatible to work with VariantBreak in creating the ' 'dataframe.') ])), # Data tab dcc.Tab( label='Data', value='data', children=html.Div( className='control-tab', children=[ # Dataset upload html.Div( 'Upload dataset:', title= 'Upload your own dataset below.', className='app-controls-name'), html.Div( id='variantmap-file-upload', title= 'Upload your own VariantBreak generated HDF5 dataset here.', children=[ dcc.Upload( id='upload-data', className='control-upload', children=html.Div([ "Drag and drop your .h5 file or ", html.A("select file.") ]), accept='.hdf5,.h5', multiple=False) ]), html.Br(), # Label file upload html.Div( 'Upload label file:', title= 'This file is used to rename and sort samples.\nExample:\n#Default ' 'name<tab>Label\nS1<tab>SampleA\nS3<tab>SampleC\nS2<tab>SampleB', className='app-controls-name'), html.Div( id='variantmap-tsv-upload', title= 'Upload a .tsv file to rename and sort samples.\nExample:\n#Default ' 'name<tab>Label\nS1<tab>SampleA\nS3<tab>SampleC\nS2<tab>SampleB', children=[ dcc.Upload( id='upload-tsv', className='control-upload', children=html.Div([ "Drag and drop your .tsv file or ", html.A("select file.") ]), accept='.txt,.tsv,.csv', multiple=False) ]), html.Br(), # Sample selection check boxes html.Div( id='output-data-info', className= 'fullwidth-app-controls-name', children=[ dcc.Checklist( id="select-samples", style={'display': 'none'}), html.Br(), html.Button( id='submit-button-samples', style={'display': 'none'}) ]) ])), # Customize tab dcc.Tab( label='Customize', value='customize', children=html.Div( className='control-tab', children=[ html.Div( id='customize-tab', className= 'fullwidth-app-controls-name', children=[ dcc.Dropdown( id='sample_filt', style={'display': 'none'}), dcc.Dropdown( id='file_filt', style={'display': 'none'}), dcc.Dropdown( id='gene_names', style={'display': 'none'}), dcc.Input( id='input_index', style={'display': 'none'}), dcc.Checklist( id="select-genetype", style={'display': 'none'}), dcc.Checklist( id="select-feature", style={'display': 'none'}), dcc.Checklist( id="select-annotation", style={'display': 'none'}), dcc.Input( id='entries_size', style={'display': 'none'}), html.Button( id='submit-button', style={'display': 'none'}) ]) ])), # Variant info tab dcc.Tab( label='Variant info', value='info', children=html.Div( className='control-tab', children=[ html.Div( id='info-tab', className= 'fullwidth-app-controls-name', children=[ html.Div( 'Click on variant to display its information' ) ]) ])) ]) ]), dcc.Loading( className='dashbio-loading', children=html.Div( id='variantmap-wrapper', children=[ # Error message box html.Div(id='error-msg', style={ 'color': 'crimson', 'text-align': 'center', 'font-size': '18px' }), # Plot VariantMap figure html.Div(id='variantmap-fig', children=[ html.Div(dcc.Graph(id='variantmap'), style={'display': 'none'}) ]), # Plot Slider html.Div(id='batch-slider', children=[ html.Div('', style={ 'textAlign': 'center', }), html.Div(dcc.Slider(id='slider', ), style={'display': 'none'}) ]) ])), # Create Store component to store JSON of dataframe and metadata dcc.Store(id='memory'), # To store variant counts dcc.Store(id='count-store'), # To store custom settings dcc.Store(id='custom-store'), # To store name dictionary dcc.Store(id='name_dict'), # To store sample labels dcc.Store(id='sample_labels'), # To store sample order dcc.Store(id='sample_order') ])
dbc.Col( [ html.Div([ html.P('Show options: '), dcc.Checklist( id='show_opt', options=[ { 'label': ' Total', 'value': 'total' }, { 'label': ' Layer', 'value': 'layer' }, { 'label': ' Element', 'value': 'ele' }, { 'label': ' Isotope', 'value': 'iso' }, ], value=['layer'], # n_clicks_timestamp=0, ), ]), ], width=2, ),
def dash_report( sessions, info=None, max_cycles=None, tags=None, signals=None, recreate_plots=None, video_only=None, ): """Create a gait report dash app. Parameters ---------- sessions : list List of session directories. For more than one session dirs, a comparison report will be created. Up to three sessions can be compared in the report. info : dict | None The patient info. If not None, some info will be shown in the report. max_cycles : dict | None Maximum number of gait cycles to plot for each variable type. If None, taken from config. tags : list | None Eclipse tags for finding dynamic gait trials. If None, will be taken from config. signals : ProgressSignals | None Instance of ProgressSignals, used to send progress updates across threads and track the cancel flag which aborts the creation of the report. If None, a dummy one will be created. recreate_plots : bool If True, force recreation of the report figures. Otherwise, cached figure data will be used, unless the report c3d files have changed (a checksum mechanism is used to verify this). video_only : bool If True, create a video-only report (no gait curves). Returns ------- dash.Dash | None The dash (flask) app, or None if report creation failed. """ sessions = [Path(s) for s in sessions] if recreate_plots is None: recreate_plots = False if video_only is None: video_only = False # relative width of left panel (1-12) # uncomment to use narrower video panel for 3-session comparison # LEFT_WIDTH = 8 if len(sessions) == 3 else 7 LEFT_WIDTH = 8 VIDS_TOTAL_HEIGHT = 88 # % of browser window height if len(sessions) < 1 or len(sessions) > 3: raise ValueError('Need a list of one to three sessions') is_comparison = len(sessions) > 1 report_name = _report_name(sessions) info = info or sessionutils.default_info() # tags for dynamic trials if tags is None: dyn_tags = cfg.eclipse.tags else: dyn_tags = tags # signals is used to track progress across threads; if not given, create a dummy one if signals is None: signals = ProgressSignals() # this tag will be shown in the menu for static trials static_tag = 'Static' # get the camera labels # reduce to a set, since there may be several labels for given id camera_labels = set(cfg.general.camera_labels.values()) # add camera labels for overlay videos # XXX: may cause trouble if camera labels already contain the string 'overlay' camera_labels_overlay = [lbl + ' overlay' for lbl in camera_labels] camera_labels.update(camera_labels_overlay) # build dict of videos for given tag / camera label # videos will be listed in session order vid_urls = dict() all_tags = dyn_tags + [static_tag] + cfg.eclipse.video_tags for tag in all_tags: vid_urls[tag] = dict() for camera_label in camera_labels: vid_urls[tag][camera_label] = list() # collect all session enfs into dict enfs = {session: dict() for session in sessions} data_enfs = list() # enfs that are used for data signals.progress.emit('Collecting trials...', 0) for session in sessions: if signals.canceled: return None enfs[session] = dict(dynamic=dict(), static=dict(), vid_only=dict()) # collect dynamic trials for each tag for tag in dyn_tags: dyns = sessionutils.get_enfs(session, tags=tag, trial_type='dynamic') if len(dyns) > 1: logger.warning(f'multiple tagged trials ({tag}) for {session}') dyn_trial = dyns[-1:] enfs[session]['dynamic'][tag] = dyn_trial # may be empty list if dyn_trial: data_enfs.extend(dyn_trial) # require at least one dynamic trial for each session if not any(enfs[session]['dynamic'][tag] for tag in dyn_tags): raise GaitDataError(f'No tagged dynamic trials found for {session}') # collect static trial (at most 1 per session) # rules: # -prefer enfs that have a corresponding c3d file, even for a video-only report # (so that the same static gets used for both video-only and full reports) # -prefer the newest static trial sts = sessionutils.get_enfs(session, trial_type='static') for st in reversed(sts): # newest first st_c3d = sessionutils.enf_to_trialfile(st, '.c3d') if st_c3d.is_file(): static_trial = [st] break else: # no c3ds were found - just pick the latest static trial static_trial = sts[-1:] enfs[session]['static'][static_tag] = static_trial if static_trial: data_enfs.extend(static_trial) # collect video-only dynamic trials for tag in cfg.eclipse.video_tags: dyn_vids = sessionutils.get_enfs(session, tags=tag) if len(dyn_vids) > 1: logger.warning( f'multiple tagged video-only trials ({tag}) for {session}' ) enfs[session]['vid_only'][tag] = dyn_vids[-1:] # collect all videos for given tag and camera, listed in session order signals.progress.emit('Finding videos...', 0) for session in sessions: for trial_type in enfs[session]: for tag, enfs_this in enfs[session][trial_type].items(): if enfs_this: enf = enfs_this[0] # only one enf per tag and session for camera_label in camera_labels: overlay = 'overlay' in camera_label real_camera_label = ( camera_label[: camera_label.find(' overlay')] if overlay else camera_label ) # need to convert filename, since get_trial_videos cannot # deal with enf names c3d = enf_to_trialfile(enf, 'c3d') vids_this = videos.get_trial_videos( c3d, camera_label=real_camera_label, vid_ext='.ogv', overlay=overlay, ) if vids_this: vid = vids_this[0] url = f'/static/{vid.name}' vid_urls[tag][camera_label].append(url) # build dcc.Dropdown options list for cameras and tags # list cameras which have videos for any tag opts_cameras = list() for camera_label in sorted(camera_labels): if any(vid_urls[tag][camera_label] for tag in all_tags): opts_cameras.append({'label': camera_label, 'value': camera_label}) # list tags which have videos for any camera opts_tags = list() for tag in all_tags: if any(vid_urls[tag][camera_label] for camera_label in camera_labels): opts_tags.append({'label': f'{tag}', 'value': tag}) # add null entry in case we got no videos at all if not opts_tags: opts_tags.append({'label': 'No videos', 'value': 'no videos', 'disabled': True}) # create (or load) the figures # this section is only run if we have c3d data if not video_only: data_c3ds = [enf_to_trialfile(enffile, 'c3d') for enffile in data_enfs] # at this point, all the c3ds need to exist missing = [fn for fn in data_c3ds if not fn.is_file()] if missing: missing_trials = ', '.join([fn.stem for fn in missing]) raise GaitDataError( f'c3d files missing for following trials: {missing_trials}' ) # see whether we can load report figures from disk digest = numutils._files_digest(data_c3ds) logger.debug(f'report data digest: {digest}') # the cached data is always saved into alphabetically first session data_dir = sorted(sessions)[0] data_fn = data_dir / f'web_report_{digest}.dat' if data_fn.is_file() and not recreate_plots: logger.info(f'loading saved report data from {data_fn}') signals.progress.emit('Loading saved report...', 0) try: with open(data_fn, 'rb') as f: saved_report_data = pickle.load(f) except UnicodeDecodeError: logger.warning('cannot open report (probably made with legacy version)') logger.warning('recreating...') saved_report_data = dict() else: saved_report_data = dict() logger.info('no saved data found or recreate forced') # make Trial instances for all dynamic and static trials # this is currently necessary even if saved figures are used trials_dyn = list() trials_dyn_dict = dict() # also organize dynamic trials by session trials_static = list() for session in sessions: trials_dyn_dict[session] = list() for tag in dyn_tags: if enfs[session]['dynamic'][tag]: if signals.canceled: return None c3dfile = enf_to_trialfile(enfs[session]['dynamic'][tag][0], 'c3d') tri = Trial(c3dfile) trials_dyn.append(tri) trials_dyn_dict[session].append(tri) if enfs[session]['static'][static_tag]: c3dfile = enf_to_trialfile(enfs[session]['static']['Static'][0], 'c3d') tri = Trial(c3dfile) trials_static.append(tri) emg_auto_layout = None # stuff that's needed to (re)create the figures if not saved_report_data: age = None if info['hetu'] is not None: # compute subject age at session time session_dates = [ sessionutils.get_session_date(session) for session in sessions ] ages = [age_from_hetu(info['hetu'], d) for d in session_dates] try: age = max(ages) except TypeError: age = None # create Markdown text for patient info patient_info_text = '##### %s ' % ( info['fullname'] if info['fullname'] else 'Name unknown' ) if info['hetu']: patient_info_text += f"({info['hetu']})" patient_info_text += '\n\n' # if age: # patient_info_text += 'Age at measurement time: %d\n\n' % age # load normal data for gait models; we have to do it here instead of # leaving it up to plot_trials, since it's session (age) specific signals.progress.emit('Loading normal data...', 0) model_normaldata = normaldata._read_configured_model_normaldata(age) # make average trials for each session avg_trials = [ AvgTrial.from_trials(trials_dyn_dict[session], sessionpath=session) for session in sessions ] # prepare for the curve-extracted value plots logger.debug('extracting values for curve-extracted plots...') vardefs_dict = dict(cfg.report.vardefs) allvars = [ vardef[0] for vardefs in vardefs_dict.values() for vardef in vardefs ] from_models = set(models.model_from_var(var) for var in allvars) if None in from_models: raise GaitDataError(f'unknown variables in extract list: {allvars}') curve_vals = { session.name: _trials_extract_values(trials, from_models=from_models) for session, trials in trials_dyn_dict.items() } # in EMG layout, keep chs that are active in any of the trials signals.progress.emit('Reading EMG data', 0) try: emgs = [tr.emg for tr in trials_dyn] emg_auto_layout = layouts._rm_dead_channels(emgs, cfg.layouts.std_emg) if not emg_auto_layout: emg_auto_layout = None except GaitDataError: emg_auto_layout = None # the layouts are specified as lists of tuples: (title, layout_spec) # where title is the page title, and layout_spec is either string or tuple. # if string, it denotes a special layout (e.g. 'patient_info') # if tuple, the first element should be the string 'layout_name' and the second # a gaitutils configured layout name; # alternatively the first element can be 'layout' and the second element a # valid gaitutils layout page_layouts = dict(cfg.web_report.page_layouts) # pick desired single variables from model and append pigvars = ( models.pig_lowerbody.varlabels_nocontext | models.pig_lowerbody_kinetics.varlabels_nocontext ) pigvars = sorted(pigvars.items(), key=lambda item: item[1]) pigvars_louts = {varlabel: ('layout', [[var]]) for var, varlabel in pigvars} page_layouts.update(pigvars_louts) # add supplementary data for normal layouts supplementary_default = dict() dd_opts_multi_upper = list() dd_opts_multi_lower = list() # loop through the layouts, create or load figures report_data_new = dict() for k, (page_label, layout_spec) in enumerate(page_layouts.items()): signals.progress.emit( f'Creating plot: {page_label}', 100 * k / len(page_layouts) ) if signals.canceled: return None # for comparison report, include session info in plot legends and # use session specific line style emg_mode = None if is_comparison: legend_type = cfg.report.comparison_legend_type style_by = cfg.report.comparison_style_by color_by = cfg.report.comparison_color_by if cfg.report.comparison_emg_as_envelope: emg_mode = 'envelope' else: legend_type = cfg.report.legend_type style_by = cfg.report.style_by color_by = cfg.report.color_by try: if saved_report_data: logger.debug(f'loading {page_label} from saved report data') if page_label not in saved_report_data: # will be caught, resulting in empty menu item raise RuntimeError else: figdata = saved_report_data[page_label] else: logger.debug(f'creating figure data for {page_label}') # the 'special' layouts are indicated by a string if isinstance(layout_spec, str): if layout_spec == 'time_dist': figdata = timedist.plot_comparison( sessions, big_fonts=False, backend='plotly' ) elif layout_spec == 'patient_info': figdata = patient_info_text elif layout_spec == 'static_kinematics': layout_ = cfg.layouts.lb_kinematics figdata = plot_trials( trials_static, layout_, model_normaldata=False, cycles='unnormalized', legend_type='short_name_with_cyclename', style_by=style_by, color_by=color_by, big_fonts=True, ) elif layout_spec == 'static_emg': layout_ = cfg.layouts.std_emg figdata = plot_trials( trials_static, layout_, model_normaldata=False, cycles='unnormalized', legend_type='short_name_with_cyclename', style_by=style_by, color_by=color_by, big_fonts=True, ) elif layout_spec == 'emg_auto': if emg_auto_layout is None: # no valid EMG channels raise RuntimeError else: figdata = plot_trials( trials_dyn, emg_auto_layout, emg_mode=emg_mode, legend_type=legend_type, style_by=style_by, color_by=color_by, supplementary_data=supplementary_default, big_fonts=True, ) elif layout_spec == 'kinematics_average': layout_ = cfg.layouts.lb_kinematics figdata = plot_trials( avg_trials, layout_, style_by=style_by, color_by=color_by, model_normaldata=model_normaldata, big_fonts=True, ) elif layout_spec == 'disabled': # exception will be caught in this loop, resulting in empty menu item raise RuntimeError else: # unrecognized layout; this will cause an exception raise Exception(f'Invalid page layout: {str(layout_spec)}') # regular layouts and curve-extracted layouts are indicated by tuple elif isinstance(layout_spec, tuple): if layout_spec[0] in ['layout_name', 'layout']: if layout_spec[0] == 'layout_name': # get a configured layout by name layout = layouts.get_layout(layout_spec[1]) else: # it's already a valid layout layout = layout_spec[1] # plot according to layout figdata = plot_trials( trials_dyn, layout, model_normaldata=model_normaldata, max_cycles=max_cycles, emg_mode=emg_mode, legend_type=legend_type, style_by=style_by, color_by=color_by, supplementary_data=supplementary_default, big_fonts=True, ) elif layout_spec[0] == 'curve_extracted': the_vardefs = vardefs_dict[layout_spec[1]] figdata = plot_extracted_box(curve_vals, the_vardefs) else: raise Exception(f'Invalid page layout: {str(layout_spec)}') else: raise Exception(f'Invalid page layout: {str(layout_spec)}') # save the newly created data if not saved_report_data: if isinstance(figdata, go.Figure): # serialize go.Figures before saving # this makes them much faster for pickle to handle # apparently dcc.Graph can eat the serialized json directly, # so no need to do anything on load figdata_ = figdata.to_plotly_json() else: figdata_ = figdata report_data_new[page_label] = figdata_ # make the upper and lower panel graphs from figdata, depending # on data type def _is_base64(s): """Test for valid base64 encoding""" try: return base64.b64encode(base64.b64decode(s)) == s except Exception: return False # this is for old style timedist figures that were in base64 # encoded svg if layout_spec == 'time_dist' and _is_base64(figdata): graph_upper = html.Img( src=f'data:image/svg+xml;base64,{figdata}', id='gaitgraph%d' % k, style={'height': '100%'}, ) graph_lower = html.Img( src=f'data:image/svg+xml;base64,{figdata}', id='gaitgraph%d' % (len(page_layouts) + k), style={'height': '100%'}, ) elif layout_spec == 'patient_info': graph_upper = dcc.Markdown(figdata) graph_lower = graph_upper else: # plotly fig -> dcc.Graph graph_upper = dcc.Graph( figure=figdata, id='gaitgraph%d' % k, style={'height': '100%'} ) graph_lower = dcc.Graph( figure=figdata, id='gaitgraph%d' % (len(page_layouts) + k), style={'height': '100%'}, ) dd_opts_multi_upper.append({'label': page_label, 'value': graph_upper}) dd_opts_multi_lower.append({'label': page_label, 'value': graph_lower}) except (RuntimeError, GaitDataError) as e: # could not create a figure logger.warning(f'failed to create figure for {page_label}: {e}') # insert the menu options but make them disabled dd_opts_multi_upper.append( {'label': page_label, 'value': page_label, 'disabled': True} ) dd_opts_multi_lower.append( {'label': page_label, 'value': page_label, 'disabled': True} ) continue opts_multi, mapper_multi_upper = _make_dropdown_lists(dd_opts_multi_upper) opts_multi, mapper_multi_lower = _make_dropdown_lists(dd_opts_multi_lower) # if plots were newly created, save them to disk if not saved_report_data: logger.debug(f'saving report data into {data_fn}') signals.progress.emit('Saving report data to disk...', 99) with open(data_fn, 'wb') as f: pickle.dump(report_data_new, f, protocol=-1) def make_left_panel(split=True, upper_value='Kinematics', lower_value='Kinematics'): """Helper to make the left graph panels. If split=True, make two stacked panels""" # the upper graph & dropdown items = [ dcc.Dropdown( id='dd-vars-upper-multi', clearable=False, options=opts_multi, value=upper_value, ), html.Div( id='div-upper', style={'height': '50%'} if split else {'height': '100%'} ), ] if split: # add the lower one items.extend( [ dcc.Dropdown( id='dd-vars-lower-multi', clearable=False, options=opts_multi, value=lower_value, ), html.Div(id='div-lower', style={'height': '50%'}), ] ) return html.Div(items, style={'height': '80vh'}) # create the app app = dash.Dash('gaitutils') # use local packaged versions of JavaScript libs etc. (no internet needed) app.css.config.serve_locally = True app.scripts.config.serve_locally = True app.title = _report_name(sessions, long_name=False) # this is for generating the classnames in the CSS num2words = { 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine', 10: 'ten', 11: 'eleven', 12: 'twelve', } classname_left = f'{num2words[LEFT_WIDTH]} columns' classname_right = f'{num2words[12 - LEFT_WIDTH]} columns' if video_only: app.layout = html.Div( [ # row html.Div( [ # single main div dcc.Dropdown( id='dd-camera', clearable=False, options=opts_cameras, value='Front camera', ), dcc.Dropdown( id='dd-video-tag', clearable=False, options=opts_tags, value=opts_tags[0]['value'], ), html.Div(id='videos'), ], className='12 columns', ), ], className='row', ) else: # the two-panel layout with graphs and video app.layout = html.Div( [ # row html.Div( [ # left main div html.H6(report_name), dcc.Checklist( id='split-left', options=[{'label': 'Two panels', 'value': 'split'}], value=[], ), # need split=True so that both panels are in initial layout html.Div(make_left_panel(split=True), id='div-left-main'), ], className=classname_left, ), html.Div( [ # right main div dcc.Dropdown( id='dd-camera', clearable=False, options=opts_cameras, value='Front camera', ), dcc.Dropdown( id='dd-video-tag', clearable=False, options=opts_tags, value=opts_tags[0]['value'], ), html.Div(id='videos'), ], className=classname_right, ), ], className='row', ) @app.callback( Output('div-left-main', 'children'), [Input('split-left', 'value')], [State('dd-vars-upper-multi', 'value')], ) def update_panel_layout(split_panels, upper_value): split = 'split' in split_panels return make_left_panel(split, upper_value=upper_value) @app.callback( Output('div-upper', 'children'), [Input('dd-vars-upper-multi', 'value')] ) def update_contents_upper_multi(sel_var): return mapper_multi_upper[sel_var] @app.callback( Output('div-lower', 'children'), [Input('dd-vars-lower-multi', 'value')] ) def update_contents_lower_multi(sel_var): return mapper_multi_lower[sel_var] def _video_elem(title, url, max_height): """Create a video element with title""" if not url: return 'No video found' vid_el = html.Video( src=url, controls=True, loop=True, preload='auto', title=title, style={'max-height': max_height, 'max-width': '100%'}, ) # return html.Div([title, vid_el]) # titles above videos return vid_el @app.callback( Output('videos', 'children'), [Input('dd-camera', 'value'), Input('dd-video-tag', 'value')], ) def update_videos(camera_label, tag): """Create a list of video divs according to camera and tag selection""" if tag == 'no videos': return 'No videos found' vid_urls_ = vid_urls[tag][camera_label] if not vid_urls_: return 'No videos found' nvids = len(vid_urls_) max_height = str(int(VIDS_TOTAL_HEIGHT / nvids)) + 'vh' return [_video_elem('video', url, max_height) for url in vid_urls_] # add a static route to serve session data. be careful outside firewalls @app.server.route('/static/<resource>') def serve_file(resource): for session in sessions: filepath = session / resource if filepath.is_file(): return flask.send_from_directory(str(session), resource) return None # add shutdown method - see http://flask.pocoo.org/snippets/67/ @app.server.route('/shutdown') def shutdown(): logger.debug('Received shutdown request...') _shutdown_server() return 'Server shutting down...' # inject some info of our own app._gaitutils_report_name = report_name # XXX: the Flask app ends up with a logger by the name of 'gaitutils', which has a default # stderr handler. since logger hierarchy corresponds to package hierarchy, # this creates a bug where all gaitutils package loggers propagate their messages into # the app logger and they get shown multiple times. as a dirty fix, we disable the # handlers for the app logger (they still get shown since they propagate to the root logger) app.logger.handlers = [] return app
def read_data(contents, filename): # print("call - read_data") if filename: content_type, content_string = contents.split(',') # Decode base64 decoded = base64.b64decode(content_string) # Load input hdf5 file into a pandas dataframe and extract metadata with pd.HDFStore( "data.h5", mode="r", driver="H5FD_CORE", driver_core_backing_store=0, driver_core_image=io.BytesIO(decoded).read()) as store: df = store['dataset'] metadata = store.get_storer('dataset').attrs.metadata else: # Load sample hdf5 into a pandas dataframe and extract metadata filename = "sample_data.h5" with pd.HDFStore(os.path.join(DATAPATH, filename), mode="r") as store: df = store['dataset'] metadata = store.get_storer('dataset').attrs.metadata # Sample_info children child_sample = [ html.Div("Input file: {}".format(filename)), html.Br(), html.Div('Select samples to display and click "SUBMIT":'), dcc.Checklist(id="select-samples", options=[{ 'label': name, 'value': name } for name in metadata['sample_names']], value=[name for name in metadata['sample_names']]), html.Br(), html.Button(id='submit-button-samples', className='customButton', children='SUBMIT') ] # Count store count row_counts = df.shape[0] # Memory data datasets = { 'df': df.to_json(orient='split', date_format='iso'), 'metadata': metadata } # Set-up customize tab # Get all unique gene names total_genes = set() if 'Gene_name' in df.columns: for genes in df.Gene_name: if genes != '': for gene in genes.split('/'): total_genes.add(gene.strip().rstrip(";")) total_genes = sorted(total_genes) # Get all unique gene types gene_types = set() if 'Gene_type' in df.columns: for t in df.Gene_type: if t != '': for _t in t.split(','): gene_types.add(_t.strip()) others = sorted( gene_types.difference( ['protein_coding', 'lncRNA', 'miRNA', 'snRNA', 'snoRNA'])) # Get labels of non-GTF annotation columns bed_annote = [] for name in metadata['annotation']: if name != 'GTF': bed_annote.append(name) # Get all unique annotation names annotes = set() for bed in bed_annote: for annote in df.loc[:, bed]: if annote != '': for _annote in annote.split('/'): annotes.add(_annote.strip()) annotes = sorted(annotes) annote_dict = {annote: annote for annote in annotes} # Create name dictionary name_dict = { 'Promoter': 'promoter', 'Exon': 'exon', 'Intron': 'intron', 'Protein coding': 'protein_coding', 'lncRNA': 'lncRNA', 'miRNA': 'miRNA', 'snRNA': 'snRNA', 'snoRNA': 'snoRNA', 'Others': others, } name_dict.update(annote_dict) # Define fixed gene types main_types = [ 'Protein coding', 'lncRNA', 'miRNA', 'snRNA', 'snoRNA', 'Others' ] # Define fixed gene features features = ['Promoter', 'Exon', 'Intron'] # Customize tab children child_customize = [ html.Div( 'Customize the heatmap by adjusting the components below and ' 'click "SUBMIT" at the end after finalizing your settings. ' 'Hover over each section header for more information.'), html.Br(), html.Div('Filter by variant file:', title='Hide variants that are present in these samples.', style={'font-weight': 'bold'}), dcc.Dropdown(id='sample_filt', options=[{ 'label': name, 'value': name } for name in metadata['sample_names']], value=None, multi=True, placeholder="Variant files", searchable=False), html.Br(), html.Div( 'Filter by filter file:', title='Hide variants that intersect with these filter files.', style={'font-weight': 'bold'}), dcc.Dropdown(id='file_filt', options=[{ 'label': name, 'value': name } for name in metadata['filter']], value=None, multi=True, placeholder="Filter files", searchable=False), html.Br(), html.Div( "Search variants by gene name:", title='Select only variants annotated with these gene names.', style={'font-weight': 'bold'}), dcc.Dropdown( id='gene_names', options=[{ 'label': name, 'value': name } for name in total_genes], value=None, multi=True, placeholder="Search gene names", ), html.Br(), html.Div( "Search variants by index:", title= 'Select only variants labeled with these indexes separated by ";"', style={'font-weight': 'bold'}), dcc.Input(id='input_index', type='text', value=None, placeholder="Search indexes"), html.Br(), html.Br(), html.Div( 'Filter by gene type:', title='Select only variants annotated with these gene types.', style={'font-weight': 'bold'}), dcc.Checklist(id="select-genetype", options=[{ 'label': name, 'value': name } for name in main_types]), html.Br(), html.Div( 'Filter by gene feature:', title= 'Select only variants annotated with these gene features.', style={'font-weight': 'bold'}), dcc.Checklist(id="select-feature", options=[{ 'label': name, 'value': name } for name in features]), html.Br(), html.Div( 'Filter by other annotations:' if len(annotes) > 0 else None, title='Select only variants annotated with these annotations.', style={'font-weight': 'bold'}), dcc.Checklist( id="select-annotation", options=[{ 'label': name, 'value': name } for name in annotes], ), html.Br(), html.Div( 'Set section size:', title='Set the number of variants to display per section.', style={'font-weight': 'bold'}), dcc.Input(id='entries_size', type='number', value=2500, placeholder='No. of SVs', debounce=True, min=100, max=500000), html.Br(), html.Br(), html.Button(id='submit-button', className='customButton', children='SUBMIT') ] return child_sample, row_counts, datasets, child_customize, name_dict
{'label': u'Montréal', 'value': 'MTL'}, {'label': 'San Francisco', 'value': 'SF'} ], # default value value='MTL' ), # Simple Checkbox html.Label('Checkboxes'), dcc.Checklist( options=[ {'label': 'New York City', 'value': 'NYC'}, {'label': u'Montréal', 'value': 'MTL'}, {'label': 'San Francisco', 'value': 'SF'} ], # and its default value value=['MTL', 'SF'] ), # Text input html.Label('Text Input'), dcc.Input(value='MTL', type='text'), # Single range slider html.Label('Slider'), dcc.Slider( min=0,
def test_ddsh001_test_dropdown_radioitems_checklist_shorthands(dash_dcc): app = Dash(__name__) TEST_OPTIONS_N_VALUES = [ [["a", "b", "c"]], [["a", "b", "c"], "b"], [["a", 3, "c"]], [["a", 3, "c"], 3], [["a", True, "c"]], [["a", True, "c"], True], [["a", 3, "c", True, False]], [["a", 3, "c", True, False], False], # {`value1`: `label1`, `value2`, `label2`, ...} [{ "one": "One", "two": "Two", "three": "Three" }], [{ "one": "One", "two": "Two", "three": "Three" }, "two"], [{ "one": 1, "two": 2, "three": False }], [{ "one": 1, "two": 2, "three": False }, "three"], [{ "one": 1, "two": True, "three": 3 }], [{ "one": 1, "two": True, "three": 3 }, "two"], # original options format [[ { "label": "one", "value": 1 }, { "label": "two", "value": True }, { "label": "three", "value": 3 }, ]], [ [ { "label": "one", "value": 1 }, { "label": "two", "value": True }, { "label": "three", "value": 3 }, ], True, ], ] layout = [] for definition in TEST_OPTIONS_N_VALUES: (option, value) = definition if len(definition) > 1 else [definition[0], None] layout.extend([ html.Div([ html.Div( f"Options={option}, Value={value}", style={ "marginBottom": 15, "marginTop": 25 }, ), dcc.Dropdown(option, value), ]), html.Div([ html.Div( f"Options={option}, Value={value}", style={ "marginBottom": 15, "marginTop": 25 }, ), dcc.RadioItems(option, value=value), ]), html.Div([ html.Div( f"Options={option}, Value={value}", style={ "marginBottom": 15, "marginTop": 25 }, ), dcc.Checklist(option, value=[value]), ]), ]) app.layout = html.Div(layout) dash_dcc.start_server(app) dash_dcc.wait_for_element(".dash-dropdown") dash_dcc.percy_snapshot( "ddsh001 - test_ddsh001_test_dropdown_radioitems_checklist_shorthands")
import dash # Code from: https://github.com/plotly/dash-labs/tree/main/docs/demos/multi_page_example1 dash.register_page(__name__, path="/") from dash import Dash, dcc, html, Input, Output, callback import plotly.express as px df = px.data.medals_wide(indexed=True) layout = html.Div([ html.P("Medals included:"), dcc.Checklist( id="heatmaps-medals", options=[{ "label": x, "value": x } for x in df.columns], value=df.columns.tolist(), ), dcc.Graph(id="heatmaps-graph"), ]) @callback(Output("heatmaps-graph", "figure"), Input("heatmaps-medals", "value")) def filter_heatmap(cols): fig = px.imshow(df[cols]) return fig
dbc.Col(width=10, children=[ dcc.Graph(id='line-chart-time', figure=fig_line_time), ]), ]), html.H2( "Has the ratio of male and female athletes changed over time?"), dbc.Row([ dbc.Col(width=2, children=[ dcc.Checklist( id='mf-ratio-checklist', options=[{ 'label': 'Winter', 'value': 'Winter' }, { 'label': 'Summer', 'value': 'Summer' }], value=['Winter', 'Summer'], labelStyle={"display": "inline-block"}, ), ]), dbc.Col(width=10, children=[ html.Div([ dcc.Graph(id='stacked-bar-gender-win', figure=fig_sb_gender_winter) ], style={'display': 'block'}), html.Div([ dcc.Graph(id='stacked-bar-gender-sum',
style={"width": "60%"}) return stats_panel plot_controls = [ make_plot_control("x-axis-selector", "x-axis", dropdown_cols, "period"), make_plot_control("y-axis-selector", "y-axis", dropdown_cols, "dm"), make_plot_control("z-axis-selector", "z-axis", dropdown_cols, "project"), html.Br(), dbc.Row( dcc.Checklist(id="logscale-selector", options=[{ 'label': 'log-x', 'value': "logx" }, { 'label': 'log-y', 'value': "logy" }], value=["logx"], labelStyle={'display': 'block'}, inputStyle={"margin-right": "15px"})), html.Br(), dbc.Row( dbc.Button(id='update-plot-button-state', n_clicks=0, children='Update')) ] graph_layout = dbc.Container([ dbc.Modal(id="pulsar-graph-detail-modal", size="xl",
html.Div( id="checklist-avoid", # style={'zIndex': 3}, children=[ html. H4('What would you like to avoid along your itinerary?' ), dcc.Checklist( id='poi-selection-unhealthy', options=[{ 'label': 'Fast-foods', 'value': 'fast_food' }, { 'label': 'Restaurants', 'value': 'restaurant' }, { 'label': 'Bars', 'value': 'bar' }, { 'label': 'Bakeries', 'value': 'bakery' }], value=['fast_food'], ), ], ), html.Div( id="slider-container", # style = {'zIndex':4}, children=[ html.H4("How much do you want to avoid these?",
def platter_app(): app = Dash(__name__) app.layout = html.Div([ html.Div(id="waitfor"), html.Label("Upload"), dcc.Upload(), html.Label("Horizontal Tabs"), dcc.Tabs( id="tabs", children=[ dcc.Tab( label="Tab one", className="test", style={"border": "1px solid magenta"}, children=[html.Div(["Test"])], ), dcc.Tab( label="Tab two", children=[ html.Div([ html.H1("This is the content in tab 2"), html.P("A graph here would be nice!"), ]) ], id="tab-one", ), dcc.Tab( label="Tab three", children=[ html.Div([html.H1("This is the content in tab 3")]) ], ), ], style={"fontFamily": "system-ui"}, content_style={ "border": "1px solid #d6d6d6", "padding": "44px" }, parent_style={ "maxWidth": "1000px", "margin": "0 auto" }, ), html.Label("Vertical Tabs"), dcc.Tabs( id="tabs1", vertical=True, children=[ dcc.Tab(label="Tab one", children=[html.Div(["Test"])]), dcc.Tab( label="Tab two", children=[ html.Div([ html.H1("This is the content in tab 2"), html.P("A graph here would be nice!"), ]) ], ), dcc.Tab( label="Tab three", children=[ html.Div([html.H1("This is the content in tab 3")]) ], ), ], ), html.Label("Dropdown"), dcc.Dropdown(options=OPTIONS, value="MTL", id="dropdown"), html.Label("Multi-Select Dropdown"), dcc.Dropdown(options=OPTIONS, value=["MTL", "SF"], multi=True), html.Label("Radio Items"), dcc.RadioItems(options=OPTIONS, value="MTL"), html.Label("Checkboxes"), dcc.Checklist(options=OPTIONS, value=["MTL", "SF"]), html.Label("Text Input"), dcc.Input(value="", placeholder="type here", id="textinput"), html.Label("Disabled Text Input"), dcc.Input( value="disabled", type="text", id="disabled-textinput", disabled=True, ), html.Label("Slider"), dcc.Slider( min=0, max=9, marks={i: f"Label {i}" if i == 1 else str(i) for i in range(1, 6)}, value=5, ), html.Label("Graph"), dcc.Graph( id="graph", figure={ "data": [{ "x": [1, 2, 3], "y": [4, 1, 4] }], "layout": { "title": "北京" }, }, ), html.Div([ html.Label("DatePickerSingle"), dcc.DatePickerSingle(id="date-picker-single", date=datetime(1997, 5, 10)), html.Div( [ html.Label("DatePickerSingle - empty input"), dcc.DatePickerSingle(), ], id="dt-single-no-date-value", ), html.Div( [ html.Label( "DatePickerSingle - initial visible month (May 97)"), dcc.DatePickerSingle( initial_visible_month=datetime(1997, 5, 10)), ], id="dt-single-no-date-value-init-month", ), ]), html.Div([ html.Label("DatePickerRange"), dcc.DatePickerRange( id="date-picker-range", start_date_id="startDate", end_date_id="endDate", start_date=datetime(1997, 5, 3), end_date_placeholder_text="Select a date!", ), html.Div( [ html.Label("DatePickerRange - empty input"), dcc.DatePickerRange( start_date_id="startDate", end_date_id="endDate", start_date_placeholder_text="Start date", end_date_placeholder_text="End date", ), ], id="dt-range-no-date-values", ), html.Div( [ html.Label( "DatePickerRange - initial visible month (May 97)"), dcc.DatePickerRange( start_date_id="startDate", end_date_id="endDate", start_date_placeholder_text="Start date", end_date_placeholder_text="End date", initial_visible_month=datetime(1997, 5, 10), ), ], id="dt-range-no-date-values-init-month", ), ]), html.Label("TextArea"), dcc.Textarea(placeholder="Enter a value... 北京", style={"width": "100%"}), html.Label("Markdown"), dcc.Markdown(""" #### Dash and Markdown Dash supports [Markdown](https://rexxars.github.io/react-markdown/). Markdown is a simple way to write and format text. It includes a syntax for things like **bold text** and *italics*, [links](https://rexxars.github.io/react-markdown/), inline `code` snippets, lists, quotes, and more. 1. Links are auto-rendered: https://dash.plotly.com. 2. This uses ~commonmark~ GitHub flavored markdown. Tables are also supported: | First Header | Second Header | | ------------- | ------------- | | Content Cell | Content Cell | | Content Cell | Content Cell | 北京 """.replace(" ", "")), dcc.Markdown(["# Line one", "## Line two"]), dcc.Markdown(), dcc.Markdown(""" ```py import python print(3) ```"""), dcc.Markdown(["```py", "import python", "print(3)", "```"]), dcc.Markdown(), ]) yield app
def make_dash_app(self, template='plotly_white', server_mode='external', port=8050, app_type='jupyter', plot_height=680, external_stylesheets=[ 'https://codepen.io/chriddyp/pen/bWLwgP.css' ], infer_proxy=False, slider_width=140, cutout_hdu=None, cutout_size=10): """ Create a Plotly/Dash app for interactive exploration Parameters ---------- template : str `plotly` style `template <https://plotly.com/python/templates/#specifying-themes-in-graph-object-figures>`_. server_mode, port : str, int If not `None`, the app server is started with `app.run_server(mode=server_mode, port=port)`. app_type : str If ``jupyter`` then `app = jupyter_dash.JupyterDash()`, else `app = dash.Dash()` plot_height : int Height in pixels of the scatter and SED+P(z) plot windows. infer_proxy : bool Run `JupyterDash.infer_jupyter_proxy_config()`, before app initilization, e.g., for running on GoogleColab. Returns ------- app : object App object following `app_type`. """ import dash from dash import dcc from dash import html import plotly.express as px from urllib.parse import urlparse, parse_qsl, urlencode import astropy.wcs as pywcs if app_type == 'dash': app = dash.Dash(__name__, external_stylesheets=external_stylesheets) else: from jupyter_dash import JupyterDash if infer_proxy: JupyterDash.infer_jupyter_proxy_config() app = JupyterDash(__name__, external_stylesheets=external_stylesheets) PLOT_TYPES = [ 'zphot-zspec', 'Mag-redshift', 'Mass-redshift', 'UVJ', 'RA/Dec', 'UV-redshift', 'chi2-redshift' ] for _t in self.extra_plots: PLOT_TYPES.append(_t) COLOR_TYPES = ['z_phot', 'z_spec', 'mass', 'sSFR', 'chi2'] #_title = f"{self.photoz.param['MAIN_OUTPUT_FILE']}" #_subhead = f"Nobj={self.photoz.NOBJ} Nfilt={self.photoz.NFILT}" _title = [ html.Strong(self.photoz.param['MAIN_OUTPUT_FILE']), ' / N', html.Sub('obj'), f'={self.photoz.NOBJ}', ' / N', html.Sub('filt'), f'={self.photoz.NFILT}', ] slider_row_style = { 'width': '90%', 'float': 'left', 'margin-left': '10px' } slider_container = { 'width': f'{slider_width}px', 'margin-left': '-25px' } check_kwargs = dict(style={ 'text-align': 'center', 'height': '14pt', 'margin-top': '-20px' }) # bool_options = {'has_zspec': 'z_spec > 0', # 'use': 'Use == 1'} if cutout_hdu is not None: cutout_wcs = pywcs.WCS(cutout_hdu.header, relax=True) cutout_data = cutout_hdu.data print('xxx', cutout_data.shape) cutout_div = html.Div( [dcc.Graph(id='cutout-figure', style={})], style={ 'right': '70px', 'width': '120px', 'height': '120px', 'border': '1px solid rgb(200,200,200)', 'top': '10px', 'position': 'absolute' }) cutout_target = 'figure' else: cutout_div = html.Div(id='cutout-figure', style={ 'left': '1px', 'width': '1px', 'height': '1px', 'bottom': '1px', 'position': 'absolute' }) cutout_data = None cutout_target = 'children' ####### App layout app.layout = html.Div([ # Selectors html.Div( [ dcc.Location(id='url', refresh=False), html.Div([ html.Div(_title, id='title-bar', style={ 'float': 'left', 'margin-top': '4pt' }), html.Div([ html.Div([ dcc.Dropdown(id='plot-type', options=[{ 'label': i, 'value': i } for i in PLOT_TYPES], value='zphot-zspec', clearable=False, style={ 'width': '120px', 'margin-right': '5px', 'margin-left': '5px', 'font-size': '8pt' }), ], style={'float': 'left'}), html.Div([ dcc.Dropdown(id='color-type', options=[{ 'label': i, 'value': i } for i in COLOR_TYPES], value='sSFR', clearable=False, style={ 'width': '80px', 'margin-right': '5px', 'font-size': '8pt' }), ], style={ 'display': 'inline-block', 'margin-left': '10px' }), ], style={'float': 'right'}), ], style=slider_row_style), html.Div( [ html.Div([ dcc.Dropdown( id='mag-filter', options=[{ 'label': i, 'value': i } for i in self.photoz.flux_columns], value=self.DEFAULT_FILTER, style={ 'width': f'{slider_width-45}px', 'margin-right': '20px', 'font-size': '8pt' }, clearable=False), ], style={'float': 'left'}), html.Div([ dcc.RangeSlider(id='mag-slider', min=12, max=32, step=0.2, value=[18, 27], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='mag-checked', options=[{ 'label': 'AB mag', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), # html.Div([ dcc.RangeSlider(id='chi2-slider', min=0, max=20, step=0.1, value=[0, 6], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='chi2-checked', options=[{ 'label': 'chi2', 'value': 'checked' }], value=[], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), html.Div([ dcc.RangeSlider(id='nfilt-slider', min=1, max=self.MAXNFILT, step=1, value=[3, self.MAXNFILT], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='nfilt-checked', options=[{ 'label': 'nfilt', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), ], style=slider_row_style), html.Div( [ html.Div([ dcc.RangeSlider(id='zphot-slider', min=-0.5, max=12, step=0.1, value=[0, self.ZMAX], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='zphot-checked', options=[{ 'label': 'z_phot', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(float='left', **slider_container)), html.Div([ dcc.RangeSlider(id='zspec-slider', min=-0.5, max=12, step=0.1, value=[-0.5, 6.5], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='zspec-checked', options=[{ 'label': 'z_spec', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), html.Div([ dcc.RangeSlider(id='mass-slider', min=7, max=13, step=0.1, value=[8, 11.8], updatemode='drag', tooltip={"placement": 'left'}), dcc.Checklist(id='mass-checked', options=[{ 'label': 'mass', 'value': 'checked' }], value=['checked'], **check_kwargs), ], style=dict(display='inline-block', **slider_container)), # Boolean dropdown # dcc.Dropdown(id='bool-checks', # options=[{'label': self.bool_options[k], # 'value': k} # for k in self.bool_options], # value=[], # multi=True, # style={'width':'100px', # 'display':'inline-block', # 'margin-left':'0px', # 'font-size':'8pt'}, # clearable=True), ], style=slider_row_style), ], style={ 'float': 'left', 'width': '55%' }), # Object-level controls html.Div([ html.Div([ html.Div('ID / RA,Dec.', style={ 'float': 'left', 'width': '100px', 'margin-top': '5pt' }), dcc.Input(id='id-input', type='text', style={ 'width': '120px', 'padding': '2px', 'display': 'inline', 'font-size': '8pt' }), html.Div(children='', id='match-sep', style={ 'margin': '5pt', 'display': 'inline', 'width': '50px', 'font-size': '8pt' }), dcc.RadioItems(id='sed-unit-selector', options=[{ 'label': i, 'value': i } for i in ['Fλ', 'Fν', 'νFν']], value='Fλ', labelStyle={ 'display': 'inline', 'padding': '3px', }, style={ 'display': 'inline', 'width': '130px' }) ], style={ 'width': '260pix', 'float': 'left', 'margin-right': '20px' }), ]), html.Div( [ # html.Div([ # ], style={'width':'120px', 'float':'left'}), html.Div(id='object-info', children='ID: ', style={ 'margin': 'auto', 'margin-top': '10px', 'font-size': '10pt' }) ], style={ 'float': 'right', 'width': '45%' }), # Plots html.Div( [ # Scatter plot dcc.Graph(id='sample-selection-scatter', hoverData={ 'points': [{ 'customdata': (self.df['id'][0], 1.0, -9.0) }] }, style={'width': '95%'}) ], style={ 'float': 'left', 'height': '70%', 'width': '49%' }), html.Div( [ # SED dcc.Graph(id='object-sed-figure', style={'width': '95%'}) ], style={ 'float': 'right', 'width': '49%', 'height': '70%' }), cutout_div ]) ##### Callback functions @app.callback(dash.dependencies.Output('url', 'search'), [ dash.dependencies.Input('plot-type', 'value'), dash.dependencies.Input('color-type', 'value'), dash.dependencies.Input('mag-filter', 'value'), dash.dependencies.Input('mag-slider', 'value'), dash.dependencies.Input('mass-slider', 'value'), dash.dependencies.Input('chi2-slider', 'value'), dash.dependencies.Input('nfilt-slider', 'value'), dash.dependencies.Input('zphot-slider', 'value'), dash.dependencies.Input('zspec-slider', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_url_state(plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input): search = f'?plot_type={plot_type}&color_type={color_type}' search += f'&mag_filter={mag_filter}' search += f'&mag={mag_range[0]},{mag_range[1]}' search += f'&mass={mass_range[0]},{mass_range[1]}' search += f'&chi2={chi2_range[0]},{chi2_range[1]}' search += f'&nfilt={nfilt_range[0]},{nfilt_range[1]}' search += f'&zphot={zphot_range[0]},{zphot_range[1]}' search += f'&zspec={zspec_range[0]},{zspec_range[1]}' if id_input is not None: search += f"&id={id_input.replace(' ', '%20')}" return search @app.callback([ dash.dependencies.Output('plot-type', 'value'), dash.dependencies.Output('color-type', 'value'), dash.dependencies.Output('mag-filter', 'value'), dash.dependencies.Output('mag-slider', 'value'), dash.dependencies.Output('mass-slider', 'value'), dash.dependencies.Output('chi2-slider', 'value'), dash.dependencies.Output('nfilt-slider', 'value'), dash.dependencies.Output('zphot-slider', 'value'), dash.dependencies.Output('zspec-slider', 'value'), dash.dependencies.Output('id-input', 'value'), ], [dash.dependencies.Input('url', 'href')]) def set_state_from_url(href): plot_type = 'zphot-zspec' color_type = 'sSFR' mag_filter = self.DEFAULT_FILTER mag_range = [18, 27] mass_range = [8, 11.6] chi2_range = [0, 4] nfilt_range = [1, self.MAXNFILT] zphot_range = [0, self.ZMAX] zspec_range = [-0.5, 6.5] id_input = None if '?' not in href: return (plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input) search = href.split('?')[1] params = search.split('&') for p in params: if 'plot_type' in p: val = p.split('=')[1] if val in PLOT_TYPES: plot_type = val elif 'color_type' in p: val = p.split('=')[1] if val in COLOR_TYPES: color_type = val elif 'mag_filter' in p: val = p.split('=')[1] if val in self.photoz.flux_columns: mag_filter = val elif 'mag=' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: mag_range = vals except ValueError: pass elif 'mass' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: mass_range = vals except ValueError: pass elif 'nfilt=' in p: try: vals = [int(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: nfilt_range = vals except ValueError: pass elif 'zspec' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: zspec_range = vals except ValueError: pass elif 'zphot' in p: try: vals = [float(v) for v in p.split('=')[1].split(',')] if len(vals) == 2: zphot_range = vals except ValueError: pass elif 'id' in p: try: id_input = p.split('=')[1].replace('%20', ' ') except ValueError: id_input = None if not id_input: id_input = None return (plot_type, color_type, mag_filter, mag_range, mass_range, chi2_range, nfilt_range, zphot_range, zspec_range, id_input) @app.callback( dash.dependencies.Output('sample-selection-scatter', 'figure'), [ dash.dependencies.Input('plot-type', 'value'), dash.dependencies.Input('color-type', 'value'), dash.dependencies.Input('mag-filter', 'value'), dash.dependencies.Input('mag-slider', 'value'), dash.dependencies.Input('mag-checked', 'value'), dash.dependencies.Input('mass-slider', 'value'), dash.dependencies.Input('mass-checked', 'value'), dash.dependencies.Input('chi2-slider', 'value'), dash.dependencies.Input('chi2-checked', 'value'), dash.dependencies.Input('nfilt-slider', 'value'), dash.dependencies.Input('nfilt-checked', 'value'), dash.dependencies.Input('zphot-slider', 'value'), dash.dependencies.Input('zphot-checked', 'value'), dash.dependencies.Input('zspec-slider', 'value'), dash.dependencies.Input('zspec-checked', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_selection(plot_type, color_type, mag_filter, mag_range, mag_checked, mass_range, mass_checked, chi2_range, chi2_checked, nfilt_range, nfilt_checked, zphot_range, zphot_checked, zspec_range, zspec_checked, id_input): """ Apply slider selections """ sel = np.isfinite(self.df['z_phot']) if 'checked' in zphot_checked: sel &= (self.df['z_phot'] > zphot_range[0]) sel &= (self.df['z_phot'] < zphot_range[1]) if 'checked' in zspec_checked: sel &= (self.df['z_spec'] > zspec_range[0]) sel &= (self.df['z_spec'] < zspec_range[1]) if 'checked' in mass_checked: sel &= (self.df['mass'] > mass_range[0]) sel &= (self.df['mass'] < mass_range[1]) if 'checked' in chi2_checked: sel &= (self.df['chi2'] >= chi2_range[0]) sel &= (self.df['chi2'] <= chi2_range[1]) if 'checked' in nfilt_checked: sel &= (self.df['nusefilt'] >= nfilt_range[0]) sel &= (self.df['nusefilt'] <= nfilt_range[1]) #print('redshift: ', sel.sum()) if mag_filter is None: mag_filter = self.DEFAULT_FILTER #self.self.df['mag'] = self.ABZP #self.self.df['mag'] -= 2.5*np.log10(self.photoz.cat[mag_filter]) mag_col = 'mag_' + mag_filter if 'checked' in mag_checked: sel &= (self.df[mag_col] > mag_range[0]) sel &= (self.df[mag_col] < mag_range[1]) self.df['mag'] = self.df[mag_col] #print('mag: ', sel.sum()) if plot_type == 'zphot-zspec': sel &= self.df['z_spec'] > 0 #print('zspec: ', sel.sum()) if id_input is not None: id_i, dr_i = parse_id_input(id_input) if id_i is not None: self.df['is_selected'] = self.df['id'] == id_i sel |= self.df['is_selected'] else: self.df['is_selected'] = False else: self.df['is_selected'] = False dff = self.df[sel] # Color-coding by color-type pulldown if color_type == 'z_phot': color_kwargs = dict(color=np.clip(dff['z_phot'], *zphot_range), color_continuous_scale='portland') elif color_type == 'z_spec': color_kwargs = dict(color=np.clip(dff['z_spec'], *zspec_range), color_continuous_scale='portland') elif color_type == 'mass': color_kwargs = dict(color=np.clip(dff['mass'], *mass_range), color_continuous_scale='magma_r') elif color_type == 'chi2': color_kwargs = dict(color=np.clip(dff['chi2'], *chi2_range), color_continuous_scale='viridis') else: color_kwargs = dict(color=np.clip(dff['ssfr'], -12., -8.), color_continuous_scale='portland_r') # Scatter plot plot_defs = { 'Mass-redshift': ('z_phot', 'mass', 'z<sub>phot</sub>', 'log Stellar mass', (-0.1, self.ZMAX), (7.5, 12.5)), 'Mag-redshift': ('z_phot', 'mag', 'z<sub>phot</sub>', f'AB mag ({mag_filter})', (-0.1, self.ZMAX), (18, 28)), 'RA/Dec': ('ra', 'dec', 'R.A.', 'Dec.', self.ra_bounds, self.dec_bounds), 'zphot-zspec': ('z_spec', 'z_phot', 'z<sub>spec</sub>', 'z<sub>phot</sub>', (0, 4.5), (0, 4.5)), 'UVJ': ('vj', 'uv', '(V-J)', '(U-V)', (-0.1, 2.5), (-0.1, 2.5)), 'UV-redshift': ('z_phot', 'uv', 'z<sub>phot</sub>', '(U-V)<sub>rest</sub>', (0, 4), (-0.1, 2.50)), 'chi2-redshift': ('z_phot', 'chi2', 'z<sub>phot</sub>', 'chi<sup>2</sup>', (0, 4), (0.1, 30)) } if plot_type in self.extra_plots: args = (*self.extra_plots[plot_type], {}, color_kwargs) elif plot_type in plot_defs: args = (*plot_defs[plot_type], {}, color_kwargs) else: args = (*plot_defs['zphot-zspec'], {}, color_kwargs) fig = update_sample_scatter(dff, *args) # Update ranges for some parameters if ('Mass' in plot_type) & ('checked' in mass_checked): fig.update_yaxes(range=mass_range) if ('Mag' in plot_type) & ('checked' in mag_checked): fig.update_yaxes(range=mag_range) if ('redshift' in plot_type) & ('checked' in zphot_checked): fig.update_xaxes(range=zphot_range) if ('zspec' in plot_type) & ('checked' in zspec_checked): fig.update_yaxes(range=zspec_range) return fig def update_sample_scatter(dff, xcol, ycol, x_label, y_label, x_range, y_range, extra, color_kwargs): """ Make scatter plot """ import plotly.graph_objects as go fig = px.scatter( data_frame=dff, x=xcol, y=ycol, custom_data=['id', 'z_phot', 'mass', 'ssfr', 'mag'], **color_kwargs) htempl = '(%{x:.2f}, %{y:.2f}) <br>' htempl += 'id: %{customdata[0]:0d} z_phot: %{customdata[1]:.2f}' htempl += '<br> mag: %{customdata[4]:.1f} ' htempl += 'mass: %{customdata[2]:.2f} ssfr: %{customdata[3]:.2f}' fig.update_traces(hovertemplate=htempl, opacity=0.7) if dff['is_selected'].sum() > 0: dffs = dff[dff['is_selected']] _sel = go.Scatter(x=dffs[xcol], y=dffs[ycol], mode="markers+text", text=[f'{id}' for id in dffs['id']], textposition="bottom center", marker=dict(color='rgba(250,0,0,0.5)', size=20, symbol='circle-open')) fig.add_trace(_sel) fig.update_xaxes(range=x_range, title_text=x_label) fig.update_yaxes(range=y_range, title_text=y_label) fig.update_layout(template=template, autosize=True, showlegend=False, margin=dict(l=0, r=0, b=0, t=20, pad=0, autoexpand=True)) if plot_height is not None: fig.update_layout(height=plot_height) fig.update_traces(marker_showscale=False, selector=dict(type='scatter')) fig.update_coloraxes(showscale=False) if (xcol, ycol) == ('z_spec', 'z_phot'): _one2one = go.Scatter(x=[0, 8], y=[0, 8], mode="lines", marker=dict(color='rgba(250,0,0,0.5)')) fig.add_trace(_one2one) fig.add_annotation(text=f'N = {len(dff)} / {len(self.df)}', xref="x domain", yref="y domain", x=0.98, y=0.05, showarrow=False) return fig def sed_cutout_figure(id_i): """ SED cutout """ from plotly.subplots import make_subplots if cutout_data is not None: ix = np.where(self.df['id'] == id_i)[0] ri, di = self.df['ra'][ix], self.df['dec'][ix] xi, yi = np.squeeze(cutout_wcs.all_world2pix([ri], [di], 0)) xp = int(np.round(xi)) yp = int(np.round(yi)) slx = slice(xp - cutout_size, xp + cutout_size + 1) sly = slice(yp - cutout_size, yp + cutout_size + 1) try: cutout = cutout_data[sly, slx] except: cutout = np.zeros((2 * cutout_size, 2 * cutout_size)) fig = px.imshow(cutout, color_continuous_scale='gray_r') fig.update_coloraxes(showscale=False) fig.update_layout(width=120, height=120, margin=dict(l=0, r=0, b=0, t=0, pad=0, autoexpand=True)) fig.update_xaxes(range=(0, 2 * cutout_size), visible=False, showticklabels=False) fig.update_yaxes(range=(0, 2 * cutout_size), visible=False, showticklabels=False) return fig def parse_id_input(id_input): """ Parse input as id or (ra dec) """ if id_input in ['None', None, '']: return None, None inp_split = id_input.replace(',', ' ').split() if len(inp_split) == 1: return int(inp_split[0]), None ra, dec = np.cast[float](inp_split) cosd = np.cos(self.df['dec'] / 180 * np.pi) dx = (self.df['ra'] - ra) * cosd dy = (self.df['dec'] - dec) dr = np.sqrt(dx**2 + dy**2) * 3600. imin = np.nanargmin(dr) return self.df['id'][imin], dr[imin] @app.callback([ dash.dependencies.Output('object-sed-figure', 'figure'), dash.dependencies.Output('object-info', 'children'), dash.dependencies.Output('match-sep', 'children'), dash.dependencies.Output('cutout-figure', cutout_target) ], [ dash.dependencies.Input('sample-selection-scatter', 'hoverData'), dash.dependencies.Input('sed-unit-selector', 'value'), dash.dependencies.Input('id-input', 'value') ]) def update_object_sed(hoverData, sed_unit, id_input): """ SED + p(z) plot """ id_i, dr_i = parse_id_input(id_input) if id_i is None: id_i = hoverData['points'][0]['customdata'][0] else: if id_i not in self.zout['id']: id_i = hoverData['points'][0]['customdata'][0] if dr_i is None: match_sep = '' else: match_sep = f'{dr_i:.1f}"' show_fnu = {'Fλ': 0, 'Fν': 1, 'νFν': 2} layout_kwargs = dict(template=template, autosize=True, showlegend=False, margin=dict(l=0, r=0, b=0, t=20, pad=0, autoexpand=True)) fig = self.photoz.show_fit_plotly(id_i, show_fnu=show_fnu[sed_unit], vertical=True, panel_ratio=[0.6, 0.4], show=False, layout_kwargs=layout_kwargs) if plot_height is not None: fig.update_layout(height=plot_height) ix = self.df['id'] == id_i if ix.sum() == 0: object_info = 'ID: N/A' else: ix = np.where(ix)[0][0] ra, dec = self.df['ra'][ix], self.df['dec'][ix] object_info = [ f'ID: {id_i} | α, δ = {ra:.6f} {dec:.6f} ', ' | ', html.A('ESO', href=utils.eso_query(ra, dec, radius=1.0, unit='s')), ' | ', html.A('CDS', href=utils.cds_query(ra, dec, radius=1.0, unit='s')), ' | ', html.A('LegacySurvey', href=utils.show_legacysurvey(ra, dec, layer='ls-dr9')), html.Br(), f"z_phot: {self.df['z_phot'][ix]:.3f} ", f" | z_spec: {self.df['z_spec'][ix]:.3f}", html.Br(), f"mag: {self.df['mag'][ix]:.2f} ", f" | mass: {self.df['mass'][ix]:.2f} ", f" | sSFR: {self.df['ssfr'][ix]:.2f}", html.Br() ] if cutout_data is None: cutout_fig = [''] else: cutout_fig = sed_cutout_figure(id_i) return fig, object_info, match_sep, cutout_fig if server_mode is not None: app.run_server(mode=server_mode, port=port) return app
def div_graph_daq(): """ Generates an HTML div that contains the DAQ graph and the display options """ return html.Div( [ # Graph division html.Div(id='div-graph-daq', className='nine columns', style={'margin-left': '10px'}), # List of options for the graph display html.Div( [ # Dropdown to choose the file from which to extract the data dcc.Dropdown(id='dropdown-file-selection', clearable=False, searchable=True, style={'margin-top': '10px'}), # Selection of the amount of time to represent (not great) html.Div([ html.Div([ dcc.Input(id='input-time-range', value=1, type='number', style={"width": "100%"}) ], style={'margin-top': '10px'}, className='six columns'), html.Div([ dcc.Dropdown(id='dropdown-time-range', clearable=False, searchable=True, options=[{ 'label': 'second(s)', 'value': 'seconds' }, { 'label': 'minute(s)', 'value': 'minutes' }, { 'label': 'hour(s)', 'value': 'hours' }, { 'label': 'day(s)', 'value': 'days' }], value='hours', style={"width": "100%"}) ], style={'margin-top': '10px'}, className='six columns') ], style={'margin-bottom': '10px'}, className='twelve columns'), # Box that shows the elapsed time html.Div(id="div-time-display", style={'margin-top': '10px'}), # Choice of graph display type (overlapped or separated) html.Div([ html.H6("Display mode", style={ 'font-weight': 'bold', 'margin-bottom': '0px', 'margin-top': '10px' }), dcc.RadioItems(options=[{ 'label': ' Separate (Vertical)', 'value': 'separate_vertical' }, { 'label': ' Separate (Horizontal)', 'value': 'separate_horizontal' }, { 'label': ' Overlapping', 'value': 'overlap' }], value='separate_vertical', id='radio-display-mode-daq', style={'margin-left': '5px'}) ]), # Checklist of the measurements to plot and their last readings html.Div([ html.Div([ html.H6("Display selection", style={ 'font-weight': 'bold', 'margin-bottom': '0px' }), dcc.Checklist(options=[], value=[], id='checklist-display-options-daq', style={'margin-left': '5px'}) ], className='six columns'), html.Div(id='div-last-daq-value', className='six columns') ], className='row', style={ 'margin-top': '0px', 'position': 'relative' }) ], className='three columns'), ], className="row", style={ "border-radius": "5px", "border-width": "5px", "border": "2px solid rgb(216, 216, 216)", "position": "relative", "height": "480px" })
def parkingFeatDash(): return dcc.Checklist( ['Подземный паркинг', 'Гостевой паркинг', 'Отсутствует/иное'], value=[], id='parking' )
dcc.Markdown( "[Survey post by /u/panchovix](https://redd.it/hph5qi) | " "[Raw data](https://docs.google.com/spreadsheets/d/1XyHaKLaWPt_ndeACJopUl39_wk4yZAUz3NkdUK9Guw0/edit?usp=sharing) | " "[Processed data](https://raw.githubusercontent.com/squaresmile/fgo-servant-survey/master/data/merged_df.csv) | " "[Atlas Academy Discord](https://discord.gg/TKJmuCR)" ), html.Div( [ html.P( "Servant Class:", style={"font-weight": "bold", "display": "inline-block"}, ), dcc.Checklist( id="class_checklist", options=dash_classes, labelStyle={"display": "inline-block"}, style={"display": "inline-block"}, value=servant_classes, ), ] ), html.Div( [ html.P( children="Servant Availability:", style={"font-weight": "bold", "display": "inline-block"}, ), dcc.Checklist( id="availability_checklist", options=dash_availability, labelStyle={"display": "inline-block"},
def cross_section_widgets_layout(self) -> html.Div: return html.Div(children=[ html.Div(children=[ dbc.Button( "Surface Settings", id=self.ids("button-open-graph-settings"), color="light", className="mr-1", ), dbc.Modal( children=[ dbc.ModalHeader("Surface Settings"), dbc.ModalBody(children=[ html.Label( style={ "font-weight": "bold", "textAlign": "Left", }, children="Select Surfaces", ), dcc.Checklist( id=self.ids("all-surfaces-checkbox"), options=[{ "label": "all", "value": "True" }], value=["True"], persistence=True, persistence_type="session", ), dcc.Checklist( id=self.ids("surfaces-checklist"), options=[{ "label": name, "value": name } for name in self.surfacenames], value=self.surfacenames, persistence=True, persistence_type="session", ), dcc.Checklist( id=self.ids("surfaces-de-checklist"), options=[{ "label": name + " SD", "value": name, "disabled": False, } for name in self.surfacenames], value=self.surfacenames, persistence=True, persistence_type="session", ), ], ), dbc.ModalFooter(children=[ dbc.Button( "Close", id=self.ids("button-close-graph-settings"), className="ml-auto", ), dbc.Button( "Apply changes", id=self.ids("button-apply-checklist"), className="ml-auto", ), ]), ], id=self.ids("modal-graph-settings"), size="sm", centered=True, backdrop=False, fade=False, ), dbc.Button("Well Settings", id=self.ids("button-open-well-settings")), dbc.Modal( children=[ dbc.ModalHeader("Well Settings"), dbc.ModalBody(children=[ html.Label( style={ "font-weight": "bold", "textAlign": "Left", }, children="Select Well Attributes", ), dcc.Checklist( id=self.ids("all-well-settings-checkbox"), options=[{ "label": "all", "value": "True" }], value=["True"], persistence=True, persistence_type="session", ), dcc.Checklist( id=self.ids("well-settings-checklist"), options=[ { "label": "Zonelog", "value": "zonelog", }, { "label": "Zonation points", "value": "zonation_points", }, { "label": "Conditional points", "value": "conditional_points", }, ], value=[ "zonelog", "zonation_points", "conditional_points", ], persistence=True, persistence_type="session", ), ], ), dbc.ModalFooter(children=[ dbc.Button( "Close", id=self.ids("button-close-well-settings"), className="ml-auto", ), dbc.Button( "Apply", id=self.ids( "button-apply-well-settings-checklist"), className="ml-auto", ), ]), ], id=self.ids("modal-well-settings"), size="sm", centered=True, backdrop=False, fade=False, ), ], ), wcc.FlexBox(children=[ html.Div(children=[ html.Label( style={ "font-weight": "bold", "textAlign": "center", }, children="Select well", ), dcc.Dropdown( id=self.ids("well-dropdown"), options=[{ "label": self.wells[wf].wellname, "value": str(wf), } for wf in self.wellfiles] + [{ "label": self.planned_wells[wf].wellname, "value": str(wf), } for wf in self.planned_wellfiles], value=str(self.wellfiles[0]), clearable=False, disabled=False, persistence=True, persistence_type="session", ), ]), ], ), html.Div(children=[ html.Div( style={ "marginTop": "0px", "height": "800px", "zIndex": -9999, }, children=[self.cross_section_graph_layout], id=self.ids("cross-section-view"), ) ]), ])
"overflowX": "scroll", 'padding': 'auto' }), dcc.Markdown('---'), html.Div(id='pko-controls'), dcc.Dropdown(id='pko-dropdown', options=[], value=None), dbc.Progress(id="pko-progress-bar", value=0, style={ 'marginBottom': '20px', 'width': '100%' }), dcc.Loading(dcc.Graph('pko-figure')), dcc.Checklist(id='pko-figure-options', options=[{ 'value': 'log', 'label': 'Logarithmic y-scale' }], value=[]), html.Button('Set RT to current view', id='pko-set-rt'), html.Button('Find largest peak', id='pko-find-largest-peak'), html.Button('Confirm retention time', id='pko-confirm-rt'), html.Button('Remove Peak', id='pko-delete', style={'float': 'right'}), html.Div(id='pko-image-clicked'), html.Div(children=[ html.Button('<< Previous', id='pko-prev'), html.Button('Suggest', id='pko-suggest-next'), html.Button('Next >>', id='pko-next') ], style={ 'text-align': 'center', 'margin': 'auto',