diff --git a/packages/dashboard/index.html b/packages/dashboard/index.html index 3b362f4..ffec0d2 100644 --- a/packages/dashboard/index.html +++ b/packages/dashboard/index.html @@ -164,6 +164,11 @@ box-shadow: var(--shadow-card); transition: box-shadow 0.2s, border-color 0.2s; } + .card-header { + font-size: 1rem; font-weight: 700; color: var(--text-bright); + margin-bottom: 1rem; padding-bottom: 0.5rem; + border-bottom: 1px solid var(--border); + } .card:hover { box-shadow: var(--shadow-hover); } @@ -771,6 +776,36 @@ +
+
Methodology: How the Hype Cycle is Calculated
+
+

This Hype Cycle uses the Norton-Bass Multigenerational Diffusion Model to calculate adoption curves for optical transceiver technologies. The model extends the classic Bass diffusion model to handle multiple generations of technology that compete and cannibalize each other.

+

Key Parameters:

+ +

Phase Classification: Technologies are classified into five phases based on their position on the adoption curve: Innovation Trigger (0–16%), Peak of Inflated Expectations (16–35%), Trough of Disillusionment (35–55%), Slope of Enlightenment (55–80%), and Plateau of Productivity (80–100%).

+

Composite Score: A weighted blend of adoption velocity (40%), market momentum from pricing data (30%), and ecosystem maturity from compatibility entries (30%). Score ranges from 0–100.

+

Data Sources: Adoption timing derived from IEEE/MSA standard ratification dates, market data from aggregated pricing across 60+ vendors, and compatibility data from 29,000+ verified switch-transceiver pairs.

+
+
+ + + +
+
5-Year Adoption Forecast
+
+
+ + +
+
Regional Adoption Heatmap
+
+
+ @@ -1532,8 +1567,115 @@ async function openHypeDetail(name) { } catch(e) { el('panel-content').textContent = 'Error: ' + e.message; } } +// ── Forecast Area Chart (SVG) ────────────────────────────────────── +var TECH_COLORS = ['#FF8100','#4deaff','#a78bfa','#34d399','#fbbf24','#f87171','#818cf8','#fb923c','#22d3ee','#e879f9','#94a3b8']; + +function renderForecastChart(techs) { + var withFc = techs.filter(function(t) { return t.fiveYearForecast && t.fiveYearForecast.length > 0; }); + if (!withFc.length) return '
No forecast data — use enriched API endpoint
'; + + var W = 900, H = 320, P = 50, PR = 30, PT = 20, PB = 40; + var cw = W - P - PR, ch = H - PT - PB; + var years = withFc[0].fiveYearForecast.map(function(f) { return f.year; }); + var numYears = years.length; + + var svg = ''; + + // Grid + Y axis + for (var y = 0; y <= 100; y += 25) { + var gy = PT + ch - (y / 100) * ch; + svg += ''; + svg += '' + y + '%'; + } + + // X axis labels + for (var xi = 0; xi < numYears; xi++) { + var xx = P + (xi / (numYears - 1)) * cw; + svg += '' + years[xi] + ''; + } + + // Lines per technology + for (var ti = 0; ti < withFc.length; ti++) { + var t = withFc[ti]; + var color = TECH_COLORS[ti % TECH_COLORS.length]; + var pts = []; + for (var fi = 0; fi < t.fiveYearForecast.length; fi++) { + var f = t.fiveYearForecast[fi]; + var fx = P + (fi / (numYears - 1)) * cw; + var fy = PT + ch - (Math.min(f.adoptionPct, 100) / 100) * ch; + pts.push(fx + ',' + fy); + } + // Area fill + svg += ''; + // Line + svg += ''; + // Dots + for (var di = 0; di < pts.length; di++) { + var dp = pts[di].split(','); + svg += ''; + } + // Label at end + var lastPt = pts[pts.length - 1].split(','); + svg += '' + esc(t.technology) + ''; + } + + svg += ''; + return svg; +} + +// ── Regional Adoption Heatmap ────────────────────────────────────── +function renderRegionalHeatmap(techs) { + var regions = ['North America (Hyperscale)', 'China (BAT/Hyperscale)', 'APAC (ex-China)', 'Europe', 'Rest of World']; + var shortRegions = ['NA', 'China', 'APAC', 'Europe', 'RoW']; + // We need regional data — fetch per tech + var h = ''; + h += ''; + for (var ri = 0; ri < shortRegions.length; ri++) { + h += ''; + } + h += '
Technology' + shortRegions[ri] + 'Peak Year
'; + return h; +} + +async function loadRegionalData(techs) { + var body = document.getElementById('heatmap-body'); + if (!body) return; + var html = ''; + for (var ti = 0; ti < techs.length; ti++) { + var t = techs[ti]; + var color = PC[t.phase] || '#8888a4'; + try { + var rd = await api('/api/hype-cycle/regional/' + encodeURIComponent(t.technology)); + var regions = rd.regions || []; + html += ''; + html += '' + esc(t.technology) + ''; + for (var ri = 0; ri < 5; ri++) { + var r = regions[ri]; + if (r) { + var share = r.marketSharePct || 0; + var opacity = Math.max(0.15, share / 45); + html += '' + share + '%
' + esc(r.adoptionPhase) + ''; + } else { + html += '—'; + } + } + html += '' + (rd.globalPeakYear || '—') + ''; + html += ''; + } catch(e) { + html += '' + esc(t.technology) + '—'; + } + } + buildDOM(body, html); +} + async function loadHypeCycle() { - var data = await api('/api/hype-cycle'); + // Use enriched endpoint for forecast data + var data; + try { + data = await api('/api/hype-cycle/enriched'); + } catch(e) { + data = await api('/api/hype-cycle'); + } var techs = data.technologies || []; el('hype-year').textContent = data.year; @@ -1560,6 +1702,17 @@ async function loadHypeCycle() { el('hype-table').querySelectorAll('tr.clickable').forEach(function(row) { row.addEventListener('click', function() { openHypeDetail(this.getAttribute('data-tech')); }); }); + + // Render forecast chart (only if enriched data has forecasts) + var fcEl = document.getElementById('forecast-chart'); + if (fcEl) buildDOM(fcEl, renderForecastChart(techs)); + + // Render regional heatmap shell, then load data async + var hmEl = document.getElementById('regional-heatmap'); + if (hmEl) { + buildDOM(hmEl, renderRegionalHeatmap(techs)); + loadRegionalData(techs); + } } // TRANSCEIVERS