Absolutely! (some of the imported libraries might not be relevant; I just copypasted a part of my app)
import pandas as pd
from datetime import datetime as dt
import numpy as np
import pickle
import dash
import dash_html_components as html
import dash_core_components as dcc
import plotly.express as px
import dash_table
from dash.dependencies import Input, Output
with open('dff.pickle', 'rb') as f:
dff = pickle.load(f)
dff['Count'] = 1
# Small data table
gr_count = dff.groupby(['Sprint', 'Team'], as_index=False, dropna=False)['Story points'].count()
gr_points = dff.groupby(['Sprint', 'Team'], as_index=False)['Story points'].sum()
pivot_count = gr_count.pivot_table(index='Team', columns='Sprint', values='Story points')
pivot_points = gr_points.pivot_table(index='Team', columns='Sprint', values='Story points')
# pivot_points = pivot_points.fillna('')
# pivot_count = pivot_count.fillna(0)
# pivot_count[pivot_count.columns] = pivot_count[pivot_count.columns].apply(np.int64)
pivot = pd.concat([pivot_count, pivot_points])
pivot = pivot.fillna('')
pivot = pivot.sort_index()
pivot = pivot.reset_index()
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1('Teams', style={'textAlign': 'center'}),
html.Div(
dcc.RadioItems(id='count-storypoints2', options=[
{'label': 'Count', 'value': 'Count'},
{'label': 'Story points', 'value': 'Story points'},
], value='Count')
),
html.Div(
dcc.Dropdown(id='quarters2', multi=True, options=[{'label': s, 'value': s} for s in sorted(dff.Quarter.unique())], value=sorted(dff.Quarter.unique()),
clearable=False)
),
html.Div([
dcc.Graph(id='teamlines', config={'displayModeBar': False, 'staticPlot': False}, className='nine columns'),
dcc.Graph(id='smallpie', config={'displayModeBar': False, 'staticPlot': False}, className='three columns')
]),
html.Div(
dcc.Graph(id='teambars', config={'displayModeBar': False, 'staticPlot': False}, className='twelve columns')
),
html.Div([
dash_table.DataTable(
id='pivot_table',
columns=[
{'name': i, 'id': i, 'deletable': False, 'selectable': True} for i in pivot.columns
],
data=pivot.to_dict('records'),
editable=True,
filter_action='none',
sort_action='native',
column_selectable='single',
row_selectable=False,
selected_columns=[],
page_action='native',
style_cell={
'minWidth': 120, 'maxWidth': 120, 'width': 120
},
style_cell_conditional=[
{
'if': {'column_id': 'Team'},
'textAlign': 'left'
}
]
)
])
])
@app.callback(
Output('teamlines', 'figure'),
Output('teambars', 'figure'),
Input('count-storypoints2', 'value'),
Input('quarters2', 'value')
)
def teams(countpoint, quarters2):
if len(quarters2) == 0:
return dash.no_update
else:
df = dff[dff.Quarter.isin(quarters2)]
df = df.groupby(['Team', 'Sprint'], as_index=False, dropna=False, sort=True)[countpoint].sum()
fig_lines = px.line(df, 'Sprint', countpoint, color='Team')
fig_lines.update_traces(mode='lines+markers')
fig_bars = px.bar(df, 'Sprint', countpoint, color='Team', barmode='group')
return fig_lines, fig_bars
@app.callback(
Output('smallpie', 'figure'),
Input('count-storypoints2', 'value'),
Input('teamlines', 'clickData')
)
def update_smallpie(countpoint, click):
if click is None:
df2 = dff[dff.Sprint == dff.Sprint.unique()[-1]]
df2 = df2.groupby(['Team', 'Sprint'], as_index=False, dropna=False, sort=True)[countpoint].sum()
fig_smallpie = px.pie(df2, values=countpoint, names='Team')
return fig_smallpie
else:
selected_sprint = click['points'][0]['x']
df2 = dff[dff.Sprint == selected_sprint]
df2 = df2.groupby(['Team', 'Sprint'], as_index=False, dropna=False, sort=True)[countpoint].sum()
fig_smallpie = px.pie(df2, values=countpoint, names='Team')
return fig_smallpie
if __name__ == '__main__':
app.run_server(debug=True)
the pickled db is here: 132.9 KB file on MEGA