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;
|
grid-row: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* --- Dashboard inputs --- */
|
||||||
|
|
||||||
|
.Select--multi .Select-value {
|
||||||
|
color: var(--primary-color);
|
||||||
|
background-color: rgba(255, 240, 240, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Tables (Dash & Custom) --- */
|
/* --- Tables (Dash & Custom) --- */
|
||||||
|
|
||||||
/* Table Menu (Exports etc) */
|
/* Table Menu (Exports etc) */
|
||||||
|
|||||||
@@ -624,6 +624,25 @@ def make_card(
|
|||||||
return 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):
|
def make_column_picker(page: str):
|
||||||
table_data = []
|
table_data = []
|
||||||
table_columns = [
|
table_columns = [
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import polars as pl
|
|||||||
import polars.selectors as cs
|
import polars.selectors as cs
|
||||||
from dash import Input, Output, callback, dcc, html, register_page
|
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 (
|
from src.utils import (
|
||||||
departements,
|
departements,
|
||||||
df,
|
df,
|
||||||
@@ -69,7 +69,7 @@ layout = [
|
|||||||
options=get_enum_values_as_dict(
|
options=get_enum_values_as_dict(
|
||||||
"acheteur_categorie"
|
"acheteur_categorie"
|
||||||
),
|
),
|
||||||
placeholder="Catégorie d'acheteur",
|
placeholder="Catégorie",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
dbc.Row(
|
dbc.Row(
|
||||||
@@ -81,14 +81,44 @@ layout = [
|
|||||||
options=options_departements,
|
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é"),
|
html.H5("Marché"),
|
||||||
dbc.Row(
|
dbc.Row(
|
||||||
dcc.Dropdown(
|
dcc.Dropdown(
|
||||||
id="dashboard_marche_type",
|
id="dashboard_marche_type",
|
||||||
placeholder="Type de marché",
|
placeholder="Type",
|
||||||
options=get_enum_values_as_dict("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(
|
dbc.Col(
|
||||||
@@ -112,13 +142,19 @@ layout = [
|
|||||||
Input("dashboard_year", "value"),
|
Input("dashboard_year", "value"),
|
||||||
Input("dashboard_acheteur_categorie", "value"),
|
Input("dashboard_acheteur_categorie", "value"),
|
||||||
Input("dashboard_acheteur_departement_code", "value"),
|
Input("dashboard_acheteur_departement_code", "value"),
|
||||||
|
Input("dashboard_titulaire_categorie", "value"),
|
||||||
Input("dashboard_marche_type", "value"),
|
Input("dashboard_marche_type", "value"),
|
||||||
|
Input("dashboard_marche_considerationsSociales", "value"),
|
||||||
|
Input("dashboard_marche_considerationsEnvironnementales", "value"),
|
||||||
)
|
)
|
||||||
def udpate_dashboard_cards(
|
def udpate_dashboard_cards(
|
||||||
dashboard_year,
|
dashboard_year,
|
||||||
dashboard_acheteur_categorie,
|
dashboard_acheteur_categorie,
|
||||||
dashboard_acheteur_departement_code,
|
dashboard_acheteur_departement_code,
|
||||||
|
dashboard_titulaire_categorie,
|
||||||
dashboard_marche_type,
|
dashboard_marche_type,
|
||||||
|
dashboard_marche_considerationsSociales,
|
||||||
|
dashboard_marche_considerationsEnvironnementales,
|
||||||
):
|
):
|
||||||
lff: pl.LazyFrame = df.lazy()
|
lff: pl.LazyFrame = df.lazy()
|
||||||
lff = lff.select(
|
lff = lff.select(
|
||||||
@@ -127,10 +163,14 @@ def udpate_dashboard_cards(
|
|||||||
cs.starts_with("titulaire"),
|
cs.starts_with("titulaire"),
|
||||||
"dateNotification",
|
"dateNotification",
|
||||||
"montant",
|
"montant",
|
||||||
|
"considerationsSociales",
|
||||||
|
"considerationsEnvironnementales",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Application des filtres
|
# Application des filtres
|
||||||
|
|
||||||
|
## Période
|
||||||
|
|
||||||
if dashboard_year:
|
if dashboard_year:
|
||||||
lff = lff.filter(pl.col("dateNotification").dt.year() == int(dashboard_year))
|
lff = lff.filter(pl.col("dateNotification").dt.year() == int(dashboard_year))
|
||||||
else:
|
else:
|
||||||
@@ -138,6 +178,8 @@ def udpate_dashboard_cards(
|
|||||||
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
pl.col("dateNotification") > (datetime.now() - timedelta(days=365))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
## Acheteur
|
||||||
|
|
||||||
if dashboard_acheteur_categorie:
|
if dashboard_acheteur_categorie:
|
||||||
lff = lff.filter(pl.col("acheteur_categorie") == 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:
|
if dashboard_marche_type:
|
||||||
lff = lff.filter(pl.col("type") == dashboard_marche_type)
|
lff = lff.filter(pl.col("type") == dashboard_marche_type)
|
||||||
|
|
||||||
# Génération des métriques
|
if dashboard_marche_considerationsSociales:
|
||||||
dff = lff.collect()
|
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_acheteurs = dff.select("acheteur_id").n_unique()
|
||||||
nb_titulaires = dff.select("titulaire_id", "titulaire_typeIdentifiant").n_unique()
|
nb_titulaires = dff.select("titulaire_id", "titulaire_typeIdentifiant").n_unique()
|
||||||
|
|
||||||
@@ -165,7 +233,6 @@ def udpate_dashboard_cards(
|
|||||||
|
|
||||||
cards = []
|
cards = []
|
||||||
|
|
||||||
# À transformer en fonction
|
|
||||||
card_basic_counts = [
|
card_basic_counts = [
|
||||||
html.P(["Nombre de marchés : ", html.Strong(str(format_number(nb_marches)))]),
|
html.P(["Nombre de marchés : ", html.Strong(str(format_number(nb_marches)))]),
|
||||||
html.P(
|
html.P(
|
||||||
@@ -179,6 +246,14 @@ def udpate_dashboard_cards(
|
|||||||
|
|
||||||
cards.append(make_card(title="Résumé", paragraphs=card_basic_counts))
|
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)
|
geographic_maps: list[dbc.Col] = get_geographic_maps(dff)
|
||||||
|
|
||||||
return dbc.Row(children=cards + geographic_maps)
|
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):
|
def get_enum_values_as_dict(column_name):
|
||||||
for column in data_schema:
|
try:
|
||||||
if column == column_name:
|
|
||||||
options = {}
|
options = {}
|
||||||
for value in data_schema[column]["enum"]:
|
for value in data_schema[column_name]["enum"]:
|
||||||
options[value] = value
|
options[value] = value
|
||||||
return options
|
return options
|
||||||
|
except KeyError:
|
||||||
return {"not_found": "not found"}
|
return {"not_found": "not found"}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user