Classe partagée pour la génération de datatables #56

This commit is contained in:
Colin Maudry
2025-11-15 21:00:28 +01:00
parent 6b6d2ca790
commit 503ec33f43
5 changed files with 85 additions and 128 deletions
+5 -34
View File
@@ -1,6 +1,7 @@
import polars as pl import polars as pl
from dash import dash_table, html from dash import html
from src.figures import DataTable
from utils import add_links_in_dict, format_values, setup_table_columns from utils import add_links_in_dict, format_values, setup_table_columns
@@ -15,7 +16,7 @@ def get_top_org_table(data, org_type: str):
dff_nb = dff.group_by(f"{org_type}_id", f"{org_type}_nom", "distance").agg( dff_nb = dff.group_by(f"{org_type}_id", f"{org_type}_nom", "distance").agg(
pl.len().alias("Attributions"), pl.sum("montant").alias("montant") pl.len().alias("Attributions"), pl.sum("montant").alias("montant")
) )
dff_nb = dff_nb.sort(by="montant", descending=True) dff_nb = dff_nb.sort(by="montant", descending=True, nulls_last=True)
dff_nb = dff_nb.cast(pl.String) dff_nb = dff_nb.cast(pl.String)
dff_nb = dff_nb.fill_null("") dff_nb = dff_nb.fill_null("")
dff_nb = format_values(dff_nb) dff_nb = format_values(dff_nb)
@@ -25,41 +26,11 @@ def get_top_org_table(data, org_type: str):
data = dff_nb.to_dicts() data = dff_nb.to_dicts()
data = add_links_in_dict(data, f"{org_type}") data = add_links_in_dict(data, f"{org_type}")
return dash_table.DataTable( return DataTable(
dtid=f"top10_{org_type}",
data=data, data=data,
markdown_options={"html": True},
page_action="native", page_action="native",
page_size=10, page_size=10,
columns=columns, columns=columns,
cell_selectable=False,
tooltip_header=tooltip, tooltip_header=tooltip,
style_cell_conditional=[
{
"if": {"column_id": "objet"},
"minWidth": "350px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "14px",
"whiteSpace": "normal",
"fontSize": "85%",
},
{
"if": {"column_id": "acheteur_nom"},
"minWidth": "200px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "16px",
# "fontSize": "85%",
"whiteSpace": "normal",
},
{
"if": {"column_id": "titulaire_nom"},
"minWidth": "200px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "16px",
"whiteSpace": "normal",
# "fontSize": "85%",
},
],
) )
+67
View File
@@ -1,4 +1,5 @@
import json import json
from typing import Literal
import plotly.express as px import plotly.express as px
import polars as pl import polars as pl
@@ -192,3 +193,69 @@ def point_on_map(lat, lon):
graph = dcc.Graph(id="map", figure=fig) graph = dcc.Graph(id="map", figure=fig)
return graph return graph
class DataTable(dash_table.DataTable):
def __init__(
self,
dtid: str,
hidden_columns: list = None,
data=None,
columns: list = None,
page_size: int = 20,
page_action: Literal["native", "custom", "none"] = "native",
sort_action: Literal["native", "custom", "none"] = "native",
filter_action: Literal["native", "custom", "none"] = "native",
**kwargs,
):
# Styles de base
style_cell_conditional = [
{
"if": {"column_id": "objet"},
"minWidth": "350px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "acheteur_nom"},
"minWidth": "250px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "titulaire_nom"},
"minWidth": "250px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
]
# Initialisation de la classe parente avec les arguments
super().__init__(
id=dtid,
data=data,
columns=columns,
cell_selectable=False,
page_size=page_size,
filter_action=filter_action,
page_action=page_action,
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
sort_action=sort_action,
sort_mode="multi",
sort_by=[],
row_deletable=False,
page_current=0,
style_cell_conditional=style_cell_conditional,
data_timestamp=0,
markdown_options={"html": True},
tooltip_duration=8000,
tooltip_delay=350,
hidden_columns=hidden_columns,
**kwargs, # Possibilité de remplacer des arguments
)
+4 -27
View File
@@ -1,10 +1,10 @@
import datetime import datetime
import polars as pl import polars as pl
from dash import Input, Output, State, callback, dash_table, dcc, html, register_page from dash import Input, Output, State, callback, dcc, html, register_page
from src.callbacks import get_top_org_table from src.callbacks import get_top_org_table
from src.figures import point_on_map from src.figures import DataTable, point_on_map
from src.utils import ( from src.utils import (
add_links_in_dict, add_links_in_dict,
df, df,
@@ -227,37 +227,14 @@ def get_last_marches_table(data) -> html.Div:
table = html.Div( table = html.Div(
className="marches_table", className="marches_table",
id="acheteur_datatable", children=DataTable(
children=dash_table.DataTable( dtid="acheteur_datatable",
data=data, data=data,
markdown_options={"html": True},
page_action="native", page_action="native",
filter_action="native", filter_action="native",
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
columns=columns, columns=columns,
tooltip_header=tooltip, tooltip_header=tooltip,
tooltip_duration=8000,
tooltip_delay=350,
cell_selectable=False,
page_size=10, page_size=10,
style_cell_conditional=[
{
"if": {"column_id": "objet"},
"minWidth": "300px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "titulaire_nom"},
"minWidth": "200px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
],
), ),
) )
return table return table
+5 -40
View File
@@ -2,8 +2,9 @@ import os
from datetime import datetime from datetime import datetime
import polars as pl import polars as pl
from dash import Input, Output, State, callback, dash_table, dcc, html, register_page from dash import Input, Output, State, callback, dcc, html, register_page
from src.figures import DataTable
from src.utils import ( from src.utils import (
add_links, add_links,
add_resource_link, add_resource_link,
@@ -35,48 +36,12 @@ register_page(
datatable = html.Div( datatable = html.Div(
className="marches_table", className="marches_table",
children=dash_table.DataTable( children=DataTable(
cell_selectable=False, dtid="table",
id="table",
page_size=20, page_size=20,
page_current=0,
page_action="custom", page_action="custom",
filter_action="custom", filter_action="custom",
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
sort_action="custom", sort_action="custom",
sort_mode="multi",
sort_by=[],
row_deletable=False,
style_cell_conditional=[
{
"if": {"column_id": "objet"},
"minWidth": "350px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "acheteur_nom"},
"minWidth": "250px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "titulaire_nom"},
"minWidth": "250px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
],
data_timestamp=0,
markdown_options={"html": True},
tooltip_duration=8000,
tooltip_delay=350,
hidden_columns=get_default_hidden_columns(schema), hidden_columns=get_default_hidden_columns(schema),
), ),
) )
@@ -244,7 +209,7 @@ def update_table(page_current, page_size, filter_query, sort_by, data_timestamp)
prevent_initial_call=True, prevent_initial_call=True,
) )
def download_data(n_clicks, filter_query, sort_by, hidden_columns: list = None): def download_data(n_clicks, filter_query, sort_by, hidden_columns: list = None):
lff: pl.LazyFrame = df # start from the original data lff: pl.LazyFrame = df.lazy() # start from the original data
# Les colonnes masquées sont supprimées # Les colonnes masquées sont supprimées
if hidden_columns: if hidden_columns:
+4 -27
View File
@@ -1,10 +1,10 @@
import datetime import datetime
import polars as pl import polars as pl
from dash import Input, Output, State, callback, dash_table, dcc, html, register_page from dash import Input, Output, State, callback, dcc, html, register_page
from src.callbacks import get_top_org_table from src.callbacks import get_top_org_table
from src.figures import point_on_map from src.figures import DataTable, point_on_map
from src.utils import ( from src.utils import (
add_links_in_dict, add_links_in_dict,
df, df,
@@ -239,37 +239,14 @@ def get_last_marches_table(data) -> html.Div:
table = html.Div( table = html.Div(
className="marches_table", className="marches_table",
id="titulaire_datatable", children=DataTable(
children=dash_table.DataTable( dtid="titulaire_data_table",
data=data, data=data,
markdown_options={"html": True},
page_action="native", page_action="native",
filter_action="native", filter_action="native",
filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."},
columns=columns, columns=columns,
tooltip_header=tooltip, tooltip_header=tooltip,
tooltip_duration=8000,
tooltip_delay=350,
cell_selectable=False,
page_size=10, page_size=10,
style_cell_conditional=[
{
"if": {"column_id": "objet"},
"minWidth": "300px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
{
"if": {"column_id": "acheteur_nom"},
"maxWidth": "400px",
"textAlign": "left",
"overflow": "hidden",
"lineHeight": "18px",
"whiteSpace": "normal",
},
],
), ),
) )
return table return table