import streamlit as st from utils.translations import _ from .sankey import afficher_sankey niveau_labels = { 0: "Produit final", 1: "Composant", 2: "Minerai", 10: "Opération", 11: "Pays d'opération", 12: "Acteur d'opération", 99: "Pays géographique" } inverse_niveau_labels = {v: k for k, v in niveau_labels.items()} def preparer_graphe(G): """Nettoie et prépare le graphe pour l'analyse.""" niveaux_temp = { node: int(str(attrs.get("niveau")).strip('"')) for node, attrs in G.nodes(data=True) if attrs.get("niveau") and str(attrs.get("niveau")).strip('"').isdigit() } G.remove_nodes_from([n for n in G.nodes() if n not in niveaux_temp]) G.remove_nodes_from( [n for n in G.nodes() if niveaux_temp.get(n) == 10 and 'Reserves' in n]) return G, niveaux_temp def selectionner_niveaux(): """Interface pour sélectionner les niveaux de départ et d'arrivée.""" st.markdown(f"## {str(_('pages.analyse.selection_nodes', 'Sélection des nœuds de départ et d\'arrivée'))}") valeur_defaut = str(_("pages.analyse.select_level", "-- Sélectionner un niveau --")) niveau_choix = [valeur_defaut] + list(niveau_labels.values()) niveau_depart = st.selectbox(str(_("pages.analyse.start_level", "Niveau de départ")), niveau_choix, key="analyse_niveau_depart") if niveau_depart == valeur_defaut: return None, None niveau_depart_int = inverse_niveau_labels[niveau_depart] niveaux_arrivee_possibles = [v for k, v in niveau_labels.items() if k > niveau_depart_int] niveaux_arrivee_choix = [valeur_defaut] + niveaux_arrivee_possibles analyse_niveau_arrivee = st.selectbox(str(_("pages.analyse.end_level", "Niveau d'arrivée")), niveaux_arrivee_choix, key="analyse_niveau_arrivee") if analyse_niveau_arrivee == valeur_defaut: return niveau_depart_int, None niveau_arrivee_int = inverse_niveau_labels[analyse_niveau_arrivee] return niveau_depart_int, niveau_arrivee_int def selectionner_minerais(G, niveau_depart, niveau_arrivee): """Interface pour sélectionner les minerais si nécessaire.""" minerais_selection = None if niveau_depart < 2 < niveau_arrivee: st.markdown(f"### {str(_('pages.analyse.select_minerals', 'Sélectionner un ou plusieurs minerais'))}") # Tous les nœuds de niveau 2 (minerai) minerais_nodes = sorted([ n for n, d in G.nodes(data=True) if d.get("niveau") and int(str(d.get("niveau")).strip('"')) == 2 ]) minerais_selection = st.multiselect( str(_("pages.analyse.filter_by_minerals", "Filtrer par minerais (optionnel)")), minerais_nodes, key="analyse_minerais" ) return minerais_selection def selectionner_noeuds(G, niveaux_temp, niveau_depart, niveau_arrivee): """Interface pour sélectionner les nœuds spécifiques de départ et d'arrivée.""" st.markdown("---") st.markdown(f"## {str(_('pages.analyse.fine_selection', 'Sélection fine des items'))}") depart_nodes = [n for n in G.nodes() if niveaux_temp.get(n) == niveau_depart] arrivee_nodes = [n for n in G.nodes() if niveaux_temp.get(n) == niveau_arrivee] noeuds_depart = st.multiselect(str(_("pages.analyse.filter_start_nodes", "Filtrer par noeuds de départ (optionnel)")), sorted(depart_nodes), key="analyse_noeuds_depart") noeuds_arrivee = st.multiselect(str(_("pages.analyse.filter_end_nodes", "Filtrer par noeuds d'arrivée (optionnel)")), sorted(arrivee_nodes), key="analyse_noeuds_arrivee") noeuds_depart = noeuds_depart if noeuds_depart else None noeuds_arrivee = noeuds_arrivee if noeuds_arrivee else None return noeuds_depart, noeuds_arrivee def configurer_filtres_vulnerabilite(): """Interface pour configurer les filtres de vulnérabilité.""" st.markdown("---") st.markdown(f"## {str(_('pages.analyse.vulnerability_filters', 'Sélection des filtres pour identifier les vulnérabilités'))}") filtrer_ics = st.checkbox(str(_("pages.analyse.filter_ics", "Filtrer les chemins contenant au moins minerai critique pour un composant (ICS > 66 %)")), key="analyse_filtrer_ics") filtrer_ivc = st.checkbox(str(_("pages.analyse.filter_ivc", "Filtrer les chemins contenant au moins un minerai critique par rapport à la concurrence sectorielle (IVC > 30)")), key="analyse_filtrer_ivc") filtrer_ihh = st.checkbox(str(_("pages.analyse.filter_ihh", "Filtrer les chemins contenant au moins une opération critique par rapport à la concentration géographique ou industrielle (IHH pays ou acteurs > 25)")), key="analyse_filtrer_ihh") ihh_type = "Pays" if filtrer_ihh: ihh_type = st.radio(str(_("pages.analyse.apply_ihh_filter", "Appliquer le filtre IHH sur :")), [str(_("pages.analyse.countries", "Pays")), str(_("pages.analyse.actors", "Acteurs"))], horizontal=True, key="analyse_ihh_type") filtrer_isg = st.checkbox(str(_("pages.analyse.filter_isg", "Filtrer les chemins contenant un pays instable (ISG ≥ 60)")), key="analyse_filtrer_isg") logique_filtrage = st.radio(str(_("pages.analyse.filter_logic", "Logique de filtrage")), [str(_("pages.analyse.or", "OU")), str(_("pages.analyse.and", "ET"))], horizontal=True, key="analyse_logique_filtrage") return filtrer_ics, filtrer_ivc, filtrer_ihh, ihh_type, filtrer_isg, logique_filtrage def interface_analyse(G_temp): st.markdown(f"# {str(_('pages.analyse.title', 'Analyse du graphe'))}") with st.expander(str(_("pages.analyse.help", "Comment utiliser cet onglet ?")), expanded=False): st.markdown("\n".join(_("pages.analyse.help_content", [ "1. Sélectionnez le niveau de départ (produit final, composant ou minerai)", "2. Choisissez le niveau d'arrivée souhaité", "3. Affinez votre sélection en spécifiant soit un ou des minerais à cibler spécifiquement ou des items précis à chaque niveau (optionnel)", "4. Définissez les critères d'analyse en sélectionnant les indices de vulnérabilité pertinents", "5. Choisissez le mode de combinaison des indices (ET/OU) selon votre besoin d'analyse", "6. Explorez le graphique généré en utilisant les contrôles de zoom et de déplacement ; vous pouvez basculer en mode plein écran pour le graphe" ]))) st.markdown("---") try: # Préparation du graphe G_temp, niveaux_temp = preparer_graphe(G_temp) # Sélection des niveaux niveau_depart, niveau_arrivee = selectionner_niveaux() if niveau_depart is None or niveau_arrivee is None: return # Sélection des minerais si nécessaire minerais_selection = selectionner_minerais(G_temp, niveau_depart, niveau_arrivee) # Sélection fine des noeuds noeuds_depart, noeuds_arrivee = selectionner_noeuds(G_temp, niveaux_temp, niveau_depart, niveau_arrivee) # Configuration des filtres de vulnérabilité filtrer_ics, filtrer_ivc, filtrer_ihh, ihh_type, filtrer_isg, logique_filtrage = configurer_filtres_vulnerabilite() # Lancement de l'analyse st.markdown("---") if st.button(str(_("pages.analyse.run_analysis", "Lancer l'analyse")), type="primary", key="analyse_lancer"): afficher_sankey( G_temp, niveau_depart=niveau_depart, niveau_arrivee=niveau_arrivee, noeuds_depart=noeuds_depart, noeuds_arrivee=noeuds_arrivee, minerais=minerais_selection, filtrer_ics=filtrer_ics, filtrer_ivc=filtrer_ivc, filtrer_ihh=filtrer_ihh, ihh_type=ihh_type, filtrer_isg=filtrer_isg, logique_filtrage=logique_filtrage ) except Exception as e: st.error(f"{str(_('errors.graph_preview_error', 'Erreur de prévisualisation du graphe :'))} {e}")