La souveraineté alimentaire introuvable : agriculture, dépendances et crise de l’État tunisien

Stratégie & Prospective · Tunisie · 2026

La souveraineté alimentaire introuvable : agriculture, dépendances et crise de l'État tunisien

Quand la guerre au Moyen-Orient révèle, derrière chaque grain de blé, un système mondialisé de gaz, d'engrais, de fret et de devises sur lequel la Tunisie ne dispose plus d'aucun levier.

SCROLL ↓

Introduction : la guerre au Moyen-Orient comme révélateur agricole

La crise géopolitique ouverte au Moyen-Orient en 2026 n'a pas seulement provoqué un choc pétrolier. Elle a également révélé une vulnérabilité beaucoup moins visible mais potentiellement plus explosive : la dépendance alimentaire et agricole des économies importatrices du Sud méditerranéen.

En Tunisie, la fermeture temporaire du détroit d'Ormuz, les perturbations du commerce maritime, les tensions sur le gaz naturel et la hausse des coûts logistiques ont immédiatement provoqué des inquiétudes sur les marchés des engrais, des céréales et des intrants agricoles.

Cette situation rappelle une réalité souvent sous-estimée : l'agriculture moderne n'est plus seulement une question de terres et de pluie. Elle dépend désormais de chaînes industrielles mondialisées extrêmement complexes.

Le blé dépend du gaz. Les rendements dépendent des engrais azotés. Les engrais phosphatés dépendent du soufre importé. Les coûts agricoles dépendent du pétrole, du transport maritime, des devises et des tensions géopolitiques.

Dans ce contexte, la guerre au Moyen-Orient agit comme un révélateur brutal des fragilités structurelles tunisiennes.

Le pays reste fortement dépendant des importations céréalières. Il dépend massivement des intrants agricoles internationaux. Son modèle alimentaire repose sur un système de subventions budgétairement coûteux. Son agriculture demeure peu productive et vulnérable aux chocs climatiques.

Plus fondamentalement encore, la crise actuelle révèle une contradiction centrale : la Tunisie continue à parler d'autosuffisance alimentaire alors même que son système agricole est profondément intégré à des chaînes mondiales sur lesquelles elle ne dispose pratiquement d'aucun contrôle.

La question n'est donc plus seulement de produire davantage de blé.

Elle est devenue beaucoup plus stratégique : comment sécuriser un système alimentaire dépendant simultanément du gaz, du pétrole, des engrais, des marchés mondiaux, du fret maritime et des équilibres géopolitiques internationaux ?

0Mq de consommation céréalière
0d'azote dans l'urée — origine gaz
0Qx/ha rendement céréalier moyen
0de la Russie dans l'export mondial de blé
I

Le retour de la géopolitique alimentaire

Pendant plusieurs décennies, la mondialisation agricole reposait sur une hypothèse implicite : les chaînes d'approvisionnement resteraient globalement stables et les crises géopolitiques ne constitueraient que des perturbations temporaires.

Les grands opérateurs du commerce mondial des céréales considéraient les guerres, les sanctions ou les tensions maritimes comme des anomalies appelées à se résorber rapidement. Cette vision s'est progressivement effondrée au cours des dernières années. La pandémie de Covid-19, la guerre en Ukraine puis les tensions au Moyen-Orient ont profondément modifié la perception du risque dans les marchés agricoles internationaux. Les acteurs du trading mondial considèrent désormais les ruptures logistiques, les restrictions à l'exportation, les sanctions financières et les conflits régionaux non plus comme des accidents mais comme des composantes permanentes du fonctionnement de l'économie mondiale.

Cette transformation est particulièrement importante pour les pays importateurs nets de produits alimentaires comme la Tunisie. Les prix agricoles mondiaux ne dépendent plus uniquement des récoltes et des conditions climatiques. Ils sont désormais étroitement liés aux tensions géopolitiques, aux coûts du fret maritime, aux assurances, aux prix de l'énergie et à la stabilité des routes commerciales internationales. Le blé illustre parfaitement cette mutation. Dans les années 1970, les États-Unis représentaient environ la moitié des exportations mondiales de blé. Aujourd'hui, la Russie est devenue le premier exportateur mondial avec près d'un quart du marché international. La mer Noire est ainsi devenue un espace central de sécurité alimentaire mondiale. La guerre en Ukraine a montré à quel point les pays dépendants des importations céréalières pouvaient devenir vulnérables à une perturbation géopolitique régionale.

Visualisation 02 · Cartogramme déformé
Le monde tel que la Tunisie le mange
Chaque pays est redimensionné selon sa part dans les importations céréalières tunisiennes. La carte cesse d'être géographique : elle devient nutritionnelle. Survolez un pays pour activer le lien.
Sélectionnez un pays

Mer Noire & corridors

~65 %

des importations de blé tendre tunisiennes proviennent de la zone mer Noire (Russie, Ukraine, Roumanie, Bulgarie). Une perturbation régionale produit immédiatement une onde de choc nationale.

Estimations sur sources ouvertes : ONAGRI, FAOSTAT, COMTRADE, presse spécialisée.

La Tunisie fait partie de ces économies particulièrement exposées. Son modèle alimentaire repose historiquement sur un contrat social centré sur la disponibilité du pain à bas prix. Depuis les années 1970, la stabilité sociale du pays dépend largement de la capacité de l'État à garantir l'accès à des produits céréaliers subventionnés. Mais ce modèle devient de plus en plus difficile à maintenir dans un contexte de hausse des coûts internationaux, de faiblesse budgétaire et de ralentissement économique. Même lors des bonnes années agricoles, la Tunisie reste fortement importatrice. Les estimations évoquées lors des débats indiquent qu'une bonne récolte peut atteindre entre 16 et 20 millions de quintaux alors que la consommation nationale avoisine environ 37 millions de quintaux. Le déficit structurel reste donc massif.

« Le pain devient simultanément un amortisseur social et une source de vulnérabilité budgétaire. »

Cette dépendance ne concerne pas uniquement le blé destiné à la consommation humaine. Une part croissante des importations sert également à l'alimentation animale. L'évolution des habitudes alimentaires et l'industrialisation progressive de l'élevage ont renforcé les besoins en céréales importées. Mais cette dynamique se heurte désormais à l'appauvrissement croissant des classes moyennes et populaires. Plusieurs analyses soulignent que la hausse du coût de la vie pousse de nombreux ménages à réduire leur consommation de protéines animales au profit des produits céréaliers subventionnés. La fragilité économique renforce ainsi mécaniquement la dépendance céréalière. Le pain devient simultanément un amortisseur social et une source de vulnérabilité budgétaire.

Visualisation 03 · Snapshots historiques
Cinquante ans de bascule sur la carte du blé mondial
Part des grands exportateurs dans le commerce mondial de blé, en pourcentage. Cliquez sur une décennie pour observer la grande inversion : les États-Unis cèdent leur leadership, la mer Noire prend le pouvoir.
Reconstitution stylisée à partir des données USDA, FAO et International Grains Council. Pourcentages exprimés en part du commerce mondial de blé.
II

Le grand angle mort : les engrais et la géopolitique des intrants

L'un des principaux enseignements de la crise actuelle est que la souveraineté alimentaire ne peut plus être pensée uniquement à partir des volumes de production céréalière.

L'agriculture moderne dépend désormais d'une chaîne industrielle mondialisée extrêmement complexe dont les engrais constituent probablement l'élément le plus stratégique. L'urée, principal engrais azoté utilisé dans le monde, dépend directement du gaz naturel. Environ 46 % de sa composition est liée à l'azote issu du gaz. Cela signifie qu'une hausse du prix du gaz ou une perturbation des flux énergétiques internationaux se répercute immédiatement sur les coûts agricoles.

La crise du détroit d'Ormuz illustre parfaitement cette vulnérabilité systémique. Une part très importante des exportations mondiales d'urée transite par cette zone stratégique. Les tensions militaires ont immédiatement provoqué des inquiétudes sur les disponibilités mondiales d'engrais. Les conséquences dépassent largement le Moyen-Orient. Lorsque les engrais deviennent plus chers ou moins disponibles, les agriculteurs réduisent leurs apports. Cette réduction affecte ensuite les rendements agricoles mondiaux et finit par se transmettre aux prix alimentaires internationaux. Plusieurs pays commencent déjà à ressentir ces effets indirects. L'Inde, par exemple, a dû réduire une partie de sa production d'engrais à cause des tensions énergétiques et gazières, ce qui pourrait affecter les prochaines récoltes et exercer une pression supplémentaire sur les marchés mondiaux.

Visualisation 04 · Diagramme de cordes
La toile invisible des dépendances agricoles
Le gaz nourrit l'urée ; l'urée nourrit le blé ; le soufre transforme le phosphate ; les devises payent l'importation. Cliquez sur un nœud pour isoler ses liens. Aucun maillon n'existe seul.
Schéma analytique. Intensité des liens : ordres de grandeur indicatifs (poids économique et critique systémique).

La Tunisie se trouve particulièrement exposée à cette situation. Son agriculture dépend fortement des intrants importés, alors même que cette dépendance reste souvent invisible dans les débats publics. Le pays produit certes du phosphate, mais cela ne signifie pas qu'il soit souverain sur l'ensemble de la chaîne des engrais. La production d'engrais phosphatés nécessite notamment du soufre, largement importé et souvent lié à des routes maritimes vulnérables. Même un pays disposant de ressources minières stratégiques peut donc rester profondément dépendant des chaînes mondiales pour les transformer et les valoriser.

Cette réalité révèle les limites du discours classique sur l'autosuffisance alimentaire. La souveraineté alimentaire ne peut plus être définie uniquement par la capacité à produire localement du blé. Elle doit intégrer l'ensemble de la chaîne agricole : engrais, énergie, transport, stockage, logistique et accès aux devises. Dans le cas tunisien, cette question devient d'autant plus sensible que la production de phosphate a fortement diminué depuis 2010, réduisant simultanément les capacités industrielles nationales et les recettes d'exportation. La Tunisie se retrouve ainsi dans une situation paradoxale : elle possède certaines ressources stratégiques mais reste dépendante des chaînes mondiales pour les valoriser.

Visualisation 05 · Chaîne de transmission
Du détroit au pain — une crise géopolitique en quatre temps
Comment un goulot d'étranglement de 33 kilomètres au large d'Oman se transforme, six mois plus tard, en ligne budgétaire à la caisse de compensation tunisienne. Quatre étapes, une seule chaîne.
Étape 01
Le détroit d'Ormuz
Un goulot d'étranglement de 33 km par lequel transite une part décisive du gaz et du pétrole mondial. La géographie devient infrastructure politique.
de largeur
Étape 02
N N N
Le gaz devient azote
Le gaz extrait des champs du Golfe se transforme en ammoniac puis en urée. 46 % de l'urée, c'est de l'azote arraché à l'atmosphère par la chaleur du méthane.
azote dans l'urée
Étape 03
La traversée maritime
Les cargos d'urée franchissent Ormuz, contournent l'Arabie, traversent Suez. Chaque escale ajoute fret, assurance et prime de risque au coût final du sac.
de prime de risque
Étape 04
Le pain tunisien
L'urée déchargée à Radès fertilise les blés du Kef, de Béja et de Bizerte. Une tension à Ormuz devient, six mois plus tard, une ligne supplémentaire à la caisse de compensation.
de délai de transmission
Schéma analytique de la chaîne de transmission gaz → urée → blé → compensation budgétaire.
III

Productivité agricole, climat et limites structurelles

La crise actuelle met également en lumière les faiblesses structurelles de l'agriculture tunisienne. La question centrale n'est pas uniquement celle des importations mais aussi celle de la productivité.

Les rendements céréaliers nord-africains restent relativement faibles comparés aux standards internationaux. Les chiffres évoqués situent les rendements tunisiens autour de 14 quintaux par hectare, contre environ 17 au Maroc et 10 en Algérie, tandis que l'Égypte obtient des résultats nettement supérieurs grâce à une agriculture fortement irriguée. Ces niveaux restent insuffisants pour réduire significativement la dépendance céréalière tunisienne.

Visualisation 06 · Contrefactuel
La trajectoire qu'on n'a pas prise
Rendements céréaliers réels comparés à trois scénarios contrefactuels. Activez les comparaisons pour faire apparaître les lignes fantômes — ce que la Tunisie aurait produit si elle avait suivi la trajectoire marocaine, égyptienne, ou un scénario d'irrigation modérée.
Reconstitution analytique sur la base de FAOSTAT (rendements observés 2000-2024). Les courbes contrefactuelles sont des projections illustratives stylisées.

Mais le problème dépasse largement la seule productivité. L'agriculture tunisienne fait désormais face à une pression climatique croissante. La raréfaction de l'eau, les sécheresses répétées et l'irrégularité des précipitations fragilisent les cycles agricoles et rendent les rendements beaucoup plus volatils. Le changement climatique transforme progressivement la sécurité alimentaire en question stratégique. Les années de bonne récolte deviennent moins prévisibles tandis que les besoins en irrigation augmentent alors même que les ressources hydriques diminuent.

Visualisation 07 · Bandes thermiques
Quand le climat devient une tendance
Stress hydrique par région et par année, 2010-2025. Plus la bande rougit, plus la sécheresse s'installe. Les quatre régions céréalières basculent toutes vers la même teinte, à des rythmes différents.
Humide
Sécheresse sévère
Reconstitution analytique du stress hydrique annuel à partir d'indices SPI et d'anomalies pluviométriques. Visualisation à but pédagogique.

Cette évolution renforce encore la dépendance aux importations. La Tunisie entre progressivement dans une zone de vulnérabilité systémique où climat, énergie, engrais et finances publiques deviennent interdépendants. Une mauvaise récolte entraîne davantage d'importations ; davantage d'importations nécessitent plus de devises ; or les devises dépendent elles-mêmes du tourisme, des exportations et de la stabilité macroéconomique. La sécurité alimentaire devient ainsi directement liée à la question monétaire et budgétaire.

Cette articulation est fondamentale car elle montre que la crise agricole tunisienne ne peut plus être traitée comme une simple question sectorielle. Elle renvoie désormais à la structure même du modèle économique national et à la capacité de l'État à gérer des dépendances critiques dans un environnement mondial devenu beaucoup plus instable.

IV

La caisse de compensation : stabilisateur social ou impasse budgétaire ?

Le système tunisien de subventions alimentaires constitue l'un des piliers historiques du contrat social national.

La caisse de compensation, créée durant la Seconde Guerre mondiale, visait initialement à stabiliser les prix dans un contexte de pénuries et d'incertitudes. Avec le temps, ce mécanisme est devenu un élément central de la régulation économique et sociale tunisienne. Il permet de maintenir artificiellement bas les prix du pain, de la farine, des pâtes ou encore du carburant. Pendant plusieurs décennies, ce système a contribué à préserver une certaine stabilité sociale.

Mais ce modèle est progressivement devenu extrêmement coûteux. La hausse des prix internationaux de l'énergie et des matières premières a considérablement augmenté la pression budgétaire. L'État tunisien doit désormais absorber simultanément les subventions énergétiques et alimentaires dans un contexte de croissance faible et d'endettement élevé. Le problème est aggravé par la structure même du système : les subventions profitent largement à l'ensemble de la population, y compris aux ménages aisés, tandis que leur suppression brutale pourrait provoquer une explosion sociale.

Visualisation 08 · Simulateur dynamique
Et si vous étiez ministre des Finances ?
Déplacez les curseurs pour ajuster les prix mondiaux du blé, du gaz et le taux de subvention. L'aiguille de la jauge réagit en temps réel. Aucun arbitrage ne tient seul.

Coût budgétaire annuel estimé

3 200 M TND
Maîtrisée Élevée Crise
Charge soutenable mais en augmentation.
Modèle de calcul stylisé à des fins pédagogiques. Les ordres de grandeur sont calibrés sur les rapports du FMI, de la Banque mondiale et du ministère des Finances tunisien.

Cette contradiction place l'État dans une impasse politique permanente. Les expériences passées montrent que les réformes des subventions constituent toujours des moments de forte tension. Le pain occupe en Tunisie une dimension hautement symbolique. Il représente à la fois un produit alimentaire de base et un marqueur historique du contrat social. Toute réforme des prix touche donc directement à la légitimité politique.

« L'État évite parfois les hausses frontales de prix mais laisse apparaître des pénuries, des ruptures d'approvisionnement ou des dégradations de qualité. »

Face à cette difficulté, l'ajustement prend souvent des formes indirectes. L'État évite parfois les hausses frontales de prix mais laisse apparaître des pénuries, des ruptures d'approvisionnement ou des dégradations de qualité. Ce mécanisme d'ajustement silencieux devient de plus en plus fréquent. La crise actuelle pourrait accélérer cette dynamique. Une hausse durable des prix mondiaux du blé, du pétrole et des engrais exercerait une pression considérable sur les finances publiques tunisiennes et rendrait le maintien du système actuel de plus en plus difficile.

V

Agriculture, souveraineté et crise de l'État

La crise alimentaire tunisienne révèle finalement une crise beaucoup plus profonde : celle de l'État stratège.

Depuis plusieurs décennies, les politiques agricoles tunisiennes oscillent entre intervention publique, ouverture aux marchés mondiaux et gestion sociale des prix. Mais cette architecture apparaît aujourd'hui de plus en plus incohérente. La Tunisie importe massivement des céréales tout en maintenant des prix administrés. Elle produit du phosphate mais dépend des importations pour certains intrants stratégiques. Elle cherche à préserver la paix sociale tout en faisant face à des contraintes budgétaires croissantes.

Cette contradiction permanente fragilise les capacités de planification de l'État. Le problème dépasse largement l'agriculture. Il touche à la capacité globale du pays à gérer ses dépendances stratégiques dans un environnement géopolitique instable. La question alimentaire est désormais inséparable de la question énergétique. Les engrais dépendent du gaz. Le transport dépend du pétrole. Les importations dépendent des devises. Les devises dépendent elles-mêmes des exportations, du tourisme et de la stabilité macroéconomique.

Visualisation 09 · Beeswarm chronologique
Les chocs ne sont plus des accidents
Chaque cercle est une perturbation des chaînes agro-alimentaires mondiales depuis 2010. Sa taille indique l'amplitude du choc, sa hauteur le secteur touché, sa couleur la nature géopolitique. Les anomalies deviennent un climat.
Sélection illustrative de chocs documentés par la presse spécialisée et les bases de données académiques sur les ruptures d'approvisionnement.

Cette interdépendance transforme la sécurité alimentaire en question de sécurité nationale. La Tunisie ne peut plus traiter séparément agriculture, énergie, commerce extérieur et politique sociale. La guerre au Moyen-Orient montre précisément pourquoi. Un choc géopolitique régional peut désormais produire simultanément une hausse des prix énergétiques, des perturbations sur les engrais, une inflation alimentaire et une pression budgétaire. Cette dynamique cumulative est particulièrement dangereuse pour les économies fortement dépendantes des importations.

VI

Repenser la souveraineté alimentaire : de l'autosuffisance impossible à la résilience stratégique

Face à cette situation, le débat tunisien reste souvent prisonnier d'une opposition simpliste entre dépendance et autosuffisance.

Or l'autosuffisance céréalière complète apparaît structurellement difficile dans les conditions climatiques et hydriques actuelles. La véritable question stratégique est ailleurs : elle consiste à construire une résilience alimentaire.

Cette approche implique de déplacer le débat. La souveraineté alimentaire ne signifie pas produire localement tout ce qui est consommé. Elle signifie sécuriser durablement les capacités d'approvisionnement, réduire les dépendances critiques et renforcer les capacités nationales de gestion des crises. Cette stratégie suppose plusieurs transformations profondes : une meilleure gestion des stocks stratégiques, une diversification des fournisseurs et des routes commerciales, ainsi qu'une réflexion beaucoup plus large sur les intrants agricoles critiques.

Visualisation 10 · Sunburst hiérarchique
L'anatomie d'une résilience à construire
Six piliers, vingt-quatre leviers. Survolez un secteur pour explorer ses sous-composantes. La résilience n'est pas un mot ; c'est une architecture institutionnelle, industrielle et sociale.
Résilience
alimentaire

Survolez un pilier pour explorer ses leviers.

Stocks stratégiques Diversification Intrants critiques Climat & eau Énergie agricole Justice sociale
Cadre analytique synthétisant les recommandations de la FAO, du World Resources Institute et des travaux universitaires sur la sécurité alimentaire des pays MENA.

La Tunisie devra probablement développer des stratégies régionales et industrielles concernant les engrais, le soufre ou certaines chaînes logistiques. La coopération maghrébine pourrait théoriquement jouer un rôle dans cette perspective, même si les blocages politiques régionaux rendent cette option difficile à court terme. La question énergétique devient également centrale. Une partie de la vulnérabilité agricole tunisienne provient directement de sa dépendance aux hydrocarbures importés. La transition énergétique pourrait donc aussi devenir une stratégie agricole.

Le développement du solaire dans les exploitations, l'amélioration de l'efficacité énergétique ou encore la production d'ammoniac vert pourraient progressivement réduire certaines dépendances structurelles. Mais ces transformations nécessitent du temps, des investissements et une véritable vision industrielle. Enfin, la question sociale reste fondamentale. La sécurité alimentaire ne peut être pensée uniquement en termes de volumes. Elle dépend également du pouvoir d'achat. Une population qui n'a plus accès aux protéines et se replie sur les produits céréaliers subventionnés révèle un appauvrissement structurel.

La crise alimentaire tunisienne n'est donc pas uniquement une crise agricole. Elle est aussi une crise sociale, budgétaire et politique.

Conclusion — de la vulnérabilité agricole à la stratégie nationale

La guerre au Moyen-Orient a révélé une réalité fondamentale : la sécurité alimentaire tunisienne dépend désormais autant de la géopolitique mondiale que des récoltes nationales.

Le blé, les engrais, le gaz, le pétrole, le transport maritime et les devises forment aujourd'hui un système profondément interdépendant.

Dans ce système, la Tunisie apparaît particulièrement vulnérable.

Mais cette vulnérabilité peut aussi devenir un point de départ stratégique.

Elle oblige à dépasser les approches sectorielles.

L'agriculture ne peut plus être pensée indépendamment de l'énergie, de l'industrie, du commerce extérieur et des finances publiques.

« Le véritable défi tunisien n'est probablement pas d'atteindre une autosuffisance impossible. Il est de construire une capacité nationale de résilience dans un monde où les chocs deviennent permanents. »

La question centrale devient alors celle de la reconstruction d'un État stratège capable d'articuler sécurité alimentaire, transition énergétique, politique industrielle et justice sociale.

Le véritable défi tunisien n'est probablement pas d'atteindre une autosuffisance impossible.

Il est de construire une capacité nationale de résilience dans un monde où les chocs géopolitiques, climatiques et énergétiques deviennent permanents.

Autrement dit, il ne s'agit plus seulement de produire davantage.

Il s'agit de survivre stratégiquement dans une économie mondiale de plus en plus instable.

${d.name}

${d.share} %

${d.desc}

`; } nodes.on('mouseenter', function(e,d){ svg.selectAll('.country').classed('dim',true); d3.select(this).classed('dim',false); updateInfo(d); }).on('mouseleave', function(){ svg.selectAll('.country').classed('dim',false); }); ScrollTrigger.create({ trigger:'#ssqCarto', start:'top 75%', onEnter:()=>{ nodes.transition().duration(800).delay((d,i)=>i*60) .attr('opacity',1); } }); })(); /* ============================================================ VIZ 03 — BARRES HORIZONTALES ANIMÉES ============================================================ */ (function(){ const container = document.getElementById('ssqBars'); if(!container) return; const rowsEl = document.getElementById('barsRows'); const ctx = document.getElementById('barsContext'); const tabs = document.querySelectorAll('#barsTabs .viz-bars-year-tab'); const flags = { us: '', ru: '', ua: '', eu: '', ca: '', au: '', ar: '' }; const data = { 1975: { rows: [ {key:'us', name:'États-Unis', val:48, color:C.sky}, {key:'ca', name:'Canada', val:18, color:C.wheatDeep}, {key:'eu', name:'France & UE', val:11, color:C.olive}, {key:'au', name:'Australie', val:9, color:C.earth}, {key:'ar', name:'Argentine', val:6, color:C.skySoft}, {key:'ru', name:'URSS/Russie', val:4, color:C.rust}, {key:'ua', name:'Ukraine', val:1, color:C.wheat} ], ctx:'L\'hégémonie américaineAu lendemain du choc pétrolier, les États-Unis dominent près de la moitié du marché mondial. Le blé est une arme diplomatique de la Guerre froide.' }, 1990: { rows: [ {key:'us', name:'États-Unis', val:35, color:C.sky}, {key:'eu', name:'France & UE', val:18, color:C.olive}, {key:'ca', name:'Canada', val:17, color:C.wheatDeep}, {key:'au', name:'Australie', val:11, color:C.earth}, {key:'ar', name:'Argentine', val:8, color:C.skySoft}, {key:'ru', name:'URSS/Russie', val:5, color:C.rust}, {key:'ua', name:'Ukraine', val:2, color:C.wheat} ], ctx:'L\'Europe émergeLa PAC européenne transforme l\'UE en second exportateur mondial. La part américaine s\'érode mais reste dominante.' }, 2005: { rows: [ {key:'us', name:'États-Unis', val:25, color:C.sky}, {key:'eu', name:'France & UE', val:16, color:C.olive}, {key:'ca', name:'Canada', val:14, color:C.wheatDeep}, {key:'ru', name:'Russie', val:13, color:C.rust}, {key:'au', name:'Australie', val:11, color:C.earth}, {key:'ar', name:'Argentine', val:9, color:C.skySoft}, {key:'ua', name:'Ukraine', val:6, color:C.wheat} ], ctx:'L\'irruption de la mer NoireLa Russie post-soviétique réinvestit l\'agriculture et devient un acteur majeur. L\'Ukraine suit la même trajectoire ascendante.' }, 2015: { rows: [ {key:'ru', name:'Russie', val:18, color:C.rust}, {key:'eu', name:'France & UE', val:17, color:C.olive}, {key:'us', name:'États-Unis', val:14, color:C.sky}, {key:'ca', name:'Canada', val:13, color:C.wheatDeep}, {key:'ua', name:'Ukraine', val:11, color:C.wheat}, {key:'au', name:'Australie', val:10, color:C.earth}, {key:'ar', name:'Argentine', val:7, color:C.skySoft} ], ctx:'La bascule s\'opèreLa Russie passe en tête. Pour la première fois depuis l\'après-guerre, les États-Unis ne sont plus le premier exportateur mondial de blé.' }, 2024: { rows: [ {key:'ru', name:'Russie', val:25, color:C.rust}, {key:'eu', name:'France & UE', val:17, color:C.olive}, {key:'au', name:'Australie', val:13, color:C.earth}, {key:'ca', name:'Canada', val:13, color:C.wheatDeep}, {key:'us', name:'États-Unis', val:11, color:C.sky}, {key:'ua', name:'Ukraine', val:8, color:C.wheat}, {key:'ar', name:'Argentine', val:7, color:C.skySoft} ], ctx:'La mer Noire au cœur du mondeLa Russie consolide son leadership avec un quart du commerce mondial. La sécurité alimentaire de l\'Afrique du Nord et du Moyen-Orient passe désormais par ses ports.' } }; let currentYear = 1975; let initialized = false; function render(year, animate){ const d = data[year]; const maxVal = 50; ctx.innerHTML = d.ctx; rowsEl.innerHTML = ''; d.rows.forEach((r, i)=>{ const row = document.createElement('div'); row.className = 'viz-bars-row'; row.innerHTML = `
${flags[r.key] || ''}${r.name}
${r.val}%
`; rowsEl.appendChild(row); const fill = row.querySelector('.viz-bars-fill'); setTimeout(()=>{ fill.style.width = (r.val/maxVal*100) + '%'; }, animate ? 80 + i*60 : 50); }); } tabs.forEach(tab=>{ tab.addEventListener('click', ()=>{ tabs.forEach(t=>t.classList.remove('active')); tab.classList.add('active'); currentYear = +tab.dataset.y; render(currentYear, true); }); }); ScrollTrigger.create({ trigger:'#ssqBars', start:'top 75%', onEnter:()=>{ if(!initialized){ render(1975, true); initialized = true; } } }); render(1975, false); })(); /* ============================================================ VIZ 04 — CHORD DIAGRAM ============================================================ */ (function(){ const svg = d3.select('#ssqChord'); if(svg.empty()) return; const W=800, H=700, cx=W/2, cy=H/2, outerR=240, innerR=220; const names = ['Gaz', 'Urée / Azote', 'Pétrole', 'Phosphate', 'Soufre', 'Blé', 'Devises', 'Fret maritime']; const colors = [C.sky, C.olive, C.ink, C.earthSoft, C.wheatDeep, C.wheat, C.rust, C.skySoft]; const matrix = [ [ 0, 28, 0, 0, 0, 0, 12, 4], [ 0, 0, 0, 0, 0, 30, 8, 6], [ 0, 0, 0, 0, 0, 0, 18, 22], [ 0, 0, 0, 0, 14, 0, 6, 4], [ 0, 0, 0, 0, 0, 0, 4, 3], [ 0, 0, 0, 0, 0, 0, 22, 14], [10, 10, 14, 8, 6, 20, 0, 6], [ 6, 4, 18, 4, 3, 12, 0, 0] ]; const chord = d3.chord().padAngle(0.05).sortSubgroups(d3.descending); const chords = chord(matrix); const g = svg.append('g').attr('transform',`translate(${cx},${cy})`); const arc = d3.arc().innerRadius(innerR).outerRadius(outerR); const ribbon = d3.ribbon().radius(innerR); const arcs = g.append('g').selectAll('path').data(chords.groups).enter().append('path') .attr('class','chord-arc') .attr('d',arc) .attr('fill',(d,i)=>colors[i]) .attr('stroke',C.paper).attr('stroke-width',1.5) .attr('opacity',0); const labels = g.append('g').selectAll('text').data(chords.groups).enter().append('text') .each(d=>{ d.angle = (d.startAngle + d.endAngle)/2; }) .attr('dy','.35em') .attr('transform', d=> `rotate(${d.angle*180/Math.PI - 90}) translate(${outerR+14}) ${d.angle>Math.PI?'rotate(180)':''}`) .attr('text-anchor', d=>d.angle>Math.PI?'end':'start') .attr('fill',C.ink) .attr('opacity',0) .text((d,i)=>names[i]); const bands = g.append('g').selectAll('path').data(chords).enter().append('path') .attr('class','chord-band') .attr('d',ribbon) .attr('fill',(d)=>colors[d.source.index]) .attr('fill-opacity',0.55) .attr('stroke',C.paper).attr('stroke-width',0.5) .attr('opacity',0); arcs.on('click', function(e, d){ const idx = d.index; bands.classed('fade', b => b.source.index !== idx && b.target.index !== idx); }); svg.on('click', function(e){ if(e.target.tagName === 'svg') bands.classed('fade', false); }); ScrollTrigger.create({ trigger:'#ssqChord', start:'top 75%', onEnter:()=>{ arcs.transition().duration(800).delay((d,i)=>i*80).attr('opacity',1); labels.transition().duration(600).delay((d,i)=>500+i*80).attr('opacity',1); bands.transition().duration(1000).delay(1200).attr('opacity',1); } }); })(); /* ============================================================ VIZ 05 — STEPS CARDS + ROULETTE CASH MACHINE Chaque chiffre du nombre cible défile verticalement ============================================================ */ (function(){ const cards = document.querySelectorAll('.viz-step-card'); if(!cards.length) return; // Construit la roulette pour un chiffre cible function buildRoller(el){ const target = String(parseInt(el.dataset.target, 10)); const prefix = el.dataset.prefix || ''; const suffix = el.dataset.suffix || ''; el.innerHTML = ''; // Préfixe (statique) if(prefix){ const ps = document.createElement('span'); ps.className = 'vsm-static'; ps.textContent = prefix; el.appendChild(ps); } // Une roulette par chiffre const rollers = []; for(let i=0;i{ const s = document.createElement('span'); s.textContent = n; inner.appendChild(s); }); wrap.appendChild(inner); el.appendChild(wrap); rollers.push({wrap, inner, digit, position: 30 + digit, totalSteps: 40 + digit, colIndex: i}); } // Suffixe (statique) if(suffix){ const ss = document.createElement('span'); ss.className = 'vsm-static'; ss.textContent = suffix; el.appendChild(ss); } return rollers; } // Lance l'animation des roulettes (effet cash machine) function spinRollers(rollers){ rollers.forEach((r, idx)=>{ // Position initiale : tout en haut (0) r.inner.style.transition = 'none'; r.inner.style.transform = 'translateY(0)'; // Force reflow void r.inner.offsetHeight; // Décalage de démarrage : colonnes de gauche démarrent en premier, // colonnes de droite mettent plus de temps à s'arrêter (effet roulette) const duration = 1.6 + idx * 0.45; // s const delay = idx * 0.08; // s r.inner.style.transition = `transform ${duration}s cubic-bezier(.18,.65,.2,1) ${delay}s`; // On translate vers le chiffre final // Hauteur d'un caractère = 1em du conteneur // Le chiffre final est à l'index r.position r.inner.style.transform = `translateY(-${r.position}em)`; }); } // Initialise toutes les roulettes const allRollers = []; document.querySelectorAll('.vsm-num[data-roll]').forEach(el=>{ const rollers = buildRoller(el); allRollers.push({card: el.closest('.viz-step-card'), rollers}); }); const observer = new IntersectionObserver((es)=>{ es.forEach(e=>{ if(e.isIntersecting){ cards.forEach(c=>{ const delay = parseInt(c.dataset.delay||'0', 10); setTimeout(()=>{ c.classList.add('in'); // Lance la roulette de cette carte après l'apparition const item = allRollers.find(a=>a.card === c); if(item){ setTimeout(()=> spinRollers(item.rollers), 650); } }, delay); }); observer.disconnect(); } }); },{threshold:.15}); observer.observe(cards[0]); })(); /* ============================================================ VIZ 06 — GHOST LINES ============================================================ */ (function(){ const svg = d3.select('#ssqGhost'); if(svg.empty()) return; const W=1100, H=480, m={t:30,r:140,b:50,l:60}; const years = d3.range(2000, 2026); const realPoints = [ [2000,13.5],[2001,11.2],[2002,9.5],[2003,16.8],[2004,15.2], [2005,12.8],[2006,14.5],[2007,11.6],[2008,7.2],[2009,18.3], [2010,15.5],[2011,15.8],[2012,12.4],[2013,17.1],[2014,11.9], [2015,14.8],[2016,8.2],[2017,12.5],[2018,17.6],[2019,15.4], [2020,11.8],[2021,9.7],[2022,8.5],[2023,7.8],[2024,13.2],[2025,14.5] ]; const morocco = years.map((y,i)=> [y, 11 + i*0.28 + Math.sin(i*0.4)*1.2]); const egypt = years.map((y,i)=> [y, 20 + i*0.45 + Math.sin(i*0.3)*0.8]); const irr = years.map((y,i)=> [y, 14 + i*0.48 + Math.sin(i*0.5)*0.7]); const datasets = { real: {data:realPoints, color:C.rust, label:'Tunisie réelle ~14 q/ha'}, ma: {data:morocco, color:C.wheatDeep, label:'Trajectoire marocaine ~18'}, eg: {data:egypt, color:C.sky, label:'Trajectoire égyptienne ~31'}, irr: {data:irr, color:C.olive, label:'Irrigation modérée ~26'} }; const active = new Set(['real']); const x = d3.scaleLinear().domain([2000, 2025]).range([m.l, W-m.r]); const y = d3.scaleLinear().domain([5, 35]).range([H-m.b, m.t]); svg.append('g').attr('transform',`translate(0,${H-m.b})`) .call(d3.axisBottom(x).tickFormat(d3.format('d')).ticks(6)) .selectAll('text').attr('font-family','JetBrains Mono, monospace').attr('font-size',10).attr('fill',C.mute); svg.append('g').attr('transform',`translate(${m.l},0)`) .call(d3.axisLeft(y).ticks(5).tickFormat(d=>d+' q/ha')) .selectAll('text').attr('font-family','JetBrains Mono, monospace').attr('font-size',10).attr('fill',C.mute); svg.selectAll('.tick line, .domain').attr('stroke',C.ink).attr('stroke-opacity',.15); y.ticks(5).forEach(t=>{ svg.append('line').attr('x1',m.l).attr('x2',W-m.r).attr('y1',y(t)).attr('y2',y(t)) .attr('stroke',C.ink).attr('stroke-opacity',.06); }); const line = d3.line().x(d=>x(d[0])).y(d=>y(d[1])).curve(d3.curveMonotoneX); const paths = {}; const labels = {}; Object.entries(datasets).forEach(([k, ds])=>{ const isReal = k === 'real'; const path = svg.append('path').datum(ds.data) .attr('fill','none').attr('stroke',ds.color) .attr('stroke-width', isReal ? 3 : 2) .attr('stroke-dasharray', isReal ? null : '4 5') .attr('opacity', isReal ? 0.95 : 0) .attr('d', line); const len = path.node().getTotalLength(); paths[k] = {path, len, isReal}; const last = ds.data[ds.data.length-1]; labels[k] = svg.append('text') .attr('x', x(last[0])+8).attr('y', y(last[1])+4) .attr('font-family','Cormorant Garamond, serif').attr('font-style','italic') .attr('font-size',12).attr('fill',ds.color).attr('font-weight',600) .attr('opacity', isReal ? 1 : 0).text(ds.label); }); ScrollTrigger.create({ trigger:'#ssqGhost', start:'top 75%', onEnter:()=>{ paths.real.path.attr('stroke-dasharray', paths.real.len+' '+paths.real.len) .attr('stroke-dashoffset', paths.real.len) .transition().duration(1800).attr('stroke-dashoffset', 0) .on('end',()=>paths.real.path.attr('stroke-dasharray', null)); } }); document.querySelectorAll('.viz-ghost-toggle').forEach(btn=>{ btn.addEventListener('click',()=>{ const k = btn.dataset.line; if(active.has(k)){ if(k==='real') return; active.delete(k); btn.classList.remove('active'); paths[k].path.transition().duration(400).attr('opacity',0); labels[k].transition().duration(400).attr('opacity',0); } else { active.add(k); btn.classList.add('active'); paths[k].path.attr('stroke-dasharray', '4 5') .attr('opacity',0) .transition().duration(900).attr('opacity',.75); labels[k].transition().duration(600).delay(400).attr('opacity',1); } }); }); })(); /* ============================================================ VIZ 07 — STRIP HEATMAP ============================================================ */ (function(){ const stripBox = document.getElementById('ssqStrip'); const rowsEl = document.getElementById('stripRows'); const yearsEl = document.getElementById('stripYears'); const tip = document.getElementById('stripTip'); const legendEl = document.getElementById('stripLegend'); if(!stripBox) return; const regions = [ {name:'Nord-Ouest', base:0.20, slope:0.025}, {name:'Cap Bon', base:0.30, slope:0.030}, {name:'Centre', base:0.45, slope:0.035}, {name:'Sud', base:0.65, slope:0.020} ]; const years = d3.range(2010, 2026); const colorScale = d3.scaleSequential( t => d3.interpolateRgb.gamma(2.2)('#F4EFE6', '#A63D3D')(t) ).domain([0, 1]); function stress(region, year, idx){ const drought = (year===2016||year===2022||year===2023||year===2024) ? 0.18 : 0; const noise = (Math.sin(idx*1.7 + region.base*10)*0.5 + 0.5)*0.08; return Math.min(1, Math.max(0, region.base + region.slope*idx + drought + noise)); } const allCells = []; regions.forEach((reg, ri)=>{ const row = document.createElement('div'); row.className = 'viz-strip-row'; row.innerHTML = `
${reg.name}
`; rowsEl.appendChild(row); const cellsBox = row.querySelector('.viz-strip-cells'); years.forEach((yr, yi)=>{ const s = stress(reg, yr, yi); const cell = document.createElement('div'); cell.className = 'viz-strip-cell'; cell.style.background = colorScale(s); cell.dataset.region = reg.name; cell.dataset.year = yr; cellsBox.appendChild(cell); allCells.push(cell); cell.addEventListener('mouseenter', ()=>{ const rect = stripBox.getBoundingClientRect(); const cr = cell.getBoundingClientRect(); tip.innerHTML = `${reg.name} · ${yr}Stress hydrique : ${Math.round(s*100)}%`; tip.style.left = (cr.left - rect.left + cr.width/2) + 'px'; tip.style.top = (cr.top - rect.top - 5) + 'px'; tip.style.opacity = 1; }); cell.addEventListener('mouseleave', ()=>tip.style.opacity = 0); }); }); years.forEach(y=>{ const yl = document.createElement('div'); yl.textContent = (y % 5 === 0 || y === 2025) ? y : ''; yearsEl.appendChild(yl); }); [0, 0.25, 0.5, 0.75, 1].forEach(t=>{ const s = document.createElement('span'); s.style.background = colorScale(t); legendEl.appendChild(s); }); ScrollTrigger.create({ trigger:'#ssqStrip', start:'top 78%', onEnter:()=>{ allCells.forEach((c,i)=>{ setTimeout(()=>c.classList.add('in'), i*10); }); } }); })(); /* ============================================================ VIZ 08 — WHAT-IF SIMULATOR ============================================================ */ (function(){ const sWheat = document.getElementById('sWheat'); const sGas = document.getElementById('sGas'); const sSub = document.getElementById('sSub'); const sHarv = document.getElementById('sHarv'); if(!sWheat) return; const vWheat = document.getElementById('vWheat'); const vGas = document.getElementById('vGas'); const vSub = document.getElementById('vSub'); const vHarv = document.getElementById('vHarv'); const out = document.getElementById('simuBudget'); const lbl = document.getElementById('simuLbl'); const needle = document.getElementById('gaugeNeedle'); const flash = document.getElementById('simuFlash'); let prevBudget = null; let prevTension = null; function update(){ const wheat = +sWheat.value; const gas = +sGas.value; const sub = +sSub.value; const harv = +sHarv.value; vWheat.textContent = wheat; vGas.textContent = gas; vSub.textContent = sub; vHarv.textContent = harv; const deficit = Math.max(0, 37 - harv); const importCost = deficit * wheat * 100 * 3.1 / 1000; const fertCost = gas * 60; const subBudget = Math.round((importCost + fertCost) * (sub/100) * 1.5 + 1200); if(prevBudget !== null && Math.abs(subBudget - prevBudget) > 5){ const startVal = prevBudget; const delta = subBudget - startVal; const duration = 400; const t0 = performance.now(); function step(t){ const k = Math.min(1, (t - t0)/duration); const eased = 1 - Math.pow(1-k, 3); const v = Math.round(startVal + delta*eased); out.textContent = v.toLocaleString('fr-FR').replace(/,/g,' ') + ' M TND'; if(k < 1) requestAnimationFrame(step); } requestAnimationFrame(step); } else { out.textContent = subBudget.toLocaleString('fr-FR').replace(/,/g,' ') + ' M TND'; } prevBudget = subBudget; const tension = Math.min(100, Math.max(0, ((wheat-180)/320)*38 + ((gas-3)/22)*30 + (sub/100)*15 + ((22-harv)/14)*17 )); const angle = -90 + (tension/100)*180; needle.style.transform = `rotate(${angle}deg)`; if(prevTension !== null && Math.abs(tension - prevTension) > 8){ flash.classList.add('on'); setTimeout(()=>flash.classList.remove('on'), 150); } prevTension = tension; out.className = 'viz-simu-result'; if(tension < 35){ out.classList.add('safe'); lbl.textContent = 'Charge soutenable. Marges budgétaires préservées.'; } else if(tension < 65){ out.classList.add('warn'); lbl.textContent = 'Tension significative. Arbitrages budgétaires nécessaires.'; } else { out.classList.add('danger'); lbl.textContent = 'Zone de crise. Risque social et financier élevé.'; } } [ {input:sWheat, val:vWheat}, {input:sGas, val:vGas}, {input:sSub, val:vSub}, {input:sHarv, val:vHarv} ].forEach(({input, val})=>{ input.addEventListener('input', ()=>{ val.parentElement.classList.add('pulse'); setTimeout(()=>val.parentElement.classList.remove('pulse'), 350); update(); }); }); update(); ScrollTrigger.create({ trigger:'#ssqSimu', start:'top 75%', onEnter:()=>{ if(reduced) return; needle.style.transform = 'rotate(-90deg)'; setTimeout(()=>{ needle.style.transform = 'rotate(90deg)'; }, 400); setTimeout(update, 1400); } }); })(); /* ============================================================ VIZ 09 — BEESWARM → tooltip titre BLANC (déjà appliqué via CSS) → AUCUNE icône à l'intérieur des cercles ============================================================ */ (function(){ const svg = d3.select('#ssqBee'); if(svg.empty()) return; const W=1100, H=460, m={t:50,r:60,b:60,l:120}; const events = [ {date:2010.8, sector:'Céréales', amp:6, type:'Climat', name:'Sécheresse Russie', desc:'Embargo russe sur l\'exportation de blé. Flambée des prix mondiaux.'}, {date:2011.0, sector:'Politique', amp:5, type:'Conflit', name:'Printemps arabe', desc:'Vague de hausse des prix alimentaires, déclencheur partiel des révoltes.'}, {date:2014.3, sector:'Énergie', amp:5, type:'Géopolitique',name:'Annexion Crimée', desc:'Premières tensions en mer Noire. Fret céréalier perturbé.'}, {date:2018.5, sector:'Engrais', amp:3, type:'Marché', name:'Tension urée Chine', desc:'Restrictions chinoises à l\'export d\'engrais.'}, {date:2020.2, sector:'Logistique',amp:8, type:'Pandémie', name:'Covid-19', desc:'Effondrement du fret mondial. Ruptures de chaînes d\'approvisionnement.'}, {date:2021.7, sector:'Énergie', amp:7, type:'Marché', name:'Choc gazier européen', desc:'Le prix du gaz se multiplie par 5. L\'urée européenne s\'effondre.'}, {date:2022.15,sector:'Céréales', amp:10,type:'Conflit', name:'Invasion de l\'Ukraine', desc:'Mer Noire bloquée. Prix du blé à des sommets historiques.'}, {date:2022.6, sector:'Engrais', amp:8, type:'Conflit', name:'Crise mondiale engrais', desc:'Pénurie d\'urée et de potasse. Agriculteurs réduisent les apports.'}, {date:2023.4, sector:'Logistique',amp:6, type:'Géopolitique',name:'Mer Rouge / Houthis', desc:'Attaques sur les cargos. Déroutement par le Cap.'}, {date:2024.1, sector:'Politique', amp:5, type:'Marché', name:'Restrictions Inde', desc:'L\'Inde restreint ses exports céréaliers et d\'engrais.'}, {date:2024.7, sector:'Énergie', amp:6, type:'Géopolitique',name:'Tensions Iran', desc:'Pression renouvelée sur Ormuz. Primes de risque.'}, {date:2025.3, sector:'Engrais', amp:5, type:'Marché', name:'Restriction phosphate Maroc', desc:'Renégociation des contrats d\'export phosphatés.'}, {date:2026.05,sector:'Logistique',amp:9, type:'Conflit', name:'Fermeture Ormuz', desc:'Choc cumulé sur gaz, urée, fret, prix alimentaires.'} ]; const sectors = ['Céréales','Engrais','Énergie','Logistique','Politique']; const colorByType = { 'Climat':C.olive, 'Conflit':C.rust, 'Géopolitique':C.wheatDeep, 'Marché':C.sky, 'Pandémie':C.earth }; const x = d3.scaleLinear().domain([2010, 2026.5]).range([m.l, W-m.r]); const y = d3.scalePoint().domain(sectors).range([m.t+20, H-m.b]).padding(0.5); const r = d3.scaleSqrt().domain([1,10]).range([8, 30]); svg.append('g').attr('transform',`translate(0,${H-m.b+10})`) .call(d3.axisBottom(x).tickFormat(d3.format('d')).ticks(8)) .selectAll('text').attr('font-family','JetBrains Mono, monospace').attr('font-size',10).attr('fill',C.mute); sectors.forEach(s=>{ svg.append('text').attr('x',m.l-15).attr('y',y(s)+5).attr('text-anchor','end') .attr('font-family','Cormorant Garamond, serif').attr('font-style','italic') .attr('font-size',13).attr('fill',C.ink).attr('font-weight',600).text(s); svg.append('line').attr('x1',m.l).attr('x2',W-m.r).attr('y1',y(s)).attr('y2',y(s)) .attr('stroke',C.ink).attr('stroke-opacity',.06); }); svg.selectAll('.tick line, .domain').attr('stroke',C.ink).attr('stroke-opacity',.15); const legG = svg.append('g').attr('transform',`translate(${m.l},10)`); let lx = 0; Object.entries(colorByType).forEach(([k,v])=>{ legG.append('circle').attr('cx',lx).attr('cy',6).attr('r',5).attr('fill',v); legG.append('text').attr('x',lx+10).attr('y',10) .attr('font-family','Inter, sans-serif').attr('font-size',11).attr('fill',C.ink).text(k); lx += k.length*7 + 30; }); const nodes = events.map(e=>({ ...e, x0: x(e.date), y0: y(e.sector) })); const sim = d3.forceSimulation(nodes) .force('x', d3.forceX(d=>d.x0).strength(0.7)) .force('y', d3.forceY(d=>d.y0).strength(0.4)) .force('collide', d3.forceCollide(d=>r(d.amp)+2)) .stop(); for(let i=0;i<200;i++) sim.tick(); // CERCLES UNIQUEMENT — aucune icône const dotGroups = svg.selectAll('.bee-group').data(nodes).enter().append('g') .attr('class','bee-group') .attr('transform',d=>`translate(${d.x},${d.y})`); const dots = dotGroups.append('circle') .attr('class','bee-dot') .attr('r',0) .attr('fill',d=>colorByType[d.type]) .attr('fill-opacity',.85) .attr('stroke',C.paper).attr('stroke-width',1.5); const tip = document.getElementById('beeTip'); const beeBox = svg.node().parentNode; dotGroups.on('mouseenter', function(e,d){ const rect = beeBox.getBoundingClientRect(); const transform = this.getAttribute('transform'); const match = transform.match(/translate\(([\d.-]+),([\d.-]+)\)/); const cx_node = parseFloat(match[1]); const cy_node = parseFloat(match[2]); const svgEl = svg.node(); const svgRect = svgEl.getBoundingClientRect(); const scaleX = svgRect.width / W; const scaleY = svgRect.height / H; const px = svgRect.left - rect.left + cx_node * scaleX; const py = svgRect.top - rect.top + cy_node * scaleY; tip.innerHTML = `${d.name}${d.desc}${d.type} · amplitude ${d.amp}/10`; tip.style.left = px + 'px'; tip.style.top = (py - r(d.amp) - 6) + 'px'; tip.style.opacity = 1; }).on('mouseleave',()=>tip.style.opacity=0); ScrollTrigger.create({ trigger:'#ssqBee', start:'top 75%', onEnter:()=>{ dots.transition().duration(800).delay((d,i)=>i*70) .attr('r', d=>r(d.amp)); } }); })(); /* ============================================================ VIZ 10 — SUNBURST ============================================================ */ (function(){ const svg = d3.select('#ssqBurst'); if(svg.empty()) return; const W = 1000, H = 1000, cx = W/2, cy = H/2; const R_INNER = 130; const R_MID = 270; const R_OUTER = 460; const data = { name:'Résilience', children:[ {name:'Stocks stratégiques', desc:'Capacités nationales de stockage, dimensionnement, rotation.', color:C.wheat, children:[ {name:'Silos modernisés', desc:'Modernisation et extension des capacités de stockage portuaire.'}, {name:'Stock tampon', desc:'Dimensionnement minimal anti-choc pour les céréales stratégiques.'}, {name:'Réseau régional', desc:'Décentralisation des stocks sur le territoire national.'}, {name:'Traçabilité', desc:'Système d\'information temps réel sur les stocks publics et privés.'} ]}, {name:'Diversification', desc:'Pluralité des fournisseurs et des routes commerciales.', color:C.olive, children:[ {name:'Multi-fournisseurs', desc:'Réduction de la dépendance à un seul corridor (mer Noire).'}, {name:'Routes alternatives', desc:'Diversification logistique : Atlantique, mer Rouge, Méditerranée.'}, {name:'Contrats long terme', desc:'Accords pluriannuels avec garanties de volume.'}, {name:'Hedging', desc:'Outils de couverture sur les marchés à terme.'} ]}, {name:'Intrants critiques', desc:'Engrais, soufre, semences, équipements.', color:C.earth, children:[ {name:'Industrie engrais', desc:'Reconstruction des capacités tunisiennes de production d\'engrais.'}, {name:'Soufre & potasse', desc:'Sécurisation des approvisionnements en intrants miniers.'}, {name:'Semences locales', desc:'Variétés résilientes au climat semi-aride.'}, {name:'Maintenance GCT', desc:'Investissement dans les outils du Groupe Chimique Tunisien.'} ]}, {name:'Climat & eau', desc:'Adaptation à la raréfaction hydrique et aux sécheresses.', color:C.sky, children:[ {name:'Goutte-à-goutte', desc:'Généralisation des techniques économes en eau.'}, {name:'Dessalement', desc:'Combinaison transition énergétique et sécurité hydrique.'}, {name:'Variétés résistantes', desc:'Recherche agronomique sur les blés résilients à la sécheresse.'}, {name:'Assurance climat', desc:'Mécanismes de mutualisation du risque climatique.'} ]}, {name:'Énergie agricole', desc:'Décarbonation et autonomisation énergétique des exploitations.', color:C.wheatDeep, children:[ {name:'Solaire agricole', desc:'Déploiement photovoltaïque dans les exploitations.'}, {name:'Ammoniac vert', desc:'Production locale d\'engrais azotés bas carbone.'}, {name:'Efficacité énergétique', desc:'Réduction de l\'intensité énergétique des chaînes agricoles.'}, {name:'Stockage local', desc:'Batteries et autoconsommation décentralisée.'} ]}, {name:'Justice sociale', desc:'Pouvoir d\'achat, ciblage des subventions, cohésion territoriale.', color:C.rust, children:[ {name:'Subventions ciblées', desc:'Réforme de la caisse de compensation au profit des plus modestes.'}, {name:'Transferts directs', desc:'Substitution par des aides monétaires conditionnelles.'}, {name:'Pouvoir d\'achat', desc:'Politique salariale articulée à la sécurité alimentaire.'}, {name:'Diversité nutritionnelle', desc:'Diversification protéique au-delà des céréales subventionnées.'} ]} ] }; const root = d3.hierarchy(data).sum(d=>d.children ? 0 : 1); const partition = d3.partition().size([Math.PI*2, R_OUTER - R_INNER]); partition(root); root.descendants().forEach(d=>{ d.y0 += R_INNER; d.y1 += R_INNER; }); const arc = d3.arc() .startAngle(d=>d.x0) .endAngle(d=>d.x1) .innerRadius(d=>{ if(d.depth === 0) return 0; if(d.depth === 1) return R_INNER; return R_MID; }) .outerRadius(d=>{ if(d.depth === 0) return 0; if(d.depth === 1) return R_MID; return R_OUTER; }) .padAngle(0.008) .padRadius(R_INNER); const g = svg.append('g').attr('transform',`translate(${cx},${cy})`); function colorFor(d){ if(d.depth === 0) return 'transparent'; let p = d; while(p.depth > 1) p = p.parent; const base = p.data.color || C.wheat; if(d.depth === 1) return base; return d3.color(base).brighter(0.7).formatHex(); } const arcs = g.selectAll('path').data(root.descendants().filter(d=>d.depth>0)).enter() .append('path') .attr('class','burst-arc') .attr('d', arc) .attr('fill', d=>colorFor(d)) .attr('stroke', C.paper).attr('stroke-width', 2) .attr('opacity', 0); const defs = svg.append('defs'); root.descendants().filter(d=>d.depth===1).forEach((d,i)=>{ const midR = (R_INNER + R_MID)/2; const mid = (d.x0 + d.x1)/2; const flip = mid > Math.PI*0.5 && mid < Math.PI*1.5; const padA = 0.015; const startA = (flip ? d.x1 - padA : d.x0 + padA) - Math.PI/2; const endA = (flip ? d.x0 + padA : d.x1 - padA) - Math.PI/2; const sx = Math.cos(startA)*midR; const sy = Math.sin(startA)*midR; const ex = Math.cos(endA)*midR; const ey = Math.sin(endA)*midR; const sweep = flip ? 0 : 1; const pathId = `burstPath1_${i}`; defs.append('path') .attr('id', pathId) .attr('d', `M ${sx} ${sy} A ${midR} ${midR} 0 0 ${sweep} ${ex} ${ey}`); g.append('text') .attr('class','burst-lbl-1') .attr('font-family','Cormorant Garamond, serif') .attr('font-style','italic').attr('font-weight',700) .attr('font-size', 19) .attr('fill', C.paper) .attr('opacity', 0) .style('letter-spacing','0.02em') .append('textPath') .attr('href', `#${pathId}`) .attr('startOffset','50%') .attr('text-anchor','middle') .text(d.data.name); }); const lvl2 = root.descendants().filter(d=>d.depth===2); lvl2.forEach(d=>{ const midAngle = (d.x0 + d.x1)/2; const r = (R_MID + R_OUTER)/2; const flip = midAngle > Math.PI && midAngle < Math.PI*2; const rotation = midAngle * 180/Math.PI - 90; const txt = g.append('text') .attr('class','burst-lbl-2') .attr('transform', `rotate(${rotation}) translate(${r},0) ${flip?'rotate(180)':''}`) .attr('text-anchor','middle') .attr('font-family','Inter, sans-serif') .attr('font-weight',500) .attr('font-size', 12) .attr('fill', C.ink) .attr('opacity', 0); const words = d.data.name.split(' '); if(words.length > 1 && d.data.name.length > 12){ const mid = Math.ceil(words.length/2); const l1 = words.slice(0, mid).join(' '); const l2 = words.slice(mid).join(' '); txt.append('tspan').attr('x', 0).attr('dy','-0.4em').text(l1); txt.append('tspan').attr('x', 0).attr('dy','1.1em').text(l2); } else { txt.attr('dy','.35em').text(d.data.name); } }); const center = document.getElementById('burstCenter'); arcs.on('mouseenter', function(e,d){ center.querySelector('h5').textContent = d.data.name; center.querySelector('p').textContent = d.data.desc || ''; center.querySelector('h5').style.color = d.depth===1 ? colorFor(d) : C.wheatDeep; }).on('mouseleave',()=>{ center.querySelector('h5').innerHTML = 'Résilience
alimentaire'; center.querySelector('h5').style.color = C.ink; center.querySelector('p').textContent = 'Survolez un pilier pour explorer ses leviers.'; }); ScrollTrigger.create({ trigger:'#ssqBurst', start:'top 75%', onEnter:()=>{ arcs.transition().duration(900).delay((d,i)=>d.depth===1 ? i*100 : 600+i*25) .attr('opacity',1); g.selectAll('.burst-lbl-1').transition().duration(600).delay(1200).attr('opacity',1); g.selectAll('.burst-lbl-2').transition().duration(600).delay(1600).attr('opacity',1); } }); })(); })();

Related posts

Le soleil en otage : souveraineté, concessions solaires et déficit stratégique en Tunisie

Le prix de la dépendance : la Tunisie face au choc énergétique de 2026

Algérie–Maroc : deux centralités stratégiques, deux vulnérabilités