diff --git a/src/callbacks.py b/src/callbacks.py index 6bf197e..6b12013 100644 --- a/src/callbacks.py +++ b/src/callbacks.py @@ -1,6 +1,7 @@ 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 @@ -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( 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.fill_null("") 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 = add_links_in_dict(data, f"{org_type}") - return dash_table.DataTable( + return DataTable( + dtid=f"top10_{org_type}", data=data, - markdown_options={"html": True}, page_action="native", page_size=10, columns=columns, - cell_selectable=False, 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%", - }, - ], ) diff --git a/src/figures.py b/src/figures.py index ec5eda1..8796e96 100644 --- a/src/figures.py +++ b/src/figures.py @@ -1,4 +1,5 @@ import json +from typing import Literal import plotly.express as px import polars as pl @@ -192,3 +193,69 @@ def point_on_map(lat, lon): graph = dcc.Graph(id="map", figure=fig) 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 + ) diff --git a/src/pages/acheteur.py b/src/pages/acheteur.py index 87ddd05..0213f67 100644 --- a/src/pages/acheteur.py +++ b/src/pages/acheteur.py @@ -1,10 +1,10 @@ import datetime 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.figures import point_on_map +from src.figures import DataTable, point_on_map from src.utils import ( add_links_in_dict, df, @@ -227,37 +227,14 @@ def get_last_marches_table(data) -> html.Div: table = html.Div( className="marches_table", - id="acheteur_datatable", - children=dash_table.DataTable( + children=DataTable( + dtid="acheteur_datatable", data=data, - markdown_options={"html": True}, page_action="native", filter_action="native", - filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."}, columns=columns, tooltip_header=tooltip, - tooltip_duration=8000, - tooltip_delay=350, - cell_selectable=False, 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 diff --git a/src/pages/tableau.py b/src/pages/tableau.py index 972a240..ab3f712 100644 --- a/src/pages/tableau.py +++ b/src/pages/tableau.py @@ -2,8 +2,9 @@ import os from datetime import datetime 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 ( add_links, add_resource_link, @@ -35,48 +36,12 @@ register_page( datatable = html.Div( className="marches_table", - children=dash_table.DataTable( - cell_selectable=False, - id="table", + children=DataTable( + dtid="table", page_size=20, - page_current=0, page_action="custom", filter_action="custom", - filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."}, 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), ), ) @@ -244,7 +209,7 @@ def update_table(page_current, page_size, filter_query, sort_by, data_timestamp) prevent_initial_call=True, ) 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 if hidden_columns: diff --git a/src/pages/titulaire.py b/src/pages/titulaire.py index 3ebeaef..72b74de 100644 --- a/src/pages/titulaire.py +++ b/src/pages/titulaire.py @@ -1,10 +1,10 @@ import datetime 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.figures import point_on_map +from src.figures import DataTable, point_on_map from src.utils import ( add_links_in_dict, df, @@ -239,37 +239,14 @@ def get_last_marches_table(data) -> html.Div: table = html.Div( className="marches_table", - id="titulaire_datatable", - children=dash_table.DataTable( + children=DataTable( + dtid="titulaire_data_table", data=data, - markdown_options={"html": True}, page_action="native", filter_action="native", - filter_options={"case": "insensitive", "placeholder_text": "Filtrer..."}, columns=columns, tooltip_header=tooltip, - tooltip_duration=8000, - tooltip_delay=350, - cell_selectable=False, 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