Continuation dans le typage et la documentation pour les autres app's
This commit is contained in:
parent
35aa7d12fa
commit
4d511cbe23
@ -1,3 +1,5 @@
|
|||||||
|
from typing import List, Tuple, Dict, Optional
|
||||||
|
import networkx as nx
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
from utils.widgets import html_expander
|
from utils.widgets import html_expander
|
||||||
@ -17,8 +19,20 @@ niveau_labels = {
|
|||||||
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
||||||
|
|
||||||
|
|
||||||
def preparer_graphe(G):
|
def preparer_graphe(
|
||||||
"""Nettoie et prépare le graphe pour l'analyse."""
|
G: nx.DiGraph,
|
||||||
|
) -> Tuple[nx.DiGraph, Dict[str, int]]:
|
||||||
|
"""
|
||||||
|
Nettoie et prépare le graphe pour l'analyse.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[nx.DiGraph, Dict[str, int]]: Un tuple contenant :
|
||||||
|
- Le graphe NetworkX proprement configuré
|
||||||
|
- Un dictionnaire des niveaux associés aux nœuds
|
||||||
|
"""
|
||||||
niveaux_temp = {
|
niveaux_temp = {
|
||||||
node: int(str(attrs.get("niveau")).strip('"'))
|
node: int(str(attrs.get("niveau")).strip('"'))
|
||||||
for node, attrs in G.nodes(data=True)
|
for node, attrs in G.nodes(data=True)
|
||||||
@ -30,8 +44,15 @@ def preparer_graphe(G):
|
|||||||
return G, niveaux_temp
|
return G, niveaux_temp
|
||||||
|
|
||||||
|
|
||||||
def selectionner_niveaux():
|
def selectionner_niveaux(
|
||||||
"""Interface pour sélectionner les niveaux de départ et d'arrivée."""
|
) -> Tuple[int|None, int|None]:
|
||||||
|
"""
|
||||||
|
Interface pour sélectionner les niveaux de départ et d'arrivée.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[int, int]: Un tuple contenant deux nombres si des nœuds ont été sélectionnés,
|
||||||
|
- None sinon
|
||||||
|
"""
|
||||||
st.markdown(f"## {str(_('pages.analyse.selection_nodes'))}")
|
st.markdown(f"## {str(_('pages.analyse.selection_nodes'))}")
|
||||||
valeur_defaut = str(_("pages.analyse.select_level"))
|
valeur_defaut = str(_("pages.analyse.select_level"))
|
||||||
niveau_choix = [valeur_defaut] + list(niveau_labels.values())
|
niveau_choix = [valeur_defaut] + list(niveau_labels.values())
|
||||||
@ -52,8 +73,23 @@ def selectionner_niveaux():
|
|||||||
return niveau_depart_int, niveau_arrivee_int
|
return niveau_depart_int, niveau_arrivee_int
|
||||||
|
|
||||||
|
|
||||||
def selectionner_minerais(G, niveau_depart, niveau_arrivee):
|
def selectionner_minerais(
|
||||||
"""Interface pour sélectionner les minerais si nécessaire."""
|
G: nx.DiGraph,
|
||||||
|
niveau_depart: int,
|
||||||
|
niveau_arrivee: int
|
||||||
|
) -> Optional[List[str]]:
|
||||||
|
"""
|
||||||
|
Interface pour sélectionner les minerais si nécessaire.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
niveau_arrivee (int): Le niveau d'arrivée sélectionné.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[List[str]]: La liste des minerais si une sélection a été effectuée,
|
||||||
|
- None sinon
|
||||||
|
"""
|
||||||
minerais_selection = None
|
minerais_selection = None
|
||||||
if niveau_depart < 2 < niveau_arrivee:
|
if niveau_depart < 2 < niveau_arrivee:
|
||||||
st.markdown(f"### {str(_('pages.analyse.select_minerals'))}")
|
st.markdown(f"### {str(_('pages.analyse.select_minerals'))}")
|
||||||
@ -72,8 +108,25 @@ def selectionner_minerais(G, niveau_depart, niveau_arrivee):
|
|||||||
return minerais_selection
|
return minerais_selection
|
||||||
|
|
||||||
|
|
||||||
def selectionner_noeuds(G, niveaux_temp, niveau_depart, niveau_arrivee):
|
def selectionner_noeuds(
|
||||||
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée."""
|
G: nx.DiGraph,
|
||||||
|
niveaux_temp: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
niveau_arrivee: int
|
||||||
|
) -> Tuple[List[str]|None, List[str]|None]:
|
||||||
|
"""
|
||||||
|
Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveaux_temp (Dict[str, int]): Dictionnaire contenant les niveaux associés aux nœuds.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
niveau_arrivee (int): Le niveau d'arrivée sélectionné.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[Tuple[List[str], List[str]]]: Un tuple contenant les listes des nœuds
|
||||||
|
- None sinon
|
||||||
|
"""
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
st.markdown(f"## {str(_('pages.analyse.fine_selection'))}")
|
st.markdown(f"## {str(_('pages.analyse.fine_selection'))}")
|
||||||
|
|
||||||
@ -93,8 +146,20 @@ def selectionner_noeuds(G, niveaux_temp, niveau_depart, niveau_arrivee):
|
|||||||
return noeuds_depart, noeuds_arrivee
|
return noeuds_depart, noeuds_arrivee
|
||||||
|
|
||||||
|
|
||||||
def configurer_filtres_vulnerabilite():
|
def configurer_filtres_vulnerabilite(
|
||||||
"""Interface pour configurer les filtres de vulnérabilité."""
|
) -> Tuple[bool, bool, bool, str, bool, str]:
|
||||||
|
"""
|
||||||
|
Interface pour configurer les filtres de vulnérabilité.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[bool, bool, bool, str, bool, str]: Un tuple contenant :
|
||||||
|
- La possibilité de filtrer les ICS
|
||||||
|
- La possibilité de filtrer les IV C
|
||||||
|
- La possibilité de filtrer les IH H
|
||||||
|
- Le type d'application pour les IH H (pays ou acteur)
|
||||||
|
- La possibilité de filtrer les IS G
|
||||||
|
- La logique de filtrage (ou ou and)
|
||||||
|
"""
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
st.markdown(f"## {str(_('pages.analyse.vulnerability_filters'))}")
|
st.markdown(f"## {str(_('pages.analyse.vulnerability_filters'))}")
|
||||||
|
|
||||||
@ -122,7 +187,15 @@ def configurer_filtres_vulnerabilite():
|
|||||||
return filtrer_ics, filtrer_ivc, filtrer_ihh, ihh_type, filtrer_isg, logique_filtrage
|
return filtrer_ics, filtrer_ivc, filtrer_ihh, ihh_type, filtrer_isg, logique_filtrage
|
||||||
|
|
||||||
|
|
||||||
def interface_analyse(G_temp):
|
def interface_analyse(
|
||||||
|
G_temp: nx.DiGraph,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Interface utilisateur pour l'analyse des graphes.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G_temp (nx.DiGraph): Le graphe NetworkX à analyser.
|
||||||
|
"""
|
||||||
st.markdown(f"# {str(_('pages.analyse.title'))}")
|
st.markdown(f"# {str(_('pages.analyse.title'))}")
|
||||||
html_expander(f"{str(_('pages.analyse.help'))}", content="\n".join(_("pages.analyse.help_content")), open_by_default=False, details_class="details_introduction")
|
html_expander(f"{str(_('pages.analyse.help'))}", content="\n".join(_("pages.analyse.help_content")), open_by_default=False, details_class="details_introduction")
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from typing import Dict, List, Tuple, Optional, Set
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
from networkx.drawing.nx_agraph import write_dot
|
from networkx.drawing.nx_agraph import write_dot
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
@ -25,8 +26,18 @@ niveau_labels = {
|
|||||||
|
|
||||||
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
||||||
|
|
||||||
def extraire_niveaux(G):
|
def extraire_niveaux(
|
||||||
"""Extrait les niveaux des nœuds du graphe"""
|
G: nx.DiGraph,
|
||||||
|
) -> Dict[str, int]:
|
||||||
|
"""
|
||||||
|
Extrait les niveaux des nœuds du graphe.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, int]: Un dictionnaire associant chaque nœud à son niveau.
|
||||||
|
"""
|
||||||
niveaux = {}
|
niveaux = {}
|
||||||
for node, attrs in G.nodes(data=True):
|
for node, attrs in G.nodes(data=True):
|
||||||
niveau_str = attrs.get("niveau")
|
niveau_str = attrs.get("niveau")
|
||||||
@ -37,8 +48,22 @@ def extraire_niveaux(G):
|
|||||||
logging.warning(f"Niveau non entier pour le noeud {node}: {niveau_str}")
|
logging.warning(f"Niveau non entier pour le noeud {node}: {niveau_str}")
|
||||||
return niveaux
|
return niveaux
|
||||||
|
|
||||||
def extraire_ics(G, u, v):
|
def extraire_ics(
|
||||||
"""Extrait la criticité d'un lien entre deux nœuds"""
|
G: nx.DiGraph,
|
||||||
|
u: str,
|
||||||
|
v: str,
|
||||||
|
) -> float:
|
||||||
|
"""
|
||||||
|
Extrait la criticité d'un lien entre deux nœuds.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
u (str): L'ID du premier nœud.
|
||||||
|
v (str): L'ID du second nœud.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float: La valeur de criticité entre les deux nœuds, ou 0 si impossible à extraire.
|
||||||
|
"""
|
||||||
data = G.get_edge_data(u, v)
|
data = G.get_edge_data(u, v)
|
||||||
if not data:
|
if not data:
|
||||||
return 0
|
return 0
|
||||||
@ -46,8 +71,29 @@ def extraire_ics(G, u, v):
|
|||||||
return float(data[0].get("ics", 0))
|
return float(data[0].get("ics", 0))
|
||||||
return float(data.get("ics", 0))
|
return float(data.get("ics", 0))
|
||||||
|
|
||||||
def extraire_chemins_selon_criteres(G, niveaux, niveau_depart, noeuds_depart, noeuds_arrivee, minerais):
|
def extraire_chemins_selon_criteres(
|
||||||
"""Extrait les chemins selon les critères spécifiés"""
|
G: nx.DiGraph,
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
noeuds_depart: Optional[List[str]],
|
||||||
|
noeuds_arrivee: Optional[List[str]],
|
||||||
|
minerais: Optional[List[str]],
|
||||||
|
) -> List[Tuple[str, ...]]:
|
||||||
|
"""
|
||||||
|
Extrait les chemins selon les critères spécifiés.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
noeuds_depart (Optional[List[str]]): Les nœuds de départ si sélectionnés.
|
||||||
|
noeuds_arrivee (Optional[List[str]]): Les nœuds d'arrivée si sélectionnés.
|
||||||
|
minerais (Optional[List[str]]): Les minerais si sélectionnés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Tuple[str, ...]]: Liste des chemins valides selon les critères spécifiés.
|
||||||
|
"""
|
||||||
|
|
||||||
chemins = []
|
chemins = []
|
||||||
if noeuds_depart and noeuds_arrivee:
|
if noeuds_depart and noeuds_arrivee:
|
||||||
for nd in noeuds_depart:
|
for nd in noeuds_depart:
|
||||||
@ -70,8 +116,24 @@ def extraire_chemins_selon_criteres(G, niveaux, niveau_depart, noeuds_depart, no
|
|||||||
|
|
||||||
return chemins
|
return chemins
|
||||||
|
|
||||||
def verifier_critere_ihh(G, chemin, niveaux, ihh_type):
|
def verifier_critere_ihh(
|
||||||
"""Vérifie si un chemin respecte le critère IHH (concentration géographique ou industrielle)"""
|
G: nx.DiGraph,
|
||||||
|
chemin: Tuple[str, ...],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
ihh_type: str,
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Vérifie si un chemin respecte le critère IHH (concentration géographique ou industrielle).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
chemin (Tuple[str, ...]): Un chemin validé selon les critères antérieurs.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
ihh_type (str): Le type d'application pour les IHH (pays ou acteur).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si le chemin respecte le critère IHH, False sinon.
|
||||||
|
"""
|
||||||
ihh_field = "ihh_pays" if ihh_type == "Pays" else "ihh_acteurs"
|
ihh_field = "ihh_pays" if ihh_type == "Pays" else "ihh_acteurs"
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
u, v = chemin[i], chemin[i + 1]
|
u, v = chemin[i], chemin[i + 1]
|
||||||
@ -84,8 +146,22 @@ def verifier_critere_ihh(G, chemin, niveaux, ihh_type):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def verifier_critere_ivc(G, chemin, niveaux):
|
def verifier_critere_ivc(
|
||||||
"""Vérifie si un chemin respecte le critère IVC (criticité par rapport à la concurrence sectorielle)"""
|
G: nx.DiGraph,
|
||||||
|
chemin: Tuple[str, ...],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Vérifie si un chemin respecte le critère IVC (criticité par rapport à la concurrence sectorielle).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
chemin (Tuple[str, ...]): Un chemin validé selon les critères antérieurs.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si le chemin respecte le critère IVC, False sinon.
|
||||||
|
"""
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
u = chemin[i]
|
u = chemin[i]
|
||||||
niveau_u = niveaux.get(u)
|
niveau_u = niveaux.get(u)
|
||||||
@ -93,8 +169,22 @@ def verifier_critere_ivc(G, chemin, niveaux):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def verifier_critere_ics(G, chemin, niveaux):
|
def verifier_critere_ics(
|
||||||
"""Vérifie si un chemin respecte le critère ICS (criticité d'un minerai pour un composant)"""
|
G: nx.DiGraph,
|
||||||
|
chemin: Tuple[str, ...],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Vérifie si un chemin respecte le critère ICS (criticité d'un minerai pour un composant).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
chemin (Tuple[str, ...]): Un chemin validé selon les critères antérieurs.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si le chemin respecte le critère ICS, False sinon.
|
||||||
|
"""
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
u, v = chemin[i], chemin[i + 1]
|
u, v = chemin[i], chemin[i + 1]
|
||||||
niveau_u = niveaux.get(u)
|
niveau_u = niveaux.get(u)
|
||||||
@ -106,8 +196,22 @@ def verifier_critere_ics(G, chemin, niveaux):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def verifier_critere_isg(G, chemin, niveaux):
|
def verifier_critere_isg(
|
||||||
"""Vérifie si un chemin contient un pays instable (ISG ≥ 60)"""
|
G: nx.DiGraph,
|
||||||
|
chemin: Tuple[str, ...],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
) -> bool:
|
||||||
|
"""
|
||||||
|
Vérifie si un chemin contient un pays instable (ISG ≥ 60).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
chemin (Tuple[str, ...]): Un chemin validé selon les critères antérieurs.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si le chemin contient un pays instable, False sinon.
|
||||||
|
"""
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
u, v = chemin[i], chemin[i + 1]
|
u, v = chemin[i], chemin[i + 1]
|
||||||
|
|
||||||
@ -120,8 +224,26 @@ def verifier_critere_isg(G, chemin, niveaux):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, niveaux_speciaux):
|
def extraire_liens_filtres(
|
||||||
"""Extrait les liens des chemins en respectant les niveaux"""
|
chemins: List[Tuple[str, ...]],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
niveau_arrivee: int,
|
||||||
|
niveaux_speciaux: List[int]
|
||||||
|
) -> Set[Tuple[str, str]]:
|
||||||
|
"""
|
||||||
|
Extrait les liens des chemins en respectant les niveaux.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
chemins (List[Tuple[str, ...]]): Liste initiale des chemins validés.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
niveau_arrivee (int): Le niveau d'arrivée sélectionné.
|
||||||
|
niveaux_speciaux (List[int]): Les niveaux spéciaux à inclure dans l'extraction.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Set[Tuple[str, str]]: Ensemble des paires de nœuds liés après filtrage.
|
||||||
|
"""
|
||||||
liens = set()
|
liens = set()
|
||||||
for chemin in chemins:
|
for chemin in chemins:
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
@ -135,9 +257,40 @@ def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, nive
|
|||||||
liens.add((u, v))
|
liens.add((u, v))
|
||||||
return liens
|
return liens
|
||||||
|
|
||||||
def filtrer_chemins_par_criteres(G, chemins, niveaux, niveau_depart, niveau_arrivee,
|
def filtrer_chemins_par_criteres(
|
||||||
filtrer_ics, filtrer_ivc, filtrer_ihh, ihh_type, filtrer_isg, logique_filtrage):
|
G: nx.DiGraph,
|
||||||
"""Filtre les chemins selon les critères de vulnérabilité"""
|
chemins: List[Tuple[str, ...]],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
niveau_arrivee: int,
|
||||||
|
filtrer_ics: bool,
|
||||||
|
filtrer_ivc: bool,
|
||||||
|
filtrer_ihh: bool,
|
||||||
|
ihh_type: str,
|
||||||
|
filtrer_isg: bool,
|
||||||
|
logique_filtrage: str,
|
||||||
|
) -> Tuple[Set[Tuple[str, str]], Set[Tuple[str, ...]]]:
|
||||||
|
"""
|
||||||
|
Filtre les chemins selon les critères de vulnérabilité.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
chemins (List[Tuple[str, ...]]): Liste initiale des chemins validés.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
niveau_arrivee (int): Le niveau d'arrivée sélectionné.
|
||||||
|
filtrer_ics (bool): Si le filtre ICS doit être appliqué.
|
||||||
|
filtrer_ivc (bool): Si le filtre IVC doit être appliqué.
|
||||||
|
filtrer_ihh (bool): Si le filtre IHH doit être appliqué.
|
||||||
|
ihh_type (str): Le type d'application pour les IHH (pays ou acteur).
|
||||||
|
filtrer_isg (bool): Si le filtre ISG doit être appliqué.
|
||||||
|
logique_filtrage (str): La logique de filtrage (ET OU).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[Set[Tuple[str, str]], Set[Tuple[str, ...]]]: Un tuple contenant :
|
||||||
|
- Les liens validés
|
||||||
|
- Les chemins filtrés finaux
|
||||||
|
"""
|
||||||
niveaux_speciaux = [1000, 1001, 1002, 1010, 1011, 1012]
|
niveaux_speciaux = [1000, 1001, 1002, 1010, 1011, 1012]
|
||||||
|
|
||||||
# Extraction des liens sans filtrage
|
# Extraction des liens sans filtrage
|
||||||
@ -176,8 +329,18 @@ def filtrer_chemins_par_criteres(G, chemins, niveaux, niveau_depart, niveau_arri
|
|||||||
|
|
||||||
return liens_filtres, chemins_filtres
|
return liens_filtres, chemins_filtres
|
||||||
|
|
||||||
def couleur_ics(p):
|
def couleur_ics(
|
||||||
"""Retourne la couleur en fonction du niveau de criticité"""
|
p: float
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Retourne la couleur en fonction du niveau de criticité.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
p (float): Valeur de criticité (entre 0 et 1).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Couleur représentative du niveau de criticité.
|
||||||
|
"""
|
||||||
if p <= 0.33:
|
if p <= 0.33:
|
||||||
return "darkgreen"
|
return "darkgreen"
|
||||||
elif p <= 0.66:
|
elif p <= 0.66:
|
||||||
@ -185,8 +348,22 @@ def couleur_ics(p):
|
|||||||
else:
|
else:
|
||||||
return "darkred"
|
return "darkred"
|
||||||
|
|
||||||
def edge_info(G, u, v):
|
def edge_info(
|
||||||
"""Génère l'info-bulle pour un lien"""
|
G: nx.DiGraph,
|
||||||
|
u: str,
|
||||||
|
v: str
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
Génère l'info-bulle pour un lien.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
u (str): L'ID du premier nœud.
|
||||||
|
v (str): L'ID du second nœud.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Texte à afficher dans l'info-bulle pour le lien spécifié.
|
||||||
|
"""
|
||||||
# Liste d'attributs à exclure des infobulles des liens
|
# Liste d'attributs à exclure des infobulles des liens
|
||||||
attributs_exclus = ["poids", "color", "fontcolor"]
|
attributs_exclus = ["poids", "color", "fontcolor"]
|
||||||
|
|
||||||
@ -198,8 +375,30 @@ def edge_info(G, u, v):
|
|||||||
base = [f"{k}: {v}" for k, v in data.items() if k not in attributs_exclus]
|
base = [f"{k}: {v}" for k, v in data.items() if k not in attributs_exclus]
|
||||||
return f"{str(_('pages.analyse.sankey.relation'))} : {u} → {v}<br>" + "<br>".join(base)
|
return f"{str(_('pages.analyse.sankey.relation'))} : {u} → {v}<br>" + "<br>".join(base)
|
||||||
|
|
||||||
def preparer_donnees_sankey(G, liens_chemins, niveaux, chemins):
|
def preparer_donnees_sankey(
|
||||||
"""Prépare les données pour le graphique Sankey"""
|
G: nx.DiGraph,
|
||||||
|
liens_chemins: Set[Tuple[str, str]],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
chemins: List[Tuple[str, ...]]
|
||||||
|
) -> Tuple[pd.DataFrame, List[str], List[List[str]], List[str], Dict[str, int]]:
|
||||||
|
"""
|
||||||
|
Prépare les données pour le graphique Sankey.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX contenant les données des produits.
|
||||||
|
liens_chemins (Set[Tuple[str, str]]): Ensemble des paires de nœuds liés.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
chemins (List[Tuple[str, ...]]): Liste initiale des chemins validés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[pd.DataFrame, List[str], List[List[str]], List[str], Dict[str, int]]:
|
||||||
|
Un tuple contenant :
|
||||||
|
- Le DataFrame lié aux chemins filtrés
|
||||||
|
- La liste triée et ordonnée des nœuds
|
||||||
|
- Les listes de données personnalisées pour les nœuds
|
||||||
|
- Les donnnées personnalisées pour les liens
|
||||||
|
- Le dictionnaire associant chaque nœud à son index
|
||||||
|
"""
|
||||||
# Liste d'attributs à exclure des infobulles des nœuds
|
# Liste d'attributs à exclure des infobulles des nœuds
|
||||||
node_attributs_exclus = ["fillcolor", "niveau"]
|
node_attributs_exclus = ["fillcolor", "niveau"]
|
||||||
|
|
||||||
@ -251,8 +450,30 @@ def preparer_donnees_sankey(G, liens_chemins, niveaux, chemins):
|
|||||||
|
|
||||||
return df_liens, sorted_nodes, customdata, link_customdata, node_indices
|
return df_liens, sorted_nodes, customdata, link_customdata, node_indices
|
||||||
|
|
||||||
def creer_graphique_sankey(G, niveaux, df_liens, sorted_nodes, customdata, link_customdata, node_indices):
|
def creer_graphique_sankey(
|
||||||
"""Crée et retourne le graphique Sankey"""
|
G: nx.DiGraph,
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
df_liens: pd.DataFrame,
|
||||||
|
sorted_nodes: List[str],
|
||||||
|
customdata: List[str],
|
||||||
|
link_customdata: List[str],
|
||||||
|
node_indices: Dict[str, int],
|
||||||
|
) -> go.Figure:
|
||||||
|
"""
|
||||||
|
Crée et retourne le graphique Sankey.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
df_liens (pd.DataFrame): Données du DataFrame lié aux chemins filtrés.
|
||||||
|
sorted_nodes (List[str]): Liste triée et ordonnée des nœuds.
|
||||||
|
customdata (List[str]): Listes de données personnalisées pour les nœuds.
|
||||||
|
link_customdata (List[str]): Données personnalisées pour les liens.
|
||||||
|
node_indices (Dict[str, int]): Dictionnaire associant chaque nœud à son index.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
go.Figure: Le graphique Sankey final.
|
||||||
|
"""
|
||||||
sources = df_liens["source"].map(node_indices).tolist()
|
sources = df_liens["source"].map(node_indices).tolist()
|
||||||
targets = df_liens["target"].map(node_indices).tolist()
|
targets = df_liens["target"].map(node_indices).tolist()
|
||||||
values = df_liens["value"].tolist()
|
values = df_liens["value"].tolist()
|
||||||
@ -291,8 +512,20 @@ def creer_graphique_sankey(G, niveaux, df_liens, sorted_nodes, customdata, link_
|
|||||||
|
|
||||||
return fig
|
return fig
|
||||||
|
|
||||||
def exporter_graphe_filtre(G, liens_chemins):
|
def exporter_graphe_filtre(
|
||||||
"""Gère l'export du graphe filtré au format DOT"""
|
G: nx.DiGraph,
|
||||||
|
liens_chemins: Set[Tuple[str, str]]
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Gère l'export du graphe filtré au format DOT.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
liens_chemins (Set[Tuple[str, str]]): Ensemble des paires de nœuds liés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
if not st.session_state.get("logged_in", False) or not liens_chemins:
|
if not st.session_state.get("logged_in", False) or not liens_chemins:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -321,13 +554,30 @@ def exporter_graphe_filtre(G, liens_chemins):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def afficher_sankey(
|
def afficher_sankey(
|
||||||
G,
|
G: nx.DiGraph,
|
||||||
niveau_depart, niveau_arrivee,
|
niveau_depart: int, niveau_arrivee: int,
|
||||||
noeuds_depart=None, noeuds_arrivee=None,
|
noeuds_depart: Optional[List[str]] = None, noeuds_arrivee: Optional[List[str]] = None,
|
||||||
minerais=None,
|
minerais=None,
|
||||||
filtrer_ics=False, filtrer_ivc=False,
|
filtrer_ics: bool = False, filtrer_ivc: bool = False,
|
||||||
filtrer_ihh=False, ihh_type="Pays", filtrer_isg=False,
|
filtrer_ihh: bool = False, ihh_type: str = "Pays", filtrer_isg: bool = False,
|
||||||
logique_filtrage="OU"):
|
logique_filtrage: str = "OU") -> None:
|
||||||
|
"""
|
||||||
|
Fonction principale qui s'occupe de la création et de l'affichage du graphique Sankey.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G: Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveau_depart, niveau_arrivee: Les niveaux initiaux pour le filtrage.
|
||||||
|
noeuds_depart, noeuds_arrivee: Les nœuds initiaux pour le filtrage.
|
||||||
|
minerais: La liste des minerais à inclure dans le filtrage.
|
||||||
|
filtrer_ics, filtrer_ivc: Les booléens pour le filtrage ICS et IVC.
|
||||||
|
filtrer_ihh: Le booléen pour le filtrage IHH.
|
||||||
|
ihh_type: Le type d'application pour les IHH (Pays ou Acteur).
|
||||||
|
filtrer_isg: Le booléen pour le filtrage ISG.
|
||||||
|
logique_filtrage: La logique de filtrage à appliquer (ET OU).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
go.Figure
|
||||||
|
"""
|
||||||
|
|
||||||
# Étape 1 : Extraction des niveaux des nœuds
|
# Étape 1 : Extraction des niveaux des nœuds
|
||||||
niveaux = extraire_niveaux(G)
|
niveaux = extraire_niveaux(G)
|
||||||
|
|||||||
@ -1,2 +1,4 @@
|
|||||||
# __init__.py – app/fiches
|
# __init__.py – app/fiches
|
||||||
from .interface import interface_fiches
|
from .interface import interface_fiches
|
||||||
|
|
||||||
|
__all__ = ["interface_fiches"]
|
||||||
|
|||||||
@ -1,24 +1,47 @@
|
|||||||
|
"""
|
||||||
|
Module de génération des fiches pour l'application.
|
||||||
|
|
||||||
|
Fonctions principales :
|
||||||
|
1. `remplacer_latex_par_mathml`
|
||||||
|
2. `markdown_to_html_rgaa`
|
||||||
|
3. `rendu_html`
|
||||||
|
4. `generer_fiche`
|
||||||
|
|
||||||
|
Toutes ces fonctions gèrent la conversion et le rendu de contenu Markdown
|
||||||
|
vers du HTML structuré avec des mathématiques, respectant les règles RGAA.
|
||||||
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
import markdown
|
import markdown
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
from latex2mathml.converter import convert as latex_to_mathml
|
from latex2mathml.converter import convert as latex_to_mathml
|
||||||
from .utils.fiche_utils import render_fiche_markdown
|
|
||||||
import pypandoc
|
import pypandoc
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
|
|
||||||
from .utils.dynamic import (
|
from app.fiches.utils import (
|
||||||
build_dynamic_sections,
|
build_dynamic_sections,
|
||||||
build_ivc_sections,
|
build_ivc_sections,
|
||||||
build_ihh_sections,
|
build_ihh_sections,
|
||||||
build_isg_sections,
|
build_isg_sections,
|
||||||
build_production_sections,
|
build_production_sections,
|
||||||
build_minerai_sections
|
build_minerai_sections,
|
||||||
|
render_fiche_markdown
|
||||||
)
|
)
|
||||||
|
|
||||||
# === Fonctions de transformation ===
|
# === Fonctions de transformation ===
|
||||||
def remplacer_latex_par_mathml(markdown_text):
|
def remplacer_latex_par_mathml(markdown_text: str) -> str:
|
||||||
|
"""
|
||||||
|
Remplace les formules LaTeX par des blocs MathML.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
markdown_text (str): Texte Markdown contenant du LaTeX.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Le même texte avec les formules LaTeX converties en MathML.
|
||||||
|
"""
|
||||||
|
|
||||||
def remplacer_bloc_display(match):
|
def remplacer_bloc_display(match):
|
||||||
formule_latex = match.group(1).strip()
|
formule_latex = match.group(1).strip()
|
||||||
try:
|
try:
|
||||||
@ -39,7 +62,17 @@ def remplacer_latex_par_mathml(markdown_text):
|
|||||||
markdown_text = re.sub(r"(?<!\$)\$(.+?)\$(?!\$)", remplacer_bloc_inline, markdown_text, flags=re.DOTALL)
|
markdown_text = re.sub(r"(?<!\$)\$(.+?)\$(?!\$)", remplacer_bloc_inline, markdown_text, flags=re.DOTALL)
|
||||||
return markdown_text
|
return markdown_text
|
||||||
|
|
||||||
def markdown_to_html_rgaa(markdown_text, caption_text=None):
|
def markdown_to_html_rgaa(markdown_text: str, caption_text: str|None) -> str:
|
||||||
|
"""
|
||||||
|
Convertit un texte Markdown en HTML structuré accessible.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
markdown_text (str): Texte Markdown à convertir.
|
||||||
|
caption_text (str, optional): Titre du tableau si applicable.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Le HTML structuré avec des attributs de contraintes ARIA.
|
||||||
|
"""
|
||||||
html = markdown.markdown(markdown_text, extensions=['tables'])
|
html = markdown.markdown(markdown_text, extensions=['tables'])
|
||||||
soup = BeautifulSoup(html, "html.parser")
|
soup = BeautifulSoup(html, "html.parser")
|
||||||
for i, table in enumerate(soup.find_all("table"), start=1):
|
for i, table in enumerate(soup.find_all("table"), start=1):
|
||||||
@ -53,7 +86,16 @@ def markdown_to_html_rgaa(markdown_text, caption_text=None):
|
|||||||
th["scope"] = "col"
|
th["scope"] = "col"
|
||||||
return str(soup)
|
return str(soup)
|
||||||
|
|
||||||
def rendu_html(contenu_md):
|
def rendu_html(contenu_md: str) -> list[str]:
|
||||||
|
"""
|
||||||
|
Rend le contenu Markdown en HTML avec une structure spécifique.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
contenu_md (str): Texte Markdown à formater.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: Liste d'étapes de construction du HTML final.
|
||||||
|
"""
|
||||||
lignes = contenu_md.split('\n')
|
lignes = contenu_md.split('\n')
|
||||||
sections_n1 = []
|
sections_n1 = []
|
||||||
section_n1_actuelle = {"titre": None, "intro": [], "sections_n2": {}}
|
section_n1_actuelle = {"titre": None, "intro": [], "sections_n2": {}}
|
||||||
@ -84,7 +126,7 @@ def rendu_html(contenu_md):
|
|||||||
html_output.append(f"<h2>{bloc['titre']}</h2>")
|
html_output.append(f"<h2>{bloc['titre']}</h2>")
|
||||||
if bloc["intro"]:
|
if bloc["intro"]:
|
||||||
intro_md = remplacer_latex_par_mathml("\n".join(bloc["intro"]))
|
intro_md = remplacer_latex_par_mathml("\n".join(bloc["intro"]))
|
||||||
html_intro = markdown_to_html_rgaa(intro_md)
|
html_intro = markdown_to_html_rgaa(intro_md, None)
|
||||||
html_output.append(html_intro)
|
html_output.append(html_intro)
|
||||||
for sous_titre, contenu in bloc["sections_n2"].items():
|
for sous_titre, contenu in bloc["sections_n2"].items():
|
||||||
contenu_md = remplacer_latex_par_mathml("\n".join(contenu))
|
contenu_md = remplacer_latex_par_mathml("\n".join(contenu))
|
||||||
@ -95,7 +137,25 @@ def rendu_html(contenu_md):
|
|||||||
|
|
||||||
return html_output
|
return html_output
|
||||||
|
|
||||||
def generer_fiche(md_source, dossier, nom_fichier, seuils):
|
def generer_fiche(md_source: str, dossier: str, nom_fichier: str, seuils: dict) -> str:
|
||||||
|
"""
|
||||||
|
Génère un document PDF et son HTML correspondant pour une fiche.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
md_source (str): Texte Markdown source contenant la fiche.
|
||||||
|
dossier (str): Dossier/rubrique de destination.
|
||||||
|
nom_fichier (str): Nom du fichier (sans extension).
|
||||||
|
seuils (dict): Valeurs de seuils pour l'analyse.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Chemin absolu vers le fichier HTML généré.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction :
|
||||||
|
- Convertit et formate les données Markdown.
|
||||||
|
- Génère un document PDF sous format XeLaTeX.
|
||||||
|
- Crée un document HTML accessible avec des mathématiques.
|
||||||
|
"""
|
||||||
front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source)
|
front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md_source)
|
||||||
context = yaml.safe_load(front_match.group(1)) if front_match else {}
|
context = yaml.safe_load(front_match.group(1)) if front_match else {}
|
||||||
|
|
||||||
|
|||||||
@ -4,20 +4,36 @@ import requests
|
|||||||
import os
|
import os
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
|
|
||||||
from .utils.tickets.display import afficher_tickets_par_fiche
|
|
||||||
from .utils.tickets.creation import formulaire_creation_ticket_dynamique
|
|
||||||
from .utils.tickets.core import rechercher_tickets_gitea
|
|
||||||
|
|
||||||
from config import GITEA_TOKEN, GITEA_URL, ORGANISATION, DEPOT_FICHES, ENV, FICHES_CRITICITE
|
from config import GITEA_TOKEN, GITEA_URL, ORGANISATION, DEPOT_FICHES, ENV, FICHES_CRITICITE
|
||||||
|
|
||||||
from utils.gitea import charger_arborescence_fiches
|
from utils.gitea import charger_arborescence_fiches
|
||||||
|
|
||||||
from .utils.fiche_utils import load_seuils, doit_regenerer_fiche
|
|
||||||
|
|
||||||
from .generer import generer_fiche
|
|
||||||
from utils.widgets import html_expander
|
from utils.widgets import html_expander
|
||||||
|
|
||||||
def interface_fiches():
|
from app.fiches.utils import (
|
||||||
|
afficher_tickets_par_fiche,
|
||||||
|
formulaire_creation_ticket_dynamique,
|
||||||
|
rechercher_tickets_gitea,
|
||||||
|
load_seuils,
|
||||||
|
doit_regenerer_fiche
|
||||||
|
)
|
||||||
|
from app.fiches.generer import generer_fiche
|
||||||
|
|
||||||
|
def interface_fiches() -> None:
|
||||||
|
"""
|
||||||
|
Affiche l'interface utilisateur des fiches.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
Aucun
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
Cette fonction initialise l'interface utilisateur qui permet aux utilisateurs d'afficher,
|
||||||
|
visualiser et interagir avec les fiches. Elle gère également :
|
||||||
|
- Le chargement de l'arborescence des fiches depuis Gitea.
|
||||||
|
- La navigation entre différentes catégories de fiches.
|
||||||
|
- L'affichage des tickets associés aux fiches.
|
||||||
|
- Le téléchargement des PDF (si disponible).
|
||||||
|
"""
|
||||||
st.markdown(f"# {str(_('pages.fiches.title'))}")
|
st.markdown(f"# {str(_('pages.fiches.title'))}")
|
||||||
html_expander(f"{str(_('pages.fiches.help'))}", content="\n".join(_("pages.fiches.help_content")), open_by_default=False, details_class="details_introduction")
|
html_expander(f"{str(_('pages.fiches.help'))}", content="\n".join(_("pages.fiches.help_content")), open_by_default=False, details_class="details_introduction")
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
|
|||||||
31
app/fiches/utils/__init__.py
Normal file
31
app/fiches/utils/__init__.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from .tickets.display import afficher_tickets_par_fiche
|
||||||
|
from .tickets.creation import formulaire_creation_ticket_dynamique
|
||||||
|
from .tickets.core import rechercher_tickets_gitea
|
||||||
|
from .fiche_utils import (
|
||||||
|
load_seuils,
|
||||||
|
doit_regenerer_fiche
|
||||||
|
)
|
||||||
|
from .dynamic import (
|
||||||
|
build_dynamic_sections,
|
||||||
|
build_ivc_sections,
|
||||||
|
build_ihh_sections,
|
||||||
|
build_isg_sections,
|
||||||
|
build_production_sections,
|
||||||
|
build_minerai_sections
|
||||||
|
)
|
||||||
|
from .fiche_utils import render_fiche_markdown
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"afficher_tickets_par_fiche",
|
||||||
|
"formulaire_creation_ticket_dynamique",
|
||||||
|
"rechercher_tickets_gitea",
|
||||||
|
"load_seuils",
|
||||||
|
"doit_regenerer_fiche",
|
||||||
|
"build_dynamic_sections",
|
||||||
|
"build_ivc_sections",
|
||||||
|
"build_ihh_sections",
|
||||||
|
"build_isg_sections",
|
||||||
|
"build_production_sections",
|
||||||
|
"build_minerai_sections",
|
||||||
|
"render_fiche_markdown"
|
||||||
|
]
|
||||||
@ -7,7 +7,22 @@ import streamlit as st
|
|||||||
from config import FICHES_CRITICITE
|
from config import FICHES_CRITICITE
|
||||||
|
|
||||||
def build_production_sections(md: str) -> str:
|
def build_production_sections(md: str) -> str:
|
||||||
|
"""
|
||||||
|
Procédure pour construire et remplacer les sections des fiches de production.
|
||||||
|
|
||||||
|
Cette fonction permet d'extraire les données du markdown, organiser
|
||||||
|
les informations sur les pays d'implantation et acteurs, puis générer
|
||||||
|
un tableau structuré dans l'intervention. Le code prend en charge
|
||||||
|
deux types de fiches : fabrication et assemblage.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
md (str): Fichier Markdown à traiter contenant la structure YAML des sections.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Markdown modifié avec les tableaux construits selon le type de fiche.
|
||||||
|
"""
|
||||||
schema = None
|
schema = None
|
||||||
|
type_fiche = None
|
||||||
front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md)
|
front_match = re.match(r"(?s)^---\n(.*?)\n---\n", md)
|
||||||
if front_match:
|
if front_match:
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -1,14 +1,33 @@
|
|||||||
# pastille.py
|
# pastille.py
|
||||||
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
PASTILLE_ICONS = {
|
PASTILLE_ICONS = {
|
||||||
"vert": "✅",
|
"vert": "✅",
|
||||||
"orange": "🔶",
|
"orange": "🔶",
|
||||||
"rouge": "🔴"
|
"rouge": "🔴"
|
||||||
}
|
}
|
||||||
|
|
||||||
def pastille(indice: str, valeur: Any, seuils: dict = None) -> str:
|
def pastille(indice: str, valeur: str, seuils: dict) -> str:
|
||||||
|
"""Renvoie l'icône Unicode correspondante à la pastille en fonction de sa valeur et des seuils.
|
||||||
|
|
||||||
|
La pastille prend une couleur (vert, orange ou rouge) selon la valeur
|
||||||
|
de l'indicateur par rapport aux seuils définis. Les icônes sont définies
|
||||||
|
comme des emojis Unicode pour faciliter leur affichage dans les interfaces
|
||||||
|
interactives comme Streamlit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
indice (str): Clé permettant d'accéder au seuil spécifique.
|
||||||
|
Exemples de valeurs possibles : "criticite", "confort".
|
||||||
|
valeur (Any): Valeur numérique à comparer aux seuils.
|
||||||
|
Généralement une float, mais peut être convertie automatiquement
|
||||||
|
en nombre si possible.
|
||||||
|
seuils (dict, optional): Dictionnaire des seuils pour chaque indicateur.
|
||||||
|
Si None, les valeurs par défaut sont utilisées selon l'état de session
|
||||||
|
Stocké dans Streamlit.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: Une icône Unicode correspondante à la pastille. Si aucune icône n'est définie,
|
||||||
|
une chaîne vide est renvoyée.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
seuils = seuils or st.session_state.get("seuils", {})
|
seuils = seuils or st.session_state.get("seuils", {})
|
||||||
|
|||||||
@ -12,22 +12,35 @@ Usage :
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
import os
|
||||||
import frontmatter, yaml, jinja2, re, pathlib
|
import frontmatter, yaml, jinja2, re, pathlib
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
import os
|
|
||||||
from utils.gitea import recuperer_date_dernier_commit
|
from utils.gitea import recuperer_date_dernier_commit
|
||||||
|
|
||||||
|
|
||||||
def load_seuils(path: str | pathlib.Path = "config/indices_seuils.yaml") -> Dict:
|
def load_seuils(path: str | pathlib.Path = "config/indices_seuils.yaml") -> Dict:
|
||||||
"""Charge le fichier YAML des seuils et renvoie le dict 'seuils'."""
|
"""Charge le fichier YAML des seuils et renvoie le dict 'seuils'.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
path (str | pathlib.Path, optional): Chemin vers le fichier des seuils. Defaults to "config/indices_seuils.yaml".
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Dictionnaire contenant les seuils.
|
||||||
|
"""
|
||||||
data = yaml.safe_load(pathlib.Path(path).read_text(encoding="utf-8"))
|
data = yaml.safe_load(pathlib.Path(path).read_text(encoding="utf-8"))
|
||||||
return data.get("seuils", {})
|
return data.get("seuils", {})
|
||||||
|
|
||||||
|
|
||||||
def _migrate_metadata(meta: Dict) -> Dict:
|
def _migrate_metadata(meta: Dict) -> Dict:
|
||||||
"""Normalise les clés YAML (ex : sheet_type → type_fiche)."""
|
"""Normalise les clés YAML (ex : sheet_type → type_fiche).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
meta (Dict): Métadonnées à normaliser.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict: Métadonnées normalisées.
|
||||||
|
"""
|
||||||
keymap = {
|
keymap = {
|
||||||
"sheet_type": "type_fiche",
|
"sheet_type": "type_fiche",
|
||||||
"indice_code": "indice_court", # si besoin
|
"indice_code": "indice_court", # si besoin
|
||||||
@ -37,12 +50,24 @@ def _migrate_metadata(meta: Dict) -> Dict:
|
|||||||
meta[new] = meta.pop(old)
|
meta[new] = meta.pop(old)
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
|
def render_fiche_markdown(
|
||||||
|
md_text: str,
|
||||||
|
seuils: Dict,
|
||||||
|
license_path: str = "assets/licence.md"
|
||||||
|
) -> str:
|
||||||
|
"""Renvoie la fiche rendue (Markdown) avec les placeholders remplacés et le tableau de version.
|
||||||
|
|
||||||
def render_fiche_markdown(md_text: str, seuils: Dict, license_path: str = "assets/licence.md") -> str:
|
Args:
|
||||||
"""Renvoie la fiche rendue (Markdown) :
|
md_text (str): Contenu Markdown brut.
|
||||||
– placeholders Jinja2 remplacés ({{ … }})
|
seuils (Dict): Tableau des versions.
|
||||||
– table seuils injectée via dict 'seuils'.
|
license_path (str, optional): Chemin vers le fichier de licence. Defaults to "assets/licence.md".
|
||||||
- licence ajoutée après le tableau de version et avant le premier titre de niveau 2
|
|
||||||
|
Returns:
|
||||||
|
str: Fiche Markdown rendue avec les placeholders remplacés et la table de version.
|
||||||
|
|
||||||
|
Note:
|
||||||
|
- Les licences sont ajoutées après le tableau de version.
|
||||||
|
- Les titres de niveau 2 doivent être présents pour l'insertion automatique de licence.
|
||||||
"""
|
"""
|
||||||
post = frontmatter.loads(md_text)
|
post = frontmatter.loads(md_text)
|
||||||
meta = _migrate_metadata(dict(post.metadata))
|
meta = _migrate_metadata(dict(post.metadata))
|
||||||
@ -81,19 +106,51 @@ def render_fiche_markdown(md_text: str, seuils: Dict, license_path: str = "asset
|
|||||||
rendered_body = f"{rendered_body}\n\n{license_content}"
|
rendered_body = f"{rendered_body}\n\n{license_content}"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# En cas d'erreur lors de la lecture du fichier de licence, continuer sans l'ajouter
|
# En cas d'erreur lors de la lecture du fichier de licence, continuer sans l'ajouter
|
||||||
|
import streamlit as st
|
||||||
|
st.error(e)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return rendered_body
|
return rendered_body
|
||||||
|
|
||||||
|
|
||||||
def fichier_plus_recent(chemin_fichier, reference):
|
def fichier_plus_recent(
|
||||||
|
chemin_fichier: str|None,
|
||||||
|
reference: datetime
|
||||||
|
) -> bool:
|
||||||
|
"""Vérifie si un fichier est plus récent que la référence donnée.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
chemin_fichier (str): Chemin vers le fichier à vérifier.
|
||||||
|
reference (datetime): Référence temporelle de comparaison.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si le fichier est plus récent, False sinon.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
modif = datetime.fromtimestamp(os.path.getmtime(chemin_fichier), tz=timezone.utc)
|
modif = datetime.fromtimestamp(os.path.getmtime(chemin_fichier), tz=timezone.utc)
|
||||||
return modif > reference
|
return modif > reference
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def doit_regenerer_fiche(html_path, fiche_type, fiche_choisie, commit_url, fichiers_criticite):
|
def doit_regenerer_fiche(
|
||||||
|
html_path: str,
|
||||||
|
fiche_type: str,
|
||||||
|
fiche_choisie: str,
|
||||||
|
commit_url: str,
|
||||||
|
fichiers_criticite: Dict[str, str]
|
||||||
|
) -> bool:
|
||||||
|
"""Détermine si une fiche doit être regénérée.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
html_path (str): Chemin vers le fichier HTML.
|
||||||
|
fiche_type (str): Type de la fiche.
|
||||||
|
fiche_choisie (str): Nom choisi pour la fiche.
|
||||||
|
commit_url (str): URL du dernier commit.
|
||||||
|
fichiers_criticite (Dict[str, str]): Dictionnaire des fichiers critiques.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True si la fiche doit être regénérée, False sinon.
|
||||||
|
"""
|
||||||
if not os.path.exists(html_path):
|
if not os.path.exists(html_path):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from typing import List, Optional, Tuple, Dict, Set
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
@ -23,8 +24,20 @@ niveau_labels = {
|
|||||||
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
||||||
|
|
||||||
|
|
||||||
def preparer_graphe(G):
|
def preparer_graphe(
|
||||||
"""Nettoie et prépare le graphe pour l'analyse."""
|
G: nx.DiGraph,
|
||||||
|
) -> Tuple[nx.DiGraph, Dict[str, int]]:
|
||||||
|
"""
|
||||||
|
Nettoie et prépare le graphe pour l'analyse.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[nx.DiGraph, Dict[str, int]]: Un tuple contenant :
|
||||||
|
- Le graphe NetworkX proprement configuré
|
||||||
|
- Un dictionnaire des niveaux associés aux nœuds
|
||||||
|
"""
|
||||||
niveaux_temp = {
|
niveaux_temp = {
|
||||||
node: int(str(attrs.get("niveau")).strip('"'))
|
node: int(str(attrs.get("niveau")).strip('"'))
|
||||||
for node, attrs in G.nodes(data=True)
|
for node, attrs in G.nodes(data=True)
|
||||||
@ -36,8 +49,19 @@ def preparer_graphe(G):
|
|||||||
return G, niveaux_temp
|
return G, niveaux_temp
|
||||||
|
|
||||||
|
|
||||||
def selectionner_minerais(G):
|
def selectionner_minerais(
|
||||||
"""Interface pour sélectionner les minerais si nécessaire."""
|
G: nx.DiGraph,
|
||||||
|
) -> Optional[List[str]]:
|
||||||
|
"""
|
||||||
|
Interface pour sélectionner les minerais si nécessaire.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[List[str]]: La liste des minerais si une sélection a été effectuée,
|
||||||
|
- None sinon
|
||||||
|
"""
|
||||||
minerais_selection = None
|
minerais_selection = None
|
||||||
|
|
||||||
st.markdown(f"## {str(_('pages.ia_nalyse.select_minerals'))}")
|
st.markdown(f"## {str(_('pages.ia_nalyse.select_minerals'))}")
|
||||||
@ -56,8 +80,25 @@ def selectionner_minerais(G):
|
|||||||
return minerais_selection
|
return minerais_selection
|
||||||
|
|
||||||
|
|
||||||
def selectionner_noeuds(G, niveaux_temp, niveau_depart):
|
def selectionner_noeuds(
|
||||||
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée."""
|
G: nx.DiGraph,
|
||||||
|
niveaux_temp: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
) -> Tuple[Optional[List[str]], List[str]]:
|
||||||
|
"""
|
||||||
|
Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveaux_temp (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[Optional[List[str]], List[str]]: Un tuple contenant :
|
||||||
|
- La liste des nœuds de départ si une sélection a été effectuée,
|
||||||
|
- None sinon
|
||||||
|
- La liste des nœuds d'arrivée
|
||||||
|
"""
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
st.markdown(f"## {str(_('pages.ia_nalyse.fine_selection'))}")
|
st.markdown(f"## {str(_('pages.ia_nalyse.fine_selection'))}")
|
||||||
|
|
||||||
@ -72,8 +113,18 @@ def selectionner_noeuds(G, niveaux_temp, niveau_depart):
|
|||||||
|
|
||||||
return noeuds_depart, noeuds_arrivee
|
return noeuds_depart, noeuds_arrivee
|
||||||
|
|
||||||
def extraire_niveaux(G):
|
def extraire_niveaux(
|
||||||
"""Extrait les niveaux des nœuds du graphe"""
|
G: nx.DiGraph,
|
||||||
|
) -> Dict[str, int]:
|
||||||
|
"""
|
||||||
|
Extrait les niveaux des nœuds du graphe.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dict[str, int]: Un dictionnaire associant chaque nœud à son niveau.
|
||||||
|
"""
|
||||||
niveaux = {}
|
niveaux = {}
|
||||||
for node, attrs in G.nodes(data=True):
|
for node, attrs in G.nodes(data=True):
|
||||||
niveau_str = attrs.get("niveau")
|
niveau_str = attrs.get("niveau")
|
||||||
@ -81,8 +132,28 @@ def extraire_niveaux(G):
|
|||||||
niveaux[node] = int(str(niveau_str).strip('"'))
|
niveaux[node] = int(str(niveau_str).strip('"'))
|
||||||
return niveaux
|
return niveaux
|
||||||
|
|
||||||
def extraire_chemins_selon_criteres(G, niveaux, niveau_depart, noeuds_depart, noeuds_arrivee, minerais):
|
def extraire_chemins_selon_criteres(
|
||||||
"""Extrait les chemins selon les critères spécifiés"""
|
G: nx.DiGraph,
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
noeuds_depart: Optional[List[str]],
|
||||||
|
noeuds_arrivee: Optional[List[str]],
|
||||||
|
minerais: Optional[List[str]],
|
||||||
|
) -> List[Tuple[str, ...]]:
|
||||||
|
"""
|
||||||
|
Extrait les chemins selon les critères spécifiés.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
noeuds_depart (Optional[List[str]]): Les nœuds de départ si sélectionnés.
|
||||||
|
noeuds_arrivee (Optional[List[str]]): Les nœuds d'arrivée si sélectionnés.
|
||||||
|
minerais (Optional[List[str]]): Les minerais si sélectionnés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[Tuple[str, ...]]: Liste des chemins valides selon les critères spécifiés.
|
||||||
|
"""
|
||||||
chemins = []
|
chemins = []
|
||||||
if noeuds_depart and noeuds_arrivee:
|
if noeuds_depart and noeuds_arrivee:
|
||||||
for nd in noeuds_depart:
|
for nd in noeuds_depart:
|
||||||
@ -105,8 +176,21 @@ def extraire_chemins_selon_criteres(G, niveaux, niveau_depart, noeuds_depart, no
|
|||||||
|
|
||||||
return chemins
|
return chemins
|
||||||
|
|
||||||
def exporter_graphe_filtre(G, liens_chemins):
|
def exporter_graphe_filtre(
|
||||||
"""Gère l'export du graphe filtré au format DOT"""
|
G: nx.DiGraph,
|
||||||
|
liens_chemins: Set[Tuple[str, str]],
|
||||||
|
) -> nx.DiGraph|None:
|
||||||
|
"""
|
||||||
|
Gère l'export du graphe filtré au format DOT.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
liens_chemins (Set[Tuple[str, str]]): Ensemble des paires de nœuds liés.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
nx.DiGraph: le graphe exporté
|
||||||
|
- Sinon aucun résultat (None)
|
||||||
|
"""
|
||||||
if not st.session_state.get("logged_in", False) or not liens_chemins:
|
if not st.session_state.get("logged_in", False) or not liens_chemins:
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -124,8 +208,26 @@ def exporter_graphe_filtre(G, liens_chemins):
|
|||||||
|
|
||||||
return(G_export)
|
return(G_export)
|
||||||
|
|
||||||
def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, niveaux_speciaux):
|
def extraire_liens_filtres(
|
||||||
"""Extrait les liens des chemins en respectant les niveaux"""
|
chemins: List[Tuple[str, ...]],
|
||||||
|
niveaux: Dict[str, int],
|
||||||
|
niveau_depart: int,
|
||||||
|
niveau_arrivee: int,
|
||||||
|
niveaux_speciaux: List[int]
|
||||||
|
) -> Set[Tuple[str, str]]:
|
||||||
|
"""
|
||||||
|
Extrait les liens des chemins en respectant les niveaux.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
chemins (List[Tuple[str, ...]]): Liste initiale des chemins validés.
|
||||||
|
niveaux (Dict[str, int]): Dictionnaire associant chaque nœud à son niveau.
|
||||||
|
niveau_depart (int): Le niveau de départ sélectionné.
|
||||||
|
niveau_arrivee (int): Le niveau d'arrivée sélectionné.
|
||||||
|
niveaux_speciaux (List[int]): Les niveaux spéciaux à inclure dans l'extraction.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Set[Tuple[str, str]]: Ensemble des paires de nœuds liés après filtrage.
|
||||||
|
"""
|
||||||
liens = set()
|
liens = set()
|
||||||
for chemin in chemins:
|
for chemin in chemins:
|
||||||
for i in range(len(chemin) - 1):
|
for i in range(len(chemin) - 1):
|
||||||
@ -139,15 +241,27 @@ def extraire_liens_filtres(chemins, niveaux, niveau_depart, niveau_arrivee, nive
|
|||||||
liens.add((u, v))
|
liens.add((u, v))
|
||||||
return liens
|
return liens
|
||||||
|
|
||||||
def interface_ia_nalyse(G_temp):
|
def interface_ia_nalyse(
|
||||||
|
G_temp: nx.DiGraph,
|
||||||
|
) -> None:
|
||||||
|
"""
|
||||||
|
Fonction principale qui s'occupe de la création du graphe pour analyse.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G_temp (nx.DiGraph): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
st.markdown(f"# {str(_('pages.ia_nalyse.title'))}")
|
st.markdown(f"# {str(_('pages.ia_nalyse.title'))}")
|
||||||
html_expander(f"{str(_('pages.ia_nalyse.help'))}", content="\n".join(_("pages.ia_nalyse.help_content")), open_by_default=False, details_class="details_introduction")
|
html_expander(f"{str(_('pages.ia_nalyse.help'))}", content="\n".join(_("pages.ia_nalyse.help_content")), open_by_default=False, details_class="details_introduction")
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
|
|
||||||
resultat = statut_utilisateur(st.session_state.username)
|
resultat = statut_utilisateur(st.session_state.username)
|
||||||
st.info(resultat["message"])
|
if resultat:
|
||||||
|
st.info(resultat["message"])
|
||||||
|
|
||||||
if resultat["statut"] is None:
|
if resultat and resultat["statut"] is None:
|
||||||
# Préparation du graphe
|
# Préparation du graphe
|
||||||
G_temp, niveaux_temp = preparer_graphe(G_temp)
|
G_temp, niveaux_temp = preparer_graphe(G_temp)
|
||||||
|
|
||||||
@ -179,7 +293,7 @@ def interface_ia_nalyse(G_temp):
|
|||||||
else:
|
else:
|
||||||
st.info(str(_("pages.ia_nalyse.empty_graph")))
|
st.info(str(_("pages.ia_nalyse.empty_graph")))
|
||||||
|
|
||||||
elif resultat["statut"] == "terminé" and resultat["telechargement"]:
|
elif resultat and resultat["statut"] == "terminé" and resultat["telechargement"]:
|
||||||
if not st.session_state.get("telechargement_confirme"):
|
if not st.session_state.get("telechargement_confirme"):
|
||||||
st.download_button(str(_("buttons.download")), resultat["telechargement"], file_name="analyse.zip", icon=":material/download:")
|
st.download_button(str(_("buttons.download")), resultat["telechargement"], file_name="analyse.zip", icon=":material/download:")
|
||||||
if st.button(str(_("pages.ia_nalyse.confirm_download")), icon=":material/task_alt:"):
|
if st.button(str(_("pages.ia_nalyse.confirm_download")), icon=":material/task_alt:"):
|
||||||
|
|||||||
@ -1,7 +1,21 @@
|
|||||||
import streamlit as st
|
import streamlit as st
|
||||||
|
import networkx as nx
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
|
|
||||||
def ajouter_produit(G):
|
def ajouter_produit(G: nx.DiGraph) -> nx.DiGraph:
|
||||||
|
"""
|
||||||
|
Ajoute un produit personnalisé dans le graphe en cours.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): graphe en cours.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
nx.DiGraph: le graphe avec le nouveau produit
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction ajoute un nouveau produit final temporaire
|
||||||
|
au graphe de référence.
|
||||||
|
"""
|
||||||
st.markdown(f"## {str(_('pages.personnalisation.add_new_product'))}")
|
st.markdown(f"## {str(_('pages.personnalisation.add_new_product'))}")
|
||||||
new_prod = st.text_input(str(_("pages.personnalisation.new_product_name")), key="new_prod")
|
new_prod = st.text_input(str(_("pages.personnalisation.new_product_name")), key="new_prod")
|
||||||
if new_prod:
|
if new_prod:
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
import streamlit as st
|
import streamlit as st
|
||||||
import json
|
import json
|
||||||
from utils.translations import get_translation as _
|
from utils.translations import get_translation as _
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
def importer_exporter_graph(G):
|
def importer_exporter_graph(G: nx.DiGraph) -> nx.DiGraph:
|
||||||
st.markdown(f"## {_('pages.personnalisation.save_restore_config')}")
|
st.markdown(f"## {_('pages.personnalisation.save_restore_config')}")
|
||||||
if st.button(str(_("pages.personnalisation.export_config")), icon=":material/save:"):
|
if st.button(str(_("pages.personnalisation.export_config")), icon=":material/save:"):
|
||||||
nodes = [n for n, d in G.nodes(data=True) if d.get("personnalisation") == "oui"]
|
nodes = [n for n, d in G.nodes(data=True) if d.get("personnalisation") == "oui"]
|
||||||
|
|||||||
@ -1,39 +1,122 @@
|
|||||||
|
from typing import List
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
def get_produits_personnalises(G):
|
def get_produits_personnalises(
|
||||||
"""Récupère la liste des produits personnalisés du niveau 0."""
|
G: nx.DiGraph
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Récupère la liste des produits personnalisés du niveau 0.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX contenant les données des produits.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Liste triée des noms de produits.
|
||||||
|
"""
|
||||||
return sorted([n for n, d in G.nodes(data=True) if d.get("niveau") == "0" and d.get("personnalisation") == "oui"])
|
return sorted([n for n, d in G.nodes(data=True) if d.get("niveau") == "0" and d.get("personnalisation") == "oui"])
|
||||||
|
|
||||||
def supprimer_produit(G, prod):
|
def supprimer_produit(
|
||||||
"""Supprime un produit du graphe."""
|
G: nx.DiGraph,
|
||||||
|
prod: str
|
||||||
|
) -> nx.DiGraph:
|
||||||
|
"""
|
||||||
|
Supprime un produit du graphe et affiche le message de succès.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX sur lequel supprimer le produit.
|
||||||
|
prod (str): Le nom du produit à supprimer.
|
||||||
|
"""
|
||||||
G.remove_node(prod)
|
G.remove_node(prod)
|
||||||
st.success(f"{prod} {str(_('pages.personnalisation.deleted'))}")
|
st.success(f"{prod} {str(_('pages.personnalisation.deleted'))}")
|
||||||
st.session_state.pop("prod_sel", None)
|
st.session_state.pop("prod_sel", None)
|
||||||
return G
|
return G
|
||||||
|
|
||||||
def get_operations_disponibles(G):
|
def get_operations_disponibles(
|
||||||
"""Récupère la liste des opérations d'assemblage disponibles."""
|
G: nx.DiGraph
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Récupère la liste des opérations d'assemblage disponibles.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX contenant les données des produits et des opérations.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Liste triée des noms des opérations.
|
||||||
|
"""
|
||||||
return sorted([
|
return sorted([
|
||||||
n for n, d in G.nodes(data=True)
|
n for n, d in G.nodes(data=True)
|
||||||
if d.get("niveau") == "10"
|
if d.get("niveau") == "10"
|
||||||
and any(G.has_edge(p, n) and G.nodes[p].get("niveau") == "0" for p in G.predecessors(n))
|
and any(G.has_edge(p, n) and G.nodes[p].get("niveau") == "0" for p in G.predecessors(n))
|
||||||
])
|
])
|
||||||
|
|
||||||
def get_operations_actuelles(G, prod):
|
def get_operations_actuelles(
|
||||||
"""Récupère les opérations actuellement liées au produit."""
|
G: nx.DiGraph,
|
||||||
|
prod: str
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Récupère les opérations actuellement liées au produit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits et des opérations.
|
||||||
|
prod (str): Le nom du produit dont récupérer les opérations.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Liste des noms des opérations actuelles.
|
||||||
|
"""
|
||||||
return [succ for succ in G.successors(prod) if G.nodes[succ].get("niveau") == "10"]
|
return [succ for succ in G.successors(prod) if G.nodes[succ].get("niveau") == "10"]
|
||||||
|
|
||||||
def get_composants_niveau1(G):
|
def get_composants_niveau1(
|
||||||
"""Récupère la liste des composants de niveau 1."""
|
G: nx.DiGraph
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Récupère la liste des composants de niveau 1.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits et des composants.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Liste triée des noms des composants.
|
||||||
|
"""
|
||||||
return sorted([n for n, d in G.nodes(data=True) if d.get("niveau") == "1"])
|
return sorted([n for n, d in G.nodes(data=True) if d.get("niveau") == "1"])
|
||||||
|
|
||||||
def get_composants_lies(G, prod):
|
def get_composants_lies(
|
||||||
"""Récupère les composants actuellement liés au produit."""
|
G: nx.DiGraph,
|
||||||
|
prod: str
|
||||||
|
) -> List[str]:
|
||||||
|
"""
|
||||||
|
Récupère les composants actuellement liés au produit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits et des composants.
|
||||||
|
prod (str): Le nom du produit dont récupérer les composants.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
List[str]: Liste des noms des composants liés.
|
||||||
|
"""
|
||||||
return [succ for succ in G.successors(prod) if G.nodes[succ].get("niveau") == "1"]
|
return [succ for succ in G.successors(prod) if G.nodes[succ].get("niveau") == "1"]
|
||||||
|
|
||||||
def mettre_a_jour_operations(G, prod, curr_ops, sel_op):
|
def mettre_a_jour_operations(
|
||||||
"""Met à jour les opérations liées au produit."""
|
G: nx.DiGraph,
|
||||||
|
prod: str,
|
||||||
|
curr_ops: List[str],
|
||||||
|
sel_op: str
|
||||||
|
) -> nx.DiGraph:
|
||||||
|
"""
|
||||||
|
Met à jour les opérations liées au produit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX contenant les données des produits et des opérations.
|
||||||
|
prod (str): Le nom du produit dont mettre à jour les opérations.
|
||||||
|
curr_ops (List[str]): Liste actuelle des opérations liées.
|
||||||
|
sel_op (str): L'opération sélectionnée pour mise à jour.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction crée ou supprime les liens entre le produit et les opérations
|
||||||
|
selon la sélection effectuée par l'utilisateur.
|
||||||
|
"""
|
||||||
|
|
||||||
none_option = str(_("pages.personnalisation.none", "-- Aucune --"))
|
none_option = str(_("pages.personnalisation.none", "-- Aucune --"))
|
||||||
for op in curr_ops:
|
for op in curr_ops:
|
||||||
if sel_op == none_option or op != sel_op:
|
if sel_op == none_option or op != sel_op:
|
||||||
@ -42,7 +125,25 @@ def mettre_a_jour_operations(G, prod, curr_ops, sel_op):
|
|||||||
G.add_edge(prod, sel_op)
|
G.add_edge(prod, sel_op)
|
||||||
return G
|
return G
|
||||||
|
|
||||||
def mettre_a_jour_composants(G, prod, linked, nouveaux):
|
def mettre_a_jour_composants(
|
||||||
|
G: nx.DiGraph,
|
||||||
|
prod: str,
|
||||||
|
linked: List[str],
|
||||||
|
nouveaux: List[str]
|
||||||
|
) -> nx.DiGraph:
|
||||||
|
"""
|
||||||
|
Met à jour les composants liés au produit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (nx.DiGraph): Le graphe NetworkX contenant les données des produits et des composants.
|
||||||
|
prod (str): Le nom du produit dont mettre à jour les composants.
|
||||||
|
linked (List[str]): Liste actuelle des composants liés.
|
||||||
|
nouveaux (List[str]): Nouvelle liste de composants à lier.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction crée ou supprime les liens entre le produit et les composants
|
||||||
|
selon la sélection effectuée par l'utilisateur.
|
||||||
|
"""
|
||||||
"""Met à jour les composants liés au produit."""
|
"""Met à jour les composants liés au produit."""
|
||||||
for comp in set(linked) - set(nouveaux):
|
for comp in set(linked) - set(nouveaux):
|
||||||
G.remove_edge(prod, comp)
|
G.remove_edge(prod, comp)
|
||||||
@ -50,7 +151,23 @@ def mettre_a_jour_composants(G, prod, linked, nouveaux):
|
|||||||
G.add_edge(prod, comp)
|
G.add_edge(prod, comp)
|
||||||
return G
|
return G
|
||||||
|
|
||||||
def modifier_produit(G):
|
def modifier_produit(
|
||||||
|
G: nx.DiGraph
|
||||||
|
) -> nx.DiGraph:
|
||||||
|
"""
|
||||||
|
Méthode de personnalisation qui permet à l'utilisateur d'ajuster un produit.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
G (Any): Le graphe NetworkX sur lequel modifier les produits et leurs composants.
|
||||||
|
Contient des données concernant la personalisation des produits,
|
||||||
|
leur niveau, et les opérations liées.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction fournit une interface utilisateur pour sélectionner
|
||||||
|
un produit à personnaliser, gérer ses composants, et définir ses opérations
|
||||||
|
d'assemblage. Elle implémente la logique de mise à jour des connexions entre
|
||||||
|
les différents éléments du graphe.
|
||||||
|
"""
|
||||||
st.markdown(f"## {str(_('pages.personnalisation.modify_product'))}")
|
st.markdown(f"## {str(_('pages.personnalisation.modify_product'))}")
|
||||||
|
|
||||||
# Sélection du produit à modifier
|
# Sélection du produit à modifier
|
||||||
|
|||||||
@ -40,11 +40,11 @@ from app.plan_d_action import (
|
|||||||
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
inverse_niveau_labels = {v: k for k, v in niveau_labels.items()}
|
||||||
|
|
||||||
|
|
||||||
def interface_plan_d_action(G_temp: nx.Graph) -> None:
|
def interface_plan_d_action(G_temp: nx.DiGraph) -> None:
|
||||||
"""Interface pour planifier l'action de sélection des minerais.
|
"""Interface pour planifier l'action de sélection des minerais.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G_temp (nx.Graph): Le graphe temporaire à analyser.
|
G_temp (nx.DiGraph): Le graphe temporaire à analyser.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
None: Modifie le state du Streamlit avec les données nécessaires
|
None: Modifie le state du Streamlit avec les données nécessaires
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
from typing import Dict, Tuple, Union, List, Set
|
from typing import Dict, Tuple, Union, List
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
def exporter_graphe_filtre(
|
def exporter_graphe_filtre(
|
||||||
G: nx.Graph,
|
G: nx.DiGraph,
|
||||||
liens_chemins: List[Tuple[Union[str, int], Union[str, int]]]
|
liens_chemins: List[Tuple[Union[str, int], Union[str, int]]]
|
||||||
) -> nx.Graph:
|
) -> nx.DiGraph:
|
||||||
"""Gère l'export du graphe filtré au format DOT.
|
"""Gère l'export du graphe filtré au format DOT.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe d'origine à exporter.
|
G (nx.DiGraph): Le graphe d'origine à exporter.
|
||||||
liens_chemins (list): Liste des tuples contenant les paires de nœuds reliées
|
liens_chemins (list): Liste des tuples contenant les paires de nœuds reliées
|
||||||
par un chemin dans le graphe, avec leurs attributs associés.
|
par un chemin dans le graphe, avec leurs attributs associés.
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
from typing import Dict
|
from typing import Dict
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
def extraire_niveaux(G: nx.Graph) -> Dict[str | int, int]:
|
def extraire_niveaux(G: nx.DiGraph) -> Dict[str | int, int]:
|
||||||
"""Extrait les niveaux des nœuds du graphe.
|
"""Extrait les niveaux des nœuds du graphe.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe d'origine à analyser.
|
G (nx.DiGraph): Le graphe d'origine à analyser.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Un dictionnaire associant chaque nœud au niveau correspondant.
|
dict: Un dictionnaire associant chaque nœud au niveau correspondant.
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
from typing import Dict, Tuple, Union
|
from typing import Dict, Tuple, Union
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
|
|
||||||
def preparer_graphe(G: nx.Graph) -> Tuple[nx.Graph, Dict[Union[str, int], int]]:
|
def preparer_graphe(G: nx.DiGraph) -> Tuple[nx.DiGraph, Dict[Union[str, int], int]]:
|
||||||
"""Nettoie et prépare le graphe pour l'analyse.
|
"""Nettoie et prépare le graphe pour l'analyse.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe d'origine à nettoyer.
|
G (nx.DiGraph): Le graphe d'origine à nettoyer.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
tuple: Un tuple contenant le graphe nettoyé et les niveaux temporels associés
|
tuple: Un tuple contenant le graphe nettoyé et les niveaux temporels associés
|
||||||
|
|||||||
@ -8,11 +8,11 @@ from utils.graph_utils import (
|
|||||||
extraire_chemins_vers
|
extraire_chemins_vers
|
||||||
)
|
)
|
||||||
|
|
||||||
def selectionner_minerais(G: nx.Graph, noeuds_depart: List[Any]) -> List[Union[str, int]]:
|
def selectionner_minerais(G: nx.DiGraph, noeuds_depart: List[Any]) -> List[Union[str, int]]:
|
||||||
"""Interface pour sélectionner les minerais si nécessaire.
|
"""Interface pour sélectionner les minerais si nécessaire.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe des relations entre les nœuds.
|
G (nx.DiGraph): Le graphe des relations entre les nœuds.
|
||||||
noeuds_depart (list): Les nœuds de départ qui doivent être considérés.
|
noeuds_depart (list): Les nœuds de départ qui doivent être considérés.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
@ -42,14 +42,14 @@ def selectionner_minerais(G: nx.Graph, noeuds_depart: List[Any]) -> List[Union[s
|
|||||||
return minerais_selection
|
return minerais_selection
|
||||||
|
|
||||||
def selectionner_noeuds(
|
def selectionner_noeuds(
|
||||||
G: nx.Graph,
|
G: nx.DiGraph,
|
||||||
niveaux_temp: Dict[Union[str, int], int],
|
niveaux_temp: Dict[Union[str, int], int],
|
||||||
niveau_depart: int
|
niveau_depart: int
|
||||||
) -> Tuple[Optional[List[Union[str, int]]], List[Union[str, int]]]:
|
) -> Tuple[Optional[List[Union[str, int]]], List[Union[str, int]]]:
|
||||||
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.
|
"""Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe des relations entre les nœuds.
|
G (nx.DiGraph): Le graphe des relations entre les nœuds.
|
||||||
niveaux_temp (dict): Dictionnaire contenant les niveaux des nœuds.
|
niveaux_temp (dict): Dictionnaire contenant les niveaux des nœuds.
|
||||||
niveau_depart (int): Niveau à partir duquel commencer la sélection.
|
niveau_depart (int): Niveau à partir duquel commencer la sélection.
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ def selectionner_noeuds(
|
|||||||
return noeuds_depart, noeuds_arrivee
|
return noeuds_depart, noeuds_arrivee
|
||||||
|
|
||||||
def extraire_chemins_selon_criteres(
|
def extraire_chemins_selon_criteres(
|
||||||
G: nx.Graph,
|
G: nx.DiGraph,
|
||||||
niveaux: Dict[str | int, int],
|
niveaux: Dict[str | int, int],
|
||||||
niveau_depart: int,
|
niveau_depart: int,
|
||||||
noeuds_depart: Optional[List[Union[str, int]]],
|
noeuds_depart: Optional[List[Union[str, int]]],
|
||||||
@ -81,7 +81,7 @@ def extraire_chemins_selon_criteres(
|
|||||||
"""Extrait les chemins selon les critères spécifiés.
|
"""Extrait les chemins selon les critères spécifiés.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
G (nx.Graph): Le graphe des relations entre les nœuds.
|
G (nx.DiGraph): Le graphe des relations entre les nœuds.
|
||||||
niveaux (dict): Dictionnaire contenant les niveaux des nœuds.
|
niveaux (dict): Dictionnaire contenant les niveaux des nœuds.
|
||||||
niveau_depart (int): Niveau à partir duquel commencer la sélection.
|
niveau_depart (int): Niveau à partir duquel commencer la sélection.
|
||||||
noeuds_depart (list, optional): Les nœuds de départ qui doivent être considérés.
|
noeuds_depart (list, optional): Les nœuds de départ qui doivent être considérés.
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
from typing import List, Dict, Optional, Any
|
||||||
|
import networkx as nx
|
||||||
import streamlit as st
|
import streamlit as st
|
||||||
import altair as alt
|
import altair as alt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
@ -6,7 +8,17 @@ import pandas as pd
|
|||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
|
|
||||||
|
|
||||||
def afficher_graphique_altair(df):
|
def afficher_graphique_altair(df: pd.DataFrame) -> None:
|
||||||
|
"""
|
||||||
|
Affiche un graphique Altair pour les données d'IHH.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
df (pd.DataFrame): DataFrame contenant les données de IHH.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction crée un graphique interactif pour visualiser les
|
||||||
|
données d'IHH selon différentes catégories et niveaux de gravité.
|
||||||
|
"""
|
||||||
# Définir les catégories originales (en français) et leur ordre
|
# Définir les catégories originales (en français) et leur ordre
|
||||||
categories_fr = ["Assemblage", "Fabrication", "Traitement", "Extraction"]
|
categories_fr = ["Assemblage", "Fabrication", "Traitement", "Extraction"]
|
||||||
|
|
||||||
@ -89,7 +101,20 @@ def afficher_graphique_altair(df):
|
|||||||
st.altair_chart(chart, use_container_width=True)
|
st.altair_chart(chart, use_container_width=True)
|
||||||
|
|
||||||
|
|
||||||
def creer_graphes(donnees):
|
def creer_graphes(donnees: Optional[List[Dict[str, Any]]]) -> None:
|
||||||
|
"""
|
||||||
|
Crée un graphique Altair pour les données d'IVC.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
donnees (Optional[List[Dict[str, Any]]]): Liste des données d'IVC.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction traite les données d'IVC et crée un graphique
|
||||||
|
interactif pour visualiser la concentration des ressources.
|
||||||
|
"""
|
||||||
if not donnees:
|
if not donnees:
|
||||||
st.warning(str(_("pages.visualisations.no_data")))
|
st.warning(str(_("pages.visualisations.no_data")))
|
||||||
return
|
return
|
||||||
@ -162,7 +187,17 @@ def creer_graphes(donnees):
|
|||||||
st.error(f"{str(_('errors.graph_creation_error'))} {e}")
|
st.error(f"{str(_('errors.graph_creation_error'))} {e}")
|
||||||
|
|
||||||
|
|
||||||
def lancer_visualisation_ihh_ics(graph):
|
def lancer_visualisation_ihh_ics(graph: nx.DiGraph) -> None:
|
||||||
|
"""
|
||||||
|
Lance une visualisation Altair pour les données d'IHH critique.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
graph (nx.DiGraph): Le graphe NetworkX contenant les données de IHH.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction traite le graphe et crée un graphique Altair
|
||||||
|
pour visualiser les données d'IHH critique.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
import networkx as nx
|
import networkx as nx
|
||||||
from utils.graph_utils import recuperer_donnees
|
from utils.graph_utils import recuperer_donnees
|
||||||
@ -180,7 +215,17 @@ def lancer_visualisation_ihh_ics(graph):
|
|||||||
st.error(f"{str(_('errors.ihh_criticality_error'))} {e}")
|
st.error(f"{str(_('errors.ihh_criticality_error'))} {e}")
|
||||||
|
|
||||||
|
|
||||||
def lancer_visualisation_ihh_ivc(graph):
|
def lancer_visualisation_ihh_ivc(graph: nx.DiGraph) -> None:
|
||||||
|
"""
|
||||||
|
Lance une visualisation Altair pour les données d'IVC.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
graph (Annx.Graphy): Le graphe NetworkX contenant les données de IV C.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Cette fonction traite le graphe et crée un graphique Altair
|
||||||
|
pour visualiser les données d'IV C.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
from utils.graph_utils import recuperer_donnees_2
|
from utils.graph_utils import recuperer_donnees_2
|
||||||
noeuds_niveau_2 = [
|
noeuds_niveau_2 = [
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import streamlit as st
|
import streamlit as st
|
||||||
from utils.widgets import html_expander
|
from utils.widgets import html_expander
|
||||||
from utils.translations import _
|
from utils.translations import _
|
||||||
|
import networkx as nx
|
||||||
|
|
||||||
from .graphes import (
|
from .graphes import (
|
||||||
lancer_visualisation_ihh_ics,
|
lancer_visualisation_ihh_ics,
|
||||||
@ -8,7 +9,23 @@ from .graphes import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def interface_visualisations(G_temp, G_temp_ivc):
|
def interface_visualisations(G_temp: nx.DiGraph, G_temp_ivc: nx.DiGraph) -> None:
|
||||||
|
"""
|
||||||
|
Affiche l'interface utilisateur des visualisations.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
G_temp : object
|
||||||
|
Graphique temporel contenant les données de IHH.
|
||||||
|
G_temp_ivc : object
|
||||||
|
Graphique temporel contenant les données d'IVC.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
-----
|
||||||
|
Cette fonction initialise l'interface utilisateur qui permet aux utilisateurs de visualiser
|
||||||
|
différentes données relatives à la gravité et au risque d'infections.
|
||||||
|
Elle gère également le traitement des erreurs liées aux graphiques temporels IHH et IV C.
|
||||||
|
"""
|
||||||
st.markdown(f"# {str(_('pages.visualisations.title'))}")
|
st.markdown(f"# {str(_('pages.visualisations.title'))}")
|
||||||
html_expander(f"{str(_('pages.visualisations.help'))}", content="\n".join(_("pages.visualisations.help_content")), open_by_default=False, details_class="details_introduction")
|
html_expander(f"{str(_('pages.visualisations.help'))}", content="\n".join(_("pages.visualisations.help_content")), open_by_default=False, details_class="details_introduction")
|
||||||
st.markdown("---")
|
st.markdown("---")
|
||||||
|
|||||||
@ -163,7 +163,7 @@
|
|||||||
"select_minerals": "Select one or more minerals",
|
"select_minerals": "Select one or more minerals",
|
||||||
"filter_by_minerals": "Filter by minerals (optional, but highly recommended)",
|
"filter_by_minerals": "Filter by minerals (optional, but highly recommended)",
|
||||||
"fine_selection": "End product selection",
|
"fine_selection": "End product selection",
|
||||||
"filter_start_nodes": "Filter by start nodes (optional, but recommended)",
|
"filter_start_nodes": "Filter by start nodes",
|
||||||
"run_analysis": "Run analysis",
|
"run_analysis": "Run analysis",
|
||||||
"confirm_download": "Confirm download",
|
"confirm_download": "Confirm download",
|
||||||
"submit_request": "Submit your request",
|
"submit_request": "Submit your request",
|
||||||
|
|||||||
@ -163,7 +163,7 @@
|
|||||||
"select_minerals": "Sélectionner un ou plusieurs minerais",
|
"select_minerals": "Sélectionner un ou plusieurs minerais",
|
||||||
"filter_by_minerals": "Filtrer par minerais (optionnel, mais recommandé)",
|
"filter_by_minerals": "Filtrer par minerais (optionnel, mais recommandé)",
|
||||||
"fine_selection": "Sélection des produits finaux",
|
"fine_selection": "Sélection des produits finaux",
|
||||||
"filter_start_nodes": "Filtrer par noeuds de départ (optionnel, mais recommandé)",
|
"filter_start_nodes": "Filtrer par noeuds de départ",
|
||||||
"run_analysis": "Lancer l'analyse",
|
"run_analysis": "Lancer l'analyse",
|
||||||
"confirm_download": "Confirmer le téléchargement",
|
"confirm_download": "Confirmer le téléchargement",
|
||||||
"submit_request": "Soumettre votre demande",
|
"submit_request": "Soumettre votre demande",
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import argparse
|
|||||||
import logging
|
import logging
|
||||||
import requests
|
import requests
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Set, Dict, Any, Optional
|
from typing import List, Set, Dict, Any
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
# Configuration du logging
|
# Configuration du logging
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user