// SCRIPT EQUIPE - Remplacement DOM apres chargement (function() { 'use strict'; var path = window.location.pathname; var isTeamRoute = path === '/team' || path === '/team/' || path.startsWith('/team/'); if (!isTeamRoute) { return; } console.log('EQUIPE: Page team detectee, preparation du remplacement DOM'); // Fonction pour charger un script externe function loadScript(src) { return new Promise(function(resolve, reject) { var script = document.createElement('script'); script.src = src; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } // Fonction pour initialiser la page equipe async function initTeamPage() { console.log('EQUIPE: Initialisation de la page'); // CSS de la page var css = '*{margin:0;padding:0;box-sizing:border-box}' + 'body{font-family:system-ui,sans-serif;background:#1a4d3a;color:#e0e0e0;padding:20px}' + '.container{max-width:1400px;margin:0 auto}' + 'header{text-align:center;margin-bottom:30px;padding:20px;background:rgba(26,77,58,0.5);border-radius:8px}' + 'h1{color:#4ade80;margin-bottom:10px}' + '.tabs{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap}' + '.tab-btn{padding:12px 24px;background:rgba(74,222,128,0.2);border:2px solid #4ade80;color:#4ade80;border-radius:6px;cursor:pointer;font-size:14px;font-weight:600}' + '.tab-btn:hover{background:rgba(74,222,128,0.3)}' + '.tab-btn.active{background:#4ade80;color:#1a4d3a}' + '.tab-content{display:none;background:rgba(26,77,58,0.3);border-radius:8px;padding:20px;margin-bottom:20px}' + '.tab-content.active{display:block}' + '#network-graph{width:100%;height:700px;background:rgba(0,0,0,0.2);border-radius:8px;border:1px solid rgba(74,222,128,0.3)}' + '#congestion-matrix{width:100%;height:600px;background:rgba(0,0,0,0.2);border-radius:8px}' + '.genesis-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:15px;margin-bottom:30px}' + '.stat-card{background:rgba(74,222,128,0.1);border:1px solid rgba(74,222,128,0.3);border-radius:6px;padding:15px}' + '.stat-value{font-size:32px;font-weight:bold;color:#4ade80}' + '.stat-label{font-size:14px;color:#a0a0a0;margin-top:5px}' + '.member-card{background:rgba(26,77,58,0.5);border:1px solid rgba(74,222,128,0.3);border-radius:6px;padding:15px;margin-bottom:15px}' + '.member-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}' + '.member-name{font-size:18px;font-weight:bold;color:#4ade80}' + '.member-avail{background:rgba(74,222,128,0.2);padding:5px 12px;border-radius:4px;font-size:14px}' + '.tech-list{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}' + '.tech-tag{background:rgba(74,222,128,0.2);border:1px solid rgba(74,222,128,0.4);padding:4px 10px;border-radius:4px;font-size:12px}' + '.warning-box{background:rgba(255,68,68,0.2);border:1px solid rgba(255,68,68,0.5);border-radius:6px;padding:15px;margin-top:20px}' + '.warning-title{color:#ff6b6b;font-weight:bold;margin-bottom:10px}' + '.uncovered{background:rgba(255,68,68,0.1);border-left:3px solid #ff6b6b;padding:10px;margin:8px 0;border-radius:4px}' + '.legend{display:flex;gap:20px;margin:20px 0;flex-wrap:wrap}' + '.legend-item{display:flex;align-items:center;gap:8px}' + '.legend-color{width:20px;height:20px;border-radius:4px}' + '.loading{text-align:center;padding:40px;color:#4ade80}'; // HTML de la page var html = '
' + '
' + '
' + '← Retour au Radar' + '
' + '
' + '

Equipe & Technologies

' + '

Visualisation des competences et identification de l\'equipe de genese MVP

' + '
' + '
' + '' + '' + '' + '
' + '
' + '
' + '
Adopt
' + '
Trial
' + '
Assess
' + '
Hold
' + '
Membres
' + '
' + '
Chargement du graphe...
' + '
' + '
' + '

Matrice de Congestion - Technologies Adopt

' + '
Chargement de la matrice...
' + '
' + '
' + '
Chargement des donnees...
' + '
' + '
'; // Injecter le CSS var styleEl = document.createElement('style'); styleEl.textContent = css; document.head.appendChild(styleEl); // Modifier le titre document.title = 'Equipe & Technologies - Laplank'; // Remplacer le contenu du body document.body.innerHTML = html; document.body.style.cssText = 'font-family:system-ui,sans-serif;background:#1a4d3a;color:#e0e0e0;padding:20px;margin:0'; // Ajouter les gestionnaires d'evenements pour les onglets document.querySelectorAll('.tab-btn').forEach(function(btn) { btn.addEventListener('click', function() { var tabName = this.getAttribute('data-tab'); document.querySelectorAll('.tab-content').forEach(function(t) { t.classList.remove('active'); }); document.querySelectorAll('.tab-btn').forEach(function(b) { b.classList.remove('active'); }); document.getElementById(tabName + '-tab').classList.add('active'); this.classList.add('active'); // Redimensionner les graphiques if (tabName === 'congestion' && window.congestionChart) { setTimeout(function() { window.congestionChart.resize(); }, 100); } if (tabName === 'network' && window.networkCy) { setTimeout(function() { window.networkCy.resize(); }, 100); } }); }); console.log('EQUIPE: DOM remplace, chargement des bibliotheques...'); // Charger les bibliotheques externes try { await loadScript('https://cdn.jsdelivr.net/npm/cytoscape@3.26.0/dist/cytoscape.min.js'); console.log('EQUIPE: Cytoscape charge'); // Utilisation du layout cose integre (pas de plugin externe necessaire) await loadScript('https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js'); console.log('EQUIPE: ECharts charge'); // Charger les donnees var response = await fetch('/team-visualization-data.json'); if (!response.ok) throw new Error('HTTP ' + response.status); var data = await response.json(); console.log('EQUIPE: Donnees chargees:', Object.keys(data)); // Initialiser les visualisations initNetwork(data); initCongestion(data); initGenesis(data); } catch (e) { console.error('EQUIPE: Erreur:', e); var errorMsg = '

Erreur de chargement

' + e.message + '

'; document.getElementById('network-graph').innerHTML = errorMsg; document.getElementById('congestion-matrix').innerHTML = errorMsg; document.getElementById('genesis-team').innerHTML = errorMsg; } } // Graphe reseau avec Cytoscape function initNetwork(data) { if (!data || !data.network) { document.getElementById('network-graph').innerHTML = '
Pas de donnees reseau
'; return; } window.networkCy = cytoscape({ container: document.getElementById('network-graph'), elements: data.network, style: [ { selector: 'node[type="technology"]', style: { 'background-color': 'data(color)', 'label': 'data(label)', 'width': function(e) { return 30 + (e.data('coverage') || 0) * 8; }, 'height': function(e) { return 30 + (e.data('coverage') || 0) * 8; }, 'color': '#fff', 'font-size': '12px', 'text-outline-width': 2, 'text-outline-color': '#000', 'text-wrap': 'wrap', 'text-max-width': 100 } }, { selector: 'node[type="member"]', style: { 'background-color': '#88ff88', 'label': 'data(label)', 'width': function(e) { return 25 + (e.data('availability') || 0) / 3; }, 'height': function(e) { return 25 + (e.data('availability') || 0) / 3; }, 'color': '#1a4d3a', 'font-size': '11px', 'font-weight': 'bold', 'shape': 'ellipse' } }, { selector: 'edge', style: { 'width': function(e) { return 1 + (e.data('weight') || 0.5); }, 'line-color': '#999', 'opacity': 0.6, 'curve-style': 'bezier' } } ], layout: { name: 'cose', nodeDimensionsIncludeLabels: true, idealEdgeLength: 100, nodeRepulsion: 4500, gravity: 0.25, numIter: 1000, animate: true, animationDuration: 800 } }); console.log('EQUIPE: Graphe reseau initialise'); } // Matrice de congestion avec ECharts function initCongestion(data) { if (!data || !data.congestionMatrix || data.congestionMatrix.length === 0) { document.getElementById('congestion-matrix').innerHTML = '
Pas de donnees matrice
'; return; } var chart = echarts.init(document.getElementById('congestion-matrix')); window.congestionChart = chart; var techs = data.congestionMatrix.map(function(r) { return r.technology; }); var members = data.congestionMatrix[0] ? data.congestionMatrix[0].members.map(function(m) { return m.fullName || m.member; }) : []; var scatter = []; data.congestionMatrix.forEach(function(row, i) { row.members.forEach(function(m, j) { if (m.hasSkill) { scatter.push({ value: [j, i], member: m.fullName || m.member, tech: row.technology, availability: m.availability }); } }); }); chart.setOption({ title: { text: 'Disponibilite des membres sur les technologies Adopt', left: 'center', textStyle: { color: '#e0e0e0' } }, tooltip: { formatter: function(p) { return p.data.member + '
Tech: ' + p.data.tech + '
Dispo: ' + p.data.availability + '%'; } }, grid: { height: '60%', top: '15%' }, xAxis: { type: 'category', data: members, axisLabel: { rotate: 45, color: '#e0e0e0' }, axisLine: { lineStyle: { color: '#4ade80' } } }, yAxis: { type: 'category', data: techs, axisLabel: { color: '#e0e0e0' }, axisLine: { lineStyle: { color: '#4ade80' } } }, visualMap: { min: 0, max: 100, calculable: true, orient: 'horizontal', left: 'center', bottom: '5%', inRange: { color: ['#1a4d3a', '#4ade80', '#86efac'] }, textStyle: { color: '#e0e0e0' } }, series: [{ type: 'scatter', data: scatter, symbolSize: function(d) { return 15 + (d[2] || 0) / 2; }, itemStyle: { color: '#4ade80', borderColor: '#1a4d3a', borderWidth: 2 }, label: { show: true, formatter: function(p) { return p.data.availability + '%'; }, color: '#1a4d3a' } }] }); window.addEventListener('resize', function() { chart.resize(); }); console.log('EQUIPE: Matrice de congestion initialisee'); } // Equipe de genese function initGenesis(data) { if (!data || !data.genesisTeam) { document.getElementById('genesis-team').innerHTML = '
Pas de donnees equipe
'; return; } var g = data.genesisTeam; var h = '
' + '
' + g.totalMembers + '
Membres selectionnes
' + '
' + g.totalCapacity + '%
Capacite totale
' + '
' + g.averageAvailability + '%
Disponibilite moyenne
' + '
' + g.coveredTechnologies + '/' + g.totalCoreTechnologies + '
Technologies couvertes
' + '
' + '

Membres de l\'equipe de genese

'; if (g.team && g.team.length > 0) { g.team.forEach(function(m) { h += '
' + '
' + '
' + (m.fullName || m.member) + '
' + '
' + (m.role || '') + ' - ' + m.seniority + ' - ' + m.coverage + ' technologie(s)
' + '
' + '
' + m.availability + '% dispo
' + '
' + '
'; if (m.technologies) { m.technologies.forEach(function(t) { h += '' + t.title + ''; }); } h += '
'; }); } else { h += '

Aucun membre ne repond aux criteres.

'; } if (g.uncoveredTechnologies && g.uncoveredTechnologies.length > 0) { h += '
Technologies Adopt non couvertes

Ces technologies critiques ne sont pas maitrisees :

'; g.uncoveredTechnologies.forEach(function(t) { h += '
' + t.title + '
Impact: ' + t.businessImpact + ' - Gap: ' + t.skillGap + ' - Couverture: ' + t.teamCoverage + ' personne(s)
'; }); h += '
'; } document.getElementById('genesis-team').innerHTML = h; console.log('EQUIPE: Equipe de genese initialisee'); } // Demarrer quand le DOM est pret if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initTeamPage); } else { initTeamPage(); } })();