def create_buttons(): global button, download_button # Play button button = Button(label='► Play', button_type="success", width=60) button.on_click(animate) play_widget = widgetbox(button, width=80, height=50, sizing_mode='fixed') spacer = Spacer(width=300, height=50) # Download button download_button1 = Button(label="Download Minimal HTML", button_type="success", width=150) download_button2 = Button(label="Download With Structures", button_type="success", width=150) download_button1.js_on_event(ButtonClick, download_simple()) download_button2.js_on_event(ButtonClick, download_extended()) download_widget1 = widgetbox(download_button1, width=200, height=50, sizing_mode='fixed') download_widget2 = widgetbox(download_button2, width=200, height=50, sizing_mode='fixed') dpanel = Row(Spacer(width=170), download_widget1, Spacer(width=10), download_widget2, width=600, sizing_mode='fixed') return play_widget, dpanel
def _get_model(self, doc, root=None, parent=None, comm=None): if root is None: return self._get_root(doc, comm) if self.object is None: model = BkSpacer() else: model = self.object properties = {} for p, value in self.param.values().items(): if (p not in Layoutable.param or p == 'name' or value is self.param[p].default): continue properties[p] = value model.update(**properties) if comm: self._wrap_bokeh_callbacks(root, model, doc, comm) ref = root.ref['id'] for js in model.select({'type': CustomJS}): js.code = js.code.replace(model.ref['id'], ref) if model._document and doc is not model._document: remove_root(model, doc) self._models[ref] = (model, parent) if self.theme: doc.theme = self.theme return model
def hdivider(line_thickness=2, border_thickness=6, top_border_thickness=6, bottom_border_thickness=6, line_color="white", border_color=BASE_BACKGROUND_COLOR): """ Generates a horizontal divider (spacer with a line) :param line_thickness: Thickness of the line :param border_thickness: Thickness of the border, total thickness = `border_thickness * 2 + line_thickness`, overrides top and bottom border thickness :param top_border_thickness: Thickness of the top border :param bottom_border_thickness: Thickness of the bottom border :param line_color: Line color :param border_color: Border color :return: The layout """ if border_thickness != 6: top = border_thickness bottom = border_thickness else: top = top_border_thickness bottom = bottom_border_thickness divider_top = Spacer(height=top, background=border_color) divider_bottom = Spacer(height=bottom, background=border_color) divider = column([ divider_top, Spacer(height=line_thickness, background=line_color), divider_bottom ], sizing_mode="stretch_width") return divider
def buildUnaggFigDict(x): toRet = {} for i in range(1,11): toRet[i] = {'plot_width': i*x, 'plot_height': i*x, 'tools': 'hover', 'x_axis_location': 'above', 'toolbar_location': None} toRet['MidSpacer'] = Spacer(**{'width':6*x, 'height':6*x}) toRet['BotSpacer'] = Spacer(**{'width':2*x, 'height':2*x}) return toRet
def compare_tab(): panel_title = Div(text="[Corridor Comparison]", css_classes = ["panel-title","text-center"]) panel_text = Div(text="""Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.""", css_classes = ["panel-content"]) #Date Range date_range = Div(text="Data References:<br>MMDDYYYY - MMDDYYYY", css_classes = ["panel-content","text-center"]) #Panel Buttons year_text = Div(text="<b>Year:", height=10) year_v1 = RangeSlider(start = 2015, end= 2017,step=1, value=(2015, 2017), height=25, bar_color="black",title = "View 1") year_v2 = RangeSlider(start = 2015, end= 2017,step=1, value=(2015, 2017), height=25, bar_color="black",title = "View 2") season_text = Div(text="<b>Season</b><br> (1=Winter, 2=Fall, 3=Spring, 4=Summer):", height=25) season_v1 = RangeSlider(start = 1, end= 4,step=1, value=(1, 2), height=25, bar_color="black",title = "View 1") season_v2 = RangeSlider(start = 1, end= 4,step=1, value=(1, 2), height=25, bar_color="black",title = "View 2") month_text = Div(text="<b>Month:", height=10) month_v1 = RangeSlider(start = 1, end= 12,step=1, value=(1, 2), height=25, bar_color="black",title = "View 1") month_v2 = RangeSlider(start = 1, end= 12,step=1, value=(1, 2), height=25, bar_color="black",title = "View 2") week_text = Div(text="<b>Day of Week:", height=10) week_v1 = RangeSlider(start = 1, end= 5,step=1, value=(1, 5), height=25, bar_color="black",title = "View 1") week_v2 = RangeSlider(start = 1, end= 5,step=1, value=(1, 5), height=25, bar_color="black",title = "View 2") time_of_day_text = Div(text="<b>Time of Day:", height=10) time_of_day_v1 = RangeSlider(start = 1, end= 24,step=1, value=(1, 7), bar_color="black", height=25) time_of_day_v2 = RangeSlider(start = 1, end= 24,step=1, value=(1, 7), bar_color="black", height=25) l1 = Div(text="test", css_classes = ["text-center"]) return row(column(panel_title, panel_text, date_range, year_text, year_v1, year_v2, Spacer(height=25), season_text, season_v1, season_v2, Spacer(height=25), month_text, month_v1, month_v2, Spacer(height=25), week_text, week_v1, week_v2, Spacer(height=25), time_of_day_text, time_of_day_v1, time_of_day_v2, height = 1000, css_classes = ["panel","col-lg-4"]), column(l1,css_classes = ["container-fluid","col-lg-8"]), css_classes = ["container-fluid","col-lg-12"])
def abm_background(): b_title = Div( text="""<h1>What is an Activity Based Model (ABM)?</h1><br>""", width=column_width) background = Div( text= """<ul><li><h3>Travel demand model that simulates individual and household transportation decisions</h3></li><br> <li><h3>Generates activities, identifies destinations for activities, determines mode of travel, and assigns routes on our network</h3></li><br> <li><h3>Considers personal and household attributes to predict:</h3></li> <ul><li>Types of activities a traveler participates in</li> <li>The individual and/or household members participating in the activity</li> <li>Where to participate in the activity</li> <li>How activities are scheduled/prioritized</li> <li>Time available to participate in those activities</li> <li>Mode of travel reach each activity</li> </ul><br> <li><h3>Produces a behaviorally realistic representation of travel compared to the trip-based model</h3></li> </ul> """, width=int(column_width * .4), style={'font-size': '150%'}) model_tbl = pd.DataFrame({ 'Travel Questions': [ 'What activities do people want to participate in?', 'Where are these activities?', 'When are these activities?', 'What travel mode is used?', 'What route is used?' ], 'Trip-Based Model': [ 'Trip generation', 'Trip distribution', 'None', 'Trip mode choice', 'Network assignment' ], 'Activity-Based Model': [ 'Activity generation and scheduling', 'Tour and trip destination choice', 'Tour and trip time of day', 'Tour and trip mode choice', 'Network assignment' ] }) div_tbl = Div(text=model_tbl.to_html( index=False, classes=["table-bordered", "table-hover"], ), width=int(column_width * .6), height=500, style={'font-size': '120%'}) return row( Spacer(width=margin), column( Spacer(height=25), b_title, row(background, Spacer(width=int(column_width * .10)), column(Spacer(height=80), div_tbl))))
def add_rank_table(self): columns = [ TableColumn(field="tool", title="Tool"), TableColumn(field="score", title="Weighted Score", formatter=NumberFormatter(format="0.00")), TableColumn(field="rank", title="Rank") ] self.data_table = DataTable(columns=columns, source=self.source, reorderable=True) buttons = zip( [self.ranking[k][0] for k in self.chosen_criteria], [self.ranking[k][1] for k in self.chosen_criteria], [self.weight_sliders[k] for k in self.weight_sliders.keys()]) self.app_layout.children.pop(1) b_layout = [[t[0], t[1], t[2]] for t in buttons] b_layout.append([self.rank_submit, self.b]) b_layout.append(widgetbox(self.data_table)) b_layout.append([self.clear_button]) b_layout.insert(0, [Spacer(width=300), self.swing_table]) self.app_layout.children.append(layout(b_layout))
def _addtodoc(self, ctrl, doc, *_): # pylint: disable=unused-argument self.__src = [ ColumnDataSource(data=i) for i in self.__data(None, None, None) ] label = (self._theme.ylabel if self._theme.dataformat != "norm" else self._theme.ylabelnormalized) self.__fig = fig = self.figure(y_range=Range1d, x_range=Range1d, y_axis_label=label, name='Ramp:Cycles') for i, j in zip(("beadarea", "beadline"), self.__src): self.addtofig(fig, i, x='zmag', y='zbead', source=j) for i, j in zip(("consensusarea", "consensusline", "beadcycles"), self.__src): self.addtofig(fig, i, x='zmag', y='z', source=j) self.addtofig(fig, "frames", x='zmag', y='z', source=self.__src[-1]) self.linkmodeltoaxes(fig) left = self.__widgets.create(self, ctrl, fig, self._theme.widgetwidth) out = self._keyedlayout(ctrl, fig) out.width = fig.plot_width out.height = fig.plot_height return stretchout( layouts.row([left, Spacer(width=20, height=left.height), out], width=left.width + out.width + 20, height=max(left.height, out.height), **self.defaultsizingmode()))
def days(): for i in Calendar().iterweekdays(): yield Div(text=f'<h2>{day_name[i]}</h2>') day = month_start - dt.timedelta(days=month_start.weekday()) while day.replace(day=1) <= month_start: for weekday in range(7): if day.month == month_start.month: contents = [Div(text=f'<h1>{day.strftime("%d")}</h1>')] for a in s.query(ActivityJournal). \ filter(ActivityJournal.start >= local_date_to_time(day), ActivityJournal.start < local_date_to_time(day + dt.timedelta(days=1))).all(): df = Statistics(s, activity_journal=a). \ by_name(ActivityReader, N.SPHERICAL_MERCATOR_X, N.SPHERICAL_MERCATOR_Y).df contents.append( map_thumbnail(map_size, map_size, df, title=False)) df = Statistics(s, activity_journal=a). \ by_name(ActivityCalculator, N.ACTIVE_DISTANCE, N.ACTIVE_TIME).df contents.append( Div(text= f'{format_km(df[N.ACTIVE_DISTANCE][0])} {format_seconds(df[N.ACTIVE_TIME][0])}' )) else: contents = [Spacer()] yield column(contents) day += dt.timedelta(days=1)
def __do_layout(self): # TODO: Generalize for 1 or 2 groups self.layout = column(row(self.select_y, self.select_linac[1], self.select_linac[2], self.avg_len_input, self.percentile_input, self.bins_input), row(self.select_energies[1], self.select_energies[2]), row(self.start_date_picker, self.end_date_picker), row(Div(text='Gamma Criteria: '), self.checkbox_button_group), self.div_summary[1], self.div_summary[2], row(Spacer(width=10), self.fig), Spacer(height=50), row(Spacer(width=10), self.histogram), Spacer(height=50), row(Spacer(width=10), self.ichart), row(self.div_center_line[1], self.div_ucl[1], self.div_lcl[1]), row(self.div_center_line[2], self.div_ucl[2], self.div_lcl[2]))
def overview_tab(): #image linke #image = load_image(abm_flow,'CT-RAMP Structure and Sub-Models') flow_image = Div( text="<img src='abm_pres/static/images/abm_flow_chart.png'>") overview_text = Div(text="""<h1>Activity Based Model Overview</h1>""", width=column_width) ctramp_text = Div( text="""<h3>Coordinated Travel - Regional Activity Modeling Platform (CT-RAMP) </h3><p>ABM model implements the CT-RAMP design and software platform. Features microsimulation of travel decisions for individual households and persons within a household as well as intra-household interactions across a range of activity and travel dimensions.</p><br> <ol><li><b>Population synthesis</b> creates and distributes households and persons for use in the ABM</li><br> <li><b>Long-Term Location Choice</b> - Models location of usual (mandatory) destinations</li><br> <li><b>Mobility</b> - Models household attributes like free parking eligibility, car ownership, transit pass, or toll transponder</li><br> <li><b>Coordinated Daily Activity-Travel Pattern</b> - Generates and schedules mandatory and non-mandatory activities for each household member.</li><br> <li><b>Tour</b> - Daily activities are organized into tours, tour mode, number, and location of stops are determined.</li><br> <li><b>Trips</b> - Mode, parking, and location of trips making up tour is determined.</li><br> <li><b>Network Simulation</b> - List of trips for each individual and/or travel party is generated and trips routes are assigned on the modeling network for auto and transit.</li> </ol>""", width=int(column_width * .5), style={'font-size': '150%'}) extra = Div( text="""<hr><ul><li>Tour: Chain of trips that start and end at home</li> <li>Person Types: 8 Person Types (1=Full time worker, 2=Part time worker, 3=University student, 4=Adult non-worker under 65, 5=retiree, 6=driving age school child, 7=pre-driving age school child, 8=preschool child)</li> <li>Activities: 10 travel purposes (work, university, school, escorting, shopping, other maintenance, eating out, visiting relatives and friends, other discretionary, and atwork)</li> <li>Modes = 21 modes at both tour and trip level</li> </ul>""", width=int(column_width * .5), css_classes=['small']) return (row(Spacer(width=margin), (column( Spacer(width=margin, height=25), overview_text, row(column(ctramp_text, extra), Spacer(width=100), column(flow_image))))))
def _figure_rows( model_evaluations: Sequence[Evaluation], include_spacer: Optional[bool], ) -> Sequence[Row]: # TODO check figure consistency rows = [] for i_figure, _ in enumerate(model_evaluations[0].lazy_figures): row_of_figures = [ evaluation.lazy_figures[i_figure]() for i_model, evaluation in enumerate(model_evaluations) ] if len(model_evaluations) == 1 and include_spacer in (None, True): row_of_figures = row_of_figures + [Spacer()] elif include_spacer is True: row_of_figures = [Spacer()] + row_of_figures rows.append( bokeh.layouts.row(row_of_figures, sizing_mode="scale_width")) return rows
def __init__(self, custom_title, data_tables): self.layout = column( Div(text="<b>DVH Analytics v%s</b>" % options.VERSION), row(custom_title['1']['planning'], Spacer(width=50), custom_title['2']['planning']), Div(text="<b>Rxs</b>", width=1000), data_tables.rxs, Div(text="<b>Plans</b>", width=1200), data_tables.plans, Div(text="<b>Beams</b>", width=1500), data_tables.beams, Div(text="<b>Beams Continued</b>", width=1500), data_tables.beams2)
def vdivider(line_thickness=1, border_thickness=3, line_color="white", border_color=BASE_BACKGROUND_COLOR): """ Generates a vertical divider (spacer with a line) :param line_thickness: Thickness of the line :param border_thickness: Thickness of the border, total thickness = `border_thickness * 2 + line_thickness` :param line_color: Line color :param border_color: Border color :return: The layout """ divider = Spacer(width=border_thickness, background=border_color) divider = row([ divider, Spacer(width=line_thickness, background=line_color), divider ], sizing_mode="stretch_height") return divider
def __do_layout(self): self.layout = column(self.button_refresh_plans, row(self.select_plan, self.select_protocol, self.select_fx), row(self.button_calculate, self.button_delete_roi), row(self.select_roi_template, self.select_roi), self.max_dose_volume, self.data_table, row(self.plot, Spacer(width=10), column(self.button_calculate_dvhs, self.plot_rois)))
def timings_plots(self): rows = [] for r in range(self.grid_dims[0]): for c in range(self.grid_dims[1] // 2): rows.append( row(widgetbox(*self.grid_controls[r, 2 * c]), self.figures[r, 2 * c], self.figures[r, 2 * c + 1])) rows.append(Spacer(height=10)) l = column(*rows) curdoc().add_root(l) curdoc().title = "Rippled eBPF Probes"
def __init__(self, sources, time_series, correlation, regression, custom_title, data_tables): self.sources = sources self.time_series = time_series self.correlation = correlation self.regression = regression self.eud_a_input = TextInput(value='', title='EUD a-value:', width=150) self.gamma_50_input = TextInput(value='', title=u"\u03b3_50:", width=150) self.td_tcd_input = TextInput(value='', title='TD_50 or TCD_50:', width=150) self.apply_button = Button(label="Apply parameters", button_type="primary", width=150) self.apply_filter = CheckboxButtonGroup( labels=["Group 1", "Group 2", "Selected"], active=[0], width=300) self.apply_button.on_click(self.apply_rad_bio_parameters) self.layout = column( Div(text="<b>DVH Analytics v%s</b>" % options.VERSION), row(custom_title['1']['rad_bio'], Spacer(width=50), custom_title['2']['rad_bio']), Div(text="<b>Published EUD Parameters from Emami" " et. al. for 1.8-2.0Gy fractions</b> (Click to apply)", width=600), data_tables.emami, Div(text="<b>Applied Parameters:</b>", width=150), row(self.eud_a_input, Spacer(width=50), self.gamma_50_input, Spacer(width=50), self.td_tcd_input, Spacer(width=50), self.apply_filter, Spacer(width=50), self.apply_button), Div(text="<b>EUD Calculations for Query</b>", width=500), data_tables.rad_bio, Spacer(width=1000, height=100))
def _figure_rows(model_evaluations: Sequence[Evaluation], include_spacer: bool) -> Sequence[Row]: # TODO check figure consistency rows = [] for i_figure, _ in enumerate(model_evaluations[0].lazy_figures): row_of_figures = [ evaluation.lazy_figures[i_figure]() for i_model, evaluation in enumerate(model_evaluations) ] if include_spacer: row_of_figures = [Spacer()] + row_of_figures rows.append( bokeh.layouts.row(row_of_figures, sizing_mode="scale_width")) return rows
def test_tab(): left_col = Div(text="""<h4>place holder</h4>""") right_col = Div(text="""<h4>figures</h4>""") h_1 = Div(text = """<h1><center>Intro Text</center></h1>""") l_1 = layout(children=[row(Spacer(height = 50)), row(column(left_col, width= 200,css_classes = ["caption", "text-center"]), column(intro), column(right_col, width= 200, css_classes = ["caption", "text-center"]), css_classes = ["container-fluid"], width = 2000)]) tab_1 = Panel(child=l_1, title = '# Introduction') return tab_1
def add_weight_changes(self): self.weight_calc() buttons = zip( [self.ranking[k][0] for k in self.chosen_criteria], [self.ranking[k][1] for k in self.chosen_criteria], [self.weight_sliders[k] for k in self.weight_sliders.keys()]) b_layout = [[t[0], t[1], t[2]] for t in buttons] b_layout.append([self.rank_submit, self.b]) b_layout.append(self.clear_button) b_layout.insert(0, [Spacer(width=300), self.swing_table]) self.app_layout.children.pop(1) self.app_layout.children.append(layout(b_layout))
def _create_content(self): title_area = [] title = Paragraph(text='Strategy Metadata Overview', css_classes=['panel-title']) title_area.append(row([title], width_policy='min')) if self._client: btn_refresh = Button(label='Refresh', width_policy='min') btn_refresh.on_click(self._on_update_metadata_info) title_area.append(Spacer()) title_area.append(row([btn_refresh], width_policy='min')) # set content in self return layout( [ title_area, # initialize with info [self._get_metadata_info()] ], sizing_mode='stretch_width')
def __init__(self, controller): super(BokehView, self).__init__(controller) # define elements self.gen_data_button = Button(label="Generate Data", button_type="success") self.kernel_select = Select(title='Kernel', options=KERNELS, value=INIT_ACTIVE_KERNEL) self.reweighting_select = Select(title='Reweighting', options=REWEIGHTINGS, value=INIT_ACTIVE_REWEIGHTING) self.classify_button = Button(label="Classify", button_type="success") self.train_table = BokehTable([[0.4, 0.1], [0.4, 0.1]]) self.test_table = BokehTable([[0.4, 0.4], [0.1, 0.1]]) self.train_fig = figure(plot_height=400, plot_width=400, title=template_title('Train', '-'), tools='', x_range=[0, 100], y_range=[-50, 5]) self.test_fig = figure(plot_height=400, plot_width=400, title=template_title('test', '-'), tools='', x_range=[0, 100], y_range=[-50, 50]) # wire callbacks self.gen_data_button.on_click(controller.generate_data) self._kernel = INIT_ACTIVE_KERNEL self.kernel_select.on_change('value', self._update_kernel) self._reweighting = INIT_ACTIVE_REWEIGHTING self.reweighting_select.on_change('value', self._update_reweighting) self.classify_button.on_click(self._classify_callback) desc = Div(text=open(join(dirname(__file__), "description.html")).read(), width=1024) # set layout inputs = widgetbox(self.kernel_select, self.reweighting_select, self.gen_data_button, self.classify_button) layout = column(row(desc), row(column(row(inputs)), column(row(self.train_fig, self.test_fig), row(self.train_table.get_layout_element(), Spacer(width=100, height=100), self.test_table.get_layout_element())))) self.layout = layout
def ranking_label_callback(self, attr, old, new, k): self.ranking[k][1].label = new if self.ranking[k][1].button_type == "danger": print("test") self.ranking[k][1].button_type = "primary" try: self.ranking[k].pop(-1) self.app_layout.children.pop(1) self.app_layout.children.append( layout([[Spacer(width=300), self.swing_table], *[self.ranking[k] for k in self.ranking.keys()], [self.rank_submit], [self.clear_button]])) except IndexError: pass
def choose_criteria_callback(self): self.chosen_criteria = [] self.chosen_criteria = self.criteria_selection.value if len(self.chosen_criteria) > 0: self.ranking = OrderedDict() self.rank_criteria() self.swing_table = swing_table.create_swing_table( self.chosen_criteria) try: self.app_layout.children.pop(1) except IndexError: pass self.app_layout.children.append( layout([[Spacer(width=300), self.swing_table], *[self.ranking[k] for k in self.ranking.keys()], [self.rank_submit], [self.clear_button]]))
#show(row(scatter1, pv)) # create bottom horizontal histogram billed = md_data[ 'Billed Units'].values # convert DataFrame column to numpy array hhist, hedges = np.histogram(billed, bins=15) hzeros = np.zeros(len(hedges) - 1) hmax = max(hhist) * 1.1 ph = figure(toolbar_location=None, plot_width=scatter1.plot_width, plot_height=200, x_range=scatter1.x_range, y_range=(0, hmax), min_border=10, min_border_left=50, y_axis_location="right") ph.yaxis[0].formatter = NumeralTickFormatter(format='$0') ph.quad(bottom=0, left=hedges[:-1], right=hedges[1:], top=hhist, color="blue", line_color=None) # lay out the plots as we would like layout = column(row(scatter1, pv), row(ph, Spacer(width=200, height=200))) #curdoc().add_root(layout) show(layout)
week_slider.on_change('value', week_slider_handler) team1_dd.on_change('value', team1_select_handler) team2_dd.on_change('value', team2_select_handler) comp_button.on_click(helper_handler) year_input.on_change('value', season_handler) # arrange layout tab1 = Panel(child=plot1_wrap, title='Scores') tab2 = Panel(child=plot2_wrap, title='Expected Wins') tab3 = Panel(child=table_wrap, title='Summary') figures = Tabs(tabs=[tab1, tab2, tab3], width=500) compare_widgets = column(team1_dd, team2_dd, comp_button) wid_spac1 = Spacer(height=30) wid_spac2 = Spacer(height=30) wid_spac3 = Spacer(height=30) lg_id_message.text = '<b><p style="color: green;">League accessed successfully.</p></b>' all_widgets = column(lg_id_input, lg_id_message, wid_spac1, compare_widgets, wid_spac2, week_slider, wid_spac3, year_input) page_title = Div( text= """<strong><h1 style="font-size: 2.5em;">ESPN Fantasy Football League Explorer</h1></strong>""", width=700, height=50) main_area = row(all_widgets, figures)
fill_alpha=PLOT10_ALPHA, fill_color='red') quadrant2 = BoxAnnotation(left=0, right=1, bottom=IC_LIM, fill_alpha=PLOT10_ALPHA, fill_color='orange') plot10.add_layout(quadrant1) plot10.add_layout(quadrant2) plot10.add_layout(quadrant3) plot10.add_layout(quadrant4) # Set up layouts and add to document notespacer = Spacer(width=TEXT_WIDTH, height=10, width_policy='auto', height_policy='fixed') # simplified set inputs = column(intro, population, iinfections, period, latent, h1, p1, drate, im, button2, button3, button, summary, stats, notespacer, notes) curdoc().title = PAGE_TITLE if ENABLE_RISK: last_plot = plot10 else: last_plot = plot9 # useful for mobile scrolling on the left side
def KPI_projects_tab(panel_title, DAYS_TO_LOAD=90): timeline_source = ColumnDataSource(data=dict( Item=[], Start=[], End=[], Color=[], start=[], end=[], ID=[], ID1=[])) class Thistab(KPI): def __init__(self, table, cols=[]): KPI.__init__(self, table, name='project', cols=cols) self.table = table self.df = None self.df_pop = None self.checkboxgroup = {} self.period_to_date_cards = {} self.ptd_startdate = datetime(datetime.today().year, 1, 1, 0, 0, 0) self.timestamp_col = 'project_startdate_actual' self.pym = PythonMongo('aion') self.groupby_dict = { 'project': 'sum', 'project_duration': 'sum', 'project_start_delay': 'mean', 'project_end_delay': ' mean', 'milestone': 'sum', 'milestone_duration': 'sum', 'milestone_start_delay': 'mean', 'milestone_end_delay': ' mean', 'task': 'sum', 'task_duration': 'sum', 'task_start_delay': 'mean', 'task_end_delay': ' mean', } self.menus = { 'status': ['all', 'open', 'closed'], 'type': [ 'all', 'research', 'reconciliation', 'audit', 'innovation', 'construction', 'manufacturing', 'conference' ], 'gender': ['all', 'male', 'female'], 'variables': list(self.groupby_dict.keys()), 'history_periods': ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], } self.status = 'all' self.pm_gender = 'all' self.m_gender = 'all' self.t_gender = 'all' self.type = 'all' self.variables = sorted(list(self.groupby_dict.keys())) self.variable = self.variables[0] self.groupby_var = 'project' self.chord_data = { 'rename': { 'project_owner': 'source', 'milestone_owner': 'target', 'remuneration': 'value' }, 'percentile_threshold': .75, } self.percentile_threshold = 10 # ------- DIVS setup begin self.page_width = 1200 txt = """<hr/><div style="text-align:center;width:{}px;height:{}px; position:relative;background:black;margin-bottom:200px"> <h1 style="color:#fff;margin-bottom:300px">{}</h1> </div>""".format(self.page_width, 50, 'Welcome') self.notification_div = { 'top': Div(text=txt, width=self.page_width, height=20), 'bottom': Div(text=txt, width=self.page_width, height=10), } self.section_divider = '-----------------------------------' self.section_headers = { 'cards': self.section_header_div(text='Period to date:{}'.format( self.section_divider), width=1000, html_header='h2', margin_top=50, margin_bottom=5), 'pop': self.section_header_div(text='Period over period:{}'.format( self.section_divider), width=600, html_header='h2', margin_top=5, margin_bottom=-155), 'chord': self.section_header_div(text='Relationships:{}'.format( self.section_divider), width=600, html_header='h2', margin_top=5, margin_bottom=-155), 'timeline': self.section_header_div(text='Project timeline:{}'.format( self.section_divider), width=600, html_header='h2', margin_top=5, margin_bottom=-155), } self.KPI_card_div = self.initialize_cards(self.page_width, height=350) start = datetime(2014, 1, 1, 0, 0, 0) end = datetime(2019, 5, 15, 0, 0, 0) self.tools = [ BoxZoomTool(), ResetTool(), PanTool(), SaveTool(), WheelZoomTool() ] self.timeline_vars = { 'projects': '', 'project': '', 'types': ['all', 'milestone', 'task', 'project'], 'type': 'all', 'DF': None, 'G': figure(title=None, x_axis_type='datetime', width=1200, height=900, y_range=[], x_range=Range1d(start, end), toolbar_location=None), 'toolbar_box': ToolbarBox() } # ----- UPDATED DIVS END # ---------------------- DIVS ---------------------------- def section_header_div(self, text, html_header='h2', width=600, margin_top=150, margin_bottom=-150): text = """<div style="margin-top:{}px;margin-bottom:-{}px;"><{} style="color:#4221cc;">{}</{}></div>"""\ .format(margin_top,margin_bottom,html_header, text, html_header) return Div(text=text, width=width, height=15) def information_div(self, width=400, height=300): txt = """ <div {}> <h4 {}>How to interpret sentiment score</h4> <ul style='margin-top:-10px;'> <li> </li> <li> </li> <li> </li> <li> </li> </ul> </div> """.format(self.div_style, self.header_style) div = Div(text=txt, width=width, height=height) return div def initialize_cards(self, width, height=250): try: txt = '' for period in ['year', 'quarter', 'month', 'week']: design = random.choice(list(KPI_card_css.keys())) txt += self.card(title='', data='', card_design=design) text = """<div style="margin-top:100px;display:flex; flex-direction:row;"> {} </div>""".format(txt) div = Div(text=text, width=width, height=height) return div except Exception: logger.error('initialize cards', exc_info=True) def load_df(self, req_startdate, req_enddate, table, cols, timestamp_col): try: # get min and max of loaded df if self.df is not None: loaded_min = self.df[timestamp_col].min() loaded_max = self.df[timestamp_col].max() if loaded_min <= req_startdate and loaded_max >= req_enddate: df = self.df[(self.df[timestamp_col] >= req_startdate) & (self.df[timestamp_col] <= req_enddate)] return df return self.pym.load_df(req_startdate, req_enddate, table=table, cols=cols, timestamp_col=timestamp_col) except Exception: logger.error('load_df', exc_info=True) def filter_df(self, df1): if self.status != 'all': df1 = df1[df1.status == self.status] if self.pm_gender != 'all': df1 = df1[df1.project_owner_gender == self.pm_gender] if self.m_gender != 'all': df1 = df1[df1.milestone_owner_gender == self.m_gender] if self.t_gender != 'all': df1 = df1[df1.task_owner_gender == self.t_gender] if self.type != 'all': df1 = df1[df1.type == self.type] return df1 def period_to_date(self, df, timestamp=None, timestamp_filter_col=None, cols=[], period='week'): try: if timestamp is None: timestamp = datetime.now() timestamp = datetime(timestamp.year, timestamp.month, timestamp.day, timestamp.hour, 0, 0) start = self.first_date_in_period(timestamp, period) # filter df[timestamp_filter_col] = pd.to_datetime( df[timestamp_filter_col], format=self.DATEFORMAT_PTD) #logger.warning('df:%s', df[self.timestamp_col]) df = df[(df[timestamp_filter_col] >= start) & (df[timestamp_filter_col] <= timestamp)] if len(cols) > 0: df = df[cols] return df except Exception: logger.error('period to date', exc_info=True) def period_over_period(self, df, start_date, end_date, period, history_periods=2, timestamp_col='timestamp_of_first_event'): try: # filter cols if necessary string = '0 {}(s) prev(current)'.format(period) # filter out the dates greater than today df_current = df.copy() df_current = self.filter_df(df_current) logger.warning('df current:%s', df_current.head(10)) df_current['period'] = string # label the days being compared with the same label if len(df_current) > 0: df_current = self.label_dates_pop(df_current, period, timestamp_col) cols = [self.variable, 'period', 'dayset'] if 'project' in self.variable: if self.variable != 'project': df_current = df_current[[ self.variable, 'period', 'dayset', 'project' ]] elif 'milestone' in self.variable: if self.variable != 'milestone': df_current = df_current[[ self.variable, 'period', 'dayset', 'milestone', 'project' ]] elif 'task' in self.variable: if self.variable != 'task': df_current = df_current[[ self.variable, 'period', 'dayset', 'task', 'milestone', 'project' ]] # zero out time information start = datetime(start_date.year, start_date.month, start_date.day, 0, 0, 0) end = datetime(end_date.year, end_date.month, end_date.day, 0, 0, 0) cols = list(df.columns) counter = 1 if isinstance(history_periods, str): history_periods = int(history_periods) # make dataframes for request no. of periods start, end = self.shift_period_range(period, start, end) while counter < history_periods and start >= self.initial_date: # load data df_temp = self.load_df(start, end, table=self.table, cols=[], timestamp_col=timestamp_col) df_temp = self.filter_df(df_temp) if df_temp is not None: if len(df_temp) > 1: df_temp[timestamp_col] = pd.to_datetime( df_temp[timestamp_col]) string = '{} {}(s) prev'.format(counter, period) # label period df_temp['period'] = string # relabel days to get matching day of week,doy, dom, for different periods df_temp = self.label_dates_pop( df_temp, period, timestamp_col) df_temp = df_temp[cols] # logger.warning('df temp loaded for %s previous: %s',counter,len(df_temp)) df_current = pd.concat([df_current, df_temp]) del df_temp gc.collect() # shift the loading window counter += 1 start, end = self.shift_period_range(period, start, end) return df_current except Exception: logger.error('period over period', exc_info=True) # label dates for period over period (pop) def pop_include_zeros(self, df_period, plotcols, period): try: # check for no data on original dates tmp_title = '0 {}(s) prev(current)'.format(period) if tmp_title not in plotcols: df_period[tmp_title] = [0] * len(df_period) plotcols.append(tmp_title) logger.warning('line 218 cols to plot:%s', plotcols) # do other periods tmp = plotcols[0] txt = tmp[1:] if isinstance(self.pop_history_periods, str): self.pop_history_periods = int(self.pop_history_periods) for i in range(1, self.pop_history_periods): tmp_txt = str(i) + txt if tmp_txt not in plotcols: df_period[tmp_txt] = [0] * len(df_period) plotcols.append(tmp_txt) clean_plotcols = [] for idx, col in enumerate(plotcols): if 'prev' in col or 'curr' in col: clean_plotcols.append(col) logger.warning( 'LINE 340 plotcols at end of pop include zeros:%s', clean_plotcols) return df_period, sorted(clean_plotcols) except Exception: logger.error('pop include zeros', exc_info=True) def label_dates_pop(self, df, period, timestamp_col): #df[timestamp_col] = pd.to_datetime(df[timestamp_col]) def label_qtr_pop(y): try: curr_quarter = int((y.month - 1) / 3 + 1) start = datetime(y.year, 3 * curr_quarter - 2, 1) return abs((start - y).days) except Exception: logger.error('df label quarter', exc_info=True) try: logger.warning('df columns:%s', list(df.columns)) if period == 'week': df['dayset'] = df[timestamp_col].dt.dayofweek elif period == 'month': df['dayset'] = df[timestamp_col].dt.day elif period == 'year': #logger.warning('LINE 218:%s', df.head(5)) df['dayset'] = df[timestamp_col].dt.dayofyear elif period == 'quarter': df['dayset'] = df[timestamp_col].apply( lambda x: label_qtr_pop(x)) return df except Exception: logger.error('label data ', exc_info=True) def get_groupby_pop_df(self, df, variable, groupby_cols): try: if df is not None: if len(df) > 0: if 'dayset' in df.columns: if variable in ['project']: df = df.groupby(groupby_cols).agg( {variable: 'count'}) df = df.reset_index() #logger.warning('LINE 286 df:%s',df) elif variable in ['milestone']: df = df.groupby(groupby_cols).agg( {variable: 'count'}) df = df.reset_index() #logger.warning('LINE 291 df:%s', df) elif variable in ['task']: df = df.groupby(groupby_cols).agg( {variable: 'count'}) df = df.reset_index() elif variable in ['remuneration']: df = df.groupby(groupby_cols).agg( {variable: 'sum'}) df = df.reset_index() else: #logger.warning('LINE 259:df:%s',df.head()) df = df.groupby(groupby_cols).agg( {variable: 'mean'}) df = df.reset_index() # clean up if self.groupby_var in df.columns and self.variable != self.groupby_var: df = df.drop([self.groupby_var], axis=1) return df except Exception: logger.error('get groupby card data', exc_info=True) def get_groupby_card_data(self, df, variable): try: if variable in ['project']: data = len(df[variable].unique()) data = "{} {}s".format(data, variable) elif variable in ['milestone']: df = df.groupby(['project']).agg({variable: 'nunique'}) data = df[variable].sum() data = "{} {}s".format(data, variable) elif variable in ['task']: df = df.groupby(['project', 'milestone']).agg({variable: 'count'}) data = df[variable].sum() data = "{} {}s".format(data, variable) elif variable in ['project_duration'] or 'delay' in variable: df = df.groupby([self.groupby_var]).agg({variable: 'mean'}) df = df.reset_index() data = "{} days".format(round(df[variable].sum(), 2)) elif variable in ['milestone_duration']: df = df.groupby([self.groupby_var, 'project']).agg({variable: 'mean'}) df = df.reset_index() data = "{} days".format(round(df[variable].sum(), 2)) elif variable in [ 'task_duration', 'task_start_delay', 'task_start_end' ]: df = df.groupby([self.groupby_var, 'project', 'milestone']).agg({variable: 'mean'}) df = df.reset_index() data = "{} hours".format(round(df[variable].sum(), 2)) elif variable in ['remuneration']: data = df[variable].sum() data = "${:,.2f}".format(data) return data except Exception: logger.error('get groupby card data', exc_info=True) # -------------------- GRAPHS ------------------------------------------- def graph_periods_to_date(self, df2, timestamp_filter_col, variable): df1 = df2.copy() #self.section_header_updater(section='cards',label=variable,margin_top=159,html_header='h2') try: df1 = self.filter_df(df1) dct = {} for idx, period in enumerate( ['week', 'month', 'quarter', 'year']): df = self.period_to_date( df1, timestamp=dashboard_config['dates']['last_date'], timestamp_filter_col=timestamp_filter_col, period=period) df = df.drop_duplicates(keep='first') # groupby to eliminate repetition data = self.get_groupby_card_data(df, variable) del df gc.collect() dct[period] = data #title = "{} to date".format(period) #p = self.card(title=title, data=data, card_design=random.choice(list(self.KPI_card_css.keys()))) #self.period_to_date_cards[period].text = p.text self.update_cards(dct) except Exception: logger.error('graph periods to date', exc_info=True) def graph_period_over_period(self, period): try: periods = [period] start_date = self.pop_start_date end_date = self.pop_end_date if isinstance(start_date, date): start_date = datetime.combine(start_date, datetime.min.time()) if isinstance(end_date, date): end_date = datetime.combine(end_date, datetime.min.time()) today = datetime.combine(datetime.today().date(), datetime.min.time()) df = self.df_pop.copy() df = self.filter_df(df) #logger.warning('LINE 363 -df:%s',df.head()) cols = [self.variable, self.timestamp_col] if self.variable != 'project': cols.append('project') if abs(start_date - end_date).days > 7: if 'week' in periods: periods.remove('week') if abs(start_date - end_date).days > 31: if 'month' in periods: periods.remove('month') if abs(start_date - end_date).days > 90: if 'quarter' in periods: periods.remove('quarter') for idx, period in enumerate(periods): df_period = self.period_over_period( df, start_date=start_date, end_date=end_date, period=period, history_periods=self.pop_history_periods, timestamp_col=self.timestamp_col) groupby_cols = ['dayset', 'period'] if len(df_period) > 0: logger.warning('LINE 473:%s', list(df_period.columns)) df_period = self.get_groupby_pop_df( df_period, variable=self.variable, groupby_cols=groupby_cols) df_period = df_period.reset_index() else: if not 'day' in df_period.columns: df_period['dayset'] = "" else: df_period = df_period.rename( index=str, columns={'day': 'dayset'}) logger.warning('LINE 478:%s', list(df_period.columns)) prestack_cols = list(df_period.columns) df_period = self.split_period_into_columns( df_period, col_to_split='period', value_to_copy=self.variable) # short term fix: filter out the unnecessary first day added by a corrupt quarter functionality if period == 'quarter': if 'dayset' in df_period.columns: min_day = df_period['dayset'].min() df_period = df_period[ df_period['dayset'] > min_day] poststack_cols = list(df_period.columns) title = "{} over {}".format(period, period) plotcols = list(np.setdiff1d(poststack_cols, prestack_cols)) # include current period if not extant df_period, plotcols = self.pop_include_zeros( df_period, plotcols=plotcols, period=period) if self.variable in [ 'task_start_delay', 'task_end_delay', 'task_duration' ]: ylabel = 'hours' elif self.variable in [ 'project_duration', 'milestone_duration', 'project_start_delay', 'project_end_delay', 'milestone_start_delay', 'milestone_end_delay' ]: ylabel = 'days' elif self.variable in ['project', 'task', 'milestone']: ylabel = '#' elif self.variable == 'remuneration': ylabel = '$' if 'dayset' not in df_period.columns: leng = len(df_period) if leng > 0: df_period['dayset'] = 0 logger.warning('LINE 549') else: logger.warning('LINE 551') df_period['dayset'] = '' logger.warning('LINE 552: df columns:%s', list(df_period.columns)) if idx == 0: p = df_period.hvplot.bar('dayset', plotcols, rot=45, title=title, stacked=False, width=1200, height=400, value_label=ylabel) else: p += df_period.hvplot.bar('dayset', plotcols, rot=45, title=title, stacked=False, width=1200, height=400, value_label=ylabel) return p except Exception: logger.error('period over period to date', exc_info=True) def chord_diagram(self, launch): try: def normalize_value(x, total): x = int((x / total) * 1000) if x <= 0: return 1 return x df = self.df.copy() # -------------- nodes data = {} data['nodes'] = [] source_list = df['milestone_owner'].tolist() names = list(set(source_list)) person_type_dict = dict(zip(df.milestone_owner, df.type)) type_dict = {} types = list(set(df['type'].tolist())) name_dict = {} for idx, name in enumerate(names): name_dict[name] = idx for idx, name in enumerate(names): type_tmp = person_type_dict[name] index = name_dict[name] data['nodes'].append({ 'OwnerID': index, 'index': idx, 'Type': type_tmp }) nodes = hv.Dataset(pd.DataFrame(data['nodes']), 'index') # --------- make the links data['links'] = [] for idx, row in df.iterrows(): src = name_dict[row['project_owner']] tgt = name_dict[row['milestone_owner']] val = row['remuneration'] data['links'].append({ 'source': src, 'target': tgt, 'value': val }) links = pd.DataFrame(data['links']) # get the individual links links = links.groupby(['source', 'target'])['value'].sum() links = links.reset_index() total = links['value'].sum() links['value'] = links['value'].apply( lambda x: normalize_value(x, total)) # filter for top percentile quantile_val = links['value'].quantile( self.chord_data['percentile_threshold']) links = links[links['value'] >= quantile_val] #logger.warning('after quantile filter:%s',len(links)) chord_ = hv.Chord((links, nodes), ['source', 'target'], ['value']) chord_.opts( opts.Chord(cmap='Category20', edge_cmap='Category20', edge_color=dim('source').str(), labels='Type', node_color=dim('index').str(), width=1000, height=1000)) return chord_ except Exception: logger.error('chord diagram', exc_info=True) def timeline(self, project, type='milestone'): try: DF = self.df.copy() if type != project: DF = DF[DF['project'] == project] if type == 'all': rename_dct = { 'milestone_enddate_proposed': 'milestone_enddate', 'milestone_startdate_proposed': 'milestone_startdate', 'task_enddate_proposed': 'task_enddate', 'task_startdate_proposed': 'task_startdate', } DF = DF.rename(index=str, columns=rename_dct) DF = DF.groupby(['milestone', 'task']).agg({ 'milestone_startdate': 'min', 'milestone_enddate': 'max', 'task_startdate': 'min', 'task_enddate': 'max', }) DF = DF.reset_index() # melt to get milestone and task into one column df = pd.melt(DF, value_vars=['milestone', 'task'], id_vars=[ 'milestone_startdate', 'milestone_enddate', 'task_startdate', 'task_enddate' ], value_name='Item', var_name='type') df = df.groupby(['Item', 'type']).agg({ 'milestone_startdate': 'min', 'milestone_enddate': 'max', 'task_startdate': 'min', 'task_enddate': 'max' }).reset_index() df = pd.melt( df, id_vars=[ 'Item', 'type', 'milestone_startdate', 'task_startdate' ], value_vars=['milestone_enddate', 'task_enddate'], value_name='End', var_name='enddate_type') # filter out where tasks label dates and vice versa df1 = df[(df['type'] == 'task') & (df['enddate_type'] == 'task_enddate')] df = df[(df['type'] == 'milestone') & (df['enddate_type'] == 'milestone_enddate')] df = pd.concat([df1, df]) df = df.drop('enddate_type', axis=1) # do startdate df = pd.melt( df, id_vars=['Item', 'type', 'End'], value_vars=['milestone_startdate', 'task_startdate'], value_name='Start', var_name='startdate_type') # filter out where tasks label dates and vice versa df1 = df[(df['type'] == 'task') & (df['startdate_type'] == 'task_startdate')] df = df[(df['type'] == 'milestone') & (df['startdate_type'] == 'milestone_startdate')] df = pd.concat([df1, df]) df = df.drop('startdate_type', axis=1) # label colors df['Color'] = df['type'].apply( lambda x: 'black' if x == 'milestone' else 'green') # organize by milestone and tasks belonging to milestone df = df.sort_values(by=['Start']).reset_index() df = df.drop('index', axis=1) #logger.warning('LINE 605 - df:%s',df.head(50)) DF = df print( '##################################################################################' ) else: start_str = type + '_startdate_proposed' end_str = type + '_enddate_proposed' # group milestone rename_dct = { start_str: 'Start', end_str: 'End', type: 'Item' } DF = DF.rename(index=str, columns=rename_dct) DF = DF[['Item', 'Start', 'End']] DF = DF.groupby(['Item']).agg({ 'Start': 'min', 'End': 'max' }) DF = DF.reset_index() color_list = [] for item in DF.Item.tolist(): color_list.append( random.choice(dashboard_config['colors'])) DF['Color'] = np.array(color_list) DF['start'] = DF['Start'].dt.strftime('%Y-%m-%d') DF['end'] = DF['End'].dt.strftime('%Y-%m-%d') DF['ID'] = DF.index + 0.6 DF['ID1'] = DF.index + 1.4 logger.warning('LINE 648 %s', DF) self.timeline_vars['DF'] = DF # update source data = dict(Item=DF.Item.tolist(), Start=DF.Start.tolist(), End=DF.End.tolist(), Color=DF.Color.tolist(), start=DF.start.tolist(), end=DF.end.tolist(), ID=DF.ID.tolist(), ID1=DF.ID1.tolist()) # <-- This is the trick, make the x_rage empty first, before assigning new value self.timeline_vars['G'].y_range.factors = [] self.timeline_vars['G'].y_range.factors = DF.Item.tolist() #self.timeline_vars['G'].x_range.factors = [] #self.timeline_vars['G'].x_range.factors = sorted(DF.Start.tolist()) timeline_source.data = data except Exception: logger.error('timeline', exc_info=True) def timeline_plot(self, DF): try: hover = HoverTool(tooltips="Task: @Item<br>\ Start: @start<br>\ End: @end") self.timeline_vars['G'].quad(left='Start', right='End', bottom='ID', top='ID1', source=timeline_source, color="Color") self.tools = [hover] + self.tools self.timeline_vars['G'].tools = self.tools self.timeline_vars['toolbar_box'] = ToolbarBox() self.timeline_vars['toolbar_box'].toolbar = Toolbar( tools=self.tools) self.timeline_vars['toolbar_box'].toolbar_location = "above" self.timeline_vars['G'].x_range.start = DF.Start.min( ) - timedelta(days=10) self.timeline_vars['G'].x_range.start = DF.End.max( ) + timedelta(days=10) return self.timeline_vars['G'] except Exception: logger.error('timeline', exc_info=True) def update(attrname, old, new): thistab.notification_updater( "Calculations underway. Please be patient") thistab.pm_gender = pm_gender_select.value thistab.m_gender = m_gender_select.value thistab.t_gender = t_gender_select.value thistab.type = type_select.value thistab.variable = variable_select.value if 'project' in thistab.variable: thistab.groupby_var = 'project' elif 'milestone' in thistab.variable: thistab.groupby_var = 'milestone' elif 'task' in thistab.variable: thistab.groupby_var = 'task' thistab.status = status_select.value thistab.graph_periods_to_date(thistab.df, thistab.timestamp_col, variable=thistab.variable) thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_pop_dates(): thistab.notification_updater( "Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.pop_start_date = datepicker_pop_start.value # trigger period over period thistab.pop_end_date = datepicker_pop_end.value thistab.df_pop = thistab.pym.load_df(start_date=thistab.pop_start_date, end_date=thistab.pop_end_date, cols=[], table=thistab.table, timestamp_col='startdate_actual') thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_history_periods(attrname, old, new): thistab.notification_updater( "Calculations underway. Please be patient") thistab.pop_history_periods = pop_number_select.value thistab.trigger += 1 stream_launch.event(launch=thistab.trigger) thistab.notification_updater("ready") def update_timeline(attrname, old, new): thistab.notification_updater( "Calculations underway. Please be patient") thistab.timeline_vars['project'] = timeline_project_select.value thistab.timeline_vars['type'] = timeline_type_select.value thistab.timeline(thistab.timeline_vars['project'], thistab.timeline_vars['type']) thistab.notification_updater("ready") try: cols = [] thistab = Thistab(table='project_composite', cols=cols) # ------------------------------------- SETUP ---------------------------- # format dates first_date_range = thistab.initial_date last_date_range = datetime.now().date() last_date = dashboard_config['dates']['last_date'] first_date = datetime(last_date.year, 4, 1, 0, 0, 0) thistab.df = thistab.pym.load_df(start_date=first_date, end_date=last_date, table=thistab.table, cols=[], timestamp_col=thistab.timestamp_col) thistab.graph_periods_to_date( thistab.df, timestamp_filter_col=thistab.timestamp_col, variable=thistab.variable) thistab.pop_end_date = last_date thistab.pop_start_date = last_date - timedelta(days=5) thistab.df_pop = thistab.pym.load_df( start_date=thistab.pop_start_date, end_date=thistab.pop_end_date, cols=[], table=thistab.table, timestamp_col=thistab.timestamp_col) thistab.timeline_vars['projects'] = sorted( list(set(thistab.df['project'].tolist()))) thistab.timeline_vars['project'] = thistab.timeline_vars['projects'][0] # MANAGE STREAM # date comes out stream in milliseconds # --------------------------------CREATE WIDGETS --------------------------------- stream_launch = streams.Stream.define('Launch', launch=-1)() datepicker_pop_start = DatePicker(title="Period start", min_date=first_date_range, max_date=last_date_range, value=thistab.pop_start_date) datepicker_pop_end = DatePicker(title="Period end", min_date=first_date_range, max_date=last_date_range, value=thistab.pop_end_date) pop_number_select = Select(title='Select # of comparative periods', value=str(thistab.pop_history_periods), options=thistab.menus['history_periods']) pop_dates_button = Button(label="Select dates, then click me!", width=15, button_type="success") type_select = Select(title='Select project type', value=thistab.type, options=thistab.menus['type']) status_select = Select(title='Select project status', value=thistab.status, options=thistab.menus['status']) pm_gender_select = Select(title="Select project owner's gender", value=thistab.pm_gender, options=thistab.menus['gender']) m_gender_select = Select(title="Select milestone owner's gender", value=thistab.m_gender, options=thistab.menus['gender']) t_gender_select = Select(title="Select task owner's gender", value=thistab.t_gender, options=thistab.menus['gender']) variable_select = Select(title='Select variable of interest', value=thistab.variable, options=thistab.menus['variables']) timeline_project_select = Select( title='Select project', value=thistab.timeline_vars['project'], options=thistab.timeline_vars['projects']) timeline_type_select = Select(title='Select granularity', value='all', options=thistab.timeline_vars['types']) # --------------------------------- GRAPHS --------------------------- hv_pop_week = hv.DynamicMap(thistab.pop_week, streams=[stream_launch]) pop_week = renderer.get_plot(hv_pop_week) hv_pop_month = hv.DynamicMap(thistab.pop_month, streams=[stream_launch]) pop_month = renderer.get_plot(hv_pop_month) hv_pop_quarter = hv.DynamicMap(thistab.pop_quarter, streams=[stream_launch]) pop_quarter = renderer.get_plot(hv_pop_quarter) hv_pop_year = hv.DynamicMap(thistab.pop_year, streams=[stream_launch]) pop_year = renderer.get_plot(hv_pop_year) hv_chord = hv.DynamicMap(thistab.chord_diagram, streams=[stream_launch]) chord = renderer.get_plot(hv_chord) thistab.timeline(thistab.timeline_vars['project'], thistab.timeline_vars['type']) timeline = thistab.timeline_plot(DF=thistab.timeline_vars['DF']) # -------------------------------- CALLBACKS ------------------------ type_select.on_change('value', update) pop_dates_button.on_click(update_pop_dates) # lags array status_select.on_change('value', update) pm_gender_select.on_change('value', update) m_gender_select.on_change('value', update) t_gender_select.on_change('value', update) variable_select.on_change('value', update) pop_number_select.on_change('value', update_history_periods) timeline_project_select.on_change('value', update_timeline) timeline_type_select.on_change('value', update_timeline) # -----------------------------------LAYOUT ---------------------------- # put the controls in a single element controls_top = WidgetBox( variable_select, type_select, status_select, pm_gender_select, m_gender_select, t_gender_select, ) controls_pop = WidgetBox(datepicker_pop_start, datepicker_pop_end, pop_number_select) controls_timeline = WidgetBox(thistab.timeline_vars['toolbar_box'], timeline_project_select, timeline_type_select) grid = gridplot([[thistab.notification_div['top']], [Spacer(width=20, height=70)], [thistab.section_headers['cards']], [thistab.KPI_card_div, controls_top], [thistab.section_headers['pop']], [Spacer(width=20, height=25)], [pop_week.state, controls_pop], [pop_month.state], [pop_quarter.state], [pop_year.state], [thistab.section_headers['chord']], [Spacer(width=20, height=25)], [chord.state], [thistab.section_headers['timeline']], [Spacer(width=20, height=25)], [timeline, controls_timeline], [thistab.notification_div['bottom']]]) # Make a tab with the layout tab = Panel(child=grid, title=panel_title) return tab except Exception: logger.error('rendering err:', exc_info=True) return tab_error_flag(panel_title)
def empty_plot(width, height): """ Creates an empty and invisible plot of the specified size. """ return Spacer(width=width, height=height)
def on_session_created(session_context): ''' If present, this function is called when a session is created. ''' print("-----------------------------------------------") start_time_database = timeit.default_timer() print("on_session_created -- begin") #import_data.setup_db_connection() #import_data.retrieve_data(uHelper.connection) import_data.retrieve_data() #uHelper.database_que.put(import_data.retrieve_data(uHelper.connection)) #uHelper.all_connection_dict, uHelper.novos_connection_dict, \ #uHelper.all_connection_table, uHelper.novos_connection_table, \ #uHelper.novos_source, uHelper.rigs_list, \ #uHelper.jobs_list, uHelper.crewshift_list = uHelper.database_que.get() print("on_session_created -- after") print("\n retrieving time: ") print(timeit.default_timer() - start_time_database) default_rig_number, rigs_list = uHelper.get_default_value( uHelper.all_connection_table, comboBx='Rigs') default_rig_number = str(default_rig_number) rigs_list = [] rigs_list = [str(item) for item in uHelper.rigs_list] uHelper.rigs_combx = Select(title='Rigs:', value=default_rig_number, width=100, sizing_mode=uHelper.sizing_mode, options=uHelper.update_combBx_values( '', rigs_list)) default_job_number, jobs_list = uHelper.get_default_value( uHelper.all_connection_table, comboBx='Jobs', selectedRig=uHelper.rigs_combx.value ) # TODO: add condition to determine 0 exists or not default_job_number = str(default_job_number) jobs_list = [] jobs_list = [str(item) for item in uHelper.jobs_list] uHelper.default_job_number = default_job_number uHelper.jobs_list = jobs_list uHelper.jobs_combx = Select(title='Jobs:', value=default_job_number, width=100, sizing_mode=uHelper.sizing_mode, options=uHelper.update_combBx_values( '', jobs_list)) default_crew, crewshift_list = uHelper.get_default_value( uHelper.all_connection_table, comboBx='CrewShift', selectedRig=uHelper.rigs_combx.value, selectedJob=uHelper.jobs_combx.value) default_crew = str(default_crew) crewshift_list = [str(item) for item in crewshift_list] uHelper.crewshift_combx = Select(title='CrewShift:', value=default_crew, width=100, sizing_mode=uHelper.sizing_mode, options=uHelper.update_combBx_values( '', crewshift_list)) # 2. checkbox group uHelper.checkbox_group_1 = CheckboxGroup(labels=["Build", "Lateral", "Vertical"], \ active=[], \ name = 'wellSelection') uHelper.checkbox_group_2 = CheckboxGroup(labels=["Driller", "Novos", "Hybrid"], \ active=[], \ name = 'connectionType') uHelper.checkbox_group_3 = CheckboxGroup(labels=["B2S", "S2S", "S2B", "Survey", "BackReam"], \ active=[], \ name = 'connectionPhase') rig, job = uHelper.rigs_combx.value, uHelper.jobs_combx.value # 1st chart uHelper.update_drillingconn_wellsect_queue = queue.Queue() uHelper.update_drillingconn_wellsect_event = threading.Event() update_drillingconn_wellsect_thread = Thread(name='update_drillingconn_wellsect_thread', \ target = lambda q, arg1, arg2, arg3, arg4: \ q.put(drillingconn_wellsect_plot.update_well_selection_data(arg1, arg2, arg3, arg4)), \ args = (uHelper.update_drillingconn_wellsect_queue, \ uHelper.update_drillingconn_wellsect_event, \ uHelper.all_connection_dict, rig, job)) update_drillingconn_wellsect_thread.start() uHelper.update_drillingconn_wellsect_event.wait() well_connection_colors, x, well_connnection_counts, well_connnection_data = uHelper.update_drillingconn_wellsect_queue.get( ) uHelper.well_connnection_source = ColumnDataSource(data=dict(colors = well_connection_colors, \ x = x, \ counts = well_connnection_counts)) well_connection_chart = figure(x_range = FactorRange(*x), \ plot_width = 1310, \ plot_height = 430, \ sizing_mode = uHelper.sizing_mode, \ title = "Drilling Connection Breakdown By Well Section") #title = "Drilling Connection Breakdown By Well Section", \ #output_backend = "webgl") well_connection_chart.vbar(x = 'x', \ width = 0.2, \ bottom = 0, \ top = 'counts', \ color = 'colors', \ source = uHelper.well_connnection_source) total_connections = sum(well_connnection_counts) uHelper.well_connection_textbox_source = ColumnDataSource(data=dict(x = [600,], \ y = [450,], \ txt= ['Total Connections: %d' % (total_connections),])) well_connection_chart_textbox = LabelSet(x='x', y='y', x_units='screen', y_units='screen', \ text='txt', source = uHelper.well_connection_textbox_source,\ text_font_size="12pt", border_line_color='black', \ border_line_width=1, text_font_style='bold') well_connection_chart.add_layout(well_connection_chart_textbox) well_connection_chart.title.align = 'center' well_connection_chart.title.text_font_size = '15pt' well_connection_chart.toolbar.active_drag = None well_connection_chart.toolbar.logo = None well_connection_chart.toolbar_location = None well_connection_chart.y_range.start = 0 well_connection_chart.x_range.range_padding = 0.1 well_connection_chart.xaxis.major_label_orientation = 1 well_connection_chart.xgrid.grid_line_color = None for well_item in well_connnection_data['well_selection']: for sub_item in well_connnection_data['Driller']: well_connection_chart.add_tools( HoverTool(tooltips=[(str(well_item), "@counts")])) print("\n1st chart loading time \n") ### 2nd chart(b2s s2b) start_time_2nd_chart = timeit.default_timer() uHelper.update_b2s_s2b_queue = queue.Queue() uHelper.update_b2s_s2b_event = threading.Event() update_b2s_s2b_thread = threading.Thread(name='update_b2s_s2b_thread', \ target = lambda q, arg1, arg2, arg3, arg4: \ q.put(b2s_s2b_plot.update_b2s_s2b_data(arg1, arg2, arg3, arg4)), \ args = (uHelper.update_b2s_s2b_queue, uHelper.update_b2s_s2b_event, uHelper.novos_connection_table, rig, job)) update_b2s_s2b_thread.start() uHelper.update_b2s_s2b_event.wait() b2s_canceled_list, b2s_completed_list, \ b2s_exception_list,b2s_failed_list, \ s2b_canceled_list, s2b_completed_list, \ s2b_exception_list, s2b_failed_list = uHelper.update_b2s_s2b_queue.get() b2s_s2b_status = ["Canceled", "Completed", "Exception", "Failed"] b2s_s2b_colors = ["#F2C80F", "#00ff0d", "#F2C80F", "#ff4600"] b2s_connection_phase = [ 'OffBottom', 'UnWeightBit', 'ClearBit', 'CleanHole', 'SetBoxHeight', 'SetWeight' ] b2s_figure = figure(x_range = b2s_connection_phase, \ plot_width = 600, \ plot_height = 300, \ sizing_mode = uHelper.sizing_mode, \ title="Bottom to Slip") uHelper.b2s_datasource = ColumnDataSource(data=dict(b2s_connection_phase = b2s_connection_phase, \ Canceled = b2s_canceled_list, \ Completed = b2s_completed_list, \ Exception = b2s_exception_list, \ Failed = b2s_failed_list)) b2s_figure.vbar_stack(b2s_s2b_status, \ x='b2s_connection_phase', \ width = 0.2, \ color = b2s_s2b_colors, \ source = uHelper.b2s_datasource) b2s_figure.title.align = 'center' b2s_figure.toolbar.active_drag = None b2s_figure.toolbar.logo = None b2s_figure.toolbar_location = None b2s_figure.y_range.start = 0 b2s_figure.x_range.range_padding = 0.1 b2s_figure.xaxis.major_label_orientation = 1 b2s_figure.xgrid.grid_line_color = None b2s_figure.ygrid.grid_line_color = None s2b_connection_phase = [ 'AddStand', 'TakeWeight', 'FlowSetpoint', 'RotateDrill', 'TagBottom' ] s2b_figure = figure(x_range = s2b_connection_phase, \ plot_width = 670, \ plot_height = 300, \ sizing_mode = uHelper.sizing_mode, \ title="Slip to Bottom") uHelper.s2b_datasource = ColumnDataSource(data=dict(s2b_connection_phase = s2b_connection_phase, \ Canceled = s2b_canceled_list, \ Completed = s2b_completed_list, \ Exception = s2b_exception_list, \ Failed = s2b_failed_list)) s2b_figure.vbar_stack(b2s_s2b_status, \ x = 's2b_connection_phase', \ width = 0.2, \ color = b2s_s2b_colors, \ source = uHelper.s2b_datasource, \ legend= [value(x) for x in b2s_s2b_status]) s2b_figure.title.align = 'center' s2b_figure.toolbar.active_drag = None s2b_figure.toolbar.logo = None s2b_figure.toolbar_location = None s2b_figure.y_range.start = 0 s2b_figure.x_range.range_padding = 0.1 s2b_figure.xaxis.major_label_orientation = 1 s2b_figure.xgrid.grid_line_color = None s2b_figure.ygrid.grid_line_color = None s2b_figure.legend.location = "top_right" s2b_figure.legend.orientation = "vertical" new_legend = s2b_figure.legend[0] s2b_figure.legend[0].plot = None s2b_figure.add_layout(new_legend, 'right') line_figure = figure(x_range=(0, 100), \ y_range=(0, 300), \ plot_width = 120, \ plot_height = 300) line_figure.line(x=[50, 50], \ y= [0, 300], \ line_width = 3, \ line_color='black') line_figure.xaxis.visible = None line_figure.yaxis.visible = None line_figure.toolbar.logo = None line_figure.toolbar_location = None line_figure.toolbar.active_drag = None line_figure.min_border_left = 10 line_figure.min_border_right = 10 line_figure.min_border_top = 0 line_figure.min_border_bottom = 0 #summary_layout = layout(row(b2s_figure, line_figure, s2b_figure), sizing_mode = uHelper.sizing_mode) print("\n 2nd chart loading time \n") print(timeit.default_timer() - start_time_2nd_chart) mTicker = uHelper.customize_ticker() start_time_main_chart = timeit.default_timer() uHelper.get_all_data_queue = queue.Queue() uHelper.get_all_data_event = threading.Event() uHelper.get_all_data_thread = threading.Thread(name = 'get_all_data_thread', \ target = lambda q, arg1, arg2: \ q.put(all_main_plot.get_all_data(arg1, arg2)), args = (uHelper.get_all_data_queue, uHelper.get_all_data_event, uHelper.all_connection_dict)) uHelper.get_all_data_thread.start() uHelper.get_all_data_event.wait() uHelper.mainplot_data_all, depth_list_all = uHelper.get_all_data_queue.get( ) depth_list_all = [str(x) for x in depth_list_all] uHelper.main_plot = figure(x_range=FactorRange(), \ y_range = (0, 50), \ plot_width = uHelper.plot_width, \ plot_height = 400, \ tools = "tap, pan, box_zoom, reset", \ sizing_mode = uHelper.sizing_mode, \ title="Overall Connection Times",\ id="main_plot_id") uHelper.main_plot.xaxis.ticker = mTicker uHelper.main_plot.title.align = 'center' uHelper.main_plot.legend.click_policy = "hide" uHelper.main_plot.title.text_font_size = '15pt' uHelper.main_plot.x_range.factors = [] uHelper.main_plot.x_range.factors = depth_list_all uHelper.mainplot_data_all['HoleDepth'] = [ "{0:.2f}".format(x) for x in uHelper.mainplot_data_all['HoleDepth'] ] #mainplot_data_all['HoleDepth'] = [str(x) for x in mainplot_data_all['HoleDepth']] #TODO: 20181001 #dur = [] #for index, item in enumerate(uHelper.mainplot_data_all['VBarTop']): # top_num = 0.0 # bottom_num = 0.0 # if uHelper.mainplot_data_all['VBarTop'][index] == '': # top_num = 0.0 # else: # top_num = float(uHelper.mainplot_data_all['VBarTop'][index]) # # if uHelper.mainplot_data_all['VBarBottom'][index] == '': # bottom_num = 0.0 # else: # bottom_num = float( uHelper.mainplot_data_all['VBarBottom'][index]) # dur.append(str(top_num - bottom_num)) uHelper.mainplot_source = ColumnDataSource(data=dict(HoleDepthRef = uHelper.mainplot_data_all['HoleDepthRef'], \ HoleDepth = uHelper.mainplot_data_all['HoleDepth'], \ VBarTop = uHelper.mainplot_data_all['VBarTop'], \ VBarBottom = uHelper.mainplot_data_all['VBarBottom'], \ VBarColors = uHelper.mainplot_data_all['VBarColors'], \ VBarType = uHelper.mainplot_data_all['VBarType'])) main_plot_vbars = uHelper.main_plot.vbar(x = 'HoleDepth', \ width = 0.1, \ bottom = 'VBarBottom', \ top = 'VBarTop', \ color = 'VBarColors', \ source = uHelper.mainplot_source, \ legend = 'VBarType') uHelper.main_plot.legend.location = "top_right" uHelper.main_plot.legend.orientation = "vertical" new_legend = uHelper.main_plot.legend[0] uHelper.main_plot.legend[0].plot = None uHelper.main_plot.add_layout(new_legend, 'right') # layout uHelper.m_well_selection = Div(text='Well Section:', height=1) uHelper.m_well_connection = Div(text='Connection Type:', height=1) uHelper.m_well_conn_phase = Div(text='Connection Phase:', height=1) start_time_rest_chart = timeit.default_timer() uHelper.version = Div(text='Version: 1.1.1', width=200, height=30) uHelper.version.css_classes = ["version"] #sidebar menu uHelper.spacer_1 = Spacer(width=200, height=10) uHelper.spacer_2 = Spacer(width=200, height=30) uHelper.spacer_3 = Spacer(width=200, height=30) uHelper.menu_column_1_layout = column(uHelper.spacer_3, widgetbox(uHelper.rigs_combx), widgetbox(uHelper.jobs_combx), widgetbox(uHelper.crewshift_combx)) uHelper.menu_column_1_layout.css_classes = ["sidebarmenucombxlayout"] uHelper.well_selection_layout = column(uHelper.m_well_selection, uHelper.checkbox_group_1) uHelper.well_connection_layout = column(uHelper.m_well_connection, uHelper.checkbox_group_2) uHelper.well_conn_phase_layout = column(uHelper.m_well_conn_phase, uHelper.checkbox_group_3) uHelper.menu_column_2_layout = column(uHelper.well_selection_layout, uHelper.well_connection_layout, uHelper.well_conn_phase_layout) uHelper.menu_column_2_layout.css_classes = ["sidebarmenucheckbxlayout"] uHelper.menu_middle_layout = layout( column(uHelper.menu_column_1_layout, uHelper.menu_column_2_layout)) uHelper.menu_middle_layout.css_classes = ["sidebarmenumiddlelayout"] uHelper.menu_top_layout = layout(column(uHelper.spacer_1, uHelper.version)) uHelper.menu_top_layout.css_classes = ["sidebarmenutoplayout"] uHelper.menu_bottom_layout = layout(column(uHelper.spacer_2)) uHelper.menu_bottom_layout.css_classes = ["sidebarmenubottomlayout"] uHelper.menu_layout = layout( column(uHelper.menu_top_layout, uHelper.menu_middle_layout, uHelper.menu_bottom_layout)) uHelper.menu_layout.css_classes = ["menulayout"] #sub_plot #sub_plot, subplot_source, subplot_dict = sub_novos_plot.create_sub_plot(doc) subplot_dict = {} subplot_dict['B2SText'] = [ 'Cleanhole - Active', 'Cleanhole - Completed', 'Setboxheight - Active', 'Setboxheight - Completed', 'Setweight - Active', 'Setweight - Completed', 'Offbottom-Active', 'Unweightbit - Active', 'Unweightbit - Completed', 'Clearbit - Active', 'Clearbit - Completed', 'Offbottom - Completed' ] subplot_dict['text_x'] = [2, 12, 22, 32, 42, 52, 2, 12, 22, 32, 42, 52] subplot_dict['B2SColors'] = [ 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white' ] subplot_dict['B2STextColors'] = [ 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black', 'black' ] subplot_dict['B2SHideColors'] = [ 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white', 'white' ] subplot_dict['subplot_x'] = [5, 15, 25, 35, 45, 55, 5, 15, 25, 35, 45, 55] subplot_dict['subplot_y'] = [ 10, 10, 10, 10, 10, 10, 25, 25, 25, 25, 25, 25 ] subplot_dict['Text'] = ['', '', '', '', '', '', '', '', '', '', '', ''] uHelper.subplot_source = ColumnDataSource(data=subplot_dict) # 3. plot uHelper.sub_plot = figure(x_range = [0, 60], \ y_range = [0, 30], \ plot_width=1540, \ plot_height= 350, \ toolbar_location=None, \ sizing_mode='scale_both') subplot_height = 40 subplot_weight = 175 uHelper.sub_plot.rect(x = 'subplot_x', \ y = 'subplot_y', \ width = subplot_weight, \ height = subplot_height, \ color = "B2SColors", \ width_units = "screen", \ height_units = "screen", \ source = uHelper.subplot_source) b2s_text = Text(x = 'text_x', \ y = 'subplot_y', \ text_color = "B2STextColors", \ text = "Text", \ text_font_size = "10pt") uHelper.sub_plot.add_glyph(uHelper.subplot_source, b2s_text) uHelper.sub_plot.xaxis.visible = None uHelper.sub_plot.yaxis.visible = None uHelper.sub_plot.background_fill_color = "#01B8AA" uHelper.sub_plot.background_fill_color = "white" uHelper.m_color_white = uHelper.sub_plot.background_fill_color uHelper.sub_plot.outline_line_color = None uHelper.sub_plot.title.align = 'center' uHelper.sub_plot.title.text_font_size = '15pt' uHelper.m_color_white = "white" uHelper.subplot_colors_length = len(subplot_dict['B2SColors']) #hide_subplot_callback = CustomJS(args=dict(m_color=m_color_white, subplot=sub_plot, subplotColorsLength=subplot_colors_length, subplotSource=subplot_source), code=""" #hide_subplot_callback = CustomJS(args=dict(m_color = uHelper.m_color_white, \ # subplot = uHelper.sub_plot, \ # subplotColorsLength = subplot_colors_length, \ # subplotSource = uHelper.subplot_source), code=""" # for(i = 0; i < subplotColorsLength; i++) { # subplotSource.data['B2SColors'][i] = 'white' # subplotSource.data['B2STextColors'][i] = 'white' # # } # subplotSource.change.emit() # subplot.background_fill_color = 'white' # """) # uHelper.main_plot.toolbar.logo = None uHelper.main_plot.toolbar_location = "above" uHelper.main_plot.css_classes = ["mainplot"] #drillingConnectionBreakdown_column = column(well_connection_chart, uHelper.main_plot, uHelper.sub_plot) drillingConnectionBreakdown_column = column(well_connection_chart) drillingConnectionBreakdown_column.sizing_mode = uHelper.sizing_mode drillingConnectionBreakdown_layout = layout( drillingConnectionBreakdown_column, sizing_mode=uHelper.sizing_mode) activity_type_stats_top = row(b2s_figure, line_figure, s2b_figure) activity_type_stats_bottom = column(uHelper.main_plot, uHelper.sub_plot) summary_layout = layout( column(activity_type_stats_top, activity_type_stats_bottom)) right_layout = layout(row(summary_layout)) #taptool = uHelper.main_plot.select(type=TapTool) #uHelper.main_plot.js_on_event(Tap, uHelper.tapcallback) #novos_length = len(uHelper.novos_connection_dict[uHelper.depth_ft_str]) #uHelper.main_plot.js_on_event(Tap, CustomJS(args=dict(allSource = uHelper.mainplot_source, \ # novosSource = uHelper.novos_source, \ # subplotSource = uHelper.subplot_source, \ # subplotColorsLength = uHelper.subplot_colors_length, \ # novosLength = novos_length, \ # subplot = uHelper.sub_plot \ # ),\ # code = sub_novos_plot.m_code)) #20180727start tabMain = Panel(title='Main', child=drillingConnectionBreakdown_layout) tabMain.tags = ["MainTag"] tabMain.name = "MainName" tabActivitytypeStats = Panel(title='Over Connection Analysis', child=right_layout) tabActivitytypeStats.tags = ["activitytypestatsTag"] tabActivitytypeStats.name = "ActivitytypeStatsName" ##################################################### #start 20180928 #depth_list_all = [str(x) for x in depth_list_all] uHelper.driller_vs_plot = figure(x_range=FactorRange(), \ y_range = (0, 50), \ plot_width = uHelper.plot_width, \ plot_height = 250, \ tools = "tap, pan, box_zoom, reset",\ sizing_mode = uHelper.sizing_mode) uHelper.driller_vs_dataset, driller_vs_display_depth_list = all_main_plot.get_all_dataset( uHelper.all_connection_dict) driller_vs_display_depth_list = [ str(x) for x in driller_vs_display_depth_list ] #uHelper.driller_vs_dataset['HoleDepth'] = ["{0:.2f}".format(x) for x in uHelper.driller_vs_dataset['HoleDepth']] #uHelper.driller_vs_dataset['HoleDepth'] = [str(x) for x in uHelper.driller_vs_dataset['HoleDepth']] uHelper.driller_vs_plot.toolbar.logo = None uHelper.driller_vs_plot.toolbar_location = "above" uHelper.driller_vs_plot.css_classes = ["DrillerVSPlot"] uHelper.driller_vs_plot.xaxis.ticker = mTicker uHelper.driller_vs_plot.title.align = 'center' uHelper.driller_vs_plot.legend.click_policy = "hide" uHelper.driller_vs_plot.x_range.factors = [] #uHelper.driller_vs_plot.x_range.factors = driller_vs_display_depth_list uHelper.driller_vs_plot.yaxis.axis_label = "Driller" uHelper.driller_vs_plot.axis.axis_label_text_font_style = "bold" uHelper.driller_vs_plot_source = ColumnDataSource(data=dict(HoleDepthRef = [], \ HoleDepth = [],\ B2S = [], \ S2S = [], \ S2B = [], \ Survey = [], \ BackReam = [])) driller_vs_plot_vbars = uHelper.driller_vs_plot.vbar_stack(uHelper.connection_phase_list,\ x = 'HoleDepth', \ width = 0.1, \ color = uHelper.color_list, \ source = uHelper.driller_vs_plot_source, \ legend = [value(x) for x in uHelper.connection_phase_list]) uHelper.driller_vs_plot.legend.location = "top_left" uHelper.driller_vs_plot.legend.orientation = "horizontal" driller_vs_new_legend = uHelper.driller_vs_plot.legend[0] uHelper.driller_vs_plot.legend[0].plot = None uHelper.driller_vs_plot.add_layout(driller_vs_new_legend, 'above') uHelper.hybrid_vs_plot = figure(x_range=FactorRange(), \ y_range = (0, 50), \ plot_width = uHelper.plot_width, \ plot_height = 250, \ tools = "tap, pan, box_zoom, reset", \ sizing_mode = uHelper.sizing_mode) #uHelper.mainplot_data_all['HoleDepth'] = ["{0:.2f}".format(x) for x in uHelper.mainplot_data_all['HoleDepth']] #mainplot_data_all['HoleDepth'] = [str(x) for x in mainplot_data_all['HoleDepth']] uHelper.hybrid_vs_plot.toolbar.logo = None uHelper.hybrid_vs_plot.toolbar_location = "above" uHelper.hybrid_vs_plot.css_classes = ["HybridVSPlot"] uHelper.hybrid_vs_plot.xaxis.ticker = mTicker uHelper.hybrid_vs_plot.title.align = 'center' uHelper.hybrid_vs_plot.x_range.factors = [] uHelper.hybrid_vs_plot.x_range.factors = driller_vs_display_depth_list uHelper.hybrid_vs_plot.yaxis.axis_label = "Hybrid" uHelper.hybrid_vs_plot.axis.axis_label_text_font_style = "bold" uHelper.hybrid_vs_plot_source = ColumnDataSource(data=dict(HoleDepthRef = [], \ HoleDepth = [],\ B2S = [], \ S2S = [], \ S2B = [], \ Survey = [], \ BackReam = [])) hybrid_vs_plot_vbars = uHelper.hybrid_vs_plot.vbar_stack(uHelper.connection_phase_list,\ x = 'HoleDepth', \ width = 0.1, \ color = uHelper.color_list, \ source = uHelper.hybrid_vs_plot_source, \ legend = [value(x) for x in uHelper.connection_phase_list]) uHelper.hybrid_vs_plot.legend.location = "top_left" uHelper.hybrid_vs_plot.legend.orientation = "horizontal" hybrid_vs_plot_new_legend = uHelper.hybrid_vs_plot.legend[0] uHelper.hybrid_vs_plot.legend[0].plot = None uHelper.hybrid_vs_plot.add_layout(hybrid_vs_plot_new_legend, 'above') uHelper.novos_vs_plot = figure(x_range=FactorRange(), \ y_range = (0, 50), \ plot_width = uHelper.plot_width, \ plot_height = 250, \ tools = "tap, pan, box_zoom, reset", \ sizing_mode = uHelper.sizing_mode) #uHelper.mainplot_data_all['HoleDepth'] = ["{0:.2f}".format(x) for x in uHelper.mainplot_data_all['HoleDepth']] #mainplot_data_all['HoleDepth'] = [str(x) for x in mainplot_data_all['HoleDepth']] uHelper.novos_vs_plot.toolbar.logo = None uHelper.novos_vs_plot.toolbar_location = "above" uHelper.novos_vs_plot.css_classes = ["NovosVSPlot"] uHelper.novos_vs_plot.xaxis.ticker = mTicker uHelper.novos_vs_plot.title.align = 'center' uHelper.novos_vs_plot.x_range.factors = [] uHelper.novos_vs_plot.x_range.factors = driller_vs_display_depth_list uHelper.novos_vs_plot.yaxis.axis_label = "NOVOS" uHelper.novos_vs_plot.axis.axis_label_text_font_style = "bold" uHelper.novos_vs_plot_source = ColumnDataSource(data=dict(HoleDepthRef = [], \ HoleDepth = [],\ B2S = [], \ S2S = [], \ S2B = [], \ Survey = [], \ BackReam = [])) novos_vs_plot_vbars = uHelper.novos_vs_plot.vbar_stack(uHelper.connection_phase_list,\ x = 'HoleDepth', \ width = 0.1, \ color = uHelper.color_list, \ source = uHelper.novos_vs_plot_source, \ legend = [value(x) for x in uHelper.connection_phase_list]) uHelper.novos_vs_plot.legend.location = "top_left" uHelper.novos_vs_plot.legend.orientation = "horizontal" novos_vs_plot_new_legend = uHelper.novos_vs_plot.legend[0] uHelper.novos_vs_plot.legend[0].plot = None uHelper.novos_vs_plot.add_layout(novos_vs_plot_new_legend, 'above') vs_driller_hybrid_novos_column = column(uHelper.driller_vs_plot, uHelper.hybrid_vs_plot, uHelper.novos_vs_plot) vs_driller_hybrid_novos_column.sizing_mode = uHelper.sizing_mode vs_driller_hybrid_novos_layout = layout(vs_driller_hybrid_novos_column, sizing_mode=uHelper.sizing_mode) vsDrillerHybridNOVOS = Panel(child=vs_driller_hybrid_novos_layout, title="Driller vs Hybrid vs Novos") vsDrillerHybridNOVOS.name = "vsDrillerHybridNOVOSName" vsDrillerHybridNOVOS.tags = ["vsDrillerHybridNOVOSTag"] #end 20180928 ################################## p3 = figure(plot_width=uHelper.plot_width, plot_height=300, toolbar_location=None) #p3.line([1, 2, 3, 4, 5], [16, 17, 12, 10, 18], line_width=3, color="red", alpha=0.5) #tabNovosConfigConnectionAnalysis = Panel(child=None, title="Novos Config Connection Analysis") p3.text([65, 65, 65], [65, 65, 65], text=["Coming Soon"], alpha=0.5, text_font_size="50pt", text_baseline="middle", text_align="center") p3.xaxis.visible = None p3.yaxis.visible = None p3.background_fill_color = "white" p3.outline_line_color = None tabNovosConfigConnectionAnalysis = Panel(child=p3, title="Activity type Stats") tabNovosConfigConnectionAnalysis.name = "NovosConfigConnectionAnalysisName" tabNovosConfigConnectionAnalysis.tags = [ "NovosConfigConnectionAnalysisTag" ] p6 = figure(plot_width=uHelper.plot_width, plot_height=300, toolbar_location=None) #p6.line([1, 2, 3, 4, 5], [16, 17, 12, 10, 18], line_width=3, color="orange", alpha=0.5) p6.text([65, 65, 65], [65, 65, 65], text=["Coming Soon"], alpha=0.5, text_font_size="50pt", text_baseline="middle", text_align="center") p6.xaxis.visible = None p6.yaxis.visible = None p6.background_fill_color = "white" p6.outline_line_color = None #tabDistributioncharts = Panel(child=None, title="Distribution charts") tabDistributioncharts = Panel(child=p6, title="Distribution charts") tabDistributioncharts.name = "DistributionchartsName" tabDistributioncharts.tags = ["DistributionchartsTag"] p7 = figure(plot_width=uHelper.plot_width, plot_height=300, toolbar_location=None) #p7.line([1, 2, 3, 4, 5], [16, 17, 12, 10, 18], line_width=3, color="black", alpha=0.5) p7.text([65, 65, 65], [65, 65, 65], text=["Coming Soon"], alpha=0.5, text_font_size="50pt", text_baseline="middle", text_align="center") p7.xaxis.visible = None p7.yaxis.visible = None p7.background_fill_color = "white" p7.outline_line_color = None tabDuplicateofContinuousinDepth = Panel(child=p7, title="Config Connection Analysis") #tabDuplicateofContinuousinDepth = Panel(child=None, title="Duplicate of Continuous in Depth") tabDuplicateofContinuousinDepth.name = "DuplicateofContinuousinDepthName" tabDuplicateofContinuousinDepth.tags = ["DuplicateofContinuousinDepthTag"] about_div = Div(text="""<p> Data Visualization <br> Copyright 2018 Precision Drilling Corporation. All rights reserved.<br> Version 1.1.1(Official Build)<br> <br> <h3>Technical Support</h3> <h4>Email:</h4> <ul style="list-style-type:circle"> <li>[email protected]</li> <li>[email protected]</li> </ul> <h4>Phone:</h4> <ul style="list-style-type:circle"> <li>403-716-4704</li> <li>403-716-4631</li> </ul> <h4>Release Note:</h4> <ul style="list-style-type:circle"> <li>Added "Driller vs Hybrid vs Novos" tab <br></li> <li>Moved "main plot" from "Main" tab to "Over Connection Analysis" Tab</li> <li>Deleted "Continuous in Depth" and "Driller vs Novos" tabs</li> <li>"Connection Type" Checklist is greyed out, when "Driller vs Hybrid vs Novos" tab is activated</li> <li>Colors are now consistent with what we have in "PowerBI"</li> <li>"Wheel zoom" is removed from plot "tool bar"</li> <li>Display the latest dataset, whenever user clicks "Reload this page" from browser</li> </ul> </p>""", width=uHelper.plot_width, height=900) about_div.css_classes = ["aboutDiv"] #about_figure = figure(plot_width=uHelper.plot_width, plot_height=300, toolbar_location=None) #p7.line([1, 2, 3, 4, 5], [16, 17, 12, 10, 18], line_width=3, color="black", alpha=0.5) #about_figure.text([65,65,65],[65,65,65], text=[ "Coming Soon"], alpha=0.5, text_font_size="50pt", text_baseline="middle", text_align="center") #about_figure.xaxis.visible = None #about_figure.yaxis.visible = None #about_figure.background_fill_color = "white" #about_figure.outline_line_color = None tabAboutPanel = Panel(child=about_div, title="About", width=uHelper.plot_width, height=900) #tabDuplicateofContinuousinDepth = Panel(child=None, title="Duplicate of Continuous in Depth") tabAboutPanel.name = "AboutPanelName" tabAboutPanel.tags = ["AboutPanelTag"] uHelper.tabs = Tabs(tabs=[tabMain, \ tabActivitytypeStats, \ vsDrillerHybridNOVOS, \ tabNovosConfigConnectionAnalysis, \ tabDistributioncharts, \ tabDuplicateofContinuousinDepth, \ tabAboutPanel], width= uHelper.plot_width, sizing_mode='scale_width') uHelper.tabs.css_classes = ["tabsbackgroundcolorblack"] print("\n main chart loading time \n") print(timeit.default_timer() - start_time_rest_chart) uHelper.spacer_4 = Spacer(width=120, height=350) uHelper.sidebar_layout = layout( column(uHelper.menu_layout, uHelper.spacer_4)) uHelper.sidebar_layout.css_classes = ["sidebarlayout"] tabs_row = row(uHelper.tabs) tabs_row.sizing_mode = uHelper.sizing_mode main_row = row(uHelper.sidebar_layout, tabs_row) main_row.sizing_mode = uHelper.sizing_mode uHelper.main_row = main_row uHelper.main_row.css_classes = ["mainrowlayout"] uHelper.main_layout = layout( uHelper.main_row, sizing_mode='scale_width') # uHelper.sizing_mode) uHelper.main_layout.css_classes = ["mainlayout"] #vbar_clicked_index_dict = {} #vbar_clicked_index_dict['index'] = [-1, ] #uHelper.selectedVbarIndexSource = ColumnDataSource(data = vbar_clicked_index_dict) #taptool = uHelper.main_plot.select(type=TapTool) ##uHelper.main_plot.js_on_event(Tap, uHelper.tapcallback) ##novos_length = len(uHelper.novos_connection_dict[uHelper.depth_ft_str]) # start_time_all = timeit.default_timer() #uHelper.main_plot.js_on_event(Tap, CustomJS(args=dict(allSource = uHelper.mainplot_source, # selectedVbarIndexSource = uHelper.selectedVbarIndexSource, \ # index2 = uHelper.index2), \ # code = sub_novos_plot.m_selected_index_code)) main_plot_vbars.data_source.on_change('selected', uHelper.handler) #uHelper.main_plot.js_on_event(Tap, CustomJS.from_py_func(uHelper.update_subplot)) print("\nbk_plotter loading time \n") print(timeit.default_timer() - start_time_all)