def test_szng004_on_focus(test, props, data_fn): app = dash.Dash(__name__) baseProps1 = get_props(data_fn=data_fn) baseProps2 = get_props(data_fn=data_fn) baseProps1.update(dict(**props, id="table1")) baseProps2.update(dict(**props, id="table2")) app.layout = Div([ DataTable(**baseProps1), DataTable(**baseProps2), ]) test.start_server(app) table2 = test.table("table2") for i in range(len(baseProps1.get("columns"))): table2.cell(0, i).click() t1 = test.driver.find_element_by_css_selector("#table1") t2 = test.driver.find_element_by_css_selector("#table2") cells_are_same_width(t1, t1) cells_are_same_width(t1, t2) assert test.get_log_errors() == []
def get_app(): app = dash.Dash(__name__) app.layout = html.Div([ DataTable( id="table", data=df[0:250], columns=[{ "name": i, "id": i, "hideable": i == "Complaint ID" } for i in rawDf.columns], editable=True, sort_action="native", include_headers_on_copy_paste=True, ), DataTable( id="table2", data=df[0:10], columns=[{ "name": i, "id": i, "deletable": True } for i in rawDf.columns], editable=True, sort_action="native", include_headers_on_copy_paste=True, ), ]) @app.callback( Output("table", "data"), [Input("table", "data_timestamp")], [State("table", "data"), State("table", "data_previous")], ) # pylint: disable=unused-argument def update_data(timestamp, current, previous): # pylint: enable=unused-argument if timestamp is None or current is None or previous is None: raise PreventUpdate modified = False if len(current) == len(previous): for (i, datum) in enumerate(current): previous_datum = previous[i] if datum["Unnamed: 0"] != previous_datum["Unnamed: 0"]: datum["Complaint ID"] = "MODIFIED" modified = True if modified: return current else: raise PreventUpdate return app
def test_szng003_on_prop_change(test, fixed_columns, fixed_rows, merge_duplicate_headers, callback_props): props = { **base_props, **fixed_columns, **fixed_rows, **merge_duplicate_headers } table = DataTable(**props, id="table") app = dash.Dash(__name__) app.layout = Div([Button(id="btn", children=["Update"]), table]) @app.callback( [Output("table", key) for key in callback_props.keys()], [Input("btn", "n_clicks")], prevent_initial_call=True, ) def callback(n_clicks): return [callback_props.get(key) for key in callback_props.keys()] test.start_server(app) target = test.driver.find_element_by_css_selector("#table") cells_are_same_width(target, target) test.driver.find_element_by_css_selector("#btn").click() cells_are_same_width(target, target) assert test.get_log_errors() == []
def test_szng002_percentages_result_in_same_widths(test): _fixed_columns = [dict(headers=True, data=1), dict(headers=True)] _fixed_rows = [dict(headers=True, data=1), dict(headers=True)] _merge_duplicate_headers = [True, False] variations = [] i = 0 for fixed_columns in _fixed_columns: for fixed_rows in _fixed_rows: for merge_duplicate_headers in _merge_duplicate_headers: variations.append({ **base_props, "fixed_columns": fixed_columns, "fixed_rows": fixed_rows, "merge_duplicate_headers": merge_duplicate_headers, "id": "table{}".format(i), }) i = i + 1 tables = [DataTable(**variation) for variation in variations] app = dash.Dash(__name__) app.layout = Div(tables) test.start_server(app) target = test.driver.find_element_by_css_selector("#table0") cells_are_same_width(target, target) for i in range(1, len(variations)): table = test.driver.find_element_by_css_selector("#table{}".format(i)) cells_are_same_width(target, table) assert test.get_log_errors() == []
def generate_table(df, page_size=10): """Generate a formatted table from a DataFrame.""" table = DataTable(id='table', columns=[{ "name": i, "id": i } for i in df.columns], data=df.to_dict("records"), page_size=page_size, style_cell={ 'textAlign': 'left', 'color': "#000000" }, style_cell_conditional=[{ 'if': { 'column_id': 'count' }, 'textAlign': 'right' }], style_data_conditional=[{ 'if': { 'row_index': 'odd' }, 'backgroundColor': 'rgb(248, 248, 248)' }], style_header={ 'backgroundColor': 'rgb(230, 230, 230)', 'fontWeight': 'bold' }) return table
def test_ttip001_displays_aligned_tooltip(test, fixed_rows, fixed_columns, ops): props = { **base_props, **fixed_rows, **fixed_columns, **ops, **dict(tooltip_data=tooltip_data_text), } app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") cell = target.cell(0, 0) tooltip = target.tooltip target.is_ready() cell.move_to() assert tooltip.exists() assert tooltip.get_text() == ";; 1-1" assert_aligned(cell.get(), tooltip.get()) mid = math.ceil(len(columns) / 2) cell = target.cell(0, mid) cell.move_to() assert_aligned(cell.get(), tooltip.get()) cell = target.cell(0, len(columns) - 1) cell.move_to() assert_aligned(cell.get(), tooltip.get()) assert test.get_log_errors() == []
def update_quote_table(quotes_and_sources, n_clicks): if n_clicks > 0: return DataTable( id="quote-table-id", data=quotes_and_sources, columns=[ { 'name': 'Speaker', 'id': 'speaker' }, { 'name': 'Quote', 'id': 'quote' }, ], style_table={'overflowX': 'auto'}, style_cell={ 'backgroundColor': 'rgba(102, 204, 204, 0.05)', 'textAlign': 'left', 'font_family': 'Arial', 'padding': '0px 10px', }, style_data={ 'height': 'auto', 'lineHeight': '30px' }, style_header={ 'backgroundColor': 'rgb(255, 255, 255)', 'text-align': 'left', }, style_as_list_view=True, )
def display_histogram(years, indicator, nbins): if (not years) or (not indicator): raise PreventUpdate df = poverty[poverty['year'].isin(years) & poverty['is_country']] fig = px.histogram(df, x=indicator, facet_col='year', color='year', title=indicator + ' Histogram', nbins=nbins, facet_col_wrap=4, height=700) fig.for_each_xaxis(lambda axis: axis.update(title='')) fig.add_annotation(text=indicator, x=0.5, y=-0.12, xref='paper', yref='paper', showarrow=False) fig.layout.paper_bgcolor = '#E5ECF6' table = DataTable(columns = [{'name': col, 'id': col} for col in df[['Country Name', 'year', indicator]].columns], data = df[['Country Name', 'year', indicator]].to_dict('records'), style_header={'whiteSpace': 'normal'}, fixed_rows={'headers': True}, virtualization=True, style_table={'height': '400px'}, sort_action='native', filter_action='native', export_format='csv', style_cell={'minWidth': '150px'}), return fig, table
def get_app(): app = dash.Dash(__name__) columns = [ dict(id="a", name="a"), dict(id="b", name="b"), dict(id="c", name="c", presentation="dropdown"), ] app.layout = DataTable( id="table", columns=columns, dropdown=dict( c=dict( options=[ dict(label="Value-0", value=0), dict(label="Value-1", value=1), dict(label="Value-2", value=2), dict(label="Value-3", value=3), ] ) ), data=[dict(a=i, b=i, c=i % 4) for i in range(100)], editable=True, ) return app
def update_dividends_table(option_stocks): print("#####################") print("# update div_details_table option_stocks: ", option_stocks) pd_df = stocksportfolio.get_dividends() pd_df.sort_values(by=["date", "Ticker"], ascending=[False, True], inplace=True) pd_df = pd_df.loc[pd_df["Ticker"].isin(option_stocks)] columns = [] for col in pd_df.columns: col_fmt = {"name": col, "id": col} if col in ["value", "Dividends"]: col_fmt["format"] = utils_dash.money col_fmt["type"] = "numeric" columns.append(col_fmt) return DataTable( id="dividends_table_id", data=pd_df.to_dict("records"), sort_action="native", columns=columns, page_size=20, style_data_conditional=[ {"if": {"row_index": "odd"}, "backgroundColor": "rgb(248, 248, 248)"}, ], style_header={"backgroundColor": "rgb(230, 230, 230)", "fontWeight": "bold"}, )
def table_current_pos(): column = [] for col in stocksportfolio.current_position().columns: col_fmt = {"name": col, "id": col} if col == "Gain/Loss Pct": col_fmt["format"] = utils_dash.percentage col_fmt["type"] = "numeric" if col in ["Current Quote", "Current Value", "Adj unit price", "Adj Cost"]: col_fmt["format"] = utils_dash.money col_fmt["type"] = "numeric" column.append(col_fmt) return DataTable( id="table", data=stocksportfolio.current_position().to_dict("records"), sort_action="native", columns=column, style_data_conditional=[ {"if": {"row_index": "odd"}, "backgroundColor": "rgb(248, 248, 248)"}, { "if": { "filter_query": "{Gain/Loss Pct} < 0", "column_id": "Gain/Loss Pct", }, "backgroundColor": "tomato", }, { "if": { "filter_query": "{Gain/Loss Pct} >= 0", "column_id": "Gain/Loss Pct", }, "backgroundColor": "dodgerblue", }, ], style_header={"backgroundColor": "rgb(230, 230, 230)", "fontWeight": "bold"}, )
def mk_empty_datatable(table_id): return DataTable( id=table_id, style_as_list_view=True, editable=False, style_header={ 'font-family': 'Rubik, sans-serif;', 'font-style': 'normal', 'font-weight': 'bold', 'font-size': '16px;', 'line-height': '22px;', 'display': 'flex;', 'letter-spacing': '0.15px;', 'margin': '1px 9px;', 'backgroundColor': 'white', 'fontWeight': 'bold', }, style_cell={ 'font-family': 'Roboto Mono, sans-serif;', 'font-style': 'normal', 'font-weight': 'normal', 'font-size': '14px;', 'line-height': '22px;', 'display': 'flex;', 'letter-spacing': '0.15px;', 'backgroundColor': '#262421;', 'margin': '1px 9px;', 'flex': 'none;', 'order': '0;', }, )
def update_calendar_live(n): df = get_calender_df( HeimdallrSettings().google_calendar_id, PROJECT_APP_PATH.user_config, num_entries=ALL_CONSTANTS.TABLE_PAGE_SIZE, ) return DataTable( id="calender-table-0", columns=[{ "name": i, "id": i } for i in df.columns], data=df.to_dict("records"), page_size=ALL_CONSTANTS.TABLE_PAGE_SIZE, style_as_list_view=True, style_data_conditional=[ { "if": { "column_id": "start", "filter_query": "{start} > 3.9" }, "backgroundColor": "green", "color": "white", }, ], # TODO: MAKE GRADIENT TO ORANGE FOR WHEN NEARING START, and GREEN WHEN IN PROGRESS )
def update_table(n) -> dict: MQTT_CLIENT.loop() compute_machines = [] if GPU_STATS: df = to_overall_gpu_process_df(copy.deepcopy(GPU_STATS)) else: df = DataFrame(["No data"], columns=("data", )) compute_machines.append( DataTable( id="gpu-table-0", columns=[{ "name": i, "id": i } for i in df.columns], data=df.to_dict("records"), page_size=ALL_CONSTANTS.TABLE_PAGE_SIZE, # style_as_list_view=True, style_data_conditional=[{ "if": { "row_index": "odd" }, "backgroundColor": "rgb(248, 248, 248)" }], style_header={ "backgroundColor": "rgb(230, 230, 230)", "fontWeight": "bold", }, )) return Div(compute_machines)
def get_app(props=dict()): app = dash.Dash(__name__) baseProps = dict( id="table", columns=[{ "name": i, "id": i } for i in rawDf.columns], data=df, editable=True, filter_action="native", fixed_columns={"headers": True}, fixed_rows={"headers": True}, page_action="native", row_deletable=True, row_selectable=True, sort_action="native", ) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def table(): return DataTable( id='stat-table', columns=[{'name': i, 'id': i} for i in ['step', 'optimizer', 'learning rate', 'weight decay', 'dropout, %']], style_table={ 'overflowY': 'scroll', 'height': '190px', 'width': '360px', 'margin-top': 0, 'margin-left': 40, }, style_cell={ 'textAlign': 'center', 'whiteSpace': 'normal', 'height': 'auto' }, style_cell_conditional=[ {'if': {'column_id': 'dropout, %'}, 'width': '30%'} ], style_data_conditional=[ {'if': {'row_index': 0}, 'color': 'red'}], style_header={ 'backgroundColor': MAIN_COLOR, 'color': 'white', 'fontWeight': 'bold' }, )
def get_project_emissions_bar_chart_figure(project_data: dt.DataTable): # Note: necessary to both convert to pandas and replace null values for hover value project_data = pd.DataFrame(project_data) project_data = project_data.replace(np.nan, "", regex=True) hover_data = {c: True for c in project_data.columns} bar = ( px.bar( project_data, y="emissions", hover_data=hover_data, labels={ "emissions": "Carbon Equivalent (kg)", "energy_consumed": "Energy Consumed (kWh)", "timestamp": "Timestamp", "project_name": "Project Name", "duration": "Duration", "emissions_detail": "Emissions Detail", "country_name": "Country Name", "country_iso_code": "Country ISO Code", "region": "Region", "cloud_provider": "Cloud Provider", "cloud_region": "Cloud Region", }, ) .update_traces(marker_color="green") .update_layout(plot_bgcolor="rgb(255,255,255)") ) return bar
def get_app(mode, data=df, page_count=None): app = dash.Dash(__name__) if page_count is None: page_count = math.ceil(len(data) / PAGE_SIZE) app.layout = DataTable( id="table", columns=[{"name": i, "id": i} for i in rawDf.columns], data=data if mode == "native" else data[0:PAGE_SIZE], editable=True, fixed_columns={"headers": True}, fixed_rows={"headers": True}, page_action=mode, page_count=page_count, page_size=PAGE_SIZE, row_deletable=True, row_selectable=True, ) if mode == "custom": @app.callback( [Output("table", "data")], [Input("table", "page_current"), Input("table", "page_size")], ) def update_table(page_current, page_size): if page_current is None or page_size is None: raise PreventUpdate return (data[page_current * page_size : (page_current + 1) * page_size],) return app
def generic_tbl_fmt(df): return DataTable( columns=[{'name': i, 'id': i, 'type': 'numeric', 'format': FormatTemplate.percentage(4)} for i in df.columns], data=df.to_dict('records'), style_cell={ 'textAlign': 'center', 'whiteSpace': 'normal', 'height': 'auto', 'color': 'white', 'backgroundColor': '#696969', }, style_header={'backgroundColor': '#000000'}, style_data_conditional=[ { 'if': { 'state': 'active' # 'active' | 'selected' }, 'backgroundColor': '#8140CF' } ], style_as_list_view=True, page_size=20, export_format='csv', style_table={'overflowX': 'auto'} )
def display_tables(json_in, selected_date): if json_in is None or selected_date is None: raise PreventUpdate df_data = pd.read_json(json_in) df_data['entry_date'] = pd.to_datetime(df_data['entry_date']).dt.date try: out_data = pd.concat(df_data.loc[df_data['entry_date']==datetime.strptime(day, '%Y-%m-%d').date()] for day in selected_date) except: out_data = df_data.loc[df_data['entry_date']==datetime.strptime(selected_date[0], '%Y-%m-%d').date()] out_data = out_data[[col for col in out_data.columns if col not in DB_ONLY_COLS]] return DataTable( data=out_data.to_dict('rows'), columns=[{'name': i, 'id': i} for i in out_data.columns], style_data={ 'whiteSpace': 'normal', 'height': 'auto' }, style_as_list_view=True, style_cell={'textAlign': 'center'}, style_header={ 'backgroundColor': '#F1F1F1', 'fontWeight': 'bold' }, style_cell_conditional=[ { 'if': {'column_id': 'Item'}, 'textAlign': 'left' } ], sort_action='native' )
def get_app(cell_selectable, markdown_options): md = "[Click me](https://www.google.com)" data = [ dict(a=md, b=md), dict(a=md, b=md), ] app = dash.Dash(__name__) props = dict( id="table", columns=[ dict(name="a", id="a", type="text", presentation="markdown"), dict(name="b", id="b", type="text", presentation="markdown"), ], data=data, cell_selectable=cell_selectable, ) if markdown_options is not None: props["markdown_options"] = markdown_options app.layout = DataTable(**props) return app
def get_app(): app = dash.Dash(__name__) columns = [{"name": i, "id": i} for i in ["a", "b"]] data = [dict(a=1, b=2), dict(a=11, b=22)] app.layout = Div([ Button(id="clear-table", children=["Clear table"]), DataTable(id="table", columns=columns, data=data), ]) @app.callback( [Output("table", "data"), Output("table", "columns")], [Input("clear-table", "n_clicks")], ) def clear_table(n_clicks): if n_clicks is None: raise PreventUpdate nonlocal columns, data return (data, columns) if n_clicks % 2 == 0 else (None, None) return app
def update_transaction_table(option_funds): print("#####################") print("# update transaction table option_funds: ", option_funds) pd_df = fundsportfolio.transactions() pd_df = pd_df.loc[pd_df["Fund Name"].isin(option_funds)] columns = [] for col in pd_df.columns: col_fmt = {"name": col, "id": col} if col in ["Value", "Adj Value"]: col_fmt["format"] = utils_dash.money col_fmt["type"] = "numeric" columns.append(col_fmt) return DataTable( id="table_transaction", data=pd_df.sort_index(ascending=True).to_dict("records"), sort_action="native", columns=columns, page_size=20, style_data_conditional=[ { "if": { "row_index": "odd" }, "backgroundColor": "rgb(248, 248, 248)" }, ], style_header={ "backgroundColor": "rgb(230, 230, 230)", "fontWeight": "bold" }, )
def test_scrol001_fixed_alignment(test, fixed_rows, fixed_columns, ops): props = {**base_props, **fixed_rows, **fixed_columns, **ops} app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") assert target.is_ready() fixed_width = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;" ) assert -get_margin(test) == fixed_width scroll_by(test, 200) wait.until( lambda: -get_margin(test) == fixed_width + 200, 3, ) scroll_by(test, -200) wait.until( lambda: -get_margin(test) == fixed_width, 3, )
def test_scrol002_edit_navigate(test, fixed_rows, fixed_columns, ops): props = {**base_props, **fixed_rows, **fixed_columns, **ops} app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") assert target.is_ready() fixed_width = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;" ) scroll_by(test, 200) # alignment is ok after editing a cell target.cell(0, 3).click() test.send_keys("abc" + Keys.ENTER) wait.until(lambda: target.cell(1, 3).is_selected(), 3) wait.until(lambda: -get_margin(test) == fixed_width + get_scroll(test), 3) # alignment is ok after navigating test.send_keys(Keys.ARROW_DOWN) test.send_keys(Keys.ARROW_RIGHT) wait.until(lambda: target.cell(2, 4).is_selected(), 3) wait.until( lambda: -get_margin(test) == fixed_width + get_scroll(test), 3, )
def get_app(props=dict(), special=False, clear=False): app = dash.Dash(__name__) baseProps = get_props(rows=200) if special: for c in baseProps.get("columns"): if c["id"] == "bbb": c["id"] = "b+bb" elif c["id"] == "ccc": c["id"] = "c cc" elif c["id"] == "ddd": c["id"] = "d:dd" elif c["id"] == "eee": c["id"] = "e-ee" elif c["id"] == "fff": c["id"] = "f_ff" elif c["id"] == "ggg": c["id"] = "g.gg" for i in range(len(baseProps["data"])): d = baseProps["data"][i] d["b+bb"] = d["bbb"] d["c cc"] = d["ccc"] d["d:dd"] = d["ddd"] d["e-ee"] = d["eee"] d["f_ff"] = d["fff"] d["g.gg"] = d["ggg"] baseProps.update(dict(filter_action="native")) baseProps.update(props) if clear: app.layout = Div( [DataTable(**baseProps), Button(id="btn", children=["Clear filters"])] ) @app.callback(Output("table", "filter_query"), Input("btn", "n_clicks")) def get_filter(n_clicks): return "" else: app.layout = DataTable(**baseProps) return app
def test_scrol001_fixed_alignment(test, fixed_rows, fixed_columns, ops): base_props = dict( id="table", columns=[{ "name": i, "id": i } for i in df.columns], row_selectable="single", row_deletable=True, data=df.to_dict("records"), fixed_rows={ "headers": True, "data": 1 }, style_cell=dict(width=150), style_table=dict(width=500), ) props = {**base_props, **fixed_rows, **fixed_columns, **ops} app = dash.Dash(__name__) app.layout = DataTable(**props) test.start_server(app) target = test.table("table") assert target.is_ready() fixed_width = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-0')).width) || 0;" ) margin_left = test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);" ) assert -margin_left == fixed_width test.driver.execute_script( "document.querySelector('#table .row-1').scrollBy(200, 0);") wait.until( lambda: -test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);" ) == fixed_width + 200, 3, ) test.driver.execute_script( "document.querySelector('#table .row-1').scrollBy(-200, 0);") wait.until( lambda: -test.driver.execute_script( "return parseFloat(getComputedStyle(document.querySelector('#table .cell-0-1')).marginLeft);" ) == fixed_width, 3, )
def get_app(props=dict(), data_fn=generate_mock_data): app = dash.Dash(__name__) baseProps = get_props(data_fn=data_fn) baseProps.update(props) app.layout = DataTable(**baseProps) return app
def make_space_table(space): """Make a data table for the given space""" columns = dragon['%s' % space].reset_index().columns return DataTable(id='%s_table' % space, columns=[{"name": i, "id": '%s' % i} for i in columns], data=get_table_data(space, []), style_header={'transform': 'translate(0px, 0px) rotate(-0.0deg)', 'max-width': '20px', 'backgroundColor': 'transparent'})
def get_app(props, data_fn): app = dash.Dash(__name__) baseProps = get_props(data_fn=data_fn) baseProps.update(props) app.layout = DataTable(**baseProps) return app