Grid de cards avec points de rupture #65
This commit is contained in:
@@ -391,8 +391,16 @@
|
|||||||
"departement": "La Réunion",
|
"departement": "La Réunion",
|
||||||
"region": "La Réunion"
|
"region": "La Réunion"
|
||||||
},
|
},
|
||||||
|
"975": {
|
||||||
|
"departement": "Saint-Pierre-et-Miquelon",
|
||||||
|
"region": "Saint-Pierre-et-Miquelon"
|
||||||
|
},
|
||||||
"976": {
|
"976": {
|
||||||
"departement": "Mayotte",
|
"departement": "Mayotte",
|
||||||
"region": "Mayotte"
|
"region": "Mayotte"
|
||||||
|
},
|
||||||
|
"977": {
|
||||||
|
"departement": "Saint-Barthelemy",
|
||||||
|
"region": "Saint-Barthelemy"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-23
@@ -417,18 +417,12 @@ def get_geographic_maps(dff: pl.DataFrame) -> list | None:
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Liste des codes départements Outre-Mer
|
|
||||||
dom_codes = [code for code in regions.keys() if code != "Métropole"]
|
|
||||||
print("dom codes", dom_codes)
|
|
||||||
|
|
||||||
def make_map_data(region_code: str) -> tuple[list, str or None]:
|
def make_map_data(region_code: str) -> tuple[list, str or None]:
|
||||||
lff: pl.LazyFrame = dff.lazy()
|
lff: pl.LazyFrame = dff.lazy()
|
||||||
if region_code == "Métropole":
|
if region_code == "Métropole":
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
(
|
(pl.col("acheteur_departement_code").str.len_chars() == 2)
|
||||||
~pl.col("acheteur_departement_code").is_in(dom_codes)
|
& (pl.col("titulaire_departement_code").str.len_chars() == 2)
|
||||||
| (~pl.col("titulaire_departement_code").is_in(dom_codes))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
lff = lff.filter(
|
lff = lff.filter(
|
||||||
@@ -436,14 +430,14 @@ def get_geographic_maps(dff: pl.DataFrame) -> list | None:
|
|||||||
| (pl.col("titulaire_departement_code") == code)
|
| (pl.col("titulaire_departement_code") == code)
|
||||||
)
|
)
|
||||||
|
|
||||||
nb_marches = lff.select("uid").group_by("uid").first().collect().height
|
nb_marches = lff.select("uid").collect()["uid"].n_unique()
|
||||||
|
|
||||||
if nb_marches == 0:
|
if nb_marches == 0:
|
||||||
return [], None
|
return [], None
|
||||||
|
|
||||||
dfs = []
|
dfs = []
|
||||||
|
|
||||||
if (code == "Métropole" and nb_marches > 20000) or (
|
if (code == "Métropole" and nb_marches > 30000) or (
|
||||||
code != "Métropole" and nb_marches > 10000
|
code != "Métropole" and nb_marches > 10000
|
||||||
):
|
):
|
||||||
_map_type: str = "chloropleth"
|
_map_type: str = "chloropleth"
|
||||||
@@ -505,10 +499,9 @@ def get_geographic_maps(dff: pl.DataFrame) -> list | None:
|
|||||||
|
|
||||||
for code in regions.keys():
|
for code in regions.keys():
|
||||||
regions[code]["data"], map_type = make_map_data(code)
|
regions[code]["data"], map_type = make_map_data(code)
|
||||||
print("region", regions[code]["name"], len(regions[code]["data"][0]), map_type)
|
|
||||||
|
|
||||||
if map_type == "chloropleth":
|
if map_type == "chloropleth":
|
||||||
map_graph = make_chloropleth_map(regions[code]) # call chloropleth function
|
map_graph = make_chloropleth_map(regions[code])
|
||||||
elif map_type == "clusters":
|
elif map_type == "clusters":
|
||||||
map_graph = make_clusters_map(regions[code])
|
map_graph = make_clusters_map(regions[code])
|
||||||
elif map_type is None:
|
elif map_type is None:
|
||||||
@@ -516,15 +509,9 @@ def get_geographic_maps(dff: pl.DataFrame) -> list | None:
|
|||||||
else:
|
else:
|
||||||
raise ValueError(f"Map type '{map_type}' not recognised")
|
raise ValueError(f"Map type '{map_type}' not recognised")
|
||||||
|
|
||||||
col = dbc.Col(
|
md = 6 if code == "Métropole" else 3
|
||||||
children=[
|
|
||||||
html.H5(regions[code]["name"]),
|
col = make_card(regions[code]["name"], md=md, fig=map_graph)
|
||||||
map_graph,
|
|
||||||
],
|
|
||||||
md=6 if code == "Métropole" else 3,
|
|
||||||
width=12,
|
|
||||||
className="mb-4",
|
|
||||||
)
|
|
||||||
cols.append(col)
|
cols.append(col)
|
||||||
|
|
||||||
return cols
|
return cols
|
||||||
@@ -543,7 +530,6 @@ def make_chloropleth_map(region: dict) -> dcc.Graph:
|
|||||||
range_color=(df_map["uid"].min(), df_map["uid"].max()),
|
range_color=(df_map["uid"].min(), df_map["uid"].max()),
|
||||||
labels={"uid": "Marchés attribués"},
|
labels={"uid": "Marchés attribués"},
|
||||||
scope="europe",
|
scope="europe",
|
||||||
width=400,
|
|
||||||
height=400,
|
height=400,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -561,7 +547,7 @@ def make_chloropleth_map(region: dict) -> dcc.Graph:
|
|||||||
return graph
|
return graph
|
||||||
|
|
||||||
|
|
||||||
def make_clusters_map(region: dict):
|
def make_clusters_map(region: dict) -> dl.Map:
|
||||||
# JavaScript functions for styling
|
# JavaScript functions for styling
|
||||||
ns = Namespace("dash_clientside", "leaflet")
|
ns = Namespace("dash_clientside", "leaflet")
|
||||||
point_to_layer = ns("pointToLayer")
|
point_to_layer = ns("pointToLayer")
|
||||||
@@ -615,6 +601,31 @@ def make_clusters_map(region: dict):
|
|||||||
return leaflet_map
|
return leaflet_map
|
||||||
|
|
||||||
|
|
||||||
|
def make_card(
|
||||||
|
title: str, subtitle=None, fig=None, paragraphs=None, md=3, width=12
|
||||||
|
) -> dbc.Col:
|
||||||
|
children = []
|
||||||
|
if title:
|
||||||
|
children.append(html.H5(title, className="card-title"))
|
||||||
|
if subtitle:
|
||||||
|
children.append(html.H6(subtitle, className="card-subtitle mb-2 text-muted"))
|
||||||
|
if fig:
|
||||||
|
children.append(fig)
|
||||||
|
if paragraphs:
|
||||||
|
for p in paragraphs:
|
||||||
|
p.className = "card-text"
|
||||||
|
children.append(p)
|
||||||
|
|
||||||
|
card = dbc.Col(
|
||||||
|
html.Div(html.Div(className="card-body", children=children), className="card"),
|
||||||
|
lg=6,
|
||||||
|
xl=4,
|
||||||
|
# width=width,
|
||||||
|
# className="mb-4",
|
||||||
|
)
|
||||||
|
return card
|
||||||
|
|
||||||
|
|
||||||
def make_column_picker(page: str):
|
def make_column_picker(page: str):
|
||||||
table_data = []
|
table_data = []
|
||||||
table_columns = [
|
table_columns = [
|
||||||
|
|||||||
+13
-24
@@ -5,9 +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 (
|
from src.figures import get_geographic_maps, make_card
|
||||||
get_geographic_maps,
|
|
||||||
)
|
|
||||||
from src.utils import (
|
from src.utils import (
|
||||||
departements,
|
departements,
|
||||||
df,
|
df,
|
||||||
@@ -52,8 +50,8 @@ layout = [
|
|||||||
dbc.Row(
|
dbc.Row(
|
||||||
[
|
[
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
width=12,
|
xl=3,
|
||||||
md=3,
|
lg=4,
|
||||||
id="filters",
|
id="filters",
|
||||||
children=[
|
children=[
|
||||||
html.H5("Période d'attribution"),
|
html.H5("Période d'attribution"),
|
||||||
@@ -87,22 +85,10 @@ layout = [
|
|||||||
),
|
),
|
||||||
dbc.Col(
|
dbc.Col(
|
||||||
width=12,
|
width=12,
|
||||||
md=9,
|
lg=8,
|
||||||
|
xl=9,
|
||||||
id="cards",
|
id="cards",
|
||||||
children=[
|
children=[],
|
||||||
dbc.Row(
|
|
||||||
(
|
|
||||||
dbc.Col(
|
|
||||||
width=6,
|
|
||||||
md=4,
|
|
||||||
className="card",
|
|
||||||
id="card_basic_counts",
|
|
||||||
)
|
|
||||||
),
|
|
||||||
className="mb-4",
|
|
||||||
),
|
|
||||||
dbc.Row(id="maps_row"),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
@@ -114,8 +100,7 @@ layout = [
|
|||||||
|
|
||||||
|
|
||||||
@callback(
|
@callback(
|
||||||
Output("card_basic_counts", "children"),
|
Output("cards", "children"),
|
||||||
Output("maps_row", "children"),
|
|
||||||
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"),
|
||||||
@@ -163,6 +148,8 @@ def udpate_dashboard_cards(
|
|||||||
total_montant = df_per_uid.select(pl.col("montant").sum()).item()
|
total_montant = df_per_uid.select(pl.col("montant").sum()).item()
|
||||||
nb_marches = df_per_uid.height
|
nb_marches = df_per_uid.height
|
||||||
|
|
||||||
|
cards = []
|
||||||
|
|
||||||
# À transformer en fonction
|
# À 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)))]),
|
||||||
@@ -175,6 +162,8 @@ def udpate_dashboard_cards(
|
|||||||
html.P(["Montant total : ", html.Strong(format_number(total_montant) + " €")]),
|
html.P(["Montant total : ", html.Strong(format_number(total_montant) + " €")]),
|
||||||
]
|
]
|
||||||
|
|
||||||
geographic_maps = get_geographic_maps(dff)
|
cards.append(make_card(title="Résumé", paragraphs=card_basic_counts))
|
||||||
|
|
||||||
return card_basic_counts, geographic_maps
|
geographic_maps: list[dbc.Col] = get_geographic_maps(dff)
|
||||||
|
|
||||||
|
return dbc.Row(children=cards + geographic_maps)
|
||||||
|
|||||||
Reference in New Issue
Block a user