Feat: remove bootstrap and replace it with css

This commit is contained in:
Bertrand Benjamin 2021-01-17 22:04:52 +01:00
parent 09ac9f01f8
commit 4bf8f4003e
3 changed files with 159 additions and 102 deletions

View File

@ -0,0 +1,41 @@
body {
margin: 0px;
font-family: 'Source Sans Pro','Roboto','Open Sans','Liberation Sans','DejaVu Sans','Verdana','Helvetica','Arial',sans-serif;
}
header {
margin: 0px 0px 20px 0px;
background-color: #333333;
color: #ffffff;
padding: 20px;
}
header > h1 {
margin: 0px;
}
main {
width: 95vw;
margin: auto;
}
#select {
margin-bottom: 20px;
}
#select > div {
width: 40vw;
margin: auto;
}
#analysis {
display: flex;
flex-flow: row wrap;
}
#analysis > * {
display: flex;
flex-flow: column;
width: 45vw;
margin: auto;
}

View File

@ -26,116 +26,133 @@ COLORS = {
3: "#68D42F", 3: "#68D42F",
} }
app = dash.Dash(external_stylesheets=[dbc.themes.SIMPLEX])
# external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"] # external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
# app = dash.Dash(__name__, external_stylesheets=external_stylesheets) # app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
# app = dash.Dash(__name__) app = dash.Dash(__name__)
app.layout = html.Div( app.layout = html.Div(
children=[ children=[
dbc.NavbarSimple( html.Header(
children=[ children=[
dbc.Alert("Dernière sauvegarde", id="lastsave", color="success"), html.H1("Analyse des notes"),
html.P("Dernière sauvegarde", id="lastsave"),
], ],
brand="Analyse des notes",
brand_href="#",
color="success",
dark=True,
), ),
html.Br(), html.Main(
dbc.Row(
[ [
dbc.Col( html.Section(
[ [
"Classe: ", html.Div(
dbc.Select( [
id="tribe", "Classe: ",
options=[ dcc.Dropdown(
{"label": t["name"], "value": t["name"]} id="tribe",
for t in config["tribes"] options=[
{"label": t["name"], "value": t["name"]}
for t in config["tribes"]
],
value=config["tribes"][0]["name"],
),
], ],
value=config["tribes"][0]["name"], style={
"display": "flex",
"flex-flow": "column",
},
), ),
] html.Div(
[
"Evaluation: ",
dcc.Dropdown(id="csv"),
],
style={
"display": "flex",
"flex-flow": "column",
},
),
],
id="select",
style={
"display": "flex",
"flex-flow": "row wrap",
},
), ),
dbc.Col( html.Div(
[ [
"Evaluation: ", html.Div(
dbc.Select(id="csv"), dash_table.DataTable(
] id="final_score_table",
columns=[
{"id": "Élève", "name": "Élève"},
{"id": "Note", "name": "Note"},
{"id": "Barème", "name": "Barème"},
],
data=[],
style_data_conditional=[
{
"if": {"row_index": "odd"},
"backgroundColor": "rgb(248, 248, 248)",
}
],
style_data={
"width": "100px",
"maxWidth": "100px",
"minWidth": "100px",
},
),
id="final_score_table_container",
),
html.Div(
[
dash_table.DataTable(
id="final_score_describe",
columns=[
{"id": "count", "name": "count"},
{"id": "mean", "name": "mean"},
{"id": "std", "name": "std"},
{"id": "min", "name": "min"},
{"id": "25%", "name": "25%"},
{"id": "50%", "name": "50%"},
{"id": "75%", "name": "75%"},
{"id": "max", "name": "max"},
],
),
dcc.Graph(
id="fig_assessment_hist",
),
dcc.Graph(id="fig_competences"),
],
id="desc_plots",
),
],
id="analysis",
), ),
], html.Div(
),
html.Br(),
dbc.Row(
[
dbc.Col(
dash_table.DataTable(
id="final_score_table",
columns=[
{"id": "Élève", "name": "Élève"},
{"id": "Note", "name": "Note"},
{"id": "Barème", "name": "Barème"},
],
data=[],
style_data_conditional=[
{
"if": {"row_index": "odd"},
"backgroundColor": "rgb(248, 248, 248)",
}
],
style_header={
"backgroundColor": "rgb(230, 230, 230)",
"fontWeight": "bold",
},
style_data={
"width": "100px",
"maxWidth": "100px",
"minWidth": "100px",
},
)
),
dbc.Col(
[ [
dash_table.DataTable( dash_table.DataTable(
id="final_score_describe", id="scores_table",
columns=[{"id": "count", "name": "count"}, columns=[
{"id": "mean", "name": "mean"}, {"id": c, "name": c} for c in NO_ST_COLUMNS.values()
{"id": "std", "name": "std"}, ],
{"id": "min", "name": "min"}, style_cell={
{"id": "25%", "name": "25%"}, "whiteSpace": "normal",
{"id": "50%", "name": "50%"}, "height": "auto",
{"id": "75%", "name": "75%"}, },
{"id": "max", "name": "max"}, style_data_conditional=[],
] editable=True,
), ),
dcc.Graph( html.Button("Ajouter un élément", id="btn_add_element"),
id="fig_assessment_hist", ],
), id="big_table",
dcc.Graph(id="fig_competences"),
]
), ),
dcc.Store(id="final_score"),
], ],
className="content",
style={
"width": "95vw",
"margin": "auto",
},
), ),
html.Br(), ],
html.Div(
[
dash_table.DataTable(
id="scores_table",
columns=[{"id": c, "name": c} for c in NO_ST_COLUMNS.values()],
style_cell={
"whiteSpace": "normal",
"height": "auto",
},
style_data_conditional=[],
editable=True,
),
dbc.Button("Ajouter un élément", id="btn_add_element"),
]
),
dcc.Store(id="final_score"),
]
) )
@ -178,9 +195,7 @@ def update_final_scores(data):
return [{}] return [{}]
scores = pp_q_scores(scores) scores = pp_q_scores(scores)
assessment_scores = scores.groupby(["Eleve"]).agg( assessment_scores = scores.groupby(["Eleve"]).agg({"Note": "sum", "Bareme": "sum"})
{"Note": "sum", "Bareme": "sum"}
)
return [assessment_scores.reset_index().to_dict("records")] return [assessment_scores.reset_index().to_dict("records")]
@ -202,7 +217,7 @@ def update_final_scores_table(data):
[dash.dependencies.Input("final_score", "data")], [dash.dependencies.Input("final_score", "data")],
) )
def update_final_scores_descr(data): def update_final_scores_descr(data):
scores = pd.DataFrame.from_records(data) scores = pd.DataFrame.from_records(data)
if scores.empty: if scores.empty:
return [[{}]] return [[{}]]
desc = scores["Note"].describe().T desc = scores["Note"].describe().T
@ -311,7 +326,6 @@ def update_competence_fig(data):
@app.callback( @app.callback(
[ [
dash.dependencies.Output("lastsave", "children"), dash.dependencies.Output("lastsave", "children"),
dash.dependencies.Output("lastsave", "color"),
], ],
[ [
dash.dependencies.Input("scores_table", "data"), dash.dependencies.Input("scores_table", "data"),
@ -323,9 +337,9 @@ def save_scores(data, csv):
scores = pd.DataFrame.from_records(data) scores = pd.DataFrame.from_records(data)
scores.to_csv(csv, index=False) scores.to_csv(csv, index=False)
except: except:
return [f"Soucis pour sauvegarder à {datetime.today()} dans {csv}"], "warning" return [f"Soucis pour sauvegarder à {datetime.today()} dans {csv}"]
else: else:
return [f"Dernière sauvegarde {datetime.today()} dans {csv}"], "success" return [f"Dernière sauvegarde {datetime.today()} dans {csv}"]
def highlight_value(df): def highlight_value(df):
@ -358,15 +372,16 @@ def highlight_value(df):
) )
def update_scores_table(csv, add_element, data): def update_scores_table(csv, add_element, data):
ctx = dash.callback_context ctx = dash.callback_context
if ctx.triggered[0]['prop_id'] == "csv.value": if ctx.triggered[0]["prop_id"] == "csv.value":
stack = pd.read_csv(csv, encoding="UTF8") stack = pd.read_csv(csv, encoding="UTF8")
elif ctx.triggered[0]['prop_id'] == "btn_add_element.n_clicks": elif ctx.triggered[0]["prop_id"] == "btn_add_element.n_clicks":
stack = pd.DataFrame.from_records(data) stack = pd.DataFrame.from_records(data)
infos = pd.DataFrame.from_records([{k: stack.iloc[-1][k] for k in NO_ST_COLUMNS.values()}]) infos = pd.DataFrame.from_records(
[{k: stack.iloc[-1][k] for k in NO_ST_COLUMNS.values()}]
)
stack = stack.append(infos) stack = stack.append(infos)
return ( return (
[{"id": c, "name": c} for c in stack.columns], [{"id": c, "name": c} for c in stack.columns],
stack.to_dict("records"), stack.to_dict("records"),
highlight_value(stack), highlight_value(stack),
) )

View File

@ -87,8 +87,9 @@ def new_exam():
@cli.command() @cli.command()
def exam_analysis(): @click.option("--debug", default=0, help="Debug mode for dash")
exam_app.run_server(debug=True) def exam_analysis(debug):
exam_app.run_server(debug=bool(debug))
@cli.command() @cli.command()