<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Triangles Pathologiques MTC</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
min-height: 100vh;
background: linear-gradient(135deg, #3b82f6, #2563eb, #1d4ed8);
overflow-x: auto;
}
.container {
position: relative;
width: 100%;
min-height: 1200px;
overflow: auto;
}
.title-section {
position: absolute;
top: 16px;
left: 16px;
z-index: 10;
max-width: 800px;
}
.main-title {
color: white;
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 8px;
}
.subtitle {
color: white;
font-size: 1.125rem;
font-weight: 500;
margin-bottom: 16px;
opacity: 0.9;
}
.info-box {
position: absolute;
top: 16px;
right: 16px;
background: rgba(255, 255, 255, 0.9);
padding: 12px;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
max-width: 300px;
}
.info-title {
font-weight: bold;
font-size: 0.875rem;
margin-bottom: 8px;
}
.info-content {
font-size: 0.75rem;
line-height: 1.4;
}
.pole-item {
display: flex;
align-items: center;
margin-bottom: 4px;
}
.pole-color {
width: 16px;
height: 16px;
border-radius: 2px;
margin-right: 8px;
}
.interactive-info {
margin-top: 8px;
padding: 8px;
background: #faf5ff;
border-radius: 4px;
}
.signature {
position: absolute;
right: 16px;
bottom: 16px;
color: white;
font-size: 0.875rem;
}
.tooltip {
position: fixed;
z-index: 50;
background: rgba(243, 244, 246, 0.95);
color: #374151;
padding: 12px;
border-radius: 8px;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
pointer-events: none;
font-size: 0.875rem;
border: 1px solid #d1d5db;
max-width: 600px;
max-height: 80vh;
overflow-y: auto;
display: none;
}
.tooltip-title {
font-weight: bold;
font-size: 1rem;
margin-bottom: 8px;
}
.modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 40;
backdrop-filter: blur(2px);
display: none;
}
.modal {
position: fixed;
inset: 0;
z-index: 50;
display: flex;
align-items: center;
justify-content: center;
padding: 16px;
display: none;
}
.modal-content {
background: white;
border-radius: 8px;
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.25);
max-width: 1024px;
width: 100%;
max-height: 90vh;
display: flex;
flex-direction: column;
}
.modal-header {
padding: 24px;
border-radius: 8px 8px 0 0;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
color: white;
}
.modal-title {
font-size: 1.5rem;
font-weight: bold;
}
.modal-subtitle {
font-size: 0.875rem;
opacity: 0.9;
margin-top: 4px;
}
.modal-organs {
font-size: 0.75rem;
opacity: 0.8;
margin-top: 8px;
}
.close-button {
background: rgba(255, 255, 255, 0.2);
color: white;
border: none;
border-radius: 50%;
padding: 12px;
cursor: pointer;
transition: all 0.2s;
}
.close-button:hover {
background: rgba(255, 255, 255, 0.3);
transform: rotate(90deg) scale(1.1);
}
.modal-body {
flex: 1;
overflow-y: auto;
padding: 24px;
}
.mechanism-section {
padding: 16px;
border-radius: 8px;
border: 2px solid;
margin-bottom: 24px;
}
.mechanism-title {
font-weight: bold;
font-size: 1.25rem;
margin-bottom: 12px;
}
.mechanism-content {
background: white;
padding: 16px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.mechanism-text {
white-space: pre-line;
font-size: 0.875rem;
line-height: 1.5;
font-family: inherit;
}
.info-grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
margin-bottom: 24px;
}
@media (min-width: 768px) {
.info-grid {
grid-template-columns: 1fr 1fr;
}
}
.info-card {
padding: 16px;
border-radius: 8px;
border: 1px solid;
}
.info-card-title {
font-weight: bold;
font-size: 1.125rem;
margin-bottom: 8px;
}
.info-card-content {
background: white;
padding: 12px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.pathology-section {
padding: 16px;
border-radius: 8px;
border: 1px solid;
margin-bottom: 24px;
}
.pathology-content {
background: white;
padding: 12px;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
font-size: 0.875rem;
line-height: 1.5;
}
.poles-section {
padding: 16px;
border-radius: 8px;
border: 1px solid;
}
.poles-grid {
display: flex;
flex-wrap: wrap;
gap: 12px;
}
.pole-card {
display: flex;
align-items: center;
background: white;
padding: 12px;
border-radius: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
border: 2px solid;
}
.pole-icon {
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 12px;
}
.pole-name {
font-weight: 600;
font-size: 0.875rem;
}
.pole-organ {
font-size: 0.75rem;
color: #6b7280;
}
.modal-footer {
background: #f3f4f6;
padding: 12px;
border-top: 1px solid #e5e7eb;
box-shadow: 0 -4px 6px rgba(0, 0, 0, 0.1);
border-radius: 0 0 8px 8px;
}
.close-modal-button {
width: 100%;
color: white;
padding: 8px 16px;
border-radius: 8px;
border: none;
cursor: pointer;
transition: all 0.2s;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
font-weight: 600;
font-size: 1rem;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.close-modal-button:hover {
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
.cursor-pointer {
cursor: pointer;
}
.transition-all {
transition: all 0.2s;
}
</style>
<div class="container">
<!-- Titre -->
<div class="title-section">
<h1 class="main-title">Triangles Pathologiques MTC</h1>
<h2 class="subtitle">Les 10 triangles pathologiques de la Médecine Traditionnelle Chinoise</h2>
</div>
<!-- SVG principal -->
<svg width="100%" height="1200" style="position: absolute; top: 0; left: 0;" viewBox="0 0 1024 1200">
<defs>
<radialGradient id="centralGradient" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#ffd700" stop-opacity="0.8" />
<stop offset="50%" stop-color="#ffa500" stop-opacity="0.6" />
<stop offset="100%" stop-color="#ff6347" stop-opacity="0.4" />
</radialGradient>
</defs>
<!-- Grand cercle central -->
<circle
cx="512"
cy="530"
r="310"
fill="url(#centralGradient)"
stroke="#8b0000"
stroke-width="5"
opacity="0.9"
/>
<!-- Lignes de connexion (seront ajoutées dynamiquement) -->
<g id="connection-lines"></g>
<!-- Zones des 5 pôles (seront ajoutées dynamiquement) -->
<g id="poles-group"></g>
</svg>
<!-- Info box -->
<div class="info-box">
<h3 class="info-title">Triangles Pathologiques MTC</h3>
<div class="info-content">
<p style="margin-bottom: 8px;">Les 10 triangles pathologiques de la MTC.</p>
<div id="poles-info"></div>
<div class="interactive-info">
<div style="font-weight: 600; color: #7c3aed; margin-bottom: 4px;">🔺 Système interactif des triangles pathologiques</div>
<div style="color: #7c2d92; margin-bottom: 4px;">Survolez un triangle → tous les triangles du même type deviennent rouges</div>
<div style="color: #6b21a8; font-size: 0.75rem;">10 couleurs distinctes • Cliquez pour les détails</div>
</div>
</div>
</div>
<!-- Signature -->
<div class="signature">Docteur Jean-Yves HENRY</div>
<!-- Tooltip -->
<div id="tooltip" class="tooltip"></div>
<!-- Modal -->
<div id="modal-overlay" class="modal-overlay"></div>
<div id="modal" class="modal">
<div class="modal-content">
<div id="modal-header" class="modal-header">
<div>
<h2 id="modal-title" class="modal-title"></h2>
<p id="modal-subtitle" class="modal-subtitle"></p>
<div id="modal-organs" class="modal-organs"></div>
</div>
<button id="close-modal-x" class="close-button">
<svg width="28" height="28" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="3" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div id="modal-body" class="modal-body"></div>
<div class="modal-footer">
<button id="close-modal-button" class="close-modal-button">Fermer</button>
</div>
</div>
</div>
</div>
<script>
// Variables globales
let hoveredElement = null;
let hoveredTriangleType = null;
let selectedTriangle = null;
// Position centrale du pentagramme
const centerX = 512;
const centerY = 530;
const radius = 240;
// Calcul des positions des 5 pôles
const polePositions = {
FEU: { x: centerX, y: centerY - radius },
TERRE: { x: centerX + radius _Math.cos(18_ Math.PI / 180), y: centerY - radius _Math.sin(18_ Math.PI / 180) },
METAL: { x: centerX + radius _Math.cos(-54_ Math.PI / 180), y: centerY - radius _Math.sin(-54_ Math.PI / 180) },
EAU: { x: centerX - radius _Math.cos(-54_ Math.PI / 180), y: centerY - radius _Math.sin(-54_ Math.PI / 180) },
BOIS: { x: centerX - radius _Math.cos(18_ Math.PI / 180), y: centerY - radius _Math.sin(18_ Math.PI / 180) }
};
// Triangles pathologiques
const trianglesPathologiques = {
'Triangle du sang': {
poles: ['BOIS', 'FEU', 'TERRE'],
organes: ['Foie', 'Cœur', 'Rate-pancréas'],
description: 'Triangle de la circulation sanguine et de l\'hémostase',
mecanisme: '– le Foie thésorise le sang\n– le Cœur mobilise le sang\n– la Rate-pancréas « maintient le sang dans les vaisseaux » (coagulation)',
marqueur_bns: 'Alpha 1',
homeopathie: 'Ferrum/Kalium/Iodum',
pathologies: 'Troubles de la coagulation, hémorragies, anémies, troubles circulatoires',
couleur: '#dc2626'
},
'Triangle de l\'énergie': {
poles: ['TERRE', 'METAL', 'EAU'],
organes: ['Rate-pancréas', 'Poumon', 'Rein'],
description: 'Triangle de la production et distribution énergétique',
mecanisme: '– la Rate-pancréas gère les sucres (alimentation)\n– le Poumon apporte l\'oxygène (synthèse d\'ATP dans les mitochondries)\n– le Rein qui décide de son utilisation',
marqueur_bns: 'Alpha 2',
homeopathie: 'Stannum/Zincum/Silicea',
pathologies: 'Fatigue chronique, troubles métaboliques, diabète, hypoxie tissulaire',
couleur: '#059669'
},
'Triangle du Yin-Yang': {
poles: ['TERRE', 'EAU', 'BOIS'],
organes: ['Rate-pancréas', 'Rein', 'Foie'],
description: 'Triangle de l\'équilibre constitutionnel et de l\'adaptation',
mecanisme: '– la Rate-pancréas gère l\'immunité (acquis)\n– le Rein gère la structure (inné)\n– le Foie manifestera la sécheresse tissulaire-acidité locale à travers des manifestations tendino-musculaires (ex.: fibromyalgie)',
marqueur_bns: 'hypo Albumines + hyper Alpha 1',
homeopathie: 'Thuya occ. (na)/Acides/Manganum',
pathologies: 'Fibromyalgie, troubles auto-immuns, déséquilibres acido-basiques, sécheresse tissulaire',
couleur: '#7c3aed'
},
'Triangle de l\'eau': {
poles: ['EAU', 'FEU', 'METAL'],
organes: ['Rein', 'Cœur', 'Poumon'],
description: 'Triangle de la régulation hydrique et thermique',
mecanisme: '– le Rein est le « réservoir de l\'eau »\n– le Cœur est le thermosiphon\n– le Poumon est le « radiateur » (« source supérieure de l\'eau » qui retourne au rein)',
marqueur_bns: 'Albumines',
homeopathie: 'Antimonium tartar./Graphites/Antimonium crud./Petroleum/Lycopodium/Causticum/Natrum mur.',
pathologies: 'Asthme (eau retourne au poumon), eczéma, œdèmes, sécheresse, troubles thyroïdiens',
couleur: '#0ea5e9'
},
'Triangle des glaires': {
poles: ['TERRE', 'METAL', 'FEU'],
organes: ['Rate-pancréas', 'Poumon', 'Cœur'],
description: 'Triangle de la gestion des mucosités et de l\'humidité pathologique',
mecanisme: '– la Rate et le Poumon gèrent les « glaires » (l\'humidité des contraintes externes)\n– Les poussées ganglionnaires signalent la plénitude Rate\n– le Cœur est en plénitude (les plénitudes viennent du fils)',
marqueur_bns: 'Gamma',
homeopathie: 'Remèdes des lithiases et du cholestérol',
pathologies: 'Lithiases (glaires sèches), cholestérol, mucosités chroniques, adénopathies',
couleur: '#f59e0b'
},
'Triangle des feux': {
poles: ['EAU', 'BOIS', 'FEU'],
organes: ['Rein', 'Foie', 'Cœur'],
description: 'Triangle de l\'inflammation destructrice et des maladies auto-immunes',
mecanisme: '– le Rein est vide d\'eau (insomnie)\n– le Foie (le bois est sec)\n– le Cœur s\'enflamme ce qui brûlera les structures sous-jacentes (maladies auto-immunes ou cancer si « vent émotionnel »)',
marqueur_bns: 'Bêta',
homeopathie: 'Remèdes du feu pathologique',
pathologies: 'Maladies auto-immunes, cancer, inflammations chroniques destructrices, insomnie',
couleur: '#ef4444'
},
'Triangle des dystonies': {
poles: ['METAL', 'BOIS', 'TERRE'],
organes: ['Poumon', 'Foie', 'Rate-pancréas'],
description: 'Triangle des déséquilibres neuro-végétatifs et émotionnels',
mecanisme: '– le Poumon est vide d\'énergie et ne peut contrôler l\'émotionnel du Foie (cycle Ko)\n– le Foie plein écrase la logique de la Rate-pancréas, qui ne peut nourrir correctement le Poumon\n(ex.: spasmophilie)',
marqueur_bns: 'Troubles neuro-végétatifs',
homeopathie: 'Arsenicum, Sepia (mg)',
pathologies: 'Spasmophilie, troubles anxieux, dystonies neuro-végétatives, irritabilité',
couleur: '#8b5cf6'
},
'Triangle de la dépression': {
poles: ['METAL', 'EAU', 'BOIS'],
organes: ['Poumon', 'Rein', 'Foie'],
description: 'Triangle de la dépression et de l\'épuisement psychique',
mecanisme: 'Le Poumon (narcissisme et confiance en soi insuffisant) ne nourrit pas le Rein (la volonté) qui ne nourrit pas le Foie-VB (les envies / courage de décider)',
marqueur_bns: 'Marqueurs de l\'épuisement',
homeopathie: 'Silicea/Graphites/Aurum/Sepia',
pathologies: 'Dépression, manque de volonté, indécision chronique, épuisement psychique',
couleur: '#64748b'
},
'Triangle de la chaleur': {
poles: ['METAL', 'BOIS', 'FEU'],
organes: ['Poumon', 'Foie', 'Cœur'],
description: 'Triangle des inflammations aiguës et de la chaleur pathologique',
mecanisme: '– le Poumon est insuffisant à contrôler le Foie\n– le Foie est en plénitude – hypofonction\n– le cœur en plénitude (chaleur) écrase le poumon\n(ex.: angine ou psoriasis)',
marqueur_bns: 'Marqueurs inflammatoires',
homeopathie: 'Aconit (s)/Ferrum phos./Belladonna (ca)',
pathologies: 'Angines, psoriasis, inflammations aiguës, fièvre, éruptions cutanées',
couleur: '#dc2626'
},
'Triangle du Shen troublé': {
poles: ['TERRE', 'EAU', 'FEU'],
organes: ['Rate-pancréas', 'Rein', 'Cœur'],
description: 'Triangle des troubles psychiatriques et de la conscience altérée',
mecanisme: '– le Pancréas est insuffisant = pas de réponse logique\n– le Rein est insuffisant = dépression / insomnie\n– le Cœur (Shen) est en plénitude (ex.: accès maniaque, délire)',
marqueur_bns: 'Troubles du Shen',
homeopathie: 'Hyosciamus (ca)/Stramonium/Fluoricum acidum',
pathologies: 'Troubles psychiatriques, délire, accès maniaque, troubles de la conscience',
couleur: '#991b1b'
}
};
// Polychrestes
const polychrestes = {
FEU: {
color: '#ff4500',
position: polePositions.FEU,
name: 'FEU',
chineseName: 'Coeur'
},
TERRE: {
color: '#ffd700',
position: polePositions.TERRE,
name: 'TERRE',
chineseName: 'RP-Estomac'
},
METAL: {
color: '#c0c0c0',
position: polePositions.METAL,
name: 'MÉTAL',
chineseName: 'Poumon-GI'
},
EAU: {
color: '#4169e1',
position: polePositions.EAU,
name: 'EAU',
chineseName: 'Rein-Vessie'
},
BOIS: {
color: '#228b22',
position: polePositions.BOIS,
name: 'BOIS',
chineseName: 'Foie-VB'
}
};
// Couleurs des triangles
const triangleColors = {
'Triangle du sang': '#e74c3c',
'Triangle de l\'énergie': '#f39c12',
'Triangle du Yin-Yang': '#2ecc71',
'Triangle de l\'eau': '#3498db',
'Triangle des glaires': '#9b59b6',
'Triangle des feux': '#e67e22',
'Triangle des dystonies': '#34495e',
'Triangle de la dépression': '#8e44ad',
'Triangle de la chaleur': '#c0392b',
'Triangle du Shen troublé': '#16a085'
};
// Fonction pour obtenir la couleur d'un triangle
function getTriangleColor(triangleName, isHighlighted = false) {
if (isHighlighted) return '#ff0000';
return triangleColors[triangleName] || '#000000';
}
// Fonction pour obtenir tous les triangles d'un pôle
function getAllTrianglesForPole(poleKey) {
return Object.entries(trianglesPathologiques)
.filter(([triangleName, triangle]) => triangle.poles.includes(poleKey))
.map(([triangleName, triangle]) => ({
name: triangleName,
...triangle
}));
}
// Gestion du tooltip
function showTooltip(x, y, content) {
const tooltip = document.getElementById('tooltip');
tooltip.innerHTML = content;
tooltip.style.left = Math.min(x + 10, window.innerWidth - 600) + 'px';
tooltip.style.top = Math.max(y - 400, 10) + 'px';
tooltip.style.display = 'block';
}
function hideTooltip() {
document.getElementById('tooltip').style.display = 'none';
}
// Création du tooltip pour triangle
function formatTriangleTooltip(triangle) {
return `
<div class="tooltip-title" style="color: ${triangleColors[triangle.name]}">
${triangle.name}
</div>
<div>
<strong>Organes reliés :</strong> ${triangle.organes.join(' • ')}
</div>
`;
}
// Gestion du modal
function showModal(triangle) {
selectedTriangle = triangle;
// Header
document.getElementById('modal-title').textContent = triangle.name;
document.getElementById('modal-subtitle').textContent = triangle.description;
document.getElementById('modal-organs').textContent = 'Organes concernés : ' + triangle.organes.join(' • ');
document.getElementById('modal-header').style.backgroundColor = triangle.couleur;
document.getElementById('close-modal-button').style.backgroundColor = triangle.couleur;
// Body
document.getElementById('modal-body').innerHTML = `
<div class="mechanism-section" style="background-color: ${triangle.couleur}15; border-color: ${triangle.couleur}">
<div class="mechanism-title" style="color: ${triangle.couleur}">
🔑 Mécanisme Physiopathologique
</div>
<div class="mechanism-content">
<div class="mechanism-text">${triangle.mecanisme}</div>
</div>
</div>
<div class="info-grid">
<div class="info-card" style="background-color: ${triangle.couleur}10">
<div class="info-card-title" style="color: ${triangle.couleur}">
🩺 Marqueur BNS
</div>
<div class="info-card-content">
<span style="font-weight: 600;">${triangle.marqueur_bns}</span>
</div>
</div>
<div class="info-card" style="background-color: ${triangle.couleur}10">
<div class="info-card-title" style="color: ${triangle.couleur}">
💊 Remèdes Homéopathiques
</div>
<div class="info-card-content">
<span style="font-size: 0.875rem;">${triangle.homeopathie}</span>
</div>
</div>
</div>
<div class="pathology-section" style="background-color: ${triangle.couleur}10">
<div class="info-card-title" style="color: ${triangle.couleur}">
🎯 Pathologies Associées
</div>
<div class="pathology-content">${triangle.pathologies}</div>
</div>
<div class="poles-section" style="background-color: ${triangle.couleur}10">
<div class="info-card-title" style="color: ${triangle.couleur}">
⭐ Pôles Énergétiques Concernés
</div>
<div class="poles-grid">
${triangle.poles.map((poleKey, index) => {
const pole = polychrestes[poleKey];
return `
<div class="pole-card" style="border-color: ${pole.color}">
<div class="pole-icon" style="background-color: ${pole.color}"></div>
<div>
<div class="pole-name">${pole.name}</div>
<div class="pole-organ">${triangle.organes[index]}</div>
</div>
</div>
`;
}).join('')}
</div>
</div>
`;
document.getElementById('modal-overlay').style.display = 'block';
document.getElementById('modal').style.display = 'flex';
}
function hideModal() {
document.getElementById('modal-overlay').style.display = 'none';
document.getElementById('modal').style.display = 'none';
selectedTriangle = null;
hoveredTriangleType = null;
}
// Dessiner les lignes de connexion
function drawConnectionLines() {
const connectionLinesGroup = document.getElementById('connection-lines');
connectionLinesGroup.innerHTML = '';
if (!hoveredTriangleType) return;
const trianglePositions = [];
Object.entries(polychrestes).forEach(([poleKey, pole]) => {
const trianglesInPole = getAllTrianglesForPole(poleKey);
trianglesInPole.forEach((triangle, index) => {
if (triangle.name === hoveredTriangleType) {
const isTopRow = index < 3;
const positionInRow = isTopRow ? index : index - 3;
const trianglesInRow = isTopRow ? Math.min(3, trianglesInPole.length) : Math.max(0, trianglesInPole.length - 3);
const spacing = 40;
const startX = pole.position.x - (trianglesInRow * spacing) / 2 + spacing / 2;
const xPos = startX + (positionInRow * spacing);
const yPos = isTopRow ? pole.position.y - 50 : pole.position.y + 70;
trianglePositions.push({ x: xPos, y: yPos });
}
});
});
// Dessiner les lignes
for (let i = 0; i < trianglePositions.length; i++) {
for (let j = i + 1; j < trianglePositions.length; j++) {
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', trianglePositions[i].x);
line.setAttribute('y1', trianglePositions[i].y);
line.setAttribute('x2', trianglePositions[j].x);
line.setAttribute('y2', trianglePositions[j].y);
line.setAttribute('stroke', '#ff0000');
line.setAttribute('stroke-width', '6');
line.setAttribute('opacity', '0.9');
connectionLinesGroup.appendChild(line);
}
}
}
// Initialiser les pôles
function initializePoles() {
const polesGroup = document.getElementById('poles-group');
const polesInfo = document.getElementById('poles-info');
Object.entries(polychrestes).forEach(([poleKey, pole]) => {
// Créer le groupe pour ce pôle
const poleGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
// Cercle principal
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('cx', pole.position.x);
circle.setAttribute('cy', pole.position.y);
circle.setAttribute('r', '120');
circle.setAttribute('fill', '#ffffff');
circle.setAttribute('opacity', '0.8');
circle.setAttribute('stroke', pole.color);
circle.setAttribute('stroke-width', '3');
circle.classList.add('cursor-pointer', 'transition-all');
circle.addEventListener('mouseenter', () => {
hoveredElement = `triangles-${poleKey}`;
circle.setAttribute('opacity', '0.95');
circle.setAttribute('stroke-width', '4');
circle.style.filter = 'drop-shadow(0 0 20px rgba(255,255,255,0.8))';
});
circle.addEventListener('mouseleave', () => {
if (!hoveredElement?.startsWith('triangle-')) {
hoveredElement = null;
circle.setAttribute('opacity', '0.8');
circle.setAttribute('stroke-width', '3');
circle.style.filter = 'none';
}
});
poleGroup.appendChild(circle);
// Texte principal
const mainText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
mainText.setAttribute('x', pole.position.x);
mainText.setAttribute('y', (poleKey === 'BOIS' || poleKey === 'FEU') ? pole.position.y - 5 : pole.position.y);
mainText.setAttribute('text-anchor', 'middle');
mainText.setAttribute('fill', 'black');
mainText.setAttribute('font-weight', 'bold');
mainText.setAttribute('font-size', '16');
mainText.textContent = pole.name;
poleGroup.appendChild(mainText);
// Texte secondaire
const subText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
subText.setAttribute('x', pole.position.x);
subText.setAttribute('y', (poleKey === 'BOIS' || poleKey === 'FEU') ? pole.position.y + 15 : pole.position.y + 20);
subText.setAttribute('text-anchor', 'middle');
subText.setAttribute('fill', 'black');
subText.setAttribute('font-size', '12');
subText.textContent = pole.chineseName;
poleGroup.appendChild(subText);
// Triangles
const triangles = getAllTrianglesForPole(poleKey);
triangles.forEach((triangle, index) => {
const isTopRow = index < 3;
const positionInRow = isTopRow ? index : index - 3;
const trianglesInRow = isTopRow ? Math.min(3, triangles.length) : Math.max(0, triangles.length - 3);
const spacing = 40;
const startX = pole.position.x - (trianglesInRow * spacing) / 2 + spacing / 2;
const xPos = startX + (positionInRow * spacing);
const yPos = isTopRow ? pole.position.y - 50 : pole.position.y + 70;
// Zone de clic invisible
const clickArea = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
clickArea.setAttribute('cx', xPos);
clickArea.setAttribute('cy', yPos);
clickArea.setAttribute('r', '15');
clickArea.setAttribute('fill', 'transparent');
clickArea.classList.add('cursor-pointer');
// Triangle visible
const triangleText = document.createElementNS('http://www.w3.org/2000/svg', 'text');
triangleText.setAttribute('x', xPos);
triangleText.setAttribute('y', yPos + 5);
triangleText.setAttribute('text-anchor', 'middle');
triangleText.setAttribute('font-size', '45');
triangleText.setAttribute('font-weight', 'bold');
triangleText.setAttribute('fill', getTriangleColor(triangle.name));
triangleText.style.filter = 'drop-shadow(3px 3px 6px rgba(0,0,0,0.5))';
triangleText.style.transition = 'all 0.3s ease';
triangleText.style.pointerEvents = 'none';
triangleText.textContent = '▲';
// Events
clickArea.addEventListener('mouseenter', (e) => {
hoveredElement = `triangle-${triangle.name}`;
hoveredTriangleType = triangle.name;
triangleText.setAttribute('font-size', '60');
triangleText.setAttribute('fill', '#ff0000');
triangleText.style.filter = 'drop-shadow(0 0 15px rgba(255,0,0,1))';
drawConnectionLines();
showTooltip(e.clientX, e.clientY, formatTriangleTooltip(triangle));
});
clickArea.addEventListener('mouseleave', () => {
hoveredElement = `triangles-${poleKey}`;
hoveredTriangleType = null;
triangleText.setAttribute('font-size', '45');
triangleText.setAttribute('fill', getTriangleColor(triangle.name));
triangleText.style.filter = 'drop-shadow(3px 3px 6px rgba(0,0,0,0.5))';
drawConnectionLines();
hideTooltip();
});
clickArea.addEventListener('click', (e) => {
e.stopPropagation();
hideTooltip();
showModal(triangle);
});
poleGroup.appendChild(clickArea);
poleGroup.appendChild(triangleText);
});
polesGroup.appendChild(poleGroup);
// Info box
const poleDiv = document.createElement('div');
poleDiv.className = 'pole-item';
poleDiv.innerHTML = `
<div class="pole-color" style="background-color: ${pole.color}"></div>
<span style="font-size: 0.75rem;">${pole.name} - ${triangles.length} triangles</span>
`;
polesInfo.appendChild(poleDiv);
});
}
// Gestion des événements globaux
document.addEventListener('mousemove', (e) => {
if (document.getElementById('tooltip').style.display === 'block') {
document.getElementById('tooltip').style.left = Math.min(e.clientX + 10, window.innerWidth - 600) + 'px';
document.getElementById('tooltip').style.top = Math.max(e.clientY - 400, 10) + 'px';
}
});
// Events pour fermer le modal
document.getElementById('modal-overlay').addEventListener('click', hideModal);
document.getElementById('close-modal-x').addEventListener('click', hideModal);
document.getElementById('close-modal-button').addEventListener('click', hideModal);
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && selectedTriangle) {
hideModal();
}
});
// Initialisation
initializePoles();
</script>