def df_to_html_table( dataframe: DataFrame, data_only: bool = False, n_mod: Optional[int] = None, formats: Optional[Dict[Any, str]] = None, ) -> Table: """Converts pandas data frame to html table """ formats = formats or {} def cast_type(val): for dtype, cast in formats.items(): if isinstance(val, dtype): try: val = cast(val) break except ValueError: break return val index_name = dataframe.index.name index_name = index_name or "#" tmp = dataframe.copy() if n_mod is not None: tmp = tmp[mod(tmp.index, n_mod) == 0].copy() data = [ Thead([Tr([Th(index_name)] + [Th(col) for col in tmp.columns])]), Tbody([ Tr([Th(cast_type(idx))] + [Td(cast_type(col)) for col in row]) for idx, row in tmp.iterrows() ]), ] return data if data_only else Table(data)
def make_options_table(self, data, header_row): return Table( # Makes the header row className="table", children=[ Thead([Tr([Th(col, scope="col") for col in header_row])]), Tbody([ Tr((Th(prop, scope="row"), Td(data[prop]))) for prop in data ]) ])
def df_to_html_table( dataframe: DataFrame, data_only: bool = False, n_mod: Optional[int] = None, ) -> Table: """Converts pandas data frame to html table """ index_name = dataframe.index.name tmp = dataframe.reset_index() tmp = tmp[mod(tmp.index, n_mod) == 0].copy() tmp = tmp.set_index(index_name) data = [ Thead([Tr([Th(tmp.index.name)] + [Th(col) for col in tmp.columns])]), Tbody([ Tr([Th(idx)] + [Td(col) for col in row]) for idx, row in tmp.iterrows() ]), ] return data if data_only else Table(data)
def monthly_html_table() -> Div: """ Build pretty monthly transaction table with names as indices and months as columns """ df = transactions_monthly() df.index = [s.strftime('%b %y') for s in df.index] expenses = [n for n in NAMES if n in df.columns and df[n].sum() <= 0] income = [n for n in NAMES if n in df.columns and df[n].sum() > 0] df = df[expenses + income].T curr = ' {:,.2f}'.format perc = '{:,.2%}'.format def circle(color): css = { 'width': '14px', 'height': '14px', 'background': color, 'display': 'inline-block', 'margin': '0 8px 0 0', 'padding': 0 } return Div(style=css) header_row = Thead([Th('Name', scope='col')] + [Th(col, scope='col') for col in df.columns], className='thead-light') # name rows name_rows = [] for cat, row in df.iterrows(): cells = [ Th([circle(color(cat)), cat], scope='row', style={'background': '#fafafa'}) ] for cell in row: style = { 'color': color('INC') if cell >= 0 else color('EXP'), 'text-align': 'right' } cells.append(Td(curr(cell or '') if cell != 0 else '', style=style)) name_rows.append(Tr(cells)) # growth row balances = list(df.sum().cumsum() + BALANCE) saving_rel = np.divide(balances, [BALANCE] + balances[:-1]) - 1 saving_abs = np.array(balances) - np.array([BALANCE] + balances[:-1]) growth_row = [ Th('GROWTH', style={ 'background': '#f5f5f5', 'border-top': 'solid 2px #CCC' }) ] for sr, sa in zip(saving_rel, saving_abs): sa = Span(curr(sa), style={ 'color': color('INC') if sr >= 0 else color('EXP'), 'font-weight': 'bold' }) sr = Span( f'{perc(sr)}', style={ 'color': color('INC', alpha=0.8) if sr >= 0 else color('EXP', alpha=0.8) }) sep = Span(' | ', style={'color': '#CCC'}) growth_row.append( Td([sr, sep, sa], style={ 'border-top': 'solid 2px #CCC', 'text-align': 'right' })) growth_row = Tr(growth_row) # total row total_row = [Th('TOTAL', style={'background': '#f5f5f5'})] for exp, inc in zip(df.loc[expenses].sum(), df.loc[income].sum()): sexp = Span(curr(exp), style={ 'color': color('EXP'), 'font-weight': 'bold' }) sinc = Span(curr(inc), style={ 'color': color('INC'), 'font-weight': 'bold' }) sep = Span(' | ', style={'color': '#CCC'}) total_row.append(Td([sexp, sep, sinc], style={'text-align': 'right'})) total_row = Tr(total_row) # balance row balance_row = [Th('BALANCE', style={'background': '#f5f5f5'})] for diff in df.sum().cumsum() + BALANCE: balance_row.append( Td(curr(diff), style={ 'font-weight': 'bold', 'text-align': 'right' })) balance_row = Tr(balance_row) all_rows = [header_row] + name_rows + [growth_row] + [total_row ] + [balance_row] return Div(Table(all_rows, className='table table-bordered table-sm'), className='table-responsive-sm')