Ajout de filtres et des donuts de catégorie #65
This commit is contained in:
@@ -190,6 +190,13 @@ p.version > a {
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
/* --- Dashboard inputs --- */
|
||||
|
||||
.Select--multi .Select-value {
|
||||
color: var(--primary-color);
|
||||
background-color: rgba(255, 240, 240, 0.4);
|
||||
}
|
||||
|
||||
/* --- Tables (Dash & Custom) --- */
|
||||
|
||||
/* Table Menu (Exports etc) */
|
||||
|
||||
@@ -624,6 +624,25 @@ def make_card(
|
||||
return card
|
||||
|
||||
|
||||
def make_donut(lff: pl.LazyFrame, names_col):
|
||||
title = data_schema[names_col]["title"]
|
||||
lff = lff.rename({names_col: title})
|
||||
lff = lff.select("uid", title)
|
||||
lff = lff.group_by(title).len("Nombre")
|
||||
lff = lff.with_columns(pl.col(title).replace(None, pl.lit("?")))
|
||||
fig = px.pie(
|
||||
lff.collect(engine="streaming"),
|
||||
values="Nombre",
|
||||
names=title,
|
||||
hole=0.4,
|
||||
color_discrete_sequence=px.colors.qualitative.Safe,
|
||||
)
|
||||
fig = fig.update_traces(texttemplate="<b>%{label}</b><br><b>%{percent}</b>")
|
||||
fig = fig.update_layout(showlegend=False, font=dict(size=14))
|
||||
graph = dcc.Graph(figure=fig)
|
||||
return graph
|
||||
|
||||
|
||||
def make_column_picker(page: str):
|
||||
table_data = []
|
||||
table_columns = [
|
||||
|
||||
@@ -5,7 +5,7 @@ import polars as pl
|
||||
import polars.selectors as cs
|
||||
from dash import Input, Output, callback, dcc, html, register_page
|
||||
|
||||
from src.figures import get_geographic_maps, make_card
|
||||
from src.figures import get_geographic_maps, make_card, make_donut
|
||||
from src.utils import (
|
||||
departements,
|
||||
df,
|
||||
@@ -69,7 +69,7 @@ layout = [
|
||||
options=get_enum_values_as_dict(
|
||||
"acheteur_categorie"
|
||||
),
|
||||
placeholder="Catégorie d'acheteur",
|
||||
placeholder="Catégorie",
|
||||
),
|
||||
),
|
||||
dbc.Row(
|
||||
@@ -81,14 +81,44 @@ layout = [
|
||||
options=options_departements,
|
||||
),
|
||||
),
|
||||
html.H5("Titulaire"),
|
||||
dbc.Row(
|
||||
dcc.Dropdown(
|
||||
id="dashboard_titulaire_categorie",
|
||||
placeholder="Catégorie",
|
||||
options=get_enum_values_as_dict(
|
||||
"titulaire_categorie"
|
||||
),
|
||||
),
|
||||
),
|
||||
html.H5("Marché"),
|
||||
dbc.Row(
|
||||
dcc.Dropdown(
|
||||
id="dashboard_marche_type",
|
||||
placeholder="Type de marché",
|
||||
placeholder="Type",
|
||||
options=get_enum_values_as_dict("type"),
|
||||
),
|
||||
),
|
||||
dbc.Row(
|
||||
dcc.Dropdown(
|
||||
id="dashboard_marche_considerationsSociales",
|
||||
placeholder="Considérations sociales",
|
||||
options=get_enum_values_as_dict(
|
||||
"considerationsSociales"
|
||||
),
|
||||
multi=True,
|
||||
),
|
||||
),
|
||||
dbc.Row(
|
||||
dcc.Dropdown(
|
||||
id="dashboard_marche_considerationsEnvironnementales",
|
||||
placeholder="Considérations environnementales",
|
||||
multi=True,
|
||||
options=get_enum_values_as_dict(
|
||||
"considerationsEnvironnementales"
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
dbc.Col(
|
||||
@@ -112,13 +142,19 @@ layout = [
|
||||
Input("dashboard_year", "value"),
|
||||
Input("dashboard_acheteur_categorie", "value"),
|
||||
Input("dashboard_acheteur_departement_code", "value"),
|
||||
Input("dashboard_titulaire_categorie", "value"),
|
||||
Input("dashboard_marche_type", "value"),
|
||||
Input("dashboard_marche_considerationsSociales", "value"),
|
||||
Input("dashboard_marche_considerationsEnvironnementales", "value"),
|
||||
)
|
||||
def udpate_dashboard_cards(
|
||||
dashboard_year,
|
||||
dashboard_acheteur_categorie,
|
||||
dashboard_acheteur_departement_code,
|
||||
dashboard_titulaire_categorie,
|
||||
dashboard_marche_type,
|
||||
dashboard_marche_considerationsSociales,
|
||||
dashboard_marche_considerationsEnvironnementales,
|
||||
):
|
||||
lff: pl.LazyFrame = df.lazy()
|
||||
lff = lff.select(
|
||||
@@ -127,10 +163,14 @@ def udpate_dashboard_cards(
|
||||
cs.starts_with("titulaire"),
|
||||
"dateNotification",
|
||||
"montant",
|
||||
"considerationsSociales",
|
||||
"considerationsEnvironnementales",
|
||||
)
|
||||
|
||||
# Application des filtres
|
||||
|
||||
## Période
|
||||
|
||||
if dashboard_year:
|
||||
lff = lff.filter(pl.col("dateNotification").dt.year() == int(dashboard_year))
|
||||
else:
|
||||
@@ -138,6 +178,8 @@ def udpate_dashboard_cards(
|
||||
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
||||
)
|
||||
|
||||
## Acheteur
|
||||
|
||||
if dashboard_acheteur_categorie:
|
||||
lff = lff.filter(pl.col("acheteur_categorie") == dashboard_acheteur_categorie)
|
||||
|
||||
@@ -148,12 +190,38 @@ def udpate_dashboard_cards(
|
||||
)
|
||||
)
|
||||
|
||||
## Titulaire
|
||||
|
||||
if dashboard_titulaire_categorie:
|
||||
lff = lff.filter(pl.col("titulaire_categorie") == dashboard_titulaire_categorie)
|
||||
|
||||
## Marché
|
||||
|
||||
if dashboard_marche_type:
|
||||
lff = lff.filter(pl.col("type") == dashboard_marche_type)
|
||||
|
||||
# Génération des métriques
|
||||
dff = lff.collect()
|
||||
if dashboard_marche_considerationsSociales:
|
||||
lff = lff.filter(
|
||||
pl.col("considerationsSociales")
|
||||
.str.split(", ")
|
||||
.list.set_intersection(dashboard_marche_considerationsSociales)
|
||||
.list.len()
|
||||
> 0
|
||||
)
|
||||
|
||||
if dashboard_marche_considerationsEnvironnementales:
|
||||
lff = lff.filter(
|
||||
pl.col("considerationsEnvironnementales")
|
||||
.str.split(", ")
|
||||
.list.set_intersection(dashboard_marche_considerationsEnvironnementales)
|
||||
.list.len()
|
||||
> 0
|
||||
)
|
||||
|
||||
# Génération des métriques
|
||||
dff = lff.collect(engine="streaming")
|
||||
|
||||
# À transformer en fonction
|
||||
nb_acheteurs = dff.select("acheteur_id").n_unique()
|
||||
nb_titulaires = dff.select("titulaire_id", "titulaire_typeIdentifiant").n_unique()
|
||||
|
||||
@@ -165,7 +233,6 @@ def udpate_dashboard_cards(
|
||||
|
||||
cards = []
|
||||
|
||||
# À transformer en fonction
|
||||
card_basic_counts = [
|
||||
html.P(["Nombre de marchés : ", html.Strong(str(format_number(nb_marches)))]),
|
||||
html.P(
|
||||
@@ -179,6 +246,14 @@ def udpate_dashboard_cards(
|
||||
|
||||
cards.append(make_card(title="Résumé", paragraphs=card_basic_counts))
|
||||
|
||||
donut_acheteur_categorie = make_donut(lff, "acheteur_categorie")
|
||||
cards.append(make_card(title="Catégorie d'acheteur", fig=donut_acheteur_categorie))
|
||||
|
||||
donut_titulaire_categorie = make_donut(lff, "titulaire_categorie")
|
||||
cards.append(
|
||||
make_card(title="Catégorie d'entreprise", fig=donut_titulaire_categorie)
|
||||
)
|
||||
|
||||
geographic_maps: list[dbc.Col] = get_geographic_maps(dff)
|
||||
|
||||
return dbc.Row(children=cards + geographic_maps)
|
||||
|
||||
+3
-3
@@ -697,12 +697,12 @@ def get_button_properties(height):
|
||||
|
||||
|
||||
def get_enum_values_as_dict(column_name):
|
||||
for column in data_schema:
|
||||
if column == column_name:
|
||||
try:
|
||||
options = {}
|
||||
for value in data_schema[column]["enum"]:
|
||||
for value in data_schema[column_name]["enum"]:
|
||||
options[value] = value
|
||||
return options
|
||||
except KeyError:
|
||||
return {"not_found": "not found"}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user