diff --git a/src/assets/style.css b/src/assets/style.css index 88f1e3f..2058973 100644 --- a/src/assets/style.css +++ b/src/assets/style.css @@ -111,3 +111,20 @@ h3 { #_pages_content { padding-top: 28px; } + +/* Vue acheteur/fournisseur */ +.wrapper { + display: grid; + grid-gap: 10px; + margin-bottom: 50px; +} + +.org_infos { + grid-column: 1; + grid-row: 1; +} + +.org_map { + grid-column: 2; + grid-row: 1; +} diff --git a/src/figures.py b/src/figures.py index 8ca0c5d..9be7fa6 100644 --- a/src/figures.py +++ b/src/figures.py @@ -2,7 +2,7 @@ import json import plotly.express as px import polars as pl -from dash import dash_table, html +from dash import dash_table, dcc, html def get_map_count_marches(lf: pl.LazyFrame): @@ -32,11 +32,11 @@ def get_map_count_marches(lf: pl.LazyFrame): df, geojson=departements, locations="Département", - color="uid", - color_continuous_scale="Reds", + # color="uid", + # color_continuous_scale="Reds", title="Nombres de marchés attribués par département (lieu d'exécution)", - range_color=(df["uid"].min(), df["uid"].max()), - labels={"uid": "Marchés attribués"}, + # range_color=(df["uid"].min(), df["uid"].max()), + # labels={"uid": "Marchés attribués"}, scope="europe", width=1000, height=800, @@ -157,3 +157,40 @@ def get_sources_tables(source_path) -> html.Div: datatable.data = df.to_dicts() return html.Div(children=datatable) + + +def point_on_map(lat, lon): + lat = float(lat) + lon = float(lon) + + # Create a scatter mapbox or choropleth map + fig = px.scatter_map( + lat=[lat], + lon=[lon], + height=300, + width=400, + color=[1], + ) + + fig.update_coloraxes(showscale=False) + + # Set map style (you can use 'open-street-map', 'carto-positron', etc.) + fig.update_layout( + mapbox_style="light", # Light, clean background + margin={"r": 0, "t": 0, "l": 0, "b": 0}, + ) + + # Optionally, center the map on France + fig.update_geos( + center=dict(lat=46.603354, lon=1.888334), # Center of France + lataxis_range=[41, 51.5], # Latitude range for France + lonaxis_range=[-5, 10], # Longitude range for France + ) + + # But scatter_mapbox doesn't use geos, so better to control via zoom/center manually + # Let's reset and use proper centering in scatter_mapbox instead: + + fig.update_layout(map_center={"lat": 46.6, "lon": 1.89}, map_zoom=4) + + graph = dcc.Graph(id="map", figure=fig) + return graph diff --git a/src/pages/acheteur.py b/src/pages/acheteur.py index f767e6b..5b14664 100644 --- a/src/pages/acheteur.py +++ b/src/pages/acheteur.py @@ -1,7 +1,8 @@ import polars as pl from dash import Input, Output, callback, dash_table, dcc, html, register_page -from src.utils import lf +from src.figures import point_on_map +from src.utils import get_annuaire_data, lf register_page( __name__, @@ -19,7 +20,27 @@ layout = [ html.Div( className="container", children=[ - html.H2(id="acheteur_title", children=""), + html.H2( + children=[ + html.Span(id="acheteur_siret"), + " - ", + html.Span(id="acheteur_nom"), + ] + ), + html.Div( + className="wrapper", + children=[ + html.Div( + className="org_infos", + children=[html.P(["Commune : ", html.Span(id="commune")])], + ), + html.Div(className="org_map", id="acheteur_map"), + # adresse + # code commune + # lat long + ], + ), + # récupérer les données de l'acheteur sur l'api annuaire html.H3("Derniers marchés publics notifiés"), html.Div(id="acheteur_last_marches", children=""), ], @@ -28,15 +49,27 @@ layout = [ @callback( - Output(component_id="acheteur_title", component_property="children"), + Output(component_id="acheteur_siret", component_property="children"), + Output(component_id="acheteur_nom", component_property="children"), + Output(component_id="commune", component_property="children"), + Output(component_id="acheteur_map", component_property="children"), Input(component_id="url", component_property="pathname"), ) def update_acheteur(url): acheteur_siret = url.split("/")[-1] if len(acheteur_siret) != 14: return f"Le SIRET renseigné doit faire 14 caractères ({acheteur_siret})" - - return acheteur_siret + data = get_annuaire_data(acheteur_siret) + data_etablissement = data["matching_etablissements"][0] + acheteur_map = point_on_map( + data_etablissement["latitude"], data_etablissement["longitude"] + ) + return ( + acheteur_siret, + data["nom_raison_sociale"], + data_etablissement["libelle_commune"], + acheteur_map, + ) @callback( diff --git a/src/utils.py b/src/utils.py index 3286b15..cc49a09 100644 --- a/src/utils.py +++ b/src/utils.py @@ -102,10 +102,10 @@ def format_number(number) -> str: return number -def get_acheteur_data(siret: str) -> dict: +def get_annuaire_data(siret: str) -> dict: url = f"https://recherche-entreprises.api.gouv.fr/search?q={siret}" response = get(url) - return response.json() + return response.json()["results"][0] def get_decp_data() -> pl.LazyFrame: