Infographics are a powerful tool for conveying complex information in a visually engaging way. They combine data, design, and storytelling to make information more accessible and memorable.
In this article, we will explore 10 outstanding infographic examples that demonstrate the versatility and impact of this medium. Each example showcases unique design elements and effective communication strategies.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Designers and developers love Subframe for its drag-and-drop interface and intuitive, responsive canvas. Create pixel-perfect UI effortlessly, ensuring your infographics are both stunning and functional.
Join the community of satisfied users and start for free today!
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI design game? With Subframe, you can create pixel-perfect infographics and UIs effortlessly. Our drag-and-drop interface ensures efficiency and stunning results.
Don't wait! Start for free and begin designing immediately. Join the community of satisfied users today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate Earnings Report</title> <style> :root { --brand-primary: #3366cc; --brand-secondary: #1a3366; --chart-positive: #34c759; --chart-negative: #ff3b30; --text-primary: #333333; --text-secondary: #666666; --background: #f8f9fa; --card-bg: #ffffff; --border-light: #e0e0e0; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; } body { background-color: var(--background); color: var(--text-primary); height: 100%; width: 100%; max-width: 700px; max-height: 700px; overflow-x: hidden; margin: 0 auto; } .infographic-container { padding: 24px; max-width: 700px; margin: 0 auto; } header { text-align: left; margin-bottom: 32px; position: relative; } .company-logo { width: 60px; height: 60px; background-color: var(--brand-primary); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-weight: 700; font-size: 24px; margin-bottom: 16px; position: relative; overflow: hidden; } .company-logo::after { content: ''; position: absolute; width: 30px; height: 30px; background-color: rgba(255, 255, 255, 0.1); border-radius: 50%; top: -10px; right: -10px; } h1 { font-size: 28px; font-weight: 700; margin-bottom: 8px; color: var(--text-primary); } h2 { font-size: 16px; font-weight: 400; color: var(--text-secondary); margin-bottom: 4px; } .fiscal-period { font-size: 14px; font-weight: 600; color: var(--brand-primary); margin-bottom: 8px; } .highlights { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 32px; } .highlight-card { background-color: var(--card-bg); border-radius: 8px; padding: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; } .highlight-card:hover { transform: translateY(-4px); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.08); } .metric-title { font-size: 13px; font-weight: 500; color: var(--text-secondary); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px; } .metric-value { font-size: 24px; font-weight: 700; margin-bottom: 4px; } .metric-change { font-size: 13px; font-weight: 500; display: flex; align-items: center; } .positive { color: var(--chart-positive); } .negative { color: var(--chart-negative); } .chart-section { background-color: var(--card-bg); border-radius: 12px; padding: 24px; margin-bottom: 24px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .chart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .chart-title { font-size: 16px; font-weight: 600; } .chart-legend { display: flex; gap: 16px; } .legend-item { display: flex; align-items: center; font-size: 13px; color: var(--text-secondary); } .legend-color { width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; } .revenue-color { background-color: var(--brand-primary); } .profit-color { background-color: var(--brand-secondary); } .chart-container { height: 200px; position: relative; } .bar-chart { display: flex; height: 100%; align-items: flex-end; gap: 12px; padding-top: 20px; } .bar-group { display: flex; flex: 1; gap: 4px; height: 100%; align-items: flex-end; } .bar { flex: 1; min-width: 12px; border-radius: 4px 4px 0 0; transition: height 1s cubic-bezier(0.23, 1, 0.32, 1); position: relative; cursor: pointer; overflow: hidden; } .bar:hover { opacity: 0.9; } .bar::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 20%; background: linear-gradient(rgba(255, 255, 255, 0.2), transparent); } .bar-label { position: absolute; top: -20px; left: 50%; transform: translateX(-50%); font-size: 11px; color: var(--text-secondary); white-space: nowrap; } .x-axis { display: flex; justify-content: space-between; margin-top: 8px; padding: 0 4px; } .axis-label { font-size: 11px; color: var(--text-secondary); flex: 1; text-align: center; } .tooltip { position: absolute; background-color: rgba(0, 0, 0, 0.8); color: white; padding: 6px 10px; border-radius: 4px; font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.2s; z-index: 10; white-space: nowrap; } .line-chart-container { position: relative; height: 200px; margin-top: 40px; } .line-chart-svg { width: 100%; height: 100%; overflow: visible; } .line-path { fill: none; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; } .revenue-line { stroke: var(--brand-primary); } .profit-line { stroke: var(--brand-secondary); } .data-point { cursor: pointer; transition: r 0.2s; } .data-point:hover { r: 6; } .segment-analysis { margin-bottom: 32px; } .segment-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; } .segment-card { background-color: var(--card-bg); border-radius: 8px; padding: 20px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .segment-title { font-size: 14px; font-weight: 600; margin-bottom: 12px; display: flex; align-items: center; } .segment-icon { width: 24px; height: 24px; border-radius: 4px; background-color: rgba(51, 102, 204, 0.1); margin-right: 8px; display: flex; align-items: center; justify-content: center; } .segment-icon svg { width: 14px; height: 14px; color: var(--brand-primary); } .segment-metrics { display: flex; justify-content: space-between; } .segment-metric { text-align: center; } .segment-value { font-size: 18px; font-weight: 600; margin-bottom: 2px; } .segment-label { font-size: 11px; color: var(--text-secondary); } .segment-progress { margin-top: 12px; height: 6px; background-color: rgba(51, 102, 204, 0.1); border-radius: 3px; overflow: hidden; } .segment-bar { height: 100%; background-color: var(--brand-primary); width: 0; border-radius: 3px; transition: width 1s ease-out; } .outlook-section { background-color: var(--card-bg); border-radius: 12px; padding: 24px; margin-bottom: 24px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .outlook-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .outlook-item { padding: 12px 0; border-bottom: 1px solid var(--border-light); } .outlook-heading { font-size: 13px; color: var(--text-secondary); margin-bottom: 4px; } .outlook-value { font-size: 16px; font-weight: 600; } .outlook-guidance { margin-top: 16px; padding: 12px; background-color: rgba(51, 102, 204, 0.05); border-radius: 6px; border-left: 3px solid var(--brand-primary); } .guidance-text { font-size: 13px; line-height: 1.5; } footer { text-align: center; font-size: 11px; color: var(--text-secondary); margin-top: 32px; padding-bottom: 16px; } @media (max-width: 600px) { .infographic-container { padding: 16px; } h1 { font-size: 24px; } .highlights { grid-template-columns: 1fr; } .segment-grid { grid-template-columns: 1fr; } .outlook-grid { grid-template-columns: 1fr; } } </style> </head> <body> <div class="infographic-container"> <header> <div class="company-logo">NV</div> <h1>NovaTech Quarterly Financial Results</h1> <div class="fiscal-period">Q3 FY2023 • October 1 - December 31, 2023</div> <h2>Financial performance exceeded market expectations with record cloud revenue</h2> </header> <div class="highlights"> <div class="highlight-card"> <div class="metric-title">Revenue</div> <div class="metric-value">$24.7B</div> <div class="metric-change positive">↑ 12.8% YoY</div> </div> <div class="highlight-card"> <div class="metric-title">Operating Income</div> <div class="metric-value">$8.2B</div> <div class="metric-change positive">↑ 9.4% YoY</div> </div> <div class="highlight-card"> <div class="metric-title">EPS (Diluted)</div> <div class="metric-value">$2.47</div> <div class="metric-change positive">↑ 14.2% YoY</div> </div> </div> <div class="chart-section"> <div class="chart-header"> <div class="chart-title">Quarterly Performance Trends</div> <div class="chart-legend"> <div class="legend-item"> <div class="legend-color revenue-color"></div> Revenue </div> <div class="legend-item"> <div class="legend-color profit-color"></div> Operating Income </div> </div> </div> <div class="chart-container"> <div class="bar-chart" id="quarterlyChart"></div> <div class="x-axis"> <div class="axis-label">Q3 FY22</div> <div class="axis-label">Q4 FY22</div> <div class="axis-label">Q1 FY23</div> <div class="axis-label">Q2 FY23</div> <div class="axis-label">Q3 FY23</div> </div> <div class="tooltip" id="barTooltip"></div> </div> </div> <div class="chart-section"> <div class="chart-header"> <div class="chart-title">Year-over-Year Growth</div> </div> <div class="line-chart-container"> <svg class="line-chart-svg" id="lineChart"></svg> <div class="tooltip" id="lineTooltip"></div> </div> </div> <div class="segment-analysis"> <h2 style="margin-bottom: 16px;">Revenue by Business Segment</h2> <div class="segment-grid"> <div class="segment-card"> <div class="segment-title"> <div class="segment-icon"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" /> </svg> </div> Cloud Services </div> <div class="segment-metrics"> <div class="segment-metric"> <div class="segment-value">$12.4B</div> <div class="segment-label">Revenue</div> </div> <div class="segment-metric"> <div class="segment-value positive">+24.6%</div> <div class="segment-label">YoY Growth</div> </div> </div> <div class="segment-progress"> <div class="segment-bar" data-width="50.2"></div> </div> </div> <div class="segment-card"> <div class="segment-title"> <div class="segment-icon"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z" /> </svg> </div> Hardware & Devices </div> <div class="segment-metrics"> <div class="segment-metric"> <div class="segment-value">$5.8B</div> <div class="segment-label">Revenue</div> </div> <div class="segment-metric"> <div class="segment-value negative">-3.2%</div> <div class="segment-label">YoY Growth</div> </div> </div> <div class="segment-progress"> <div class="segment-bar" data-width="23.5"></div> </div> </div> <div class="segment-card"> <div class="segment-title"> <div class="segment-icon"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 9l3 3-3 3m5 0h3M5 20h14a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /> </svg> </div> Enterprise Software </div> <div class="segment-metrics"> <div class="segment-metric"> <div class="segment-value">$4.2B</div> <div class="segment-label">Revenue</div> </div> <div class="segment-metric"> <div class="segment-value positive">+8.7%</div> <div class="segment-label">YoY Growth</div> </div> </div> <div class="segment-progress"> <div class="segment-bar" data-width="17.0"></div> </div> </div> <div class="segment-card"> <div class="segment-title"> <div class="segment-icon"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z" /> </svg> </div> Services & Support </div> <div class="segment-metrics"> <div class="segment-metric"> <div class="segment-value">$2.3B</div> <div class="segment-label">Revenue</div> </div> <div class="segment-metric"> <div class="segment-value positive">+5.6%</div> <div class="segment-label">YoY Growth</div> </div> </div> <div class="segment-progress"> <div class="segment-bar" data-width="9.3"></div> </div> </div> </div> </div> <div class="outlook-section"> <h2 style="margin-bottom: 20px;">Q4 FY2023 Outlook & Guidance</h2> <div class="outlook-grid"> <div class="outlook-item"> <div class="outlook-heading">Projected Revenue</div> <div class="outlook-value">$25.0B - $25.7B</div> </div> <div class="outlook-item"> <div class="outlook-heading">Operating Margin</div> <div class="outlook-value">32% - 33%</div> </div> <div class="outlook-item"> <div class="outlook-heading">EPS Guidance</div> <div class="outlook-value">$2.52 - $2.60</div> </div> <div class="outlook-item"> <div class="outlook-heading">Capital Expenditure</div> <div class="outlook-value">$3.2B - $3.5B</div> </div> </div> <div class="outlook-guidance"> <div class="guidance-text"> "We expect continued momentum in our cloud business with additional expansion in operating margins as we scale. The recent GreenEdge acquisition is expected to be accretive to earnings by Q1 FY2024." </div> </div> </div> <footer> Data as of January 25, 2024 • Investor Relations • NovaTech, Inc. </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Bar Chart Data const quarterlyData = [ { quarter: 'Q3 FY22', revenue: 21.9, income: 7.5 }, { quarter: 'Q4 FY22', revenue: 22.7, income: 7.8 }, { quarter: 'Q1 FY23', revenue: 23.2, income: 7.9 }, { quarter: 'Q2 FY23', revenue: 24.0, income: 8.0 }, { quarter: 'Q3 FY23', revenue: 24.7, income: 8.2 } ]; // Line Chart Data const growthData = [ { quarter: 'Q3 FY22', revenueGrowth: 8.2, profitGrowth: 6.8 }, { quarter: 'Q4 FY22', revenueGrowth: 9.1, profitGrowth: 7.3 }, { quarter: 'Q1 FY23', revenueGrowth: 10.5, profitGrowth: 8.2 }, { quarter: 'Q2 FY23', revenueGrowth: 11.7, profitGrowth: 8.9 }, { quarter: 'Q3 FY23', revenueGrowth: 12.8, profitGrowth: 9.4 } ]; // Initialize tooltip elements const barTooltip = document.getElementById('barTooltip'); const lineTooltip = document.getElementById('lineTooltip'); // Render Bar Chart function renderBarChart() { const chartContainer = document.getElementById('quarterlyChart'); const maxRevenue = Math.max(...quarterlyData.map(d => d.revenue)) * 1.1; chartContainer.innerHTML = ''; quarterlyData.forEach(data => { const barGroup = document.createElement('div'); barGroup.className = 'bar-group'; // Revenue Bar const revenueBar = document.createElement('div'); revenueBar.className = 'bar'; revenueBar.style.backgroundColor = 'var(--brand-primary)'; revenueBar.style.height = '0'; setTimeout(() => { revenueBar.style.height = `${(data.revenue / maxRevenue) * 100}%`; }, 100); const revenueLabel = document.createElement('div'); revenueLabel.className = 'bar-label'; revenueLabel.textContent = '$' + data.revenue + 'B'; revenueBar.appendChild(revenueLabel); revenueBar.addEventListener('mousemove', (e) => { barTooltip.textContent = `Revenue: $${data.revenue}B (${data.quarter})`; barTooltip.style.opacity = '1'; barTooltip.style.left = `${e.pageX + 10}px`; barTooltip.style.top = `${e.pageY - 30}px`; }); revenueBar.addEventListener('mouseleave', () => { barTooltip.style.opacity = '0'; }); // Operating Income Bar const incomeBar = document.createElement('div'); incomeBar.className = 'bar'; incomeBar.style.backgroundColor = 'var(--brand-secondary)'; incomeBar.style.height = '0'; setTimeout(() => { incomeBar.style.height = `${(data.income / maxRevenue) * 100}%`; }, 300); const incomeLabel = document.createElement('div'); incomeLabel.className = 'bar-label'; incomeLabel.textContent = '$' + data.income + 'B'; incomeBar.appendChild(incomeLabel); incomeBar.addEventListener('mousemove', (e) => { barTooltip.textContent = `Operating Income: $${data.income}B (${data.quarter})`; barTooltip.style.opacity = '1'; barTooltip.style.left = `${e.pageX + 10}px`; barTooltip.style.top = `${e.pageY - 30}px`; }); incomeBar.addEventListener('mouseleave', () => { barTooltip.style.opacity = '0'; }); barGroup.appendChild(revenueBar); barGroup.appendChild(incomeBar); chartContainer.appendChild(barGroup); }); } // Render Line Chart function renderLineChart() { const svg = document.getElementById('lineChart'); const width = svg.clientWidth; const height = svg.clientHeight; const padding = 40; // Clear previous content svg.innerHTML = ''; // Calculate scales const maxYValue = Math.max( ...growthData.map(d => Math.max(d.revenueGrowth, d.profitGrowth)) ) * 1.1; const xScale = (width - padding * 2) / (growthData.length - 1); const yScale = (height - padding * 2) / maxYValue; // Generate paths let revenuePath = `M${padding},${height - padding - growthData[0].revenueGrowth * yScale}`; let profitPath = `M${padding},${height - padding - growthData[0].profitGrowth * yScale}`; // Add grid lines for (let i = 0; i <= 5; i++) { const y = height - padding - (maxYValue * yScale * (i / 5)); const line = document.createElementNS('http://www.w3.org/2000/svg', 'line'); line.setAttribute('x1', padding); line.setAttribute('y1', y); line.setAttribute('x2', width - padding); line.setAttribute('y2', y); line.setAttribute('stroke', '#e0e0e0'); line.setAttribute('stroke-width', '1'); line.setAttribute('stroke-dasharray', '4,4'); svg.appendChild(line); const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', padding - 10); text.setAttribute('y', y + 4); text.setAttribute('text-anchor', 'end'); text.setAttribute('font-size', '10'); text.setAttribute('fill', '#666'); text.textContent = `${Math.round(maxYValue * (i / 5))}%`; svg.appendChild(text); } // Generate paths and add data points growthData.forEach((d, i) => { const x = padding + i * xScale; const yRevenue = height - padding - d.revenueGrowth * yScale; const yProfit = height - padding - d.profitGrowth * yScale; if (i > 0) { revenuePath += ` L${x},${yRevenue}`; profitPath += ` L${x},${yProfit}`; } // Create x-axis labels const text = document.createElementNS('http://www.w3.org/2000/svg', 'text'); text.setAttribute('x', x); text.setAttribute('y', height - padding + 20); text.setAttribute('text-anchor', 'middle'); text.setAttribute('font-size', '10'); text.setAttribute('fill', '#666'); text.textContent = d.quarter; svg.appendChild(text); // Add data points with tooltips const revenuePoint = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); revenuePoint.setAttribute('cx', x); revenuePoint.setAttribute('cy', yRevenue); revenuePoint.setAttribute('r', 4); revenuePoint.setAttribute('fill', 'var(--brand-primary)'); revenuePoint.setAttribute('class', 'data-point'); revenuePoint.addEventListener('mousemove', (e) => { lineTooltip.textContent = `Revenue Growth: ${d.revenueGrowth}% (${d.quarter})`; lineTooltip.style.opacity = '1'; lineTooltip.style.left = `${e.pageX + 10}px`; lineTooltip.style.top = `${e.pageY - 30}px`; }); revenuePoint.addEventListener('mouseleave', () => { lineTooltip.style.opacity = '0'; }); const profitPoint = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); profitPoint.setAttribute('cx', x); profitPoint.setAttribute('cy', yProfit); profitPoint.setAttribute('r', 4); profitPoint.setAttribute('fill', 'var(--brand-secondary)'); profitPoint.setAttribute('class', 'data-point'); profitPoint.addEventListener('mousemove', (e) => { lineTooltip.textContent = `Operating Income Growth: ${d.profitGrowth}% (${d.quarter})`; lineTooltip.style.opacity = '1'; lineTooltip.style.left = `${e.pageX + 10}px`; lineTooltip.style.top = `${e.pageY - 30}px`; }); profitPoint.addEventListener('mouseleave', () => { lineTooltip.style.opacity = '0'; }); svg.appendChild(revenuePoint); svg.appendChild(profitPoint); }); // Add paths const revenueLine = document.createElementNS('http://www.w3.org/2000/svg', 'path'); revenueLine.setAttribute('d', revenuePath); revenueLine.setAttribute('class', 'line-path revenue-line'); revenueLine.style.strokeDasharray = revenueLine.getTotalLength(); revenueLine.style.strokeDashoffset = revenueLine.getTotalLength(); svg.appendChild(revenueLine); const profitLine = document.createElementNS('http://www.w3.org/2000/svg', 'path'); profitLine.setAttribute('d', profitPath); profitLine.setAttribute('class', 'line-path profit-line'); profitLine.style.strokeDasharray = profitLine.getTotalLength(); profitLine.style.strokeDashoffset = profitLine.getTotalLength(); svg.appendChild(profitLine); // Animate paths setTimeout(() => { revenueLine.style.transition = 'stroke-dashoffset 1.5s ease-in-out'; revenueLine.style.strokeDashoffset = '0'; setTimeout(() => { profitLine.style.transition = 'stroke-dashoffset 1.5s ease-in-out'; profitLine.style.strokeDashoffset = '0'; }, 300); }, 500); // Add legend const legendGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g'); // Revenue legend const revLegendRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); revLegendRect.setAttribute('x', width - padding - 140); revLegendRect.setAttribute('y', 10); revLegendRect.setAttribute('width', 10); revLegendRect.setAttribute('height', 10); revLegendRect.setAttribute('fill', 'var(--brand-primary)'); legendGroup.appendChild(revLegendRect); const revLegendText = document.createElementNS('http://www.w3.org/2000/svg', 'text'); revLegendText.setAttribute('x', width - padding - 125); revLegendText.setAttribute('y', 18); revLegendText.setAttribute('font-size', '11'); revLegendText.setAttribute('fill', '#666'); revLegendText.textContent = 'Revenue Growth'; legendGroup.appendChild(revLegendText); // Profit legend const profitLegendRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); profitLegendRect.setAttribute('x', width - padding - 140); profitLegendRect.setAttribute('y', 30); profitLegendRect.setAttribute('width', 10); profitLegendRect.setAttribute('height', 10); profitLegendRect.setAttribute('fill', 'var(--brand-secondary)'); legendGroup.appendChild(profitLegendRect); const profitLegendText = document.createElementNS('http://www.w3.org/2000/svg', 'text'); profitLegendText.setAttribute('x', width - padding - 125); profitLegendText.setAttribute('y', 38); profitLegendText.setAttribute('font-size', '11'); profitLegendText.setAttribute('fill', '#666'); profitLegendText.textContent = 'Operating Income Growth'; legendGroup.appendChild(profitLegendText); svg.appendChild(legendGroup); } // Animate segment progress bars function animateProgressBars() { const bars = document.querySelectorAll('.segment-bar'); bars.forEach(bar => { setTimeout(() => { bar.style.width = `${bar.dataset.width}%`; }, 500); }); } // Initialize the charts renderBarChart(); renderLineChart(); animateProgressBars(); // Redraw on window resize for responsiveness window.addEventListener('resize', function() { renderLineChart(); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Weather Trends Infographic</title> <style> :root { --primary-dark: #1a3c5e; --primary: #2978b5; --primary-light: #8ecae6; --secondary: #70c1b3; --accent: #50a28e; --highlight: #f8f1aa; --text-light: #f2f9ff; --text-dark: #333c4d; --rain: #6baed6; --snow: #c6dbef; --sun: #ffca3a; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(145deg, var(--primary-dark), var(--primary)); color: var(--text-light); display: flex; flex-direction: column; align-items: center; justify-content: flex-start; min-height: 100vh; padding: 20px; overflow-x: hidden; } .container { width: 100%; max-width: 700px; height: 700px; background: rgba(255, 255, 255, 0.08); backdrop-filter: blur(10px); border-radius: 20px; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2); padding: 25px; overflow-y: auto; display: flex; flex-direction: column; gap: 20px; } header { text-align: center; margin-bottom: 10px; } h1 { font-size: 2.2rem; font-weight: 700; background: linear-gradient(90deg, var(--primary-light), var(--secondary)); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); margin-bottom: 8px; letter-spacing: -0.5px; } .subtitle { font-size: 1rem; font-weight: 300; opacity: 0.9; max-width: 85%; margin: 0 auto; } .dashboard { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: auto; gap: 20px; } .card { background: rgba(255, 255, 255, 0.1); border-radius: 15px; padding: 18px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; position: relative; overflow: hidden; } .card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15); } .card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 4px; background: linear-gradient(90deg, var(--primary-light), var(--secondary)); opacity: 0; transition: opacity 0.3s ease; } .card:hover::before { opacity: 1; } .card-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 12px; display: flex; align-items: center; gap: 8px; } .card-title i { font-size: 1.3rem; color: var(--secondary); } .temp-trend { grid-column: 1 / -1; height: 220px; } .temp-chart-container { height: 170px; margin-top: 10px; position: relative; } .data-point { position: absolute; width: 12px; height: 12px; border-radius: 50%; background-color: var(--primary-light); transform: translate(-50%, -50%); cursor: pointer; z-index: 5; box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.1); transition: all 0.3s ease; } .data-point:hover { transform: translate(-50%, -50%) scale(1.3); background-color: var(--highlight); } .data-line { position: absolute; height: 2px; background: linear-gradient(90deg, var(--primary-light), var(--secondary)); z-index: 1; } .tooltip { position: absolute; background-color: var(--primary-dark); color: var(--text-light); padding: 10px; border-radius: 6px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2); font-size: 0.85rem; pointer-events: none; opacity: 0; transform: translateY(10px); transition: all 0.3s ease; z-index: 10; width: max-content; max-width: 200px; } .tooltip::after { content: ''; position: absolute; bottom: -5px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid var(--primary-dark); } .data-point:hover .tooltip { opacity: 1; transform: translateY(-5px); } .chart-labels { display: flex; justify-content: space-between; margin-top: 8px; padding: 0 10px; color: rgba(255, 255, 255, 0.7); font-size: 0.75rem; } .precip-type { display: flex; flex-direction: column; gap: 10px; } .precip-bar { height: 12px; background-color: rgba(255, 255, 255, 0.1); border-radius: 6px; overflow: hidden; position: relative; } .precip-fill { height: 100%; border-radius: 6px; transition: width 1s cubic-bezier(0.34, 1.56, 0.64, 1); } .rain-fill { background: linear-gradient(90deg, var(--primary-light), var(--rain)); width: 0; } .snow-fill { background: linear-gradient(90deg, var(--primary-light), var(--snow)); width: 0; } .precip-label { display: flex; justify-content: space-between; font-size: 0.85rem; margin-bottom: 3px; } .precip-value { font-weight: 600; } .extreme-events { position: relative; } .event-list { margin-top: 15px; max-height: 140px; overflow-y: auto; } .event-item { display: flex; padding: 8px 0; border-bottom: 1px solid rgba(255, 255, 255, 0.1); gap: 10px; align-items: center; } .event-icon { width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; background-color: rgba(255, 255, 255, 0.15); font-size: 0.9rem; } .event-details { flex: 1; } .event-title { font-weight: 600; font-size: 0.9rem; } .event-date { color: rgba(255, 255, 255, 0.7); font-size: 0.75rem; } .monthly-avg { text-align: center; } .gauge-container { position: relative; height: 120px; margin: 15px 0; } .gauge { width: 100%; height: 100%; position: relative; } .gauge-bg { position: absolute; width: 150px; height: 75px; top: 50%; left: 50%; transform: translate(-50%, -50%); background: conic-gradient( var(--primary-light) 0%, var(--secondary) 50%, var(--highlight) 100% ); border-radius: 150px 150px 0 0; clip-path: polygon(0 100%, 50% 0, 100% 100%); opacity: 0.3; } .gauge-fill { position: absolute; width: 130px; height: 65px; top: 50%; left: 50%; transform: translate(-50%, -50%); background: conic-gradient( var(--primary-light) 0%, var(--secondary) 50%, var(--highlight) 100% ); border-radius: 130px 130px 0 0; clip-path: polygon(0 100%, 50% 0, 100% 100%); } .gauge-center { position: absolute; width: 20px; height: 20px; border-radius: 50%; background-color: var(--primary-dark); border: 3px solid var(--primary-light); bottom: 0; left: 50%; transform: translateX(-50%); z-index: 2; } .gauge-needle { position: absolute; height: 65px; width: 4px; background-color: var(--highlight); bottom: 0px; left: 50%; transform: translateX(-50%) rotate(-90deg); transform-origin: bottom center; transition: transform 1.5s cubic-bezier(0.34, 1.56, 0.64, 1); z-index: 1; border-radius: 4px 4px 0 0; } .gauge-value { font-size: 1.5rem; font-weight: 700; color: var(--highlight); margin-top: 10px; } .compare-normal { font-size: 0.85rem; color: rgba(255, 255, 255, 0.8); } .temp-day { display: flex; flex-direction: column; align-items: center; } .day-night { display: flex; justify-content: space-around; width: 100%; margin-top: 20px; } .temp-circle { width: 80px; height: 80px; border-radius: 50%; display: flex; align-items: center; justify-content: center; flex-direction: column; background: linear-gradient(145deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.05)); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; } .temp-circle:hover { transform: scale(1.1); } .day-temp { border: 2px solid var(--sun); } .night-temp { border: 2px solid var(--primary-light); } .temp-value { font-size: 1.5rem; font-weight: 700; } .temp-label { font-size: 0.8rem; opacity: 0.8; } .temp-diff { margin-top: 15px; font-size: 0.9rem; padding: 5px 10px; background-color: rgba(255, 255, 255, 0.1); border-radius: 5px; display: inline-block; } .legend { display: flex; gap: 15px; justify-content: center; margin-top: 20px; font-size: 0.8rem; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 12px; height: 12px; border-radius: 50%; } footer { margin-top: 20px; text-align: center; font-size: 0.8rem; opacity: 0.7; } .rain-legend { background-color: var(--rain); } .snow-legend { background-color: var(--snow); } .temp-legend { background-color: var(--highlight); } @media (max-width: 600px) { .dashboard { grid-template-columns: 1fr; } h1 { font-size: 1.8rem; } .temp-trend { height: 250px; } .temp-chart-container { height: 200px; } .card-title { font-size: 1.1rem; } .gauge-bg, .gauge-fill { width: 120px; height: 60px; } .gauge-needle { height: 55px; } } /* Animations */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes fadeIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .container { animation: fadeIn 0.6s ease-out forwards; } .card { animation: fadeIn 0.6s ease-out forwards; animation-delay: calc(var(--delay) * 0.1s); opacity: 0; } .gauge-value { animation: pulse 2s infinite; } /* Scrollbar styling */ ::-webkit-scrollbar { width: 6px; } ::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 3px; } ::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.2); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.3); } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css"> </head> <body> <div class="container"> <header> <h1>Climate Pulse: PNW 2023</h1> <p class="subtitle">Tracking Pacific Northwest's weather patterns and anomalies with comparative historical data</p> </header> <div class="dashboard"> <div class="card temp-trend" style="--delay:0"> <div class="card-title"> <i class="fas fa-temperature-high"></i> <span>Temperature Trends (°F)</span> </div> <div class="temp-chart-container" id="tempChart"> <!-- Data points and lines will be added dynamically --> </div> <div class="chart-labels"> <span>Jan</span> <span>Mar</span> <span>May</span> <span>Jul</span> <span>Sep</span> <span>Nov</span> </div> <div class="legend"> <div class="legend-item"> <div class="legend-color temp-legend"></div> <span>2023 Temps</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color:rgba(255,255,255,0.5)"></div> <span>10-Year Average</span> </div> </div> </div> <div class="card precip-type" style="--delay:1"> <div class="card-title"> <i class="fas fa-cloud-rain"></i> <span>Precipitation Distribution</span> </div> <div class="precip-label"> <span>Rainfall</span> <span class="precip-value">72%</span> </div> <div class="precip-bar"> <div class="precip-fill rain-fill" id="rainFill"></div> </div> <div class="precip-label"> <span>Snowfall</span> <span class="precip-value">36%</span> </div> <div class="precip-bar"> <div class="precip-fill snow-fill" id="snowFill"></div> </div> <div class="legend" style="margin-top:10px"> <div class="legend-item"> <div class="legend-color rain-legend"></div> <span>Rain</span> </div> <div class="legend-item"> <div class="legend-color snow-legend"></div> <span>Snow</span> </div> </div> </div> <div class="card extreme-events" style="--delay:2"> <div class="card-title"> <i class="fas fa-exclamation-triangle"></i> <span>Notable Weather Events</span> </div> <div class="event-list"> <div class="event-item"> <div class="event-icon"><i class="fas fa-fire"></i></div> <div class="event-details"> <div class="event-title">Record High: 107°F</div> <div class="event-date">August 17, 2023</div> </div> </div> <div class="event-item"> <div class="event-icon"><i class="fas fa-snowflake"></i></div> <div class="event-details"> <div class="event-title">Late Season Snow: 4.2 in</div> <div class="event-date">April 3, 2023</div> </div> </div> <div class="event-item"> <div class="event-icon"><i class="fas fa-cloud-showers-heavy"></i></div> <div class="event-details"> <div class="event-title">Rainfall Record: 3.8 in/24hr</div> <div class="event-date">November 12, 2023</div> </div> </div> <div class="event-item"> <div class="event-icon"><i class="fas fa-wind"></i></div> <div class="event-details"> <div class="event-title">Wind Gusts: 67 mph</div> <div class="event-date">December 1, 2023</div> </div> </div> </div> </div> <div class="card monthly-avg" style="--delay:3"> <div class="card-title"> <i class="fas fa-calendar-day"></i> <span>November Averages</span> </div> <div class="gauge-container"> <div class="gauge"> <div class="gauge-bg"></div> <div class="gauge-fill"></div> <div class="gauge-center"></div> <div class="gauge-needle" id="gaugeNeedle"></div> </div> </div> <div class="gauge-value">47.5°F</div> <div class="compare-normal">3.2°F above normal</div> </div> <div class="card temp-day" style="--delay:4"> <div class="card-title"> <i class="fas fa-sun"></i> <span>Day/Night Temperature Gap</span> </div> <div class="day-night"> <div class="temp-circle day-temp"> <span class="temp-value">62°F</span> <span class="temp-label">Daytime</span> </div> <div class="temp-circle night-temp"> <span class="temp-value">42°F</span> <span class="temp-label">Nighttime</span> </div> </div> <div class="temp-diff"> <i class="fas fa-exchange-alt"></i> 20°F daily variation </div> </div> </div> <footer> Data sourced from NOAA and local weather stations • Last updated: December 12, 2023 </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Temperature chart data const tempData = [ { month: 'Jan', temp: 38, avg: 34, x: '8%', y: '65%' }, { month: 'Feb', temp: 42, avg: 38, x: '20%', y: '55%' }, { month: 'Mar', temp: 48, avg: 44, x: '28%', y: '40%' }, { month: 'Apr', temp: 53, avg: 51, x: '36%', y: '30%' }, { month: 'May', temp: 60, avg: 58, x: '44%', y: '15%' }, { month: 'Jun', temp: 68, avg: 64, x: '52%', y: '5%' }, { month: 'Jul', temp: 75, avg: 69, x: '60%', y: '2%' }, { month: 'Aug', temp: 74, avg: 70, x: '68%', y: '3%' }, { month: 'Sep', temp: 67, avg: 65, x: '76%', y: '8%' }, { month: 'Oct', temp: 57, avg: 54, x: '84%', y: '25%' }, { month: 'Nov', temp: 47, avg: 44, x: '92%', y: '40%' } ]; const chartContainer = document.getElementById('tempChart'); // Create avg temp line const avgLine = document.createElement('div'); avgLine.className = 'data-line'; avgLine.style.bottom = '20%'; avgLine.style.left = '8%'; avgLine.style.width = '84%'; avgLine.style.background = 'rgba(255, 255, 255, 0.3)'; chartContainer.appendChild(avgLine); // Create data points and connect with lines for (let i = 0; i < tempData.length - 1; i++) { const current = tempData[i]; const next = tempData[i + 1]; // Create data point const dataPoint = document.createElement('div'); dataPoint.className = 'data-point'; dataPoint.style.left = current.x; dataPoint.style.top = current.y; // Add tooltip const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; tooltip.textContent = `${current.month}: ${current.temp}°F (Avg: ${current.avg}°F)`; dataPoint.appendChild(tooltip); chartContainer.appendChild(dataPoint); // Connect with line if (i < tempData.length - 1) { const x1 = parseFloat(current.x); const y1 = parseFloat(current.y); const x2 = parseFloat(next.x); const y2 = parseFloat(next.y); const length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) * 700 / 100; const angle = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; const line = document.createElement('div'); line.className = 'data-line'; line.style.width = `${length}px`; line.style.left = current.x; line.style.top = current.y; line.style.transformOrigin = 'left center'; line.style.transform = `rotate(${angle}deg)`; line.style.background = 'linear-gradient(90deg, var(--highlight), var(--secondary))'; chartContainer.appendChild(line); } } // Add the last data point const lastPoint = document.createElement('div'); lastPoint.className = 'data-point'; lastPoint.style.left = tempData[tempData.length - 1].x; lastPoint.style.top = tempData[tempData.length - 1].y; const lastTooltip = document.createElement('div'); lastTooltip.className = 'tooltip'; lastTooltip.textContent = `${tempData[tempData.length - 1].month}: ${tempData[tempData.length - 1].temp}°F (Avg: ${tempData[tempData.length - 1].avg}°F)`; lastPoint.appendChild(lastTooltip); chartContainer.appendChild(lastPoint); // Animate precipitation bars setTimeout(() => { document.getElementById('rainFill').style.width = '72%'; document.getElementById('snowFill').style.width = '36%'; }, 500); // Animate gauge needle setTimeout(() => { // Position at 47.5°F which is about 60% of the way from 0 to 90 degrees document.getElementById('gaugeNeedle').style.transform = 'translateX(-50%) rotate(-36deg)'; }, 800); // Make cards draggable for touch interfaces const cards = document.querySelectorAll('.card'); cards.forEach(card => { // Add hover effect for desktop devices card.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-5px)'; }); card.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Engagement Dashboard</title> <style> :root { --primary: #5252e8; --secondary: #ff4fc9; --tertiary: #00c9a7; --fb: #3b5998; --insta: linear-gradient(45deg, #f09433 0%, #e6683c 25%, #dc2743 50%, #cc2366 75%, #bc1888 100%); --twitter: #1da1f2; --linkedin: #0077b5; --tiktok: #000000; --white: #ffffff; --dark: #1e1e2f; --gray: #8a8a9b; --light-gray: #f5f5f7; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', 'Roboto', sans-serif; } body { background-color: var(--light-gray); color: var(--dark); overflow-x: hidden; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; display: flex; flex-direction: column; background-color: var(--white); border-radius: 20px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.05); overflow-y: auto; } header { text-align: center; margin-bottom: 25px; } h1 { font-size: 28px; margin-bottom: 10px; background: linear-gradient(to right, var(--primary), var(--secondary)); -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 800; } .time-period { display: flex; justify-content: center; gap: 10px; margin-bottom: 20px; } .time-btn { background: var(--light-gray); border: none; padding: 8px 15px; border-radius: 20px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; } .time-btn.active { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; box-shadow: 0 4px 15px rgba(82, 82, 232, 0.3); } .metrics-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 25px; } .metric-card { background: white; border-radius: 15px; padding: 15px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); display: flex; flex-direction: column; transition: transform 0.3s ease; } .metric-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .metric-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .metric-title { font-size: 14px; color: var(--gray); display: flex; align-items: center; gap: 5px; } .metric-icon { width: 18px; height: 18px; } .metric-value { font-size: 28px; font-weight: 700; } .metric-growth { font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 3px; } .growth-positive { color: var(--tertiary); } .growth-negative { color: #ff4757; } .platform-chart { margin-bottom: 25px; } .chart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .chart-title { font-size: 18px; font-weight: 700; } .platform-legend { display: flex; gap: 15px; } .legend-item { display: flex; align-items: center; gap: 5px; font-size: 12px; } .legend-color { width: 10px; height: 10px; border-radius: 50%; } .chart-container { height: 250px; position: relative; } .engagement-by-post { margin-bottom: 25px; } .top-posts { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 15px; } .post-card { background: white; border-radius: 15px; overflow: hidden; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease; cursor: pointer; position: relative; } .post-card:hover { transform: scale(1.05); } .post-image { width: 100%; height: 120px; object-fit: cover; } .post-overlay { position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.6); padding: 10px; color: white; font-size: 12px; } .post-platform { position: absolute; top: 10px; right: 10px; width: 25px; height: 25px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 14px; } .platform-fb { background: var(--fb); } .platform-insta { background: #e1306c; } .platform-twitter { background: var(--twitter); } .platform-linkedin { background: var(--linkedin); } .platform-tiktok { background: var(--tiktok); } .post-stats { display: flex; justify-content: space-between; font-size: 12px; margin-top: 5px; } .audience-insights { margin-bottom: 25px; } .age-gender-chart { height: 200px; display: flex; gap: 20px; } .age-chart, .gender-chart { flex: 1; border-radius: 15px; padding: 15px; background: white; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); } .chart-title-sm { font-size: 16px; font-weight: 600; margin-bottom: 15px; text-align: center; } .gender-container { display: flex; height: 120px; align-items: center; justify-content: center; gap: 30px; } .gender-stat { display: flex; flex-direction: column; align-items: center; } .gender-icon { font-size: 32px; margin-bottom: 10px; } .gender-value { font-size: 20px; font-weight: 700; } .gender-label { font-size: 14px; color: var(--gray); } .female-icon { color: var(--secondary); } .male-icon { color: var(--primary); } .other-icon { color: var(--tertiary); } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } @keyframes slideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .metric-card, .platform-chart, .engagement-by-post, .audience-insights { animation: slideIn 0.5s ease forwards; } .metric-card:nth-child(1) { animation-delay: 0.1s; } .metric-card:nth-child(2) { animation-delay: 0.2s; } .metric-card:nth-child(3) { animation-delay: 0.3s; } .metric-card:nth-child(4) { animation-delay: 0.4s; } .tooltip { position: absolute; background: rgba(0, 0, 0, 0.8); color: white; padding: 8px 12px; border-radius: 5px; font-size: 12px; opacity: 0; transition: opacity 0.3s; pointer-events: none; z-index: 100; } .platform-chart-canvas { width: 100%; height: 100%; } /* Loading animation */ @keyframes loading { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .loading { display: flex; justify-content: center; align-items: center; height: 100%; } .loading-spinner { width: 50px; height: 50px; border: 5px solid rgba(0, 0, 0, 0.1); border-radius: 50%; border-top-color: var(--primary); animation: loading 1s ease-in-out infinite; } /* Responsive styles */ @media (max-width: 700px) { .metrics-grid { grid-template-columns: 1fr; } .age-gender-chart { flex-direction: column; height: auto; } .top-posts { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); } h1 { font-size: 24px; } .platform-legend { flex-wrap: wrap; justify-content: center; } } /* Hover effects */ .metric-value { transition: transform 0.3s, color 0.3s; } .metric-card:hover .metric-value { transform: scale(1.1); color: var(--primary); } /* Progress bar styling */ .progress-container { height: 10px; background-color: var(--light-gray); border-radius: 5px; margin-top: 5px; overflow: hidden; } .progress-bar { height: 100%; border-radius: 5px; width: 0; transition: width 1s ease-in-out; } /* Animation for progress */ @keyframes progress { from { width: 0; } } /* Age bars */ .age-bars { display: flex; flex-direction: column; gap: 10px; height: 120px; justify-content: center; } .age-group { display: flex; align-items: center; gap: 10px; } .age-label { width: 45px; font-size: 12px; text-align: right; } .age-bar-container { flex: 1; height: 12px; background: var(--light-gray); border-radius: 6px; overflow: hidden; position: relative; } .age-bar { height: 100%; background: linear-gradient(to right, var(--primary), var(--secondary)); width: 0; transition: width 1s ease-out; border-radius: 6px; } .age-percentage { font-size: 12px; font-weight: 500; width: 35px; } /* Switch to toggle dark mode */ .mode-switch { position: absolute; top: 20px; right: 20px; display: flex; align-items: center; gap: 5px; cursor: pointer; } .switch { position: relative; display: inline-block; width: 40px; height: 20px; } .switch input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--light-gray); transition: .4s; border-radius: 34px; } .slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 2px; bottom: 2px; background-color: white; transition: .4s; border-radius: 50%; } input:checked + .slider { background: linear-gradient(to right, var(--primary), var(--secondary)); } input:checked + .slider:before { transform: translateX(20px); } .mode-icon { font-size: 14px; } /* Dark mode styles */ body.dark-mode { background-color: var(--dark); } .dark-mode .container { background-color: #232342; color: var(--white); } .dark-mode .metric-card, .dark-mode .age-chart, .dark-mode .gender-chart { background-color: #2a2a4a; color: var(--white); } .dark-mode .time-btn { background-color: #2a2a4a; color: var(--white); } .dark-mode .age-bar-container, .dark-mode .progress-container { background-color: #38384f; } .dark-mode .gender-label { color: #b3b3c9; } /* Responsive adjustments for smaller screens */ @media (max-width: 500px) { .metrics-grid { grid-template-columns: 1fr; } .time-period { flex-wrap: wrap; } } /* Interesting hover pattern for platform chart */ .platform-chart:hover::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: radial-gradient(circle at var(--x, center) var(--y, center), rgba(255, 255, 255, 0.1) 0%, transparent 60%); pointer-events: none; z-index: 1; border-radius: 15px; } /* Widget for adding a custom annotation */ .note-widget { position: fixed; bottom: 20px; right: 20px; background: white; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); cursor: pointer; z-index: 1000; transition: all 0.3s ease; } .note-widget:hover { transform: scale(1.1); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15); } .dark-mode .note-widget { background: #2a2a4a; color: white; } .note-panel { position: fixed; bottom: 70px; right: 20px; width: 250px; background: white; border-radius: 15px; padding: 15px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1); z-index: 1000; transform: scale(0); transform-origin: bottom right; transition: transform 0.3s ease; } .note-panel.show { transform: scale(1); } .dark-mode .note-panel { background: #2a2a4a; color: white; } .quick-actions { display: flex; justify-content: space-around; margin-top: 10px; } .action-btn { background: var(--light-gray); border: none; padding: 5px 10px; border-radius: 15px; cursor: pointer; font-size: 12px; transition: all 0.3s ease; } .action-btn:hover { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; } .dark-mode .action-btn { background: #38384f; color: white; } </style> </head> <body> <div class="container"> <div class="mode-switch"> <span class="mode-icon">☀️</span> <label class="switch"> <input type="checkbox" id="darkModeToggle"> <span class="slider"></span> </label> <span class="mode-icon">🌙</span> </div> <header> <h1>Social Media Performance</h1> <div class="time-period"> <button class="time-btn" data-period="week">This Week</button> <button class="time-btn active" data-period="month">This Month</button> <button class="time-btn" data-period="quarter">This Quarter</button> </div> </header> <div class="metrics-grid"> <div class="metric-card"> <div class="metric-header"> <div class="metric-title"> <svg class="metric-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M16 8C17.5913 8 19.1174 8.63214 20.2426 9.75736C21.3679 10.8826 22 12.4087 22 14V21H18V14C18 13.4696 17.7893 12.9609 17.4142 12.5858C17.0391 12.2107 16.5304 12 16 12C15.4696 12 14.9609 12.2107 14.5858 12.5858C14.2107 12.9609 14 13.4696 14 14V21H10V14C10 12.4087 10.6321 10.8826 11.7574 9.75736C12.8826 8.63214 14.4087 8 16 8Z" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M6 9H2V21H6V9Z" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M4 6C5.10457 6 6 5.10457 6 4C6 2.89543 5.10457 2 4 2C2.89543 2 2 2.89543 2 4C2 5.10457 2.89543 6 4 6Z" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Total Followers </div> </div> <div class="metric-value">158,742</div> <div class="metric-growth growth-positive"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 15L12 9L6 15" stroke="#00C9A7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 4.2% from last month </div> <div class="progress-container"> <div class="progress-bar" style="background: linear-gradient(to right, #5252e8, #ff4fc9)"></div> </div> </div> <div class="metric-card"> <div class="metric-header"> <div class="metric-title"> <svg class="metric-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 20.9992H21M3 20.9992H6.5M12 11.9992H21M3 11.9992H6.5M12 2.99924H21M3 2.99924H6.5" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round"/> <path d="M9 6C9.55228 6 10 5.55228 10 5C10 4.44772 9.55228 4 9 4C8.44772 4 8 4.44772 8 5C8 5.55228 8.44772 6 9 6Z" fill="#8A8A9B"/> <path d="M9 15C9.55228 15 10 14.5523 10 14C10 13.4477 9.55228 13 9 13C8.44772 13 8 13.4477 8 14C8 14.5523 8.44772 15 9 15Z" fill="#8A8A9B"/> <path d="M9 24C9.55228 24 10 23.5523 10 23C10 22.4477 9.55228 22 9 22C8.44772 22 8 22.4477 8 23C8 23.5523 8.44772 24 9 24Z" fill="#8A8A9B"/> </svg> Engagement Rate </div> </div> <div class="metric-value">4.8%</div> <div class="metric-growth growth-positive"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 15L12 9L6 15" stroke="#00C9A7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 0.7% from last month </div> <div class="progress-container"> <div class="progress-bar" style="background: linear-gradient(to right, #00c9a7, #5252e8)"></div> </div> </div> <div class="metric-card"> <div class="metric-header"> <div class="metric-title"> <svg class="metric-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M12 15C13.6569 15 15 13.6569 15 12C15 10.3431 13.6569 9 12 9C10.3431 9 9 10.3431 9 12C9 13.6569 10.3431 15 12 15Z" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M19.4 15.05C19.2669 15.3833 19.2272 15.7459 19.286 16.1004C19.3448 16.4549 19.5001 16.7868 19.73 17.06L19.79 17.12C19.976 17.306 20.1235 17.5289 20.2241 17.7751C20.3248 18.0213 20.3766 18.2857 20.3766 18.5525C20.3766 18.8194 20.3248 19.0838 20.2241 19.3299C20.1235 19.5761 19.976 19.799 19.79 19.985C19.604 20.171 19.3811 20.3185 19.1349 20.4191C18.8888 20.5198 18.6243 20.5716 18.3575 20.5716C18.0906 20.5716 17.8262 20.5198 17.5801 20.4191C17.3339 20.3185 17.111 20.171 16.925 19.985L16.865 19.925C16.5918 19.6951 16.2599 19.5398 15.9054 19.481C15.5509 19.4222 15.1883 19.4619 14.855 19.595C14.5277 19.7213 14.2428 19.9419 14.0357 20.2327C13.8286 20.5234 13.7079 20.8721 13.69 21.235V21.4C13.69 21.9305 13.4793 22.4391 13.1042 22.8142C12.7291 23.1893 12.2204 23.4 11.69 23.4C11.1595 23.4 10.6509 23.1893 10.2758 22.8142C9.90069 22.4391 9.69 21.9305 9.69 21.4V21.31C9.66546 20.9319 9.52821 20.5699 9.30255 20.2725C9.07688 19.9751 8.77252 19.7549 8.42999 19.64C8.09666 19.5069 7.73405 19.4672 7.37956 19.526C7.02508 19.5848 6.69317 19.7401 6.41999 19.97L6.35999 20.03C6.17403 20.216 5.95112 20.3635 5.70493 20.4641C5.45875 20.5648 5.19434 20.6166 4.92749 20.6166C4.66065 20.6166 4.39623 20.5648 4.15005 20.4641C3.90387 20.3635 3.68095 20.216 3.49499 20.03C3.30903 19.844 3.16148 19.6211 3.06088 19.3749C2.96028 19.1288 2.90845 18.8643 2.90845 18.5975C2.90845 18.3307 2.96028 18.0662 3.06088 17.8201C3.16148 17.5739 3.30903 17.351 3.49499 17.165L3.55499 17.105C3.78491 16.8318 3.94021 16.4999 3.99899 16.1454C4.05777 15.7909 4.01803 15.4283 3.88499 15.095C3.7587 14.7677 3.53815 14.4828 3.2474 14.2757C2.95664 14.0686 2.60794 13.9479 2.24499 13.93H2.07999C1.54956 13.93 1.04086 13.7193 0.665782 13.3442C0.290699 12.9691 0.0799971 12.4604 0.0799971 11.93C0.0799971 11.3996 0.290699 10.8909 0.665782 10.5158C1.04086 10.1407 1.54956 9.93001 2.07999 9.93001H2.16999C2.54812 9.90547 2.91015 9.76822 3.20749 9.54255C3.50484 9.31688 3.72509 9.01252 3.83999 8.67C3.97303 8.33667 4.01276 7.97405 3.95398 7.61957C3.8952 7.26508 3.73991 6.93317 3.50999 6.66L3.44999 6.6C3.26403 6.41404 3.11648 6.19112 3.01588 5.94494C2.91528 5.69875 2.86345 5.43434 2.86345 5.1675C2.86345 4.90066 2.91528 4.63624 3.01588 4.39006C3.11648 4.14388 3.26403 3.92096 3.44999 3.735C3.63595 3.54904 3.85887 3.40149 4.10505 3.30089C4.35123 3.20029 4.61565 3.14846 4.88249 3.14846C5.14934 3.14846 5.41375 3.20029 5.65993 3.30089C5.90612 3.40149 6.12903 3.54904 6.31499 3.735L6.37499 3.795C6.64817 4.02492 6.98008 4.18021 7.33456 4.23899C7.68905 4.29778 8.05166 4.25804 8.38499 4.125H8.38499C8.71228 3.99871 8.99716 3.77817 9.2043 3.48741C9.41143 3.19666 9.53213 2.84795 9.54999 2.485V2.32C9.54999 1.78957 9.76069 1.28086 10.1358 0.905782C10.5109 0.530699 11.0196 0.320007 11.55 0.320007C12.0804 0.320007 12.5891 0.530699 12.9642 0.905782C13.3393 1.28086 13.55 1.78957 13.55 2.32V2.41C13.5679 2.77295 13.6886 3.12165 13.8957 3.41241C14.1028 3.70317 14.3877 3.92371 14.715 4.05C15.0483 4.18304 15.4109 4.22278 15.7654 4.16399C16.1199 4.10521 16.4518 3.94992 16.725 3.72L16.785 3.66C16.971 3.47404 17.1939 3.32649 17.4401 3.22589C17.6862 3.12529 17.9507 3.07346 18.2175 3.07346C18.4843 3.07346 18.7488 3.12529 18.9949 3.22589C19.2411 3.32649 19.464 3.47404 19.65 3.66C19.836 3.84596 19.9835 4.06888 20.0841 4.31506C20.1847 4.56124 20.2366 4.82566 20.2366 5.0925C20.2366 5.35935 20.1847 5.62376 20.0841 5.86994C19.9835 6.11612 19.836 6.33904 19.65 6.525L19.59 6.585C19.3601 6.85818 19.2048 7.19008 19.146 7.54457C19.0872 7.89906 19.1269 8.26167 19.26 8.595V8.595C19.3863 8.92229 19.6068 9.20716 19.8976 9.4143C20.1883 9.62143 20.5371 9.74213 20.9 9.76V9.76C21.4304 9.76 21.9391 9.9707 22.3142 10.3458C22.6893 10.7209 22.9 11.2296 22.9 11.76C22.9 12.2904 22.6893 12.7991 22.3142 13.1742C21.9391 13.5493 21.4304 13.76 20.9 13.76H20.81C20.4471 13.7779 20.0984 13.8986 19.8076 14.1057C19.5169 14.3128 19.3063 14.5977 19.18 14.925L19.4 15.05Z" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> Click-Through Rate </div> </div> <div class="metric-value">2.3%</div> <div class="metric-growth growth-negative"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M6 9L12 15L18 9" stroke="#ff4757" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 0.5% from last month </div> <div class="progress-container"> <div class="progress-bar" style="background: linear-gradient(to right, #ff4fc9, #ff4757)"></div> </div> </div> <div class="metric-card"> <div class="metric-header"> <div class="metric-title"> <svg class="metric-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M4 21.4V2.6C4 2.26863 4.26863 2 4.6 2H16.4C16.7314 2 17 2.26863 17 2.6V21.4C17 21.7314 16.7314 22 16.4 22H4.6C4.26863 22 4 21.7314 4 21.4Z" stroke="#8A8A9B" stroke-width="2"/> <path d="M17 6H20.4C20.7314 6 21 6.26863 21 6.6V21.4C21 21.7314 20.7314 22 20.4 22H17" stroke="#8A8A9B" stroke-width="2"/> <path d="M9 12H12" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round"/> <path d="M8 16H13" stroke="#8A8A9B" stroke-width="2" stroke-linecap="round"/> </svg> Content Published </div> </div> <div class="metric-value">68</div> <div class="metric-growth growth-positive"> <svg width="12" height="12" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M18 15L12 9L6 15" stroke="#00C9A7" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> </svg> 12 more than last month </div> <div class="progress-container">
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Medical Data Infographic</title> <style> :root { --primary: #2c7b90; --primary-light: #7bbfd1; --secondary: #b06b9c; --accent: #548c60; --light: #f5f7fa; --dark: #2a3642; --gray: #e0e5ec; --gray-dark: #b4bbc7; --font-main: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--font-main); background-color: var(--light); color: var(--dark); line-height: 1.6; overflow-x: hidden; height: 100%; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--primary-light) var(--gray); } .container::-webkit-scrollbar { width: 8px; } .container::-webkit-scrollbar-track { background: var(--gray); border-radius: 4px; } .container::-webkit-scrollbar-thumb { background-color: var(--primary-light); border-radius: 4px; } header { margin-bottom: 25px; position: relative; } header::after { content: ''; position: absolute; bottom: -10px; left: 0; width: 100%; height: 2px; background: linear-gradient(90deg, var(--primary) 0%, var(--primary-light) 50%, var(--light) 100%); } h1 { font-size: 28px; font-weight: 700; color: var(--primary); margin-bottom: 8px; } h2 { font-size: 20px; font-weight: 600; color: var(--dark); margin: 20px 0 15px; } p { margin-bottom: 1rem; font-size: 15px; color: var(--dark); } .section { background-color: white; border-radius: 12px; padding: 20px; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; } .section:hover { transform: translateY(-4px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.08); } .stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin: 20px 0; } .stat-card { background: white; border-radius: 8px; padding: 16px; text-align: center; position: relative; overflow: hidden; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; cursor: pointer; } .stat-card:hover { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } .stat-card::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 4px; background: var(--primary-light); transform: scaleX(0); transform-origin: left; transition: transform 0.3s ease; } .stat-card:hover::before { transform: scaleX(1); } .stat-card h3 { font-size: 14px; font-weight: 500; color: var(--dark); margin-bottom: 10px; } .stat-value { font-size: 24px; font-weight: 700; color: var(--primary); margin-bottom: 4px; display: flex; align-items: center; justify-content: center; } .stat-icon { width: 20px; height: 20px; margin-right: 8px; display: inline-block; background-size: contain; background-repeat: no-repeat; opacity: 0.8; } .trend-up, .trend-down { font-size: 12px; font-weight: 600; display: inline-flex; align-items: center; } .trend-up { color: var(--accent); } .trend-down { color: var(--secondary); } .trend-icon { margin-right: 4px; } .chart-container { height: 250px; margin: 20px 0; position: relative; overflow: hidden; } .chart-tooltip { position: absolute; background: white; border-radius: 4px; padding: 8px 12px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); pointer-events: none; opacity: 0; transition: opacity 0.2s; z-index: 10; font-size: 12px; } .legend { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 16px; justify-content: center; } .legend-item { display: flex; align-items: center; font-size: 13px; cursor: pointer; } .legend-color { width: 12px; height: 12px; border-radius: 50%; margin-right: 6px; } .demographics { display: flex; justify-content: space-between; margin: 24px 0; } .demographics-chart { width: 160px; height: 160px; position: relative; } .demographics-info { flex: 1; padding-left: 24px; } .demographics-list { list-style: none; margin-top: 16px; } .demographics-list li { font-size: 14px; padding: 4px 0; display: flex; align-items: center; } .demographics-list li::before { content: ''; display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 8px; } .key-insight { background-color: rgba(44, 123, 144, 0.05); border-left: 3px solid var(--primary); padding: 16px; margin: 20px 0; border-radius: 0 6px 6px 0; } .key-insight p { margin: 0; font-size: 14px; } .key-insight strong { color: var(--primary); } .toggle-view { display: flex; align-items: center; justify-content: center; margin: 20px 0; gap: 12px; } .toggle-btn { padding: 8px 16px; background: white; border: 1px solid var(--gray-dark); border-radius: 20px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.2s ease; } .toggle-btn.active { background: var(--primary); color: white; border-color: var(--primary); } .toggle-btn:hover:not(.active) { background: var(--gray); } .tabs { display: flex; border-bottom: 1px solid var(--gray); margin-bottom: 16px; } .tab { padding: 10px 16px; font-size: 14px; cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.2s ease; } .tab.active { border-bottom-color: var(--primary); color: var(--primary); font-weight: 500; } .tab-content { display: none; } .tab-content.active { display: block; animation: fadeIn 0.3s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .loader { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.8); justify-content: center; align-items: center; z-index: 1000; } .loader-inner { width: 40px; height: 40px; border: 3px solid var(--gray); border-top-color: var(--primary); border-radius: 50%; animation: spin 0.8s linear infinite; } @keyframes spin { to { transform: rotate(360deg); } } .filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 16px; } .filter-btn { background: white; border: 1px solid var(--gray-dark); border-radius: 16px; padding: 6px 12px; font-size: 13px; cursor: pointer; transition: all 0.2s ease; } .filter-btn.active { background: var(--primary-light); color: white; border-color: var(--primary-light); } @media (max-width: 600px) { .stats-grid { grid-template-columns: 1fr; } .demographics { flex-direction: column; align-items: center; } .demographics-info { padding-left: 0; padding-top: 16px; } h1 { font-size: 24px; } h2 { font-size: 18px; } } </style> </head> <body> <div class="container"> <header> <h1>Clinical Outcomes Dashboard</h1> <p>Quarterly report highlighting key patient data, treatment efficacy, and clinical outcomes across departments.</p> </header> <div class="tabs"> <div class="tab active" data-tab="overview">Overview</div> <div class="tab" data-tab="patient-outcomes">Patient Outcomes</div> <div class="tab" data-tab="department-analysis">Department Analysis</div> </div> <div class="tab-content active" id="overview"> <div class="filters"> <button class="filter-btn active" data-period="quarterly">Quarterly</button> <button class="filter-btn" data-period="annual">Annual</button> <button class="filter-btn" data-period="five-year">5-Year Trend</button> </div> <div class="stats-grid"> <div class="stat-card"> <h3>Average Length of Stay</h3> <div class="stat-value"><span class="stat-icon" style="background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"%232c7b90\"><path d=\"M19 3h-4.18C14.4 1.84 13.3 1 12 1c-1.3 0-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm2 14H7v-2h7v2zm3-4H7v-2h10v2zm0-4H7V7h10v2z\"/></svg>');"></span>4.2 days</div> <div class="trend-down"><span class="trend-icon">↓</span>0.8 days from Q3</div> </div> <div class="stat-card"> <h3>30-Day Readmission Rate</h3> <div class="stat-value"><span class="stat-icon" style="background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"%232c7b90\"><path d=\"M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z\"/></svg>');"></span>5.3%</div> <div class="trend-up"><span class="trend-icon">↑</span>0.4% from Q3</div> </div> <div class="stat-card"> <h3>Patient Satisfaction Score</h3> <div class="stat-value"><span class="stat-icon" style="background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"%232c7b90\"><path d=\"M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z\"/></svg>');"></span>8.7/10</div> <div class="trend-up"><span class="trend-icon">↑</span>0.3 from Q3</div> </div> <div class="stat-card"> <h3>Medication Error Rate</h3> <div class="stat-value"><span class="stat-icon" style="background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"%232c7b90\"><path d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z\"/></svg>');"></span>1.2%</div> <div class="trend-down"><span class="trend-icon">↓</span>0.3% from Q3</div> </div> </div> <div class="section"> <h2>Clinical Outcomes by Department</h2> <div class="chart-container" id="departments-chart"></div> <div class="legend" id="departments-legend"></div> </div> <div class="key-insight"> <p><strong>Key Insight:</strong> Cardiology has shown a 12% improvement in patient outcomes this quarter, attributed to the new telemonitoring protocol implemented in September.</p> </div> </div> <div class="tab-content" id="patient-outcomes"> <div class="section"> <h2>Patient Demographics</h2> <div class="demographics"> <div class="demographics-chart" id="age-chart"></div> <div class="demographics-info"> <h3>Patient Age Distribution</h3> <p>The majority of patients treated this quarter fall within the 55-74 age range, with a notable 8% increase in geriatric patients (75+) compared to last quarter.</p> <ul class="demographics-list"> <li style="--color: #7bbfd1">18-34: 16%</li> <li style="--color: #2c7b90">35-54: 25%</li> <li style="--color: #b06b9c">55-74: 38%</li> <li style="--color: #548c60">75+: 21%</li> </ul> </div> </div> </div> <div class="section"> <h2>Treatment Efficacy</h2> <div class="toggle-view"> <button class="toggle-btn active" data-view="improvement">Improvement Rate</button> <button class="toggle-btn" data-view="recurrence">Recurrence Rate</button> </div> <div class="chart-container" id="efficacy-chart"></div> <div class="key-insight"> <p><strong>Clinical Insight:</strong> Antibiotic treatment protocols for respiratory infections show a 94% efficacy rate when administered within the first 48 hours of symptom onset versus 76% when treatment is delayed.</p> </div> </div> </div> <div class="tab-content" id="department-analysis"> <div class="section"> <h2>Clinical Resource Utilization</h2> <div class="chart-container" id="resources-chart"></div> <div class="legend" id="resources-legend"></div> </div> <div class="section"> <h2>Department-Specific Metrics</h2> <div class="stats-grid"> <div class="stat-card"> <h3>Cardiology</h3> <div class="stat-value">93%</div> <p>Treatment adherence rate</p> </div> <div class="stat-card"> <h3>Oncology</h3> <div class="stat-value">87%</div> <p>Protocol compliance</p> </div> <div class="stat-card"> <h3>Neurology</h3> <div class="stat-value">4.7d</div> <p>Average length of stay</p> </div> <div class="stat-card"> <h3>Pediatrics</h3> <div class="stat-value">2.9%</div> <p>Readmission rate</p> </div> </div> <div class="key-insight"> <p><strong>Resource Insight:</strong> The Nephrology department has decreased MRI utilization by 17% through implementation of enhanced screening protocols while maintaining diagnostic accuracy rates above 98%.</p> </div> </div> </div> </div> <div class="loader"> <div class="loader-inner"></div> </div> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> // Initialize charts when DOM is loaded document.addEventListener('DOMContentLoaded', function() { // Set up tab navigation const tabs = document.querySelectorAll('.tab'); tabs.forEach(tab => { tab.addEventListener('click', () => { // Remove active class from all tabs and content document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active')); // Add active class to clicked tab and corresponding content tab.classList.add('active'); const tabContentId = tab.getAttribute('data-tab'); document.getElementById(tabContentId).classList.add('active'); // Redraw charts when tab becomes visible redrawVisibleCharts(); }); }); // Filter buttons const filterBtns = document.querySelectorAll('.filter-btn'); filterBtns.forEach(btn => { btn.addEventListener('click', () => { filterBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); // Show loader document.querySelector('.loader').style.display = 'flex'; // Simulate data loading setTimeout(() => { updateChartsBasedOnFilter(btn.getAttribute('data-period')); document.querySelector('.loader').style.display = 'none'; }, 600); }); }); // Toggle view buttons const toggleBtns = document.querySelectorAll('.toggle-btn'); toggleBtns.forEach(btn => { btn.addEventListener('click', () => { toggleBtns.forEach(b => b.classList.remove('active')); btn.classList.add('active'); // Show loader document.querySelector('.loader').style.display = 'flex'; // Simulate data loading setTimeout(() => { updateEfficiencyChart(btn.getAttribute('data-view')); document.querySelector('.loader').style.display = 'none'; }, 600); }); }); // Style demographics list items document.querySelectorAll('.demographics-list li').forEach(li => { const color = getComputedStyle(li).getPropertyValue('--color'); li.style.setProperty('--color', color); li.style.setProperty('color', color); li.querySelector('::before').style.backgroundColor = color; }); // Initialize charts initializeCharts(); // Add styling for demographics list markers document.querySelectorAll('.demographics-list li').forEach(li => { const color = li.style.getPropertyValue('--color'); li.style.setProperty('--marker-color', color); li.querySelector('::before').style.backgroundColor = color; }); // Add hover effects to stat cards const statCards = document.querySelectorAll('.stat-card'); statCards.forEach(card => { card.addEventListener('mouseenter', () => { card.style.transform = 'translateY(-5px)'; card.style.boxShadow = '0 8px 16px rgba(0, 0, 0, 0.1)'; }); card.addEventListener('mouseleave', () => { card.style.transform = 'translateY(0)'; card.style.boxShadow = '0 2px 8px rgba(0, 0, 0, 0.05)'; }); }); }); // Chart initialization function initializeCharts() { // Department outcomes chart const deptCtx = document.getElementById('departments-chart').getContext('2d'); const deptChart = new Chart(deptCtx, { type: 'bar', data: { labels: ['Cardiology', 'Neurology', 'Oncology', 'Pediatrics', 'Internal Med'], datasets: [{ label: 'Patient Outcomes Score', data: [87, 82, 79, 91, 84], backgroundColor: '#2c7b90', borderColor: '#2c7b90', borderWidth: 1 }, { label: 'Resource Efficiency', data: [78, 75, 81, 89, 79], backgroundColor: '#b06b9c', borderColor: '#b06b9c', borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, max: 100, ticks: { callback: function(value) { return value + '%'; } } } }, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { return context.dataset.label + ': ' + context.raw + '%'; } } } }, animation: { duration: 1500, easing: 'easeOutQuart' } } }); // Create custom legend for departments chart createCustomLegend('departments-legend', deptChart); // Age distribution pie chart const ageCtx = document.getElementById('age-chart').getContext('2d'); const ageChart = new Chart(ageCtx, { type: 'doughnut', data: { labels: ['18-34', '35-54', '55-74', '75+'], datasets: [{ data: [16, 25, 38, 21], backgroundColor: ['#7bbfd1', '#2c7b90', '#b06b9c', '#548c60'], borderWidth: 0 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { return context.label + ': ' + context.raw + '%'; } } } }, cutout: '60%', animation: { animateRotate: true, animateScale: true } } }); // Treatment efficacy line chart const efficacyCtx = document.getElementById('efficacy-chart').getContext('2d'); const efficacyChart = new Chart(efficacyCtx, { type: 'line', data: { labels: ['Week 1', 'Week 2', 'Week 3', 'Week 4', 'Week 5', 'Week 6', 'Week 7', 'Week 8'], datasets: [{ label: 'Cardiology', data: [72, 78, 83, 87, 89, 90, 92, 94], borderColor: '#2c7b90', backgroundColor: 'rgba(44, 123, 144, 0.1)', tension: 0.3, fill: true }, { label: 'Neurology', data: [65, 70, 74, 78, 81, 83, 85, 86], borderColor: '#b06b9c', backgroundColor: 'rgba(176, 107, 156, 0.1)', tension: 0.3, fill: true }, { label: 'Oncology', data: [58, 63, 68, 73, 77, 80, 82, 84], borderColor: '#548c60', backgroundColor: 'rgba(84, 140, 96, 0.1)', tension: 0.3, fill: true }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: false, min: 50, max: 100, ticks: { callback: function(value) { return value + '%'; } } } }, plugins: { legend: { position: 'top' }, tooltip: { mode: 'index', intersect: false, callbacks: { label: function(context) { return context.dataset.label + ': ' + context.raw + '%'; } } } }, interaction: { mode: 'nearest', axis: 'x', intersect: false }, animation: { duration: 1500 } } }); // Resource utilization radar chart const resourcesCtx = document.getElementById('resources-chart').getContext('2d'); const resourcesChart = new Chart(resourcesCtx, { type: 'radar', data: { labels: ['Staff Utilization', 'Equipment Usage', 'Space Efficiency', 'Medication Management', 'Documentation', 'Time Efficiency'], datasets: [{ label: 'Cardiology', data: [87, 83, 76, 92, 80, 85], borderColor: '#2c7b90', backgroundColor: 'rgba(44, 123, 144, 0.2)', pointBackgroundColor: '#2c7b90', borderWidth: 2 }, { label: 'Neurology', data: [82, 90, 72, 86, 78, 80], borderColor: '#b06b9c', backgroundColor: 'rgba(176, 107, 156, 0.2)', pointBackgroundColor: '#b06b9c', borderWidth: 2 }, { label: 'Oncology', data: [78, 85, 80, 88, 85, 75], borderColor: '#548c60', backgroundColor: 'rgba(84, 140, 96, 0.2)', pointBackgroundColor: '#548c60', borderWidth: 2 }] }, options: { responsive: true, maintainAspectRatio: false, scales: { r: { angleLines: { display: true, color: 'rgba(0, 0, 0, 0.1)' }, suggestedMin: 50, suggestedMax: 100, ticks: { stepSize: 10, callback: function(value) { return value + '%'; } } } }, plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { return context.dataset.label + ': ' + context.raw + '%'; } } } } } }); // Create custom legend for resources chart createCustomLegend('resources-legend', resourcesChart); // Store chart references for later updates window.charts = { departments: deptChart, age: ageChart, efficacy: efficacyChart, resources: resourcesChart }; } function createCustomLegend(legendId, chart) { const legendContainer = document.getElementById(legendId); legendContainer.innerHTML = ''; chart.data.datasets.forEach((dataset, i) => { const legendItem = document.createElement('div'); legendItem.classList.add('legend-item'); const colorBox = document.createElement('span'); colorBox.classList.add('legend-color'); colorBox.style.backgroundColor = dataset.backgroundColor instanceof Array ? dataset.backgroundColor[0] : dataset.backgroundColor; const text = document.createElement('span'); text.textContent = dataset.label; legendItem.appendChild(colorBox); legendItem.appendChild(text); // Add interactivity to legend items legendItem.addEventListener('click', () => { // Toggle dataset visibility const meta = chart.getDatasetMeta(i); meta.hidden = meta.hidden === null ? !chart.data.datasets[i].hidden : null; chart.update(); // Toggle opacity of legend item legendItem.style.opacity = meta.hidden ? 0.5 : 1; }); legendContainer.appendChild(legendItem); }); } function updateChartsBasedOnFilter(period) { // Update departments chart based on selected time period const deptChart = window.charts.departments; if (period === 'quarterly') { deptChart.data.datasets[0].data = [87, 82, 79, 91, 84]; deptChart.data.datasets[1].data = [78, 75, 81, 89, 79]; } else if (period === 'annual') { deptChart.data.datasets[0].data = [84, 79, 76, 89, 82]; deptChart.data.datasets[1].data = [75, 73, 79, 86, 77]; } else if (period === 'five-year') { deptChart.data.datasets[0].data = [79, 74, 72, 86, 78]; deptChart.data.datasets[1].data = [70, 68, 74, 82, 72]; } // Apply animation deptChart.data.datasets.forEach((dataset, i) => { dataset._meta = {}; }); deptChart.update(); // Update other visible charts as needed redrawVisibleCharts(); } function updateEfficiencyChart(view) { const efficacyChart = window.charts.efficacy; if (view === 'improvement') { efficacyChart.data.datasets[0].data = [72, 78, 83, 87, 89, 90, 92, 94]; efficacyChart.data.datasets[1].data = [65, 70, 74, 78, 81, 83, 85, 86]; efficacyChart.data.datasets[2].data = [58, 63, 68, 73, 77, 80, 82, 84]; efficacyChart.options.scales.y.title = { display: true, text: 'Improvement Rate (%)' }; } else if (view === 'recurrence') { efficacyChart.data.datasets[0].data = [15, 12, 10, 8, 7, 6, 5, 4]; efficacyChart.data.datasets[1].data = [18, 16, 14, 12, 10, 9, 8, 7]; efficacyChart.data.datasets[2].data = [22, 19, 17, 14, 12, 10, 9, 8]; efficacyChart.options.scales.y = { beginAtZero: true, max: 25, ticks: { callback: function(value) { return value + '%'; } }, title: { display: true, text: 'Recurrence Rate (%)' } }; } efficacyChart.update(); } function redrawVisibleCharts() { // Update only charts that are currently visible const activeTab = document.querySelector('.tab-content.active'); if (activeTab.id === 'overview') { if (window.charts.departments) window.charts.departments.update(); } else if (activeTab.id === 'patient-outcomes') { if (window.charts.age) window.charts.age.update(); if (window.charts.efficacy) window.charts.efficacy.update(); } else if (activeTab.id === 'department-analysis') { if (window.charts.resources) window.charts.resources.update(); } } // List items styling for demographics document.querySelectorAll('.demographics-list li').forEach(item => { const color = item.style.getPropertyValue('--color'); item.style.setProperty('--marker-color', color); item.querySelector('::before').style.backgroundColor = color; }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Environmental Sustainability Infographic</title> <style> :root { --earth-brown: #8D6E63; --leaf-green: #66BB6A; --water-blue: #42A5F5; --sunset-orange: #FF7043; --soil-tan: #D7CCC8; --forest-dark: #2E7D32; --sky-light: #BBDEFB; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #F5F5F5; overflow-x: hidden; color: #424242; width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; } .container { width: 700px; height: 700px; position: relative; overflow: hidden; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); border-radius: 16px; background: linear-gradient(135deg, #F5F5F5 0%, #E0F7FA 100%); } .title-section { text-align: center; padding: 20px; background-color: rgba(255, 255, 255, 0.8); margin-bottom: 15px; border-bottom: 4px solid var(--leaf-green); position: relative; z-index: 10; } h1 { font-size: 28px; color: var(--forest-dark); margin-bottom: 10px; font-weight: 700; letter-spacing: 0.5px; } .subtitle { font-size: 16px; color: #555; max-width: 500px; margin: 0 auto; } .infographic-content { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; padding: 0 20px 20px; height: calc(100% - 150px); overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--leaf-green) transparent; } .infographic-content::-webkit-scrollbar { width: 8px; } .infographic-content::-webkit-scrollbar-thumb { background-color: var(--leaf-green); border-radius: 4px; } .infographic-content::-webkit-scrollbar-track { background: transparent; } .info-card { background-color: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; overflow: hidden; height: 220px; display: flex; flex-direction: column; } .info-card:hover { transform: translateY(-5px); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); } .info-card::before { content: ""; position: absolute; top: 0; left: 0; width: 6px; height: 100%; border-radius: 3px 0 0 3px; } .water-card::before { background-color: var(--water-blue); } .forest-card::before { background-color: var(--leaf-green); } .energy-card::before { background-color: var(--sunset-orange); } .waste-card::before { background-color: var(--earth-brown); } .card-title { font-size: 18px; font-weight: 600; margin-bottom: 15px; color: #333; display: flex; align-items: center; } .card-title i { margin-right: 8px; font-size: 20px; width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; border-radius: 50%; } .water-card .card-title i { background-color: rgba(66, 165, 245, 0.15); color: var(--water-blue); } .forest-card .card-title i { background-color: rgba(102, 187, 106, 0.15); color: var(--leaf-green); } .energy-card .card-title i { background-color: rgba(255, 112, 67, 0.15); color: var(--sunset-orange); } .waste-card .card-title i { background-color: rgba(141, 110, 99, 0.15); color: var(--earth-brown); } .card-content { flex: 1; display: flex; flex-direction: column; } .stat-number { font-size: 36px; font-weight: 700; margin: 10px 0; display: flex; align-items: baseline; } .water-card .stat-number { color: var(--water-blue); } .forest-card .stat-number { color: var(--leaf-green); } .energy-card .stat-number { color: var(--sunset-orange); } .waste-card .stat-number { color: var(--earth-brown); } .stat-unit { font-size: 16px; font-weight: 400; margin-left: 5px; opacity: 0.8; } .card-description { font-size: 14px; line-height: 1.5; color: #666; flex: 1; } .info-toggle { margin-top: auto; font-size: 14px; color: #0288D1; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 6px 0; border-top: 1px solid #f0f0f0; transition: color 0.2s ease; } .info-toggle:hover { color: #01579B; } .info-toggle i { margin-left: 5px; transition: transform 0.3s ease; } .info-toggle.expanded i { transform: rotate(180deg); } .detailed-info { background-color: rgba(245, 245, 245, 0.95); position: absolute; bottom: 0; left: 0; right: 0; padding: 20px; border-radius: 0 0 12px 12px; transform: translateY(100%); transition: transform 0.3s ease; z-index: 5; max-height: 80%; overflow-y: auto; } .detailed-info.visible { transform: translateY(0); } .detailed-info h4 { font-size: 16px; margin-bottom: 10px; color: #333; } .detailed-info p { font-size: 14px; line-height: 1.5; margin-bottom: 10px; color: #555; } .detailed-info .close-btn { position: absolute; top: 10px; right: 10px; background: none; border: none; color: #555; cursor: pointer; font-size: 16px; display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%; transition: background-color 0.2s; } .detailed-info .close-btn:hover { background-color: rgba(0, 0, 0, 0.05); } .action-tips { margin-top: 15px; } .tip-item { display: flex; align-items: baseline; margin-bottom: 8px; } .tip-item::before { content: "•"; margin-right: 8px; color: var(--leaf-green); font-size: 18px; } .progress-container { width: 100%; height: 8px; background-color: #E0E0E0; border-radius: 4px; overflow: hidden; margin: 5px 0 15px; } .progress-bar { height: 100%; border-radius: 4px; width: 0%; transition: width 1.5s cubic-bezier(0.22, 0.61, 0.36, 1); } .water-card .progress-bar { background-color: var(--water-blue); } .forest-card .progress-bar { background-color: var(--leaf-green); } .energy-card .progress-bar { background-color: var(--sunset-orange); } .waste-card .progress-bar { background-color: var(--earth-brown); } .data-source { font-size: 12px; font-style: italic; opacity: 0.7; margin-top: 10px; } .nature-bg { position: absolute; bottom: 0; left: 0; width: 100%; height: 100px; z-index: -1; opacity: 0.2; } .tree { position: absolute; bottom: 0; width: 60px; height: 100px; } .tree-trunk { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 10px; height: 40px; background-color: var(--earth-brown); border-radius: 2px; } .tree-top { position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%); width: 50px; height: 70px; background-color: var(--leaf-green); border-radius: 50% 50% 50% 50%; } .tree:nth-child(1) { left: 10%; transform: scale(0.8); } .tree:nth-child(2) { left: 25%; transform: scale(1.2); } .tree:nth-child(3) { left: 50%; transform: scale(0.7); } .tree:nth-child(4) { left: 75%; transform: scale(1); } .tree:nth-child(5) { left: 90%; transform: scale(0.9); } .water-drop { position: absolute; width: 20px; height: 20px; background-color: var(--water-blue); border-radius: 0 50% 50% 50%; transform: rotate(45deg); animation: waterFall 4s infinite ease-in-out; opacity: 0; } @keyframes waterFall { 0% { transform: rotate(45deg) translateY(-100px); opacity: 0; } 10% { opacity: 0.7; } 80% { opacity: 0.7; } 100% { transform: rotate(45deg) translateY(700px); opacity: 0; } } .footer { text-align: center; padding: 15px; background-color: rgba(255, 255, 255, 0.8); position: absolute; bottom: 0; width: 100%; border-top: 2px solid var(--leaf-green); } .footer p { font-size: 14px; color: #555; } .action-button { display: inline-block; background-color: var(--leaf-green); color: white; padding: 8px 16px; border-radius: 20px; margin-top: 10px; text-decoration: none; font-weight: 500; font-size: 14px; transition: background-color 0.3s, transform 0.2s; cursor: pointer; box-shadow: 0 2px 8px rgba(102, 187, 106, 0.3); } .action-button:hover { background-color: var(--forest-dark); transform: translateY(-2px); box-shadow: 0 4px 12px rgba(102, 187, 106, 0.4); } @media (max-width: 700px) { .infographic-content { grid-template-columns: 1fr; } h1 { font-size: 24px; } .subtitle { font-size: 14px; } .info-card { height: auto; min-height: 200px; } } .chart-container { margin: 10px 0; position: relative; height: 40px; display: flex; } .chart-bar { height: 100%; display: flex; align-items: center; justify-content: center; color: white; font-size: 12px; font-weight: bold; position: relative; transition: width 1s ease-out; overflow: hidden; } .chart-label { position: absolute; bottom: -20px; font-size: 12px; color: #666; text-align: center; width: 100%; } /* Accessibility enhancements */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* Animations */ @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } .pulse-animation { animation: pulse 3s infinite ease-in-out; } /* Interactive elements */ .fact-bubble { position: absolute; background-color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); transition: transform 0.3s ease, box-shadow 0.3s ease; z-index: 5; opacity: 0; animation: fadeIn 0.5s forwards; animation-delay: 2s; } .fact-bubble:hover { transform: scale(1.1); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25); } .fact-bubble:nth-child(1) { top: 100px; right: 30px; width: 50px; height: 50px; background-color: rgba(66, 165, 245, 0.9); } .fact-bubble:nth-child(2) { top: 180px; left: 40px; width: 40px; height: 40px; background-color: rgba(102, 187, 106, 0.9); animation-delay: 2.3s; } .fact-bubble:nth-child(3) { bottom: 150px; right: 60px; width: 45px; height: 45px; background-color: rgba(255, 112, 67, 0.9); animation-delay: 2.6s; } .fact-tooltip { position: absolute; background-color: white; border-radius: 8px; padding: 10px 15px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); font-size: 14px; color: #333; max-width: 200px; z-index: 10; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .fact-tooltip::before { content: ''; position: absolute; width: 10px; height: 10px; background-color: white; transform: rotate(45deg); } .tooltip-right::before { left: -5px; top: 50%; transform: translateY(-50%) rotate(45deg); } .tooltip-left::before { right: -5px; top: 50%; transform: translateY(-50%) rotate(45deg); } .tooltip-bottom::before { top: -5px; left: 50%; transform: translateX(-50%) rotate(45deg); } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } </style> </head> <body> <div class="container"> <div class="title-section"> <h1>Our Planet's Vital Signs</h1> <p class="subtitle">Tracking key environmental indicators and their impacts on our shared ecosystem</p> </div> <div class="infographic-content"> <div class="info-card water-card"> <h3 class="card-title"><i class="fas fa-tint"></i>Freshwater Resources</h3> <div class="card-content"> <p class="card-description">Global freshwater withdrawals have tripled over the last 50 years with growing demands.</p> <div class="stat-number">2.2 <span class="stat-unit">billion</span></div> <p class="card-description">people lack access to safely managed drinking water services worldwide.</p> <div class="progress-container"> <div class="progress-bar" data-percent="70"></div> </div> </div> <div class="info-toggle">Learn more <i class="fas fa-chevron-down"></i></div> <div class="detailed-info"> <button class="close-btn"><i class="fas fa-times"></i></button> <h4>Water Scarcity: A Growing Global Crisis</h4> <p>By 2025, two-thirds of the world's population may face water shortages. Water scarcity affects every continent and around 2.8 billion people around the world at least one month out of every year.</p> <div class="chart-container"> <div class="chart-bar" style="width: 45%; background-color: var(--water-blue);"> 45% <div class="chart-label">Agriculture</div> </div> <div class="chart-bar" style="width: 30%; background-color: var(--leaf-green);"> 30% <div class="chart-label">Industry</div> </div> <div class="chart-bar" style="width: 25%; background-color: var(--sunset-orange);"> 25% <div class="chart-label">Domestic</div> </div> </div> <div class="action-tips"> <h4>What You Can Do:</h4> <div class="tip-item">Fix leaky faucets – a dripping tap can waste over 3,000 gallons annually</div> <div class="tip-item">Install water-efficient appliances that can reduce usage by 20%</div> <div class="tip-item">Collect rainwater for gardening and outdoor cleaning</div> </div> <p class="data-source">Source: UN-Water, World Resources Institute (2022)</p> </div> </div> <div class="info-card forest-card"> <h3 class="card-title"><i class="fas fa-tree"></i>Deforestation</h3> <div class="card-content"> <p class="card-description">Forests cover 31% of the world's land area, but are disappearing at an alarming rate.</p> <div class="stat-number">10 <span class="stat-unit">million ha</span></div> <p class="card-description">of forest are destroyed annually – equivalent to 30 football fields every minute.</p> <div class="progress-container"> <div class="progress-bar" data-percent="85"></div> </div> </div> <div class="info-toggle">Learn more <i class="fas fa-chevron-down"></i></div> <div class="detailed-info"> <button class="close-btn"><i class="fas fa-times"></i></button> <h4>The Lungs of Our Planet Are Shrinking</h4> <p>Between 1990 and 2020, the world lost 420 million hectares of forest – an area larger than the European Union. Primary rainforests are being destroyed at twice the rate they were just a decade ago.</p> <div class="chart-container"> <div class="chart-bar" style="width: 40%; background-color: var(--forest-dark);"> 40% <div class="chart-label">Agriculture</div> </div> <div class="chart-bar" style="width: 28%; background-color: var(--earth-brown);"> 28% <div class="chart-label">Logging</div> </div> <div class="chart-bar" style="width: 32%; background-color: var(--sunset-orange);"> 32% <div class="chart-label">Development</div> </div> </div> <div class="action-tips"> <h4>What You Can Do:</h4> <div class="tip-item">Choose FSC-certified wood and paper products</div> <div class="tip-item">Support forest conservation organizations</div> <div class="tip-item">Reduce consumption of palm oil, a major driver of rainforest destruction</div> </div> <p class="data-source">Source: Global Forest Watch, FAO (2021)</p> </div> </div> <div class="info-card energy-card"> <h3 class="card-title"><i class="fas fa-bolt"></i>Renewable Energy</h3> <div class="card-content"> <p class="card-description">The shift to clean energy is accelerating but still lags behind fossil fuels.</p> <div class="stat-number">29% <span class="stat-unit">of electricity</span></div> <p class="card-description">came from renewable sources globally in 2020, with rapid growth in solar and wind capacity.</p> <div class="progress-container"> <div class="progress-bar" data-percent="29"></div> </div> </div> <div class="info-toggle">Learn more <i class="fas fa-chevron-down"></i></div> <div class="detailed-info"> <button class="close-btn"><i class="fas fa-times"></i></button> <h4>Powering a Sustainable Future</h4> <p>Renewable energy costs have fallen dramatically – solar PV prices dropped by 82% between 2010-2019. The International Energy Agency projects that by 2026, global renewable electricity capacity is forecast to rise more than 60% from 2020 levels.</p> <div class="chart-container"> <div class="chart-bar" style="width: 37%; background-color: #42A5F5;"> 37% <div class="chart-label">Hydro</div> </div> <div class="chart-bar" style="width: 26%; background-color: #FFCA28;"> 26% <div class="chart-label">Solar</div> </div> <div class="chart-bar" style="width: 25%; background-color: #90CAF9;"> 25% <div class="chart-label">Wind</div> </div> <div class="chart-bar" style="width: 12%; background-color: #66BB6A;"> 12% <div class="chart-label">Other</div> </div> </div> <div class="action-tips"> <h4>What You Can Do:</h4> <div class="tip-item">Switch to a renewable energy provider for your home</div> <div class="tip-item">Consider installing solar panels – average payback period is now 6-8 years</div> <div class="tip-item">Invest in energy-efficient appliances and LED lighting</div> </div> <p class="data-source">Source: International Renewable Energy Agency (IRENA), IEA (2022)</p> </div> </div> <div class="info-card waste-card"> <h3 class="card-title"><i class="fas fa-recycle"></i>Plastic Pollution</h3> <div class="card-content"> <p class="card-description">Plastic waste has become one of our most urgent environmental problems.</p> <div class="stat-number">400 <span class="stat-unit">million tons</span></div> <p class="card-description">of plastic are produced annually, with only 9% ever being recycled since plastic production began.</p> <div class="progress-container"> <div class="progress-bar" data-percent="91"></div> </div> </div> <div class="info-toggle">Learn more <i class="fas fa-chevron-down"></i></div> <div class="detailed-info"> <button class="close-btn"><i class="fas fa-times"></i></button> <h4>The Plastic Crisis in Our Oceans</h4> <p>Every year, about 8 million tons of plastic waste escapes into the oceans. By 2050, there could be more plastic than fish in the sea by weight. Microplastics have been found everywhere from the deepest ocean trenches to human blood.</p> <div class="chart-container"> <div class="chart-bar" style="width: 40%; background-color: var(--earth-brown);"> 40% <div class="chart-label">Packaging</div> </div> <div class="chart-bar" style="width: 20%; background-color: #8D6E63;"> 20% <div class="chart-label">Consumer</div> </div> <div class="chart-bar" style="width: 17%; background-color: #A1887F;"> 17% <div class="chart-label">Construction</div> </div> <div class="chart-bar" style="width: 23%; background-color: #BCAAA4;"> 23% <div class="chart-label">Other</div> </div> </div> <div class="action-tips"> <h4>What You Can Do:</h4> <div class="tip-item">Use reusable shopping bags, water bottles, and coffee cups</div> <div class="tip-item">Choose products with minimal or plastic-free packaging</div> <div class="tip-item">Participate in beach or community cleanup events</div> </div> <p class="data-source">Source: UNEP, Ellen MacArthur Foundation (2022)</p> </div> </div> </div> <div class="nature-bg"> <div class="tree"> <div class="tree-trunk"></div> <div class="tree-top"></div> </div> <div class="tree"> <div class="tree-trunk"></div> <div class="tree-top"></div> </div> <div class="tree"> <div class="tree-trunk"></div> <div class="tree-top"></div> </div> <div class="tree"> <div class="tree-trunk"></div> <div class="tree-top"></div> </div> <div class="tree"> <div class="tree-trunk"></div> <div class="tree-top"></div> </div> </div> <div class="fact-bubble" data-fact="By 2050, 5 billion people could be facing water scarcity due to climate change."> <i class="fas fa-water" style="color: white;"></i> </div> <div class="fact-bubble" data-fact="The Amazon rainforest produces 20% of Earth's oxygen and is home to 10% of all known species."> <i class="fas fa-leaf" style="color: white;"></i> </div> <div class="fact-bubble" data-fact="A plastic bottle takes up to 450 years to decompose in the ocean."> <i class="fas fa-trash-alt" style="color: white;"></i> </div> <div class="fact-tooltip"></div> <footer class="footer"> <p>Take action today for a sustainable tomorrow</p> <div class="action-button">Get Involved Now</div> </footer> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize progress bars const progressBars = document.querySelectorAll('.progress-bar'); setTimeout(() => { progressBars.forEach(bar => { const percent = bar.getAttribute('data-percent'); bar.style.width = percent + '%'; }); }, 500); // Toggle detailed info const infoToggles = document.querySelectorAll('.info-toggle'); infoToggles.forEach(toggle => { toggle.addEventListener('click', function() { const detailedInfo = this.nextElementSibling; const isVisible = detailedInfo.classList.contains('visible'); // Close all other detailed info sections document.querySelectorAll('.detailed-info.visible').forEach(info => { info.classList.remove('visible'); info.previousElementSibling.classList.remove('expanded'); }); if (!isVisible) { detailedInfo.classList.add('visible'); this.classList.add('expanded'); } else { detailedInfo.classList.remove('visible'); this.classList.remove('expanded'); } }); }); // Close buttons for detailed info const closeButtons = document.querySelectorAll('.detailed-info .close-btn'); closeButtons.forEach(button => { button.addEventListener('click', function() { const detailedInfo = this.parentElement; detailedInfo.classList.remove('visible'); detailedInfo.previousElementSibling.classList.remove('expanded'); }); }); // Water drop animation function createWaterDrop() { const drop = document.createElement('div'); drop.classList.add('water-drop'); drop.style.left = Math.random() * 100 + '%'; document.querySelector('.container').appendChild(drop); // Remove drop after animation completes setTimeout(() => { drop.remove(); }, 4000); } setInterval(createWaterDrop, 2000); // Fact bubbles tooltips const factBubbles = document.querySelectorAll('.fact-bubble'); const factTooltip = document.querySelector('.fact-tooltip'); factBubbles.forEach(bubble => { bubble.addEventListener('mouseenter', function(e) { const fact = this.getAttribute('data-fact'); factTooltip.textContent = fact; // Position tooltip const bubbleRect = this.getBoundingClientRect(); const containerRect = document.querySelector('.container').getBoundingClientRect(); // Calculate position relative to container const bubbleTop = bubbleRect.top - containerRect.top; const bubbleLeft = bubbleRect.left - containerRect.left; const bubbleWidth = bubbleRect.width; const bubbleHeight = bubbleRect.height; // Determine tooltip position factTooltip.className = 'fact-tooltip'; if (bubbleLeft > 350) { // Left side factTooltip.classList.add('tooltip-left'); factTooltip.style.right = (containerRect.width - bubbleLeft) + 'px'; factTooltip.style.left = 'auto'; factTooltip.style.top = (bubbleTop + bubbleHeight/2 - 15) + 'px'; } else { // Right side factTooltip.classList.add('tooltip-right'); factTooltip.style.left = (bubbleLeft + bubbleWidth) + 'px'; factTooltip.style.right = 'auto'; factTooltip.style.top = (bubbleTop + bubbleHeight/2 - 15) + 'px'; } factTooltip.style.opacity = '1'; }); bubble.addEventListener('mouseleave', function() { factTooltip.style.opacity = '0'; }); }); // Action button animation const actionButton = document.querySelector('.action-button'); actionButton.addEventListener('click', function() { this.classList.add('pulse-animation'); setTimeout(() => { this.classList.remove('pulse-animation'); }, 1000); }); // Chart animation const chartBars = document.querySelectorAll('.chart-bar'); chartBars.forEach(bar => { const originalWidth = bar.style.width; bar.style.width = '0'; setTimeout(() => { bar.style.width = originalWidth; }, 500); }); // Ensure focused elements have visible focus indicators document.querySelectorAll('button, .action-button, .info-toggle, .fact-bubble').forEach(element => { element.addEventListener('focus', function() { this.style.outline = '2px solid var(--leaf-green)'; }); element.addEventListener('blur', function() { this.style.outline = 'none'; }); }); }); </script> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Product Roadmap Infographic</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', sans-serif; } :root { --primary: #2D46B9; --secondary: #5165F4; --accent: #FF4D6A; --accent-light: #FF8A9E; --dark: #1A1E36; --light: #F4F6FF; --gray: #8A92B2; --success: #00D09C; --warning: #FFBB38; } @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); body { background-color: var(--light); color: var(--dark); height: 100%; width: 100%; overflow-x: hidden; position: relative; } .container { max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow-y: auto; position: relative; background: linear-gradient(135deg, #f4f6ff 0%, #e8ecff 100%); box-shadow: 0 10px 30px rgba(45, 70, 185, 0.08); border-radius: 16px; } .header { text-align: center; margin-bottom: 30px; position: relative; } .header h1 { font-size: 2.2rem; font-weight: 700; margin-bottom: 10px; background: linear-gradient(90deg, var(--primary), var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: relative; display: inline-block; } .header p { font-size: 1rem; color: var(--gray); max-width: 80%; margin: 0 auto; line-height: 1.5; } .animated-dots { position: absolute; width: 100%; height: 40px; top: -15px; left: 0; z-index: -1; } .dot { position: absolute; width: 6px; height: 6px; border-radius: 50%; background-color: var(--accent-light); opacity: 0.6; animation: float 6s infinite ease-in-out; } @keyframes float { 0%, 100% { transform: translateY(0) scale(1); opacity: 0.6; } 50% { transform: translateY(-20px) scale(1.5); opacity: 0.3; } } .timeline-container { position: relative; padding-left: 50px; } .timeline-line { position: absolute; top: 0; left: 20px; width: 4px; height: 0; background: linear-gradient(to bottom, var(--primary), var(--accent)); border-radius: 4px; transition: height 1.5s ease; } .timeline-item { margin-bottom: 40px; position: relative; opacity: 0; transform: translateX(30px); transition: all 0.5s ease; } .timeline-marker { position: absolute; width: 32px; height: 32px; left: -41px; top: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: var(--light); border: 3px solid var(--primary); box-shadow: 0 0 0 4px rgba(45, 70, 185, 0.1); cursor: pointer; transition: all 0.3s ease; z-index: 2; } .timeline-marker i { font-size: 14px; color: var(--primary); } .timeline-marker:hover { transform: scale(1.1); box-shadow: 0 0 0 6px rgba(45, 70, 185, 0.15); } .timeline-content { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 8px 20px rgba(45, 70, 185, 0.1); transition: all 0.3s ease; cursor: pointer; position: relative; overflow: hidden; border-left: 4px solid var(--primary); } .timeline-content:hover { transform: translateY(-5px); box-shadow: 0 12px 30px rgba(45, 70, 185, 0.15); } .timeline-date { position: absolute; top: 20px; right: 20px; font-size: 0.85rem; font-weight: 500; color: var(--gray); background: var(--light); padding: 4px 10px; border-radius: 20px; } .timeline-title { font-size: 1.25rem; margin-bottom: 10px; font-weight: 600; color: var(--primary); padding-right: 80px; } .timeline-description { font-size: 0.95rem; color: var(--gray); line-height: 1.5; margin-bottom: 15px; } .timeline-meta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 15px; } .timeline-tag { font-size: 0.75rem; background: rgba(45, 70, 185, 0.1); color: var(--primary); padding: 4px 12px; border-radius: 20px; font-weight: 500; } .progress-bar { height: 6px; background: var(--light); border-radius: 3px; margin-top: 15px; position: relative; overflow: hidden; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--primary), var(--secondary)); border-radius: 3px; width: 0; transition: width 1s ease; } .status-indicator { position: absolute; top: 20px; right: 20px; width: 12px; height: 12px; border-radius: 50%; } .status-completed { background-color: var(--success); } .status-in-progress { background-color: var(--warning); } .status-upcoming { background-color: var(--gray); } .dependencies { display: none; margin-top: 15px; padding-top: 15px; border-top: 1px dashed rgba(138, 146, 178, 0.3); } .dependencies h4 { font-size: 0.9rem; color: var(--dark); margin-bottom: 8px; } .dependencies ul { padding-left: 20px; } .dependencies li { font-size: 0.85rem; color: var(--gray); margin-bottom: 4px; } .timeline-content.expanded .dependencies { display: block; animation: fadeIn 0.5s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } } .tech-icon { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; background: rgba(45, 70, 185, 0.1); border-radius: 6px; margin-right: 6px; } .tech-icon i { font-size: 14px; color: var(--primary); } .legend { display: flex; justify-content: center; gap: 20px; margin-bottom: 30px; } .legend-item { display: flex; align-items: center; font-size: 0.85rem; color: var(--gray); } .legend-dot { width: 10px; height: 10px; border-radius: 50%; margin-right: 6px; } .floating-cta { position: absolute; bottom: 30px; right: 30px; width: 50px; height: 50px; border-radius: 50%; background: linear-gradient(135deg, var(--primary), var(--secondary)); box-shadow: 0 6px 15px rgba(45, 70, 185, 0.3); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; z-index: 100; } .floating-cta i { color: white; font-size: 18px; } .floating-cta:hover { transform: scale(1.1) rotate(45deg); } .tooltip { position: absolute; left: 0; top: 0; background: var(--dark); color: white; padding: 8px 12px; border-radius: 6px; font-size: 0.8rem; pointer-events: none; opacity: 0; transition: opacity 0.3s ease; z-index: 1000; white-space: nowrap; } @media (max-width: 600px) { .container { padding: 15px; } .header h1 { font-size: 1.8rem; } .header p { font-size: 0.9rem; max-width: 95%; } .timeline-container { padding-left: 35px; } .timeline-marker { left: -35px; width: 26px; height: 26px; } .timeline-line { left: 15px; } .timeline-title { font-size: 1.1rem; padding-right: 60px; } .timeline-date { font-size: 0.75rem; top: 15px; right: 15px; } .timeline-item { margin-bottom: 30px; } } </style> </head> <body> <div class="container"> <div class="header"> <div class="animated-dots"></div> <h1>NexGen Product Evolution</h1> <p>Strategic development plan for our AI-powered platform, highlighting key features and implementation milestones through 2025</p> </div> <div class="legend"> <div class="legend-item"> <div class="legend-dot status-completed"></div> <span>Completed</span> </div> <div class="legend-item"> <div class="legend-dot status-in-progress"></div> <span>In Progress</span> </div> <div class="legend-item"> <div class="legend-dot status-upcoming"></div> <span>Upcoming</span> </div> </div> <div class="timeline-container"> <div class="timeline-line"></div> <div class="timeline-item" data-progress="100" data-status="completed"> <div class="timeline-marker"> <i class="fas fa-check"></i> </div> <div class="timeline-content"> <div class="status-indicator status-completed"></div> <div class="timeline-date">Q3 2023</div> <h3 class="timeline-title">Core Platform Architecture</h3> <p class="timeline-description">Established microservices foundation with containerized deployment, enabling scalable and resilient infrastructure for all future modules.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-code"></i> Backend</span> <span class="timeline-tag"><i class="fas fa-server"></i> Infrastructure</span> </div> <div class="dependencies"> <h4>Key Accomplishments:</h4> <ul> <li>Kubernetes cluster implementation with auto-scaling</li> <li>CI/CD pipeline with automated testing</li> <li>Distributed database architecture</li> </ul> </div> </div> </div> <div class="timeline-item" data-progress="85" data-status="in-progress"> <div class="timeline-marker"> <i class="fas fa-cog"></i> </div> <div class="timeline-content"> <div class="status-indicator status-in-progress"></div> <div class="timeline-date">Q1 2024</div> <h3 class="timeline-title">AI Analytics Engine</h3> <p class="timeline-description">Real-time data processing system with predictive analytics capabilities, providing actionable insights through customizable dashboards.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-brain"></i> AI/ML</span> <span class="timeline-tag"><i class="fas fa-chart-line"></i> Analytics</span> </div> <div class="dependencies"> <h4>Dependencies:</h4> <ul> <li>Core Platform Architecture</li> <li>Data warehousing infrastructure</li> <li>API integration framework</li> </ul> </div> </div> </div> <div class="timeline-item" data-progress="60" data-status="in-progress"> <div class="timeline-marker"> <i class="fas fa-cog"></i> </div> <div class="timeline-content"> <div class="status-indicator status-in-progress"></div> <div class="timeline-date">Q2 2024</div> <h3 class="timeline-title">Enterprise Integration Hub</h3> <p class="timeline-description">Unified gateway for seamless connections with third-party solutions, including pre-built connectors for major CRM, ERP, and collaboration tools.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-plug"></i> Integration</span> <span class="timeline-tag"><i class="fas fa-link"></i> API</span> </div> <div class="dependencies"> <h4>Dependencies:</h4> <ul> <li>Core Platform Architecture</li> <li>Security authentication framework</li> <li>Data transformation services</li> </ul> </div> </div> </div> <div class="timeline-item" data-progress="30" data-status="in-progress"> <div class="timeline-marker"> <i class="fas fa-cog"></i> </div> <div class="timeline-content"> <div class="status-indicator status-in-progress"></div> <div class="timeline-date">Q3 2024</div> <h3 class="timeline-title">Advanced Security Framework</h3> <p class="timeline-description">Zero-trust architecture with AI-powered threat detection and multi-factor biometric authentication, ensuring maximum data protection.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-shield-alt"></i> Security</span> <span class="timeline-tag"><i class="fas fa-user-shield"></i> Compliance</span> </div> <div class="dependencies"> <h4>Dependencies:</h4> <ul> <li>Core Platform Architecture</li> <li>AI Analytics Engine</li> <li>User identity management system</li> </ul> </div> </div> </div> <div class="timeline-item" data-progress="0" data-status="upcoming"> <div class="timeline-marker"> <i class="fas fa-hourglass"></i> </div> <div class="timeline-content"> <div class="status-indicator status-upcoming"></div> <div class="timeline-date">Q1 2025</div> <h3 class="timeline-title">Quantum-Ready Computing Layer</h3> <p class="timeline-description">Future-proofing architecture with quantum-compatible algorithms and hybrid processing capabilities for next-generation computational challenges.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-atom"></i> Quantum</span> <span class="timeline-tag"><i class="fas fa-microchip"></i> Computing</span> </div> <div class="dependencies"> <h4>Dependencies:</h4> <ul> <li>All previous development phases</li> <li>Quantum simulation environment</li> <li>Advanced cryptography protocols</li> </ul> </div> </div> </div> <div class="timeline-item" data-progress="0" data-status="upcoming"> <div class="timeline-marker"> <i class="fas fa-hourglass"></i> </div> <div class="timeline-content"> <div class="status-indicator status-upcoming"></div> <div class="timeline-date">Q3 2025</div> <h3 class="timeline-title">Immersive Collaboration Suite</h3> <p class="timeline-description">Extended reality workspace with spatial computing interfaces, enabling seamless virtual collaboration across global teams with digital twin integration.</p> <div class="progress-bar"> <div class="progress-fill"></div> </div> <div class="timeline-meta"> <span class="timeline-tag"><i class="fas fa-vr-cardboard"></i> XR</span> <span class="timeline-tag"><i class="fas fa-users"></i> Collaboration</span> </div> <div class="dependencies"> <h4>Dependencies:</h4> <ul> <li>Enterprise Integration Hub</li> <li>Advanced Security Framework</li> <li>3D rendering engine</li> </ul> </div> </div> </div> </div> <div class="tooltip"></div> <div class="floating-cta"> <i class="fas fa-rocket"></i> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Create animated dots const dotsContainer = document.querySelector('.animated-dots'); for (let i = 0; i < 20; i++) { const dot = document.createElement('div'); dot.classList.add('dot'); dot.style.left = `${Math.random() * 100}%`; dot.style.top = `${Math.random() * 100}%`; dot.style.animationDelay = `${Math.random() * 5}s`; dotsContainer.appendChild(dot); } // Animate timeline appearance const timelineItems = document.querySelectorAll('.timeline-item'); const timelineLine = document.querySelector('.timeline-line'); // Set initial timeline height setTimeout(() => { const timelineContainer = document.querySelector('.timeline-container'); timelineLine.style.height = `${timelineContainer.offsetHeight - 40}px`; }, 100); // Animate timeline items setTimeout(() => { timelineItems.forEach((item, index) => { setTimeout(() => { item.style.opacity = '1'; item.style.transform = 'translateX(0)'; // Set progress bar fill const progressBar = item.querySelector('.progress-fill'); const progressPercentage = item.dataset.progress; progressBar.style.width = `${progressPercentage}%`; }, 300 * index); }); }, 500); // Timeline item click to expand timelineItems.forEach(item => { const content = item.querySelector('.timeline-content'); content.addEventListener('click', () => { const currentlyExpanded = document.querySelector('.timeline-content.expanded'); if (currentlyExpanded && currentlyExpanded !== content) { currentlyExpanded.classList.remove('expanded'); } content.classList.toggle('expanded'); // Update timeline height after expansion setTimeout(() => { const timelineContainer = document.querySelector('.timeline-container'); timelineLine.style.height = `${timelineContainer.offsetHeight - 40}px`; }, 300); }); }); // Tooltip functionality const tooltip = document.querySelector('.tooltip'); const markers = document.querySelectorAll('.timeline-marker'); markers.forEach(marker => { marker.addEventListener('mouseenter', (e) => { const item = marker.closest('.timeline-item'); const status = item.dataset.status; let statusText = 'Upcoming'; if (status === 'completed') { statusText = 'Completed'; } else if (status === 'in-progress') { statusText = 'In Progress'; } tooltip.textContent = statusText; tooltip.style.opacity = '1'; const rect = marker.getBoundingClientRect(); tooltip.style.left = `${rect.left + window.scrollX - 20}px`; tooltip.style.top = `${rect.top + window.scrollY - 35}px`; }); marker.addEventListener('mouseleave', () => { tooltip.style.opacity = '0'; }); }); // Floating CTA button const floatingCta = document.querySelector('.floating-cta'); floatingCta.addEventListener('click', () => { // Scroll to the top of the timeline const timelineContainer = document.querySelector('.timeline-container'); timelineContainer.scrollIntoView({ behavior: 'smooth' }); // Add a little celebration animation floatingCta.style.transform = 'scale(1.2) rotate(360deg)'; setTimeout(() => { floatingCta.style.transform = 'scale(1) rotate(0deg)'; }, 600); }); // Make timeline responsive const resizeObserver = new ResizeObserver(() => { const timelineContainer = document.querySelector('.timeline-container'); timelineLine.style.height = `${timelineContainer.offsetHeight - 40}px`; }); resizeObserver.observe(document.querySelector('.container')); }); </script> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Tech Stack Overview Infographic</title> <style> :root { --neon-blue: #00f7ff; --neon-purple: #cc00ff; --neon-green: #39ff14; --neon-pink: #ff00f7; --dark-bg: #0a0e17; --dark-bg-2: #141927; --dark-bg-3: #1c2333; --text-primary: #ffffff; --text-secondary: #b3b3b3; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--dark-bg); color: var(--text-primary); min-height: 700px; display: flex; justify-content: center; align-items: center; overflow-x: hidden; overflow-y: auto; user-select: none; } .container { width: 100%; max-width: 700px; height: 700px; padding: 20px; position: relative; overflow: hidden; } .header { text-align: center; margin-bottom: 30px; position: relative; z-index: 2; } .title { font-size: 2.2rem; margin-bottom: 10px; background: linear-gradient(90deg, var(--neon-blue), var(--neon-purple)); -webkit-background-clip: text; background-clip: text; color: transparent; text-shadow: 0 0 10px rgba(0, 247, 255, 0.3); font-weight: 800; } .subtitle { font-size: 1rem; color: var(--text-secondary); max-width: 80%; margin: 0 auto; } .masonry-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 15px; position: relative; height: 450px; z-index: 3; } .grid-item { background-color: var(--dark-bg-2); border-radius: 12px; cursor: pointer; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 20px 10px; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); } .grid-item:hover { transform: translateY(-5px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.4), 0 0 15px rgba(0, 247, 255, 0.3); } .grid-item:before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: linear-gradient(90deg, transparent, var(--neon-blue), var(--neon-purple), transparent); transform: scaleX(0); transform-origin: left; transition: transform 0.4s ease; } .grid-item:hover:before { transform: scaleX(1); } .item-icon { font-size: 2.5rem; margin-bottom: 10px; transition: transform 0.3s ease, color 0.3s ease; } .grid-item:hover .item-icon { transform: scale(1.1); } .item-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 5px; text-align: center; } .frontend .item-icon { color: var(--neon-blue); } .backend .item-icon { color: var(--neon-green); } .database .item-icon { color: var(--neon-purple); } .devops .item-icon { color: var(--neon-pink); } .grid-item.span-2 { grid-column: span 2; } .grid-item.span-row-2 { grid-row: span 2; } .detail-panel { position: absolute; top: 0; right: -100%; width: 100%; height: 100%; background-color: var(--dark-bg-3); z-index: 10; padding: 30px; transition: right 0.4s cubic-bezier(0.77, 0, 0.175, 1); border-left: 2px solid var(--neon-blue); box-shadow: -5px 0 15px rgba(0, 0, 0, 0.5); display: flex; flex-direction: column; } .detail-panel.active { right: 0; } .panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .panel-title { font-size: 1.8rem; font-weight: 700; background: linear-gradient(90deg, var(--neon-blue), var(--neon-purple)); -webkit-background-clip: text; background-clip: text; color: transparent; } .close-btn { background: none; border: none; color: var(--text-secondary); font-size: 1.5rem; cursor: pointer; transition: color 0.2s ease; } .close-btn:hover { color: var(--neon-blue); } .panel-content { flex: 1; overflow-y: auto; padding-right: 10px; } .panel-content::-webkit-scrollbar { width: 5px; } .panel-content::-webkit-scrollbar-track { background: var(--dark-bg); border-radius: 10px; } .panel-content::-webkit-scrollbar-thumb { background: var(--neon-blue); border-radius: 10px; } .tech-description { margin-bottom: 25px; line-height: 1.6; } .tech-features { margin-top: 20px; } .feature-item { display: flex; align-items: flex-start; margin-bottom: 15px; background-color: rgba(255, 255, 255, 0.05); padding: 15px; border-radius: 8px; transition: transform 0.2s ease, background-color 0.2s ease; } .feature-item:hover { transform: translateX(5px); background-color: rgba(255, 255, 255, 0.1); } .feature-icon { margin-right: 10px; color: var(--neon-blue); font-size: 1.2rem; } .feature-text h4 { margin-bottom: 5px; font-size: 1rem; } .feature-text p { font-size: 0.9rem; color: var(--text-secondary); } .network-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1; opacity: 0.3; } .network-point { position: absolute; width: 4px; height: 4px; background-color: var(--neon-blue); border-radius: 50%; box-shadow: 0 0 10px var(--neon-blue); } .footer { position: absolute; bottom: 20px; left: 0; width: 100%; text-align: center; font-size: 0.8rem; color: var(--text-secondary); z-index: 2; } .footer-text { padding: 5px 10px; background-color: rgba(0, 0, 0, 0.3); border-radius: 20px; display: inline-block; } .legend { display: flex; justify-content: center; gap: 15px; margin: 20px auto; z-index: 2; position: relative; } .legend-item { display: flex; align-items: center; font-size: 0.8rem; } .legend-color { width: 12px; height: 12px; border-radius: 50%; margin-right: 5px; } .legend-frontend { background-color: var(--neon-blue); box-shadow: 0 0 5px var(--neon-blue); } .legend-backend { background-color: var(--neon-green); box-shadow: 0 0 5px var(--neon-green); } .legend-database { background-color: var(--neon-purple); box-shadow: 0 0 5px var(--neon-purple); } .legend-devops { background-color: var(--neon-pink); box-shadow: 0 0 5px var(--neon-pink); } /* Responsive */ @media screen and (max-width: 600px) { .masonry-grid { grid-template-columns: repeat(2, 1fr); height: auto; } .title { font-size: 1.8rem; } .subtitle { font-size: 0.9rem; } .legend { flex-wrap: wrap; } } @keyframes pulse { 0% { transform: scale(1); opacity: 0.8; } 50% { transform: scale(1.1); opacity: 1; } 100% { transform: scale(1); opacity: 0.8; } } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .grid-item { animation: fadeIn 0.5s ease forwards; opacity: 0; } .grid-item:nth-child(1) { animation-delay: 0.1s; } .grid-item:nth-child(2) { animation-delay: 0.2s; } .grid-item:nth-child(3) { animation-delay: 0.3s; } .grid-item:nth-child(4) { animation-delay: 0.4s; } .grid-item:nth-child(5) { animation-delay: 0.5s; } .grid-item:nth-child(6) { animation-delay: 0.6s; } .grid-item:nth-child(7) { animation-delay: 0.7s; } .grid-item:nth-child(8) { animation-delay: 0.8s; } .grid-item:nth-child(9) { animation-delay: 0.9s; } .grid-item:nth-child(10) { animation-delay: 1s; } .highlight-connection { position: absolute; height: 2px; background: linear-gradient(90deg, var(--neon-blue), var(--neon-purple)); transform-origin: left; animation: connectionGrow 1.5s ease-out; opacity: 0; z-index: 1; } @keyframes connectionGrow { 0% { transform: scaleX(0); opacity: 1; } 100% { transform: scaleX(1); opacity: 0; } } .tooltip { position: absolute; background-color: var(--dark-bg-3); color: var(--text-primary); padding: 10px 15px; border-radius: 5px; font-size: 0.8rem; z-index: 100; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); pointer-events: none; opacity: 0; transition: opacity 0.2s ease; border-left: 3px solid var(--neon-blue); max-width: 250px; } </style> </head> <body> <div class="container"> <div class="header"> <h1 class="title">Modern Tech Stack Blueprint</h1> <p class="subtitle">Explore the interconnected technologies that power today's scalable applications</p> </div> <div class="legend"> <div class="legend-item"> <div class="legend-color legend-frontend"></div> <span>Frontend</span> </div> <div class="legend-item"> <div class="legend-color legend-backend"></div> <span>Backend</span> </div> <div class="legend-item"> <div class="legend-color legend-database"></div> <span>Database</span> </div> <div class="legend-item"> <div class="legend-color legend-devops"></div> <span>DevOps</span> </div> </div> <div class="masonry-grid"> <div class="grid-item frontend" data-category="frontend" data-tech="react"> <div class="item-icon">⚛️</div> <h3 class="item-title">React</h3> </div> <div class="grid-item backend" data-category="backend" data-tech="node"> <div class="item-icon">🟢</div> <h3 class="item-title">Node.js</h3> </div> <div class="grid-item database span-2" data-category="database" data-tech="mongodb"> <div class="item-icon">🍃</div> <h3 class="item-title">MongoDB</h3> </div> <div class="grid-item frontend" data-category="frontend" data-tech="typescript"> <div class="item-icon">📘</div> <h3 class="item-title">TypeScript</h3> </div> <div class="grid-item devops span-row-2" data-category="devops" data-tech="docker"> <div class="item-icon">🐳</div> <h3 class="item-title">Docker</h3> </div> <div class="grid-item backend" data-category="backend" data-tech="graphql"> <div class="item-icon">◢</div> <h3 class="item-title">GraphQL</h3> </div> <div class="grid-item database" data-category="database" data-tech="redis"> <div class="item-icon">🔻</div> <h3 class="item-title">Redis</h3> </div> <div class="grid-item frontend span-2" data-category="frontend" data-tech="nextjs"> <div class="item-icon">▲</div> <h3 class="item-title">Next.js</h3> </div> <div class="grid-item devops" data-category="devops" data-tech="kubernetes"> <div class="item-icon">☸️</div> <h3 class="item-title">Kubernetes</h3> </div> <div class="grid-item backend" data-category="backend" data-tech="go"> <div class="item-icon">🔵</div> <h3 class="item-title">Go</h3> </div> </div> <div class="network-container" id="networkContainer"></div> <div class="detail-panel" id="detailPanel"> <div class="panel-header"> <h2 class="panel-title" id="panelTitle">Technology</h2> <button class="close-btn" id="closePanel">×</button> </div> <div class="panel-content" id="panelContent"></div> </div> <div class="tooltip" id="tooltip"></div> <div class="footer"> <div class="footer-text">Click on any technology to explore its capabilities and integrations</div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Technologies data const techData = { react: { title: "React", category: "Frontend", description: "A declarative JavaScript library for building user interfaces with component-based architecture. React's virtual DOM efficiently updates the UI by minimizing direct DOM manipulation.", features: [ { title: "Component Architecture", description: "Build encapsulated components that manage their own state, then compose them to make complex UIs." }, { title: "Virtual DOM", description: "A lightweight representation of the DOM that optimizes rendering performance." }, { title: "React Hooks", description: "Function-based approach to use state and lifecycle features without writing classes." }, { title: "Unidirectional Data Flow", description: "Makes code more predictable and easier to debug by restricting direct state manipulation." } ], connects: ["typescript", "nextjs", "node"] }, node: { title: "Node.js", category: "Backend", description: "An asynchronous event-driven JavaScript runtime designed to build scalable network applications. Node.js uses a non-blocking I/O model that makes it lightweight and efficient.", features: [ { title: "Event-Driven Architecture", description: "Non-blocking I/O operations for handling multiple connections concurrently." }, { title: "NPM Ecosystem", description: "Access to over 1 million packages for rapid development." }, { title: "Single-Threaded with Event Loop", description: "Handles asynchronous operations efficiently without thread management complexity." }, { title: "Cross-Platform Compatibility", description: "Runs on Windows, macOS, and Linux environments consistently." } ], connects: ["react", "mongodb", "graphql", "redis"] }, mongodb: { title: "MongoDB", category: "Database", description: "A document-oriented NoSQL database that stores data in flexible, JSON-like documents. Designed for scalability and developer agility, MongoDB excels at handling large volumes of unstructured data.", features: [ { title: "Document Data Model", description: "Flexible schema design allowing nested data structures and arrays." }, { title: "Horizontal Scaling", description: "Native sharding distributes data across multiple machines." }, { title: "Aggregation Framework", description: "Powerful query processing with data transformation capabilities." }, { title: "MongoDB Atlas", description: "Cloud database service with automated deployment, scaling, and operations." } ], connects: ["node", "graphql"] }, typescript: { title: "TypeScript", category: "Frontend", description: "A superset of JavaScript that adds static typing, enhancing code quality and understandability. TypeScript provides better tooling, error-catching, and documentation for complex JavaScript applications.", features: [ { title: "Static Type Checking", description: "Catch errors during development rather than at runtime." }, { title: "Enhanced IDE Support", description: "Better autocompletion, navigation, and refactoring tools." }, { title: "Interfaces & Type Declarations", description: "Define contracts between code parts with explicit type definitions." }, { title: "Progressive Adoption", description: "Can be integrated incrementally into existing JavaScript projects." } ], connects: ["react", "nextjs", "node", "graphql"] }, docker: { title: "Docker", category: "DevOps", description: "A platform that enables developers to build, package, and distribute applications as lightweight containers. Docker ensures consistency across environments, from development to production.", features: [ { title: "Containerization", description: "Package applications with all dependencies in isolated environments." }, { title: "Docker Compose", description: "Define multi-container applications in a single file." }, { title: "Docker Hub", description: "Repository of container images for quick deployment." }, { title: "Resource Efficiency", description: "Containers share OS resources but remain isolated from each other." } ], connects: ["kubernetes", "node", "go"] }, graphql: { title: "GraphQL", category: "Backend", description: "A query language and runtime for APIs that prioritizes giving clients exactly the data they request. GraphQL provides a more efficient, powerful, and flexible alternative to traditional REST.", features: [ { title: "Single Endpoint", description: "All data accessible through one API endpoint, reducing network requests." }, { title: "Precise Data Fetching", description: "Clients specify exactly what data they need, reducing over-fetching." }, { title: "Strong Typing System", description: "Self-documenting API with a schema that defines available data." }, { title: "Real-time Updates", description: "Built-in subscription support for live data changes." } ], connects: ["react", "node", "mongodb"] }, redis: { title: "Redis", category: "Database", description: "An in-memory data structure store used as a database, cache, message broker, and streaming engine. Redis delivers sub-millisecond response times, enabling extremely fast applications.", features: [ { title: "In-Memory Data Storage", description: "Extremely fast data operations with optional persistence." }, { title: "Versatile Data Structures", description: "Supports strings, hashes, lists, sets, and more specialized types." }, { title: "Pub/Sub Messaging", description: "Built-in support for real-time messaging between systems." }, { title: "Lua Scripting", description: "Execute atomic operations with custom logic directly on the server." } ], connects: ["node", "go"] }, nextjs: { title: "Next.js", category: "Frontend", description: "A React framework that enables server-side rendering, static site generation, and more. Next.js provides production-ready features like routing, image optimization, and API endpoints.", features: [ { title: "Hybrid Rendering", description: "Server-side rendering, static generation, and client-side rendering in one framework." }, { title: "File-based Routing", description: "Intuitive page creation based on file system structure." }, { title: "API Routes", description: "Build API endpoints as part of your Next.js application." }, { title: "Built-in Optimizations", description: "Automatic image, font, and script optimization for performance." } ], connects: ["react", "typescript"] }, kubernetes: { title: "Kubernetes", category: "DevOps", description: "An open-source container orchestration platform for automating deployment, scaling, and management of containerized applications. Kubernetes handles service discovery, load balancing, and self-healing.", features: [ { title: "Container Orchestration", description: "Automate the deployment and scaling of containerized applications." }, { title: "Auto-scaling", description: "Automatically adjust resources based on demand patterns." }, { title: "Self-healing", description: "Automatically replaces and reschedules containers when nodes fail." }, { title: "Declarative Configuration", description: "Define application state in YAML, and K8s maintains that desired state." } ], connects: ["docker", "go"] }, go: { title: "Go", category: "Backend", description: "A statically typed, compiled programming language designed for simplicity and efficiency. Go excels at building fast, reliable, and efficient backend services with built-in concurrency.", features: [ { title: "Goroutines", description: "Lightweight threads for concurrent programming without complex thread management." }, { title: "Static Compilation", description: "Compiles to a single binary with no external dependencies." }, { title: "Standard Library", description: "Comprehensive built-in packages for common tasks like HTTP servers and JSON handling." }, { title: "Memory Management", description: "Efficient garbage collection with lower latency than traditional GC languages." } ], connects: ["kubernetes", "docker", "redis"] } }; // Initialize network visualization const networkContainer = document.getElementById('networkContainer'); function createNetworkPoints() { // Clear existing points networkContainer.innerHTML = ''; // Create random points for (let i = 0; i < 50; i++) { const point = document.createElement('div'); point.classList.add('network-point'); // Random position const left = Math.random() * 100; const top = Math.random() * 100; point.style.left = `${left}%`; point.style.top = `${top}%`; // Random animation const animationDuration = 3 + Math.random() * 5; point.style.animation = `pulse ${animationDuration}s infinite`; networkContainer.appendChild(point); } } createNetworkPoints(); // Panel interactions const detailPanel = document.getElementById('detailPanel'); const panelTitle = document.getElementById('panelTitle'); const panelContent = document.getElementById('panelContent'); const closePanel = document.getElementById('closePanel'); // Add click event to all grid items const gridItems = document.querySelectorAll('.grid-item'); gridItems.forEach(item => { item.addEventListener('click', function() { const tech = this.getAttribute('data-tech'); showTechDetails(tech); }); // Add tooltip item.addEventListener('mouseenter', function(e) { const tech = this.getAttribute('data-tech'); const category = this.getAttribute('data-category'); showTooltip(e, tech, category); }); item.addEventListener('mouseleave', function() { hideTooltip(); }); item.addEventListener('mousemove', function(e) { moveTooltip(e); }); }); closePanel.addEventListener('click', function() { detailPanel.classList.remove('active'); }); function showTechDetails(tech) { const data = techData[tech]; if (!data) return; panelTitle.textContent = data.title; let contentHTML = ` <p class="tech-description">${data.description}</p> <div class="tech-features"> <h3>Key Capabilities</h3> `; data.features.forEach(feature => { contentHTML += ` <div class="feature-item"> <div class="feature-icon">✦</div> <div class="feature-text"> <h4>${feature.title}</h4> <p>${feature.description}</p> </div> </div> `; }); contentHTML += '</div>'; panelContent.innerHTML = contentHTML; detailPanel.classList.add('active'); // Show connections showConnections(tech); } // Tooltip functionality const tooltip = document.getElementById('tooltip'); function showTooltip(e, tech, category) { const data = techData[tech]; if (!data) return; let categoryColor; switch(category) { case 'frontend': categoryColor = 'var(--neon-blue)'; break; case 'backend': categoryColor = 'var(--neon-green)'; break; case 'database': categoryColor = 'var(--neon-purple)'; break; case 'devops': categoryColor = 'var(--neon-pink)'; break; default: categoryColor = 'var(--neon-blue)'; } tooltip.innerHTML = ` <strong style="color: ${categoryColor}">${data.title}</strong><br> <span style="opacity: 0.8; font-size: 0.75rem;">${data.category}</span> `; tooltip.style.borderLeftColor = categoryColor; moveTooltip(e); tooltip.style.opacity = '1'; } function hideTooltip() { tooltip.style.opacity = '0'; } function moveTooltip(e) { // Position tooltip with offset const x = e.clientX + 15; const y = e.clientY + 10; // Ensure tooltip stays within viewport const tooltipWidth = tooltip.offsetWidth; const tooltipHeight = tooltip.offsetHeight; const viewportWidth = window.innerWidth; const viewportHeight = window.innerHeight; let finalX = x; let finalY = y; if (x + tooltipWidth > viewportWidth) { finalX = x - tooltipWidth - 30; } if (y + tooltipHeight > viewportHeight) { finalY = y - tooltipHeight - 20; } tooltip.style.left = `${finalX}px`; tooltip.style.top = `${finalY}px`; } // Connection visualization function showConnections(tech) { // Remove any existing connections document.querySelectorAll('.highlight-connection').forEach(el => el.remove()); const connections = techData[tech].connects || []; connections.forEach(connectedTech => { // Get positions of the source and target elements const sourceEl = document.querySelector(`[data-tech="${tech}"]`); const targetEl = document.querySelector(`[data-tech="${connectedTech}"]`); if (sourceEl && targetEl) { createConnection(sourceEl, targetEl); } }); } function createConnection(source, target) { // Get the center positions of both elements const sourceRect = source.getBoundingClientRect(); const targetRect = target.getBoundingClientRect(); const containerRect = document.querySelector('.container').getBoundingClientRect(); // Calculate center points const sourceX = sourceRect.left + sourceRect.width / 2 - containerRect.left; const sourceY = sourceRect.top + sourceRect.height / 2 - containerRect.top; const targetX = targetRect.left + targetRect.width / 2 - containerRect.left; const targetY = targetRect.top + targetRect.height / 2 - containerRect.top; // Calculate distance and angle const dx = targetX - sourceX; const dy = targetY - sourceY; const distance = Math.sqrt(dx * dx + dy * dy); const angle = Math.atan2(dy, dx) * 180 / Math.PI; // Create connection line const connection = document.createElement('div'); connection.classList.add('highlight-connection'); // Position and rotate connection.style.width = `${distance}px`; connection.style.left = `${sourceX}px`; connection.style.top = `${sourceY}px`; connection.style.transform = `rotate(${angle}deg)`; // Add to container document.querySelector('.container').appendChild(connection); // Trigger animation setTimeout(() => { if (connection) connection.remove(); }, 1500); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>User Journey Visualization</title> <style> :root { --primary: #ff7e5f; --primary-light: #ff9e7a; --secondary: #feb47b; --text-dark: #2c3e50; --text-light: #34495e; --bg-light: #f9f7f4; --bg-medium: #f0ece3; --accent: #7eb7ff; --success: #7bffb4; --warning: #ffd97e; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--bg-light); color: var(--text-dark); width: 100%; height: 100vh; overflow: hidden; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; overflow: auto; position: relative; scrollbar-width: thin; scrollbar-color: var(--primary) var(--bg-medium); } .container::-webkit-scrollbar { width: 8px; } .container::-webkit-scrollbar-track { background: var(--bg-medium); border-radius: 10px; } .container::-webkit-scrollbar-thumb { background-color: var(--primary); border-radius: 10px; } h1 { text-align: center; margin-bottom: 30px; font-size: 28px; color: var(--primary); font-weight: 600; position: relative; } h1::after { content: ''; position: absolute; bottom: -10px; left: 50%; transform: translateX(-50%); width: 80px; height: 3px; background: linear-gradient(to right, var(--primary), var(--secondary)); border-radius: 2px; } .journey-map { display: flex; flex-direction: column; align-items: center; margin-top: 20px; padding-bottom: 40px; position: relative; } .map-line { position: absolute; top: 0; bottom: 0; left: 50%; width: 4px; background: linear-gradient(to bottom, var(--primary), var(--secondary)); transform: translateX(-50%); z-index: 1; border-radius: 2px; } .journey-step { display: flex; width: 100%; margin-bottom: 40px; position: relative; z-index: 2; opacity: 0; transform: translateY(20px); transition: all 0.5s ease; } .journey-step.visible { opacity: 1; transform: translateY(0); } .step-number { width: 50px; height: 50px; background: linear-gradient(135deg, var(--primary), var(--secondary)); color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 20px; box-shadow: 0 4px 10px rgba(255, 126, 95, 0.3); position: relative; z-index: 3; margin: 0 20px; flex-shrink: 0; transition: transform 0.3s ease, box-shadow 0.3s ease; } .step-content { flex: 1; background-color: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 15px rgba(0, 0, 0, 0.05); position: relative; transition: transform 0.3s ease, box-shadow 0.3s ease; } .step-content::before { content: ''; position: absolute; width: 0; height: 0; top: 20px; } .journey-step:nth-child(odd) { flex-direction: row-reverse; } .journey-step:nth-child(odd) .step-content::before { right: -10px; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-left: 10px solid white; } .journey-step:nth-child(even) .step-content::before { left: -10px; border-top: 10px solid transparent; border-bottom: 10px solid transparent; border-right: 10px solid white; } .step-title { margin-bottom: 10px; color: var(--primary); font-size: 18px; font-weight: 600; } .step-description { font-size: 14px; line-height: 1.5; color: var(--text-light); margin-bottom: 15px; } .touchpoint { display: inline-block; background-color: var(--bg-medium); padding: 8px 12px; border-radius: 20px; font-size: 12px; margin-right: 6px; margin-bottom: 6px; transition: all 0.2s ease; } .touchpoint:hover { background-color: var(--secondary); color: white; transform: translateY(-2px); } .emotion-meter { height: 6px; background-color: var(--bg-medium); border-radius: 3px; margin-top: 15px; position: relative; overflow: hidden; } .emotion-value { height: 100%; border-radius: 3px; transition: width 1s ease-in-out; } .journey-step:hover .step-number { transform: scale(1.1); box-shadow: 0 6px 15px rgba(255, 126, 95, 0.4); } .journey-step:hover .step-content { transform: translateY(-5px); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08); } .decision-point { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; } .decision-option { background-color: var(--accent); color: white; padding: 5px 10px; border-radius: 15px; font-size: 12px; cursor: pointer; transition: all 0.2s ease; opacity: 0.8; } .decision-option:hover { opacity: 1; transform: scale(1.05); } .micro-animation { width: 30px; height: 30px; position: absolute; bottom: -15px; left: 50%; transform: translateX(-50%); background-color: white; border-radius: 50%; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; z-index: 4; overflow: hidden; } .pulse { position: absolute; width: 100%; height: 100%; background-color: rgba(255, 126, 95, 0.2); border-radius: 50%; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(0); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } } .compass { position: absolute; width: 15px; height: 15px; border-radius: 50%; background-color: white; display: flex; align-items: center; justify-content: center; } .compass::after { content: ''; width: 6px; height: 6px; background-color: var(--primary); border-radius: 50%; animation: pulse-small 1.5s infinite; } @keyframes pulse-small { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.4); opacity: 0.5; } 100% { transform: scale(1); opacity: 1; } } .loading-bar { position: absolute; bottom: 0; left: 0; height: 3px; background-color: var(--primary); border-radius: 1.5px; animation: loading 2s linear infinite; } @keyframes loading { 0% { width: 0%; } 50% { width: 100%; } 100% { width: 0%; } } .legend { display: flex; justify-content: center; align-items: center; flex-wrap: wrap; gap: 15px; margin-bottom: 20px; padding: 10px 15px; background-color: white; border-radius: 8px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); } .legend-item { display: flex; align-items: center; font-size: 12px; color: var(--text-light); } .legend-icon { width: 12px; height: 12px; border-radius: 50%; margin-right: 5px; } @media (max-width: 600px) { .journey-step { flex-direction: column !important; align-items: center; } .journey-step .step-content { margin-top: 15px; width: 100%; } .journey-step .step-content::before { display: none; } .map-line { left: calc(50% - 25px); } } .progress-indicator { position: fixed; top: 20px; right: 20px; width: 40px; height: 40px; border-radius: 50%; background-color: white; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); display: flex; align-items: center; justify-content: center; z-index: 10; font-size: 12px; font-weight: bold; color: var(--primary); } .progress-indicator::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; border: 2px solid var(--bg-medium); } .progress-indicator::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: 50%; border: 2px solid transparent; border-top-color: var(--primary); animation: spin 1.5s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } </style> </head> <body> <div class="container"> <h1>Customer Experience Journey</h1> <div class="legend"> <div class="legend-item"> <div class="legend-icon" style="background-color: var(--success);"></div> <span>Positive Experience</span> </div> <div class="legend-item"> <div class="legend-icon" style="background-color: var(--warning);"></div> <span>Neutral Experience</span> </div> <div class="legend-item"> <div class="legend-icon" style="background-color: var(--primary);"></div> <span>Pain Point</span> </div> </div> <div class="journey-map"> <div class="map-line"></div> <div class="journey-step"> <div class="step-number">1</div> <div class="step-content"> <h3 class="step-title">Discovery</h3> <p class="step-description">Users first encounter our product through social media, search engines, or referrals. They're seeking solutions to specific problems and beginning to research options.</p> <div class="touchpoint-container"> <span class="touchpoint">Social Media</span> <span class="touchpoint">Search Results</span> <span class="touchpoint">Blog Posts</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 60%; background-color: var(--warning);"></div> </div> <div class="micro-animation"> <div class="compass"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">2</div> <div class="step-content"> <h3 class="step-title">Initial Engagement</h3> <p class="step-description">Users explore our landing page, scanning for relevant features and benefits. This is where first impressions form and users decide whether to continue.</p> <div class="touchpoint-container"> <span class="touchpoint">Homepage</span> <span class="touchpoint">Feature Lists</span> <span class="touchpoint">Reviews</span> </div> <div class="decision-point"> <span class="decision-option">Learn More</span> <span class="decision-option">Exit Site</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 70%; background-color: var(--success);"></div> </div> <div class="micro-animation"> <div class="pulse"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">3</div> <div class="step-content"> <h3 class="step-title">Research & Consideration</h3> <p class="step-description">Users dive deeper into product details, compare pricing plans, and read customer testimonials. They're evaluating whether our product meets their specific needs.</p> <div class="touchpoint-container"> <span class="touchpoint">Pricing Page</span> <span class="touchpoint">Case Studies</span> <span class="touchpoint">FAQ Section</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 55%; background-color: var(--warning);"></div> </div> <div class="micro-animation"> <div class="loading-bar"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">4</div> <div class="step-content"> <h3 class="step-title">Sign-Up Process</h3> <p class="step-description">Users create accounts and navigate the onboarding flow. This critical stage can make or break user retention—too much friction leads to abandonment.</p> <div class="touchpoint-container"> <span class="touchpoint">Registration Form</span> <span class="touchpoint">Email Verification</span> <span class="touchpoint">Welcome Screen</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 40%; background-color: var(--primary);"></div> </div> <div class="micro-animation"> <div class="pulse"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">5</div> <div class="step-content"> <h3 class="step-title">First-Use Experience</h3> <p class="step-description">Users interact with core features for the first time. They're exploring the interface, testing functionality, and determining if the product delivers on its promises.</p> <div class="touchpoint-container"> <span class="touchpoint">Dashboard</span> <span class="touchpoint">Tutorial</span> <span class="touchpoint">First Project</span> </div> <div class="decision-point"> <span class="decision-option">Complete Setup</span> <span class="decision-option">Skip Tutorial</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 85%; background-color: var(--success);"></div> </div> <div class="micro-animation"> <div class="compass"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">6</div> <div class="step-content"> <h3 class="step-title">Adoption & Regular Use</h3> <p class="step-description">Users incorporate the product into their workflow. They develop habits, discover advanced features, and potentially recommend the product to others.</p> <div class="touchpoint-container"> <span class="touchpoint">Recurring Sessions</span> <span class="touchpoint">Feature Discovery</span> <span class="touchpoint">Support Access</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 90%; background-color: var(--success);"></div> </div> <div class="micro-animation"> <div class="pulse"></div> </div> </div> </div> <div class="journey-step"> <div class="step-number">7</div> <div class="step-content"> <h3 class="step-title">Renewal & Advocacy</h3> <p class="step-description">Users decide whether to continue their subscription. Satisfied users become advocates, leaving reviews and referring colleagues. Dissatisfied users may churn.</p> <div class="touchpoint-container"> <span class="touchpoint">Renewal Notification</span> <span class="touchpoint">Feedback Survey</span> <span class="touchpoint">Referral Program</span> </div> <div class="decision-point"> <span class="decision-option">Renew Subscription</span> <span class="decision-option">Upgrade Plan</span> <span class="decision-option">Cancel</span> </div> <div class="emotion-meter"> <div class="emotion-value" style="width: 75%; background-color: var(--success);"></div> </div> <div class="micro-animation"> <div class="loading-bar"></div> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Reveal animation for journey steps const journeySteps = document.querySelectorAll('.journey-step'); function checkVisibility() { const windowHeight = window.innerHeight; const scrollTop = document.querySelector('.container').scrollTop; journeySteps.forEach((step, index) => { const stepTop = step.offsetTop; const stepHeight = step.offsetHeight; // If element is in viewport if (stepTop < (scrollTop + windowHeight - 100) && (stepTop + stepHeight) > scrollTop) { setTimeout(() => { step.classList.add('visible'); }, index * 150); } }); } // Initial check checkVisibility(); // Check on scroll document.querySelector('.container').addEventListener('scroll', checkVisibility); // Touchpoint interaction const touchpoints = document.querySelectorAll('.touchpoint'); touchpoints.forEach(point => { point.addEventListener('click', function() { this.style.backgroundColor = 'var(--accent)'; this.style.color = 'white'; setTimeout(() => { this.style.backgroundColor = ''; this.style.color = ''; }, 1000); }); }); // Decision point interaction const decisions = document.querySelectorAll('.decision-option'); decisions.forEach(decision => { decision.addEventListener('click', function() { // Reset all decisions in this group const siblings = this.parentElement.querySelectorAll('.decision-option'); siblings.forEach(sib => { sib.style.backgroundColor = 'var(--accent)'; sib.style.opacity = '0.8'; }); // Highlight selected this.style.backgroundColor = 'var(--primary)'; this.style.opacity = '1'; }); }); // Progress indicator const container = document.querySelector('.container'); const totalHeight = container.scrollHeight - container.clientHeight; container.addEventListener('scroll', function() { const scrolled = (container.scrollTop / totalHeight) * 100; document.querySelector('.progress-indicator').textContent = Math.round(scrolled) + '%'; }); // Create the progress indicator element const progressIndicator = document.createElement('div'); progressIndicator.className = 'progress-indicator'; progressIndicator.textContent = '0%'; document.body.appendChild(progressIndicator); // Animation for emotion meters setTimeout(() => { const emotionValues = document.querySelectorAll('.emotion-value'); emotionValues.forEach(value => { const width = value.style.width; value.style.width = '0%'; setTimeout(() => { value.style.width = width; }, 100); }); }, 500); // Make all steps visible initially journeySteps.forEach((step, index) => { setTimeout(() => { step.classList.add('visible'); }, index * 150); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Startup Growth Infographic</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { width: 100%; height: 100%; overflow: hidden; background-color: #f8f9fa; } .container { width: 100%; max-width: 700px; height: 700px; margin: 0 auto; padding: 20px; background-color: #f8f9fa; position: relative; overflow: hidden; } .header { position: relative; margin-bottom: 20px; z-index: 3; } h1 { font-size: 32px; font-weight: 800; color: #1a1a2e; margin-bottom: 5px; position: relative; display: inline-block; } h1::after { content: ""; position: absolute; width: 100%; height: 8px; background: linear-gradient(90deg, #4361ee, #3a0ca3); bottom: 5px; left: 0; z-index: -1; opacity: 0.3; } .subtitle { font-size: 16px; color: #4a4a68; margin-bottom: 30px; max-width: 90%; line-height: 1.4; } .graph-container { width: 100%; height: 280px; position: relative; margin-bottom: 25px; background: #fff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.05); padding: 20px; overflow: hidden; transition: all 0.3s ease; } .graph-container:hover { box-shadow: 0 8px 30px rgba(0,0,0,0.08); transform: translateY(-2px); } .graph-title { font-weight: 600; font-size: 18px; color: #1a1a2e; margin-bottom: 15px; display: flex; justify-content: space-between; align-items: center; } .legend { display: flex; gap: 15px; font-size: 12px; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 12px; height: 12px; border-radius: 3px; } .graph { width: 100%; height: 200px; position: relative; } .axis { position: absolute; width: 100%; height: 1px; background-color: #e0e0e0; bottom: 0; left: 0; } .y-axis { position: absolute; width: 1px; height: 100%; background-color: #e0e0e0; bottom: 0; left: 0; } .y-labels { position: absolute; left: 5px; height: 100%; display: flex; flex-direction: column; justify-content: space-between; font-size: 10px; color: #999; } .y-label { transform: translateY(50%); } .x-labels { position: absolute; bottom: -20px; width: 100%; display: flex; justify-content: space-between; font-size: 10px; color: #999; } .lines { position: absolute; top: 0; left: 40px; width: calc(100% - 50px); height: 100%; } .line { position: absolute; height: 3px; background-color: transparent; bottom: 0; width: 0; opacity: 0; transition: width 1.5s cubic-bezier(0.25, 0.1, 0.25, 1), opacity 0.5s ease; } .line-path { stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: dash 2s linear forwards; animation-delay: 0.5s; } @keyframes dash { to { stroke-dashoffset: 0; } } .data-points { position: absolute; top: 0; left: 40px; width: calc(100% - 50px); height: 100%; } .data-point { position: absolute; width: 12px; height: 12px; border-radius: 50%; transform: translate(-50%, 50%); transition: all 0.3s ease; cursor: pointer; opacity: 0; animation: fadeIn 0.5s forwards; animation-delay: 1.5s; } @keyframes fadeIn { to { opacity: 1; } } .data-point:hover { transform: translate(-50%, 50%) scale(1.5); z-index: 5; } .tooltip { position: absolute; background-color: #1a1a2e; color: white; padding: 8px 12px; border-radius: 6px; font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.2s; transform: translate(-50%, -120%); z-index: 10; white-space: nowrap; box-shadow: 0 4px 12px rgba(0,0,0,0.15); } .tooltip:after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: #1a1a2e transparent transparent transparent; } .metrics-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px; margin-bottom: 20px; } .metric-card { background: white; border-radius: 10px; padding: 15px; box-shadow: 0 4px 15px rgba(0,0,0,0.04); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .metric-card:hover { transform: translateY(-5px); box-shadow: 0 8px 25px rgba(0,0,0,0.08); } .metric-card:hover .metric-icon { transform: scale(1.2); } .metric-card:hover::before { transform: scale(2.5); opacity: 0.1; } .metric-card::before { content: ""; position: absolute; width: 50px; height: 50px; border-radius: 50%; bottom: -25px; right: -25px; transition: all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94); opacity: 0.05; } .metric-icon { font-size: 24px; margin-bottom: 10px; transition: all 0.3s ease; position: relative; z-index: 2; } .metric-label { font-size: 12px; font-weight: 500; color: #4a4a68; margin-bottom: 5px; } .metric-value { font-size: 20px; font-weight: 700; color: #1a1a2e; } .stages-container { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 4px 20px rgba(0,0,0,0.05); margin-bottom: 20px; } .stages-title { font-weight: 600; font-size: 18px; color: #1a1a2e; margin-bottom: 15px; } .stages { display: flex; justify-content: space-between; position: relative; margin-top: 30px; } .stage { display: flex; flex-direction: column; align-items: center; position: relative; z-index: 2; flex: 1; } .stage-dot { width: 20px; height: 20px; border-radius: 50%; margin-bottom: 10px; position: relative; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; font-size: 12px; } .stage-label { font-size: 11px; font-weight: 600; text-align: center; color: #4a4a68; max-width: 80px; } .stage-progress { position: absolute; top: 10px; left: 0; height: 2px; background-color: #e0e0e0; width: 100%; z-index: 1; } .progress-fill { position: absolute; top: 0; left: 0; height: 100%; width: 0; transition: width 1.5s cubic-bezier(0.25, 0.46, 0.45, 0.94); } .cta-container { display: flex; justify-content: center; margin-top: 20px; } .cta-button { background: linear-gradient(90deg, #4361ee, #3a0ca3); color: white; border: none; padding: 12px 24px; border-radius: 30px; font-weight: 600; font-size: 14px; cursor: pointer; transition: all 0.3s ease; transform: scale(1); box-shadow: 0 4px 15px rgba(67, 97, 238, 0.3); } .cta-button:hover { transform: scale(1.05); box-shadow: 0 6px 20px rgba(67, 97, 238, 0.4); } .pattern { position: absolute; width: 300px; height: 300px; border-radius: 50%; background: radial-gradient(circle, rgba(67, 97, 238, 0.05) 0%, rgba(255, 255, 255, 0) 70%); z-index: 1; pointer-events: none; } .pattern-1 { top: -150px; right: -100px; } .pattern-2 { bottom: -150px; left: -100px; } @media (max-width: 600px) { h1 { font-size: 28px; } .subtitle { font-size: 14px; } .metrics-container { grid-template-columns: repeat(2, 1fr); } .metric-card:last-child { grid-column: span 2; } .stage-label { font-size: 10px; max-width: 60px; } } @media (max-width: 400px) { .container { padding: 15px; } h1 { font-size: 24px; } .graph-container { height: 250px; } .metrics-container { grid-template-columns: 1fr; } .metric-card { grid-column: span 1 !important; } } </style> </head> <body> <div class="container"> <div class="pattern pattern-1"></div> <div class="pattern pattern-2"></div> <div class="header"> <h1>Startup Growth Trajectory</h1> <p class="subtitle">A data-driven analysis of successful startup growth patterns across funding rounds and key performance metrics</p> </div> <div class="graph-container"> <div class="graph-title"> <span>Revenue Growth by Funding Stage</span> <div class="legend"> <div class="legend-item"> <div class="legend-color" style="background-color: #4361ee;"></div> <span>Avg. Revenue</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: #f72585;"></div> <span>Top Performers</span> </div> </div> </div> <div class="graph"> <div class="y-axis"></div> <div class="axis"></div> <div class="y-labels"> <div class="y-label">$10M</div> <div class="y-label">$7.5M</div> <div class="y-label">$5M</div> <div class="y-label">$2.5M</div> <div class="y-label">$0</div> </div> <div class="x-labels"> <div>Pre-Seed</div> <div>Seed</div> <div>Series A</div> <div>Series B</div> <div>Series C</div> </div> <svg class="lines" viewBox="0 0 630 200" preserveAspectRatio="none"> <path class="line-path" d="M50,180 L170,150 L290,100 L410,70 L530,30" fill="none" stroke="#4361ee" stroke-width="3"></path> <path class="line-path" d="M50,165 L170,120 L290,70 L410,25 L530,5" fill="none" stroke="#f72585" stroke-width="3"></path> </svg> <div class="data-points"></div> </div> </div> <div class="metrics-container"> <div class="metric-card" data-color="#4361ee"> <div class="metric-icon">🚀</div> <div class="metric-label">User Growth Rate</div> <div class="metric-value">127%</div> </div> <div class="metric-card" data-color="#f72585"> <div class="metric-icon">💰</div> <div class="metric-label">Avg. Series A Round</div> <div class="metric-value">$8.2M</div> </div> <div class="metric-card" data-color="#4cc9f0"> <div class="metric-icon">⏱️</div> <div class="metric-label">Months to Series B</div> <div class="metric-value">22</div> </div> </div> <div class="stages-container"> <div class="stages-title">Typical Growth Journey</div> <div class="stages"> <div class="stage-progress"> <div class="progress-fill" style="background: linear-gradient(90deg, #4361ee, #f72585);"></div> </div> <div class="stage"> <div class="stage-dot" style="background-color: #4361ee;">1</div> <div class="stage-label">Validate Problem & Solution</div> </div> <div class="stage"> <div class="stage-dot" style="background-color: #5e60ce;">2</div> <div class="stage-label">Launch MVP & Product-Market Fit</div> </div> <div class="stage"> <div class="stage-dot" style="background-color: #7209b7;">3</div> <div class="stage-label">Revenue Generation & Scaling</div> </div> <div class="stage"> <div class="stage-dot" style="background-color: #b5179e;">4</div> <div class="stage-label">Process Optimization & Expansion</div> </div> <div class="stage"> <div class="stage-dot" style="background-color: #f72585;">5</div> <div class="stage-label">Market Dominance & Exit Strategy</div> </div> </div> </div> <div class="cta-container"> <button class="cta-button">Download Full Investor Report</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize tooltip element const tooltip = document.createElement('div'); tooltip.className = 'tooltip'; document.body.appendChild(tooltip); // Initialize data points for the graph const dataPoints = [ { x: 50, y: 180, color: '#4361ee', value: '$0.5M', stage: 'Pre-Seed' }, { x: 170, y: 150, color: '#4361ee', value: '$1.2M', stage: 'Seed' }, { x: 290, y: 100, color: '#4361ee', value: '$3.8M', stage: 'Series A' }, { x: 410, y: 70, color: '#4361ee', value: '$5.6M', stage: 'Series B' }, { x: 530, y: 30, color: '#4361ee', value: '$8.5M', stage: 'Series C' }, { x: 50, y: 165, color: '#f72585', value: '$0.8M', stage: 'Pre-Seed' }, { x: 170, y: 120, color: '#f72585', value: '$2.3M', stage: 'Seed' }, { x: 290, y: 70, color: '#f72585', value: '$5.5M', stage: 'Series A' }, { x: 410, y: 25, color: '#f72585', value: '$9.1M', stage: 'Series B' }, { x: 530, y: 5, color: '#f72585', value: '$14.3M', stage: 'Series C' } ]; const dataPointsContainer = document.querySelector('.data-points'); // Create data points dataPoints.forEach((point, index) => { const dataPoint = document.createElement('div'); dataPoint.className = 'data-point'; dataPoint.style.left = `${point.x}px`; dataPoint.style.bottom = `${200 - point.y}px`; dataPoint.style.backgroundColor = point.color; dataPoint.style.animationDelay = `${1.5 + (index * 0.1)}s`; dataPoint.addEventListener('mouseenter', (e) => { tooltip.innerHTML = `${point.stage}: ${point.value}`; tooltip.style.opacity = '1'; tooltip.style.left = `${e.target.getBoundingClientRect().left}px`; tooltip.style.top = `${e.target.getBoundingClientRect().top - 10}px`; }); dataPoint.addEventListener('mouseleave', () => { tooltip.style.opacity = '0'; }); dataPointsContainer.appendChild(dataPoint); }); // Apply background colors to metric cards document.querySelectorAll('.metric-card').forEach(card => { const color = card.getAttribute('data-color'); card.style.setProperty('--card-color', color); card.querySelector('.metric-icon').style.color = color; card.style.borderLeft = `4px solid ${color}`; card.style.setProperty('--hover-color', color); card.addEventListener('mouseenter', () => { card.style.boxShadow = `0 8px 25px ${color}22`; }); card.addEventListener('mouseleave', () => { card.style.boxShadow = '0 4px 15px rgba(0,0,0,0.04)'; }); card.querySelector('.metric-value').style.color = color; card.style.setProperty('--card-color', color); card.style.setProperty('--hover-color', color); card.addEventListener('mouseenter', () => { card.style.boxShadow = `0 8px 25px ${color}22`; }); card.addEventListener('mouseleave', () => { card.style.boxShadow = '0 4px 15px rgba(0,0,0,0.04)'; }); card.querySelector('.metric-icon').style.color = color; card.querySelector('.metric-value').style.color = color; }); // Animate stage progress after a delay setTimeout(() => { document.querySelector('.progress-fill').style.width = '70%'; }, 1000); // Add hover effect for stages document.querySelectorAll('.stage').forEach((stage, index) => { stage.addEventListener('mouseenter', () => { document.querySelector('.progress-fill').style.width = `${(index + 1) * 25}%`; }); stage.addEventListener('mouseleave', () => { document.querySelector('.progress-fill').style.width = '70%'; }); }); // Add pulse animation to CTA button const ctaButton = document.querySelector('.cta-button'); ctaButton.addEventListener('click', (e) => { e.preventDefault(); ctaButton.style.transform = 'scale(0.95)'; setTimeout(() => { ctaButton.style.transform = 'scale(1.05)'; setTimeout(() => { ctaButton.style.transform = 'scale(1)'; }, 150); }, 150); }); // Make pattern follow mouse movement slightly document.addEventListener('mousemove', (e) => { const xAxis = (window.innerWidth / 2 - e.pageX) / 50; const yAxis = (window.innerHeight / 2 - e.pageY) / 50; document.querySelector('.pattern-1').style.transform = `translate(${xAxis}px, ${yAxis}px)`; document.querySelector('.pattern-2').style.transform = `translate(${-xAxis}px, ${-yAxis}px)`; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Industry Trends 2023-2024</title> <style> :root { --primary: #18385c; --secondary: #4a6f8a; --tertiary: #9db3c8; --highlight: #e07a5f; --light: #f0f5f9; --grey: #d8e1e9; --dark: #2c3e50; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; } body { background-color: var(--light); color: var(--dark); max-width: 700px; max-height: 700px; overflow-x: hidden; overflow-y: auto; } .infographic-container { padding: 2rem; display: grid; grid-template-rows: auto auto 1fr; gap: 1.5rem; height: 100%; max-height: 700px; } header { text-align: center; padding-bottom: 1rem; border-bottom: 1px solid var(--tertiary); } h1 { color: var(--primary); font-size: 1.8rem; font-weight: 600; margin-bottom: 0.5rem; letter-spacing: -0.5px; } .subtitle { color: var(--secondary); font-size: 1rem; font-weight: 400; } .dashboard { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; } @media (max-width: 600px) { .dashboard { grid-template-columns: 1fr; } } .card { background: white; border-radius: 6px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); padding: 1.5rem; transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; overflow: hidden; } .card:hover { transform: translateY(-5px); box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1); } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .card-title { font-size: 1rem; font-weight: 600; color: var(--primary); } .icon { width: 18px; height: 18px; opacity: 0.7; } .insight-value { font-size: 2rem; font-weight: 700; color: var(--primary); margin-bottom: 0.5rem; } .insight-trend { display: flex; align-items: center; font-size: 0.85rem; } .trend-up { color: #3ac47d; } .trend-down { color: #d16969; } .pie-chart-container, .bar-chart-container, .heat-map-container { height: 180px; position: relative; } .sector-legend { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.5rem; margin-top: 1rem; font-size: 0.8rem; } .legend-item { display: flex; align-items: center; } .legend-color { width: 10px; height: 10px; border-radius: 50%; margin-right: 0.5rem; } .tooltip { position: absolute; background: rgba(255, 255, 255, 0.95); border-radius: 4px; padding: 0.5rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); font-size: 0.8rem; pointer-events: none; z-index: 10; display: none; } .tooltip-title { font-weight: 600; margin-bottom: 0.25rem; } .tooltip-value { color: var(--secondary); } .forecast-section { grid-column: span 2; } @media (max-width: 600px) { .forecast-section { grid-column: span 1; } } .heat-map { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(2, 1fr); gap: 0.5rem; height: 100%; } .heat-map-cell { border-radius: 4px; display: flex; align-items: center; justify-content: center; color: white; font-weight: 500; font-size: 0.9rem; cursor: pointer; transition: transform 0.2s ease; } .heat-map-cell:hover { transform: scale(1.05); } /* Key Indicators Section */ .key-indicators { grid-column: span 2; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; } @media (max-width: 600px) { .key-indicators { grid-column: span 1; } } .indicator-card { background: white; border-radius: 6px; padding: 1rem; text-align: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); transition: transform 0.2s ease; } .indicator-card:hover { transform: translateY(-3px); } .indicator-title { font-size: 0.85rem; color: var(--secondary); margin-bottom: 0.5rem; } .indicator-value { font-size: 1.5rem; font-weight: 600; color: var(--primary); } .timeline-selector { display: flex; align-items: center; justify-content: center; gap: 1rem; margin: 1rem 0; } .time-option { padding: 0.4rem 0.8rem; border-radius: 20px; background: var(--grey); font-size: 0.8rem; cursor: pointer; transition: all 0.2s ease; } .time-option.active { background: var(--primary); color: white; } .pulse { position: absolute; top: 1rem; right: 1rem; width: 6px; height: 6px; border-radius: 50%; background: var(--highlight); } .pulse:before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background: var(--highlight); animation: pulse 2s infinite; transform: scale(1); opacity: 0; } @keyframes pulse { 0% { transform: scale(1); opacity: 0.7; } 70% { transform: scale(3); opacity: 0; } 100% { transform: scale(1); opacity: 0; } } .footnote { font-size: 0.75rem; color: var(--secondary); text-align: center; margin-top: 1rem; font-style: italic; } /* Loading animation for charts */ .loading-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; background: rgba(255, 255, 255, 0.8); z-index: 5; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .loading-spinner { width: 30px; height: 30px; border: 3px solid var(--grey); border-top: 3px solid var(--primary); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .attribution { position: absolute; bottom: 0.5rem; right: 0.5rem; font-size: 0.65rem; color: var(--tertiary); } </style> </head> <body> <div class="infographic-container"> <header> <h1>Enterprise Tech Sector Analysis: 2023-2024</h1> <p class="subtitle">Q4 2023 market performance data and 2024 forecast indicators</p> <div class="timeline-selector"> <div class="time-option" data-period="q2">Q2 2023</div> <div class="time-option" data-period="q3">Q3 2023</div> <div class="time-option active" data-period="q4">Q4 2023</div> <div class="time-option" data-period="forecast">2024 Forecast</div> </div> </header> <div class="key-indicators"> <div class="indicator-card"> <div class="indicator-title">Market Growth</div> <div class="indicator-value">+6.8%</div> </div> <div class="indicator-card"> <div class="indicator-title">Investment Volume</div> <div class="indicator-value">$82.4B</div> </div> <div class="indicator-card"> <div class="indicator-title">Innovation Index</div> <div class="indicator-value">78.3</div> </div> <div class="indicator-card"> <div class="indicator-title">Market Volatility</div> <div class="indicator-value">23.5%</div> </div> </div> <div class="dashboard"> <div class="card"> <div class="pulse"></div> <div class="card-header"> <h3 class="card-title">Sector Performance Distribution</h3> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="10" /> <path d="M12 16v-4M12 8h.01" /> </svg> </div> <div class="pie-chart-container"> <canvas id="pieChart"></canvas> <div class="loading-overlay"> <div class="loading-spinner"></div> </div> </div> <div class="sector-legend" id="pieLegend"> <!-- Legend will be populated by JS --> </div> </div> <div class="card"> <div class="card-header"> <h3 class="card-title">Revenue Growth by Segment</h3> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="10" /> <path d="M12 16v-4M12 8h.01" /> </svg> </div> <div class="bar-chart-container"> <canvas id="barChart"></canvas> <div class="loading-overlay"> <div class="loading-spinner"></div> </div> </div> <div class="tooltip" id="barTooltip"> <div class="tooltip-title">Cloud Services</div> <div class="tooltip-value">+32.5%</div> </div> </div> <div class="card forecast-section"> <div class="card-header"> <h3 class="card-title">2024 Opportunity Heat Map</h3> <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="10" /> <path d="M12 16v-4M12 8h.01" /> </svg> </div> <div class="heat-map-container"> <div class="heat-map" id="heatMap"> <!-- Heat map cells will be populated by JS --> </div> <div class="loading-overlay"> <div class="loading-spinner"></div> </div> </div> <p class="footnote">Based on market sentiment analysis and growth projections from 320+ industry analysts</p> </div> </div> <div class="attribution">Data current as of December 15, 2023</div> </div> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script> document.addEventListener('DOMContentLoaded', function() { // Show loading states const loadingOverlays = document.querySelectorAll('.loading-overlay'); loadingOverlays.forEach(overlay => { overlay.style.opacity = '1'; }); // Simulate data loading setTimeout(() => { loadingOverlays.forEach(overlay => { overlay.style.opacity = '0'; }); initializeCharts(); initializeHeatMap(); }, 800); // Timeline selector functionality const timeOptions = document.querySelectorAll('.time-option'); timeOptions.forEach(option => { option.addEventListener('click', function() { // Remove active class from all options timeOptions.forEach(opt => opt.classList.remove('active')); // Add active class to clicked option this.classList.add('active'); // Show loading state loadingOverlays.forEach(overlay => { overlay.style.opacity = '1'; }); // Simulate data update setTimeout(() => { loadingOverlays.forEach(overlay => { overlay.style.opacity = '0'; }); updateChartsBasedOnTimeline(this.dataset.period); }, 600); }); }); }); // Data for different time periods const data = { q2: { pieData: [18, 42, 15, 25], barData: [15.2, 28.7, 8.3, 19.5, 6.8], heatMapData: [ {label: 'Cloud', value: 85}, {label: 'AI/ML', value: 79}, {label: 'Cyber', value: 82}, {label: 'IoT', value: 68}, {label: '5G', value: 72}, {label: 'Fintech', value: 65}, {label: 'Edge', value: 58}, {label: 'AR/VR', value: 49} ] }, q3: { pieData: [21, 38, 16, 25], barData: [18.1, 31.5, 9.0, 17.6, 8.2], heatMapData: [ {label: 'Cloud', value: 87}, {label: 'AI/ML', value: 82}, {label: 'Cyber', value: 84}, {label: 'IoT', value: 71}, {label: '5G', value: 75}, {label: 'Fintech', value: 69}, {label: 'Edge', value: 63}, {label: 'AR/VR', value: 53} ] }, q4: { pieData: [25, 36, 17, 22], barData: [21.3, 34.2, 11.7, 15.8, 10.5], heatMapData: [ {label: 'Cloud', value: 92}, {label: 'AI/ML', value: 89}, {label: 'Cyber', value: 87}, {label: 'IoT', value: 73}, {label: '5G', value: 78}, {label: 'Fintech', value: 71}, {label: 'Edge', value: 67}, {label: 'AR/VR', value: 58} ] }, forecast: { pieData: [30, 35, 16, 19], barData: [24.8, 38.7, 15.3, 14.2, 13.9], heatMapData: [ {label: 'Cloud', value: 95}, {label: 'AI/ML', value: 94}, {label: 'Cyber', value: 91}, {label: 'IoT', value: 77}, {label: '5G', value: 82}, {label: 'Fintech', value: 76}, {label: 'Edge', value: 74}, {label: 'AR/VR', value: 67} ] } }; let pieChart, barChart; function initializeCharts() { // Pie Chart const pieCtx = document.getElementById('pieChart').getContext('2d'); pieChart = new Chart(pieCtx, { type: 'doughnut', data: { labels: ['Cloud Infrastructure', 'Enterprise Software', 'Cybersecurity', 'Hardware'], datasets: [{ data: data.q4.pieData, backgroundColor: [ '#3670b0', '#5993d3', '#84bbe5', '#b8e1ff' ], borderWidth: 1 }] }, options: { responsive: true, maintainAspectRatio: false, cutout: '60%', plugins: { legend: { display: false }, tooltip: { callbacks: { label: function(context) { const label = context.label || ''; const value = context.parsed || 0; return `${label}: ${value}%`; } } } }, animation: { animateRotate: true, animateScale: true } } }); // Create legend createPieLegend(); // Bar Chart const barCtx = document.getElementById('barChart').getContext('2d'); barChart = new Chart(barCtx, { type: 'bar', data: { labels: ['Cloud', 'AI/ML', 'Security', 'SaaS', 'Edge'], datasets: [{ label: 'Growth Rate (%)', data: data.q4.barData, backgroundColor: '#3670b0', borderColor: '#18385c', borderWidth: 1, borderRadius: 4, }] }, options: { responsive: true, maintainAspectRatio: false, scales: { y: { beginAtZero: true, grid: { display: true, color: 'rgba(0, 0, 0, 0.05)' }, ticks: { callback: function(value) { return value + '%'; } } }, x: { grid: { display: false } } }, plugins: { legend: { display: false }, tooltip: { enabled: false, external: externalTooltipHandler } }, animation: { duration: 1000 } } }); } function createPieLegend() { const legend = document.getElementById('pieLegend'); legend.innerHTML = ''; const colors = ['#3670b0', '#5993d3', '#84bbe5', '#b8e1ff']; const labels = ['Cloud Infrastructure', 'Enterprise Software', 'Cybersecurity', 'Hardware']; for (let i = 0; i < labels.length; i++) { const item = document.createElement('div'); item.className = 'legend-item'; const colorBox = document.createElement('div'); colorBox.className = 'legend-color'; colorBox.style.backgroundColor = colors[i]; const text = document.createElement('span'); text.textContent = labels[i]; item.appendChild(colorBox); item.appendChild(text); legend.appendChild(item); } } function initializeHeatMap() { const heatMap = document.getElementById('heatMap'); const heatMapData = data.q4.heatMapData; heatMap.innerHTML = ''; heatMapData.forEach(item => { const cell = document.createElement('div'); cell.className = 'heat-map-cell'; cell.textContent = item.label; // Calculate color based on value (from red to green) const intensity = Math.min(Math.max(item.value / 100, 0), 1); const color = getHeatMapColor(intensity); cell.style.backgroundColor = color; // Add hover effect to show value cell.addEventListener('mouseenter', function() { const tooltip = document.createElement('div'); tooltip.className = 'tooltip-value'; tooltip.textContent = `Score: ${item.value}/100`; tooltip.style.position = 'absolute'; tooltip.style.bottom = '0'; tooltip.style.left = '0'; tooltip.style.right = '0'; tooltip.style.textAlign = 'center'; tooltip.style.background = 'rgba(0,0,0,0.7)'; tooltip.style.color = 'white'; tooltip.style.padding = '3px'; tooltip.style.fontSize = '0.75rem'; tooltip.style.borderBottomLeftRadius = '4px'; tooltip.style.borderBottomRightRadius = '4px'; cell.appendChild(tooltip); }); cell.addEventListener('mouseleave', function() { const tooltip = cell.querySelector('.tooltip-value'); if (tooltip) { cell.removeChild(tooltip); } }); heatMap.appendChild(cell); }); } function getHeatMapColor(intensity) { // Generate colors from cold (blue) to hot (red) const r = Math.round(intensity * 220); const g = Math.round((1 - Math.pow(intensity - 0.5, 2) * 4) * 180); const b = Math.round((1 - intensity) * 220); return `rgb(${r}, ${g}, ${b})`; } function externalTooltipHandler(context) { // Tooltip Element const {chart, tooltip} = context; const tooltipEl = document.getElementById('barTooltip'); // Hide if no tooltip if (tooltip.opacity === 0) { tooltipEl.style.display = 'none'; return; } // Set Text if (tooltip.body) { const titleLines = tooltip.title || []; const bodyLines = tooltip.body.map(b => b.lines); const titleElement = tooltipEl.querySelector('.tooltip-title'); titleElement.textContent = titleLines[0]; const valueElement = tooltipEl.querySelector('.tooltip-value'); valueElement.textContent = bodyLines[0]; } // Position tooltip const position = chart.canvas.getBoundingClientRect(); tooltipEl.style.display = 'block'; tooltipEl.style.left = position.left + window.pageXOffset + tooltip.caretX - (tooltipEl.offsetWidth / 2) + 'px'; tooltipEl.style.top = position.top + window.pageYOffset + tooltip.caretY - tooltipEl.offsetHeight - 10 + 'px'; } function updateChartsBasedOnTimeline(period) { // Update pie chart data pieChart.data.datasets[0].data = data[period].pieData; pieChart.update(); // Update bar chart data barChart.data.datasets[0].data = data[period].barData; barChart.update(); // Update heat map const heatMap = document.getElementById('heatMap'); const heatMapData = data[period].heatMapData; heatMap.innerHTML = ''; heatMapData.forEach(item => { const cell = document.createElement('div'); cell.className = 'heat-map-cell'; cell.textContent = item.label; const intensity = Math.min(Math.max(item.value / 100, 0), 1); const color = getHeatMapColor(intensity); cell.style.backgroundColor = color; cell.addEventListener('mouseenter', function() { const tooltip = document.createElement('div'); tooltip.className = 'tooltip-value'; tooltip.textContent = `Score: ${item.value}/100`; tooltip.style.position = 'absolute'; tooltip.style.bottom = '0'; tooltip.style.left = '0'; tooltip.style.right = '0'; tooltip.style.textAlign = 'center'; tooltip.style.background = 'rgba(0,0,0,0.7)'; tooltip.style.color = 'white'; tooltip.style.padding = '3px'; tooltip.style.fontSize = '0.75rem'; tooltip.style.borderBottomLeftRadius = '4px'; tooltip.style.borderBottomRightRadius = '4px'; cell.appendChild(tooltip); }); cell.addEventListener('mouseleave', function() { const tooltip = cell.querySelector('.tooltip-value'); if (tooltip) { cell.removeChild(tooltip); } }); heatMap.appendChild(cell); }); // Update key indicators based on period const indicators = { q2: ['5.3%', '$67.8B', '72.5', '28.7%'], q3: ['6.1%', '$75.2B', '75.8', '26.1%'], q4: ['6.8%', '$82.4B', '78.3', '23.5%'], forecast: ['7.6%', '$94.1B', '82.5', '19.2%'] }; const indicatorValues = document.querySelectorAll('.indicator-value'); indicatorValues[0].textContent = indicators[period][0]; indicatorValues[1].textContent = indicators[period][1]; indicatorValues[2].textContent = indicators[period][2]; indicatorValues[3].textContent = indicators[period][3]; // Add a subtle animation to the indicators indicatorValues.forEach(value => { value.style.transform = 'scale(1.1)'; setTimeout(() => { value.style.transform = 'scale(1)'; }, 200); }); } </script> </body> </html>