Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>MarketGap - Market Intelligence Dashboard</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"> | |
| <script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap'); | |
| :root { | |
| --primary: #6366f1; | |
| --primary-dark: #4f46e5; | |
| --secondary: #06b6d4; | |
| --accent: #f59e0b; | |
| --success: #10b981; | |
| --warning: #f59e0b; | |
| --danger: #ef4444; | |
| --dark: #1e293b; | |
| --light: #f8fafc; | |
| } | |
| body { | |
| font-family: 'Inter', sans-serif; | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| min-height: 100vh; | |
| } | |
| .glass-morphism { | |
| background: rgba(255, 255, 255, 0.1); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| border-radius: 16px; | |
| } | |
| .gradient-text { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| background-clip: text; | |
| } | |
| .pulse-animation { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 1; } | |
| 50% { opacity: 0.5; } | |
| 100% { opacity: 1; } | |
| } | |
| .floating { | |
| animation: floating 3s ease-in-out infinite; | |
| } | |
| @keyframes floating { | |
| 0% { transform: translateY(0px); } | |
| 50% { transform: translateY(-10px); } | |
| 100% { transform: translateY(0px); } | |
| } | |
| .chart-container { | |
| background: rgba(255, 255, 255, 0.95); | |
| border-radius: 16px; | |
| box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); | |
| backdrop-filter: blur(4px); | |
| } | |
| .loading-spinner { | |
| border: 3px solid #f3f3f3; | |
| border-top: 3px solid var(--primary); | |
| border-radius: 50%; | |
| width: 40px; | |
| height: 40px; | |
| animation: spin 1s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .metric-card { | |
| transition: all 0.3s ease; | |
| } | |
| .metric-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); | |
| } | |
| .opportunity-card { | |
| transition: all 0.3s ease; | |
| border-left: 4px solid var(--primary); | |
| } | |
| .opportunity-card:hover { | |
| transform: translateX(5px); | |
| box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); | |
| } | |
| .btn-primary { | |
| background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%); | |
| border: none; | |
| color: white; | |
| padding: 12px 24px; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| cursor: pointer; | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 8px 16px rgba(99, 102, 241, 0.3); | |
| } | |
| .btn-secondary { | |
| background: rgba(255, 255, 255, 0.2); | |
| border: 1px solid rgba(255, 255, 255, 0.3); | |
| color: white; | |
| padding: 12px 24px; | |
| border-radius: 8px; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| cursor: pointer; | |
| } | |
| .btn-secondary:hover { | |
| background: rgba(255, 255, 255, 0.3); | |
| transform: translateY(-2px); | |
| } | |
| .keyword-tag { | |
| background: rgba(255, 255, 255, 0.2); | |
| border: 1px solid rgba(255, 255, 255, 0.3); | |
| color: white; | |
| padding: 4px 12px; | |
| border-radius: 20px; | |
| font-size: 14px; | |
| margin: 2px; | |
| display: inline-block; | |
| } | |
| .trend-indicator { | |
| display: inline-flex; | |
| align-items: center; | |
| gap: 4px; | |
| font-size: 12px; | |
| font-weight: 600; | |
| } | |
| .trend-up { color: var(--success); } | |
| .trend-down { color: var(--danger); } | |
| .trend-neutral { color: var(--warning); } | |
| .sentiment-positive { color: var(--success); } | |
| .sentiment-negative { color: var(--danger); } | |
| .sentiment-neutral { color: var(--warning); } | |
| .animate-fade-in { | |
| animation: fadeIn 0.6s ease-out; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(20px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .scrollbar-hide { | |
| -ms-overflow-style: none; | |
| scrollbar-width: none; | |
| } | |
| .scrollbar-hide::-webkit-scrollbar { | |
| display: none; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Background Animation --> | |
| <div id="vanta-bg" class="fixed inset-0 z-0"></div> | |
| <!-- Navigation --> | |
| <nav class="relative z-10 glass-morphism m-4 p-4 flex justify-between items-center animate-fade-in"> | |
| <div class="flex items-center gap-3"> | |
| <div class="w-10 h-10 bg-gradient-to-r from-indigo-500 to-purple-600 rounded-lg flex items-center justify-center"> | |
| <i data-feather="trending-up" class="text-white"></i> | |
| </div> | |
| <h1 class="text-xl font-bold text-white">MarketGap</h1> | |
| </div> | |
| <div class="flex items-center gap-4"> | |
| <button id="refresh-btn" class="btn-secondary"> | |
| <i data-feather="refresh-cw" class="w-4 h-4 inline mr-2"></i>Refresh | |
| </button> | |
| <button id="export-btn" class="btn-primary"> | |
| <i data-feather="download" class="w-4 h-4 inline mr-2"></i>Export | |
| </button> | |
| </div> | |
| </nav> | |
| <!-- Main Content --> | |
| <div class="relative z-10 container mx-auto px-4 py-8"> | |
| <!-- Header Section --> | |
| <div class="text-center mb-12 animate-fade-in" data-aos="fade-up"> | |
| <h2 class="text-5xl font-bold text-white mb-4 gradient-text">Market Intelligence Dashboard</h2> | |
| <p class="text-xl text-white/80 max-w-2xl mx-auto"> | |
| Discover hidden market opportunities with AI-powered trend analysis across multiple platforms | |
| </p> | |
| </div> | |
| <!-- Input Section --> | |
| <div class="glass-morphism p-8 mb-12 animate-fade-in" data-aos="fade-up" data-aos-delay="200"> | |
| <div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> | |
| <div> | |
| <label class="block text-white font-semibold mb-3">Keywords to Analyze</label> | |
| <input | |
| id="keywords-input" | |
| type="text" | |
| placeholder="e.g., AI productivity, remote work, sustainable packaging" | |
| class="w-full px-4 py-3 rounded-lg bg-white/20 border border-white/30 text-white placeholder-white/60 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" | |
| > | |
| <div class="mt-2 flex flex-wrap gap-2" id="keyword-tags"> | |
| <span class="keyword-tag">AI productivity</span> | |
| <span class="keyword-tag">remote work</span> | |
| <span class="keyword-tag">sustainable packaging</span> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block text-white font-semibold mb-3">Analysis Options</label> | |
| <div class="grid grid-cols-2 gap-4 mb-4"> | |
| <div> | |
| <label class="block text-white/80 text-sm mb-1">Time Period</label> | |
| <select id="time-period" class="w-full px-3 py-2 rounded-lg bg-white/20 border border-white/30 text-white"> | |
| <option value="7">7 days</option> | |
| <option value="30" selected>30 days</option> | |
| <option value="90">90 days</option> | |
| <option value="365">1 year</option> | |
| </select> | |
| </div> | |
| <div> | |
| <label class="block text-white/80 text-sm mb-1">Data Sources</label> | |
| <select id="data-sources" class="w-full px-3 py-2 rounded-lg bg-white/20 border border-white/30 text-white"> | |
| <option value="all" selected>All Sources</option> | |
| <option value="reddit">Reddit</option> | |
| <option value="twitter">Twitter</option> | |
| <option value="github">GitHub</option> | |
| <option value="news">News</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="flex gap-3"> | |
| <button id="analyze-btn" class="btn-primary flex-1"> | |
| <i data-feather="search" class="w-4 h-4 inline mr-2"></i>Analyze Trends | |
| </button> | |
| <button id="quick-scan-btn" class="btn-secondary"> | |
| <i data-feather="zap" class="w-4 h-4 inline mr-2"></i>Quick Scan | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Metrics Overview --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12 animate-fade-in" data-aos="fade-up" data-aos-delay="300"> | |
| <div class="metric-card glass-morphism p-6 text-center"> | |
| <div class="text-3xl font-bold text-white mb-2" id="total-data-points">0</div> | |
| <div class="text-white/70">Data Points</div> | |
| <div class="trend-indicator trend-up mt-2"> | |
| <i data-feather="trending-up" class="w-4 h-4"></i> | |
| <span>+12.5%</span> | |
| </div> | |
| </div> | |
| <div class="metric-card glass-morphism p-6 text-center"> | |
| <div class="text-3xl font-bold text-white mb-2" id="market-gaps">0</div> | |
| <div class="text-white/70">Market Gaps</div> | |
| <div class="trend-indicator trend-up mt-2"> | |
| <i data-feather="trending-up" class="w-4 h-4"></i> | |
| <span>+8.3%</span> | |
| </div> | |
| </div> | |
| <div class="metric-card glass-morphism p-6 text-center"> | |
| <div class="text-3xl font-bold text-white mb-2" id="avg-sentiment">0.0</div> | |
| <div class="text-white/70">Avg Sentiment</div> | |
| <div class="trend-indicator trend-neutral mt-2"> | |
| <i data-feather="minus" class="w-4 h-4"></i> | |
| <span>Neutral</span> | |
| </div> | |
| </div> | |
| <div class="metric-card glass-morphism p-6 text-center"> | |
| <div class="text-3xl font-bold text-white mb-2" id="confidence-score">0%</div> | |
| <div class="text-white/70">Confidence</div> | |
| <div class="trend-indicator trend-up mt-2"> | |
| <i data-feather="trending-up" class="w-4 h-4"></i> | |
| <span>+15.2%</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Main Dashboard --> | |
| <div class="grid grid-cols-1 lg:grid-cols-3 gap-8 animate-fade-in" data-aos="fade-up" data-aos-delay="400"> | |
| <!-- Left Column: Charts --> | |
| <div class="lg:col-span-2 space-y-8"> | |
| <!-- Trend Timeline Chart --> | |
| <div class="chart-container p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h3 class="text-xl font-bold text-gray-800">Trend Timeline</h3> | |
| <div class="flex gap-2"> | |
| <button class="btn-secondary text-sm px-3 py-1"> | |
| <i data-feather="bar-chart-2" class="w-3 h-3"></i> | |
| </button> | |
| <button class="btn-secondary text-sm px-3 py-1"> | |
| <i data-feather="pie-chart" class="w-3 h-3"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div id="trend-timeline-chart" style="height: 300px;"></div> | |
| </div> | |
| <!-- Source Distribution --> | |
| <div class="chart-container p-6"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">Data Source Distribution</h3> | |
| <div id="source-distribution-chart" style="height: 250px;"></div> | |
| </div> | |
| <!-- Sentiment Heatmap --> | |
| <div class="chart-container p-6"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">Sentiment Analysis</h3> | |
| <div id="sentiment-heatmap-chart" style="height: 300px;"></div> | |
| </div> | |
| </div> | |
| <!-- Right Column: Opportunities --> | |
| <div class="space-y-8"> | |
| <!-- Top Opportunities --> | |
| <div class="chart-container p-6"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">Top Opportunities</h3> | |
| <div id="opportunities-list" class="space-y-3"> | |
| <div class="opportunity-card bg-gradient-to-r from-indigo-50 to-purple-50 p-4 rounded-lg"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h4 class="font-semibold text-gray-800 text-sm">AI Productivity Tools</h4> | |
| <span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full">High</span> | |
| </div> | |
| <p class="text-xs text-gray-600 mb-2">Growing demand for AI-powered productivity solutions</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-xs text-gray-500">Evidence: 0.85</span> | |
| <span class="text-xs text-indigo-600 font-semibold">Explore →</span> | |
| </div> | |
| </div> | |
| <div class="opportunity-card bg-gradient-to-r from-cyan-50 to-blue-50 p-4 rounded-lg"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h4 class="font-semibold text-gray-800 text-sm">Remote Work Platforms</h4> | |
| <span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded-full">Medium</span> | |
| </div> | |
| <p class="text-xs text-gray-600 mb-2">Hybrid work solutions gaining traction</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-xs text-gray-500">Evidence: 0.72</span> | |
| <span class="text-xs text-cyan-600 font-semibold">Explore →</span> | |
| </div> | |
| </div> | |
| <div class="opportunity-card bg-gradient-to-r from-emerald-50 to-teal-50 p-4 rounded-lg"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h4 class="font-semibold text-gray-800 text-sm">Sustainable Packaging</h4> | |
| <span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full">High</span> | |
| </div> | |
| <p class="text-xs text-gray-600 mb-2">Eco-friendly packaging solutions in demand</p> | |
| <div class="flex justify-between items-center"> | |
| <span class="text-xs text-gray-500">Evidence: 0.68</span> | |
| <span class="text-xs text-emerald-600 font-semibold">Explore →</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Market Gaps --> | |
| <div class="chart-container p-6"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">Market Gaps</h3> | |
| <div id="market-gaps-chart" style="height: 200px;"></div> | |
| </div> | |
| <!-- Keyword Network --> | |
| <div class="chart-container p-6"> | |
| <h3 class="text-xl font-bold text-gray-800 mb-4">Keyword Network</h3> | |
| <div id="keyword-network-chart" style="height: 250px;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Detailed Analysis Section --> | |
| <div class="mt-12 animate-fade-in" data-aos="fade-up" data-aos-delay="500"> | |
| <div class="chart-container p-8"> | |
| <h3 class="text-2xl font-bold text-gray-800 mb-6">Detailed Market Analysis</h3> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> | |
| <div> | |
| <h4 class="text-lg font-semibold text-gray-700 mb-4">Cross-Platform Correlations</h4> | |
| <div id="correlations-chart" style="height: 300px;"></div> | |
| </div> | |
| <div> | |
| <h4 class="text-lg font-semibold text-gray-700 mb-4">ROI Estimates</h4> | |
| <div id="roi-chart" style="height: 300px;"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Loading Overlay --> | |
| <div id="loading-overlay" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center hidden"> | |
| <div class="glass-morphism p-8 rounded-lg text-center"> | |
| <div class="loading-spinner mx-auto mb-4"></div> | |
| <p class="text-white text-lg">Analyzing market trends...</p> | |
| <p class="text-white/70 text-sm mt-2">This may take a few moments</p> | |
| </div> | |
| </div> | |
| <!-- Scripts --> | |
| <script src="https://cdn.jsdelivr.net/npm/three@0.155.0/build/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script> | |
| <script> | |
| // Initialize AOS | |
| AOS.init({ | |
| duration: 800, | |
| once: true | |
| }); | |
| // Initialize Feather Icons | |
| feather.replace(); | |
| // Initialize Vanta Background | |
| VANTA.GLOBE({ | |
| el: "#vanta-bg", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0x6366f1, | |
| backgroundColor: 0x1e293b, | |
| size: 1.2 | |
| }); | |
| // Sample data for charts | |
| const sampleData = { | |
| timeline: { | |
| keywords: ['AI productivity', 'remote work', 'sustainable packaging'], | |
| dates: Array.from({length: 30}, (_, i) => { | |
| const date = new Date(); | |
| date.setDate(date.getDate() - (29 - i)); | |
| return date.toISOString().split('T')[0]; | |
| }), | |
| volumes: { | |
| 'AI productivity': Array.from({length: 30}, () => Math.floor(Math.random() * 1000) + 500), | |
| 'remote work': Array.from({length: 30}, () => Math.floor(Math.random() * 800) + 300), | |
| 'sustainable packaging': Array.from({length: 30}, () => Math.floor(Math.random() * 600) + 200) | |
| } | |
| }, | |
| sources: { | |
| 'Reddit': 35, | |
| 'Twitter': 25, | |
| 'GitHub': 20, | |
| 'News': 15, | |
| 'Google Trends': 5 | |
| }, | |
| sentiments: { | |
| 'AI productivity': 0.72, | |
| 'remote work': 0.45, | |
| 'sustainable packaging': 0.68 | |
| }, | |
| opportunities: [ | |
| { name: 'AI Productivity Tools', score: 0.85, confidence: 0.92 }, | |
| { name: 'Remote Work Platforms', score: 0.72, confidence: 0.78 }, | |
| { name: 'Sustainable Packaging', score: 0.68, confidence: 0.85 }, | |
| { name: 'Mental Health Apps', score: 0.65, confidence: 0.73 }, | |
| { name: 'Electric Vehicle Charging', score: 0.58, confidence: 0.69 } | |
| ], | |
| marketGaps: [ | |
| { name: 'Supply Gap 1', value: 45 }, | |
| { name: 'Demand Indicator', value: 35 }, | |
| { name: 'Competition Void', value: 20 } | |
| ] | |
| }; | |
| // Initialize Charts | |
| function initCharts() { | |
| // Timeline Chart | |
| const timelineChart = echarts.init(document.getElementById('trend-timeline-chart')); | |
| const timelineOption = { | |
| title: { text: 'Trend Volume Over Time', textStyle: { color: '#374151' } }, | |
| tooltip: { trigger: 'axis' }, | |
| legend: { data: sampleData.timeline.keywords, top: 30 }, | |
| grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, | |
| xAxis: { type: 'category', data: sampleData.timeline.dates, axisLabel: { rotate: 45 } }, | |
| yAxis: { type: 'value', name: 'Volume' }, | |
| series: sampleData.timeline.keywords.map(keyword => ({ | |
| name: keyword, | |
| type: 'line', | |
| smooth: true, | |
| data: sampleData.timeline.volumes[keyword], | |
| lineStyle: { width: 3 }, | |
| areaStyle: { opacity: 0.1 } | |
| })) | |
| }; | |
| timelineChart.setOption(timelineOption); | |
| // Source Distribution Chart | |
| const sourceChart = echarts.init(document.getElementById('source-distribution-chart')); | |
| const sourceOption = { | |
| title: { text: 'Data Sources', textStyle: { color: '#374151' } }, | |
| tooltip: { trigger: 'item' }, | |
| series: [{ | |
| type: 'pie', | |
| radius: ['40%', '70%'], | |
| data: Object.entries(sampleData.sources).map(([name, value]) => ({ name, value })), | |
| emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } | |
| }] | |
| }; | |
| sourceChart.setOption(sourceOption); | |
| // Sentiment Heatmap | |
| const sentimentChart = echarts.init(document.getElementById('sentiment-heatmap-chart')); | |
| const sentimentOption = { | |
| title: { text: 'Sentiment by Keyword', textStyle: { color: '#374151' } }, | |
| tooltip: { position: 'top' }, | |
| grid: { height: '50%', top: '10%' }, | |
| xAxis: { type: 'category', data: ['Reddit', 'Twitter', 'GitHub', 'News'], splitArea: { show: true } }, | |
| yAxis: { type: 'category', data: sampleData.timeline.keywords, splitArea: { show: true } }, | |
| visualMap: { min: -1, max: 1, calculable: true, orient: 'horizontal', left: 'center', bottom: '15%' }, | |
| series: [{ | |
| name: 'Sentiment', | |
| type: 'heatmap', | |
| data: sampleData.timeline.keywords.flatMap((keyword, i) => | |
| ['Reddit', 'Twitter', 'GitHub', 'News'].map((source, j) => [j, i, Math.random() * 2 - 1]) | |
| ), | |
| label: { show: true } | |
| }] | |
| }; | |
| sentimentChart.setOption(sentimentOption); | |
| // Market Gaps Chart | |
| const gapsChart = echarts.init(document.getElementById('market-gaps-chart')); | |
| const gapsOption = { | |
| title: { text: 'Gap Types', textStyle: { color: '#374151' } }, | |
| tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } }, | |
| xAxis: { type: 'category', data: sampleData.marketGaps.map(item => item.name) }, | |
| yAxis: { type: 'value' }, | |
| series: [{ | |
| type: 'bar', | |
| data: sampleData.marketGaps.map(item => item.value), | |
| itemStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ | |
| { offset: 0, color: '#6366f1' }, | |
| { offset: 1, color: '#8b5cf6' } | |
| ]) } | |
| }] | |
| }; | |
| gapsChart.setOption(gapsOption); | |
| // Keyword Network | |
| const networkChart = echarts.init(document.getElementById('keyword-network-chart')); | |
| const networkOption = { | |
| title: { text: 'Keyword Relationships', textStyle: { color: '#374151' } }, | |
| series: [{ | |
| type: 'graph', | |
| layout: 'force', | |
| symbolSize: 50, | |
| roam: true, | |
| label: { show: true }, | |
| edgeSymbol: ['circle', 'arrow'], | |
| edgeSymbolSize: [4, 10], | |
| data: sampleData.timeline.keywords.map(name => ({ name, value: Math.random() * 100 })), | |
| links: sampleData.timeline.keywords.flatMap((source, i) => | |
| sampleData.timeline.keywords.slice(i + 1).map(target => ({ | |
| source, | |
| target, | |
| value: Math.random() * 10 | |
| })) | |
| ), | |
| lineStyle: { opacity: 0.9, width: 2, curveness: 0.3 } | |
| }] | |
| }; | |
| networkChart.setOption(networkOption); | |
| // Correlations Chart | |
| const corrChart = echarts.init(document.getElementById('correlations-chart')); | |
| const corrOption = { | |
| title: { text: 'Platform Correlations', textStyle: { color: '#374151' } }, | |
| xAxis: { type: 'category', data: ['Reddit', 'Twitter', 'GitHub', 'News'] }, | |
| yAxis: { type: 'category', data: ['Reddit', 'Twitter', 'GitHub', 'News'] }, | |
| visualMap: { min: 0, max: 1, calculable: true, orient: 'horizontal', left: 'center', bottom: '15%' }, | |
| series: [{ | |
| type: 'heatmap', | |
| data: ['Reddit', 'Twitter', 'GitHub', 'News'].flatMap((source, i) => | |
| ['Reddit', 'Twitter', 'GitHub', 'News'].map((target, j) => [j, i, i === j ? 1 : Math.random()]) | |
| ) | |
| }] | |
| }; | |
| corrChart.setOption(corrOption); | |
| // ROI Chart | |
| const roiChart = echarts.init(document.getElementById('roi-chart')); | |
| const roiOption = { | |
| title: { text: 'ROI Potential', textStyle: { color: '#374151' } }, | |
| tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c}%' }, | |
| series: [{ | |
| name: 'ROI', | |
| type: 'gauge', | |
| detail: { formatter: '{value}%' }, | |
| data: [{ value: 75, name: 'Potential ROI' }] | |
| }] | |
| }; | |
| roiChart.setOption(roiOption); | |
| // Responsive charts | |
| window.addEventListener('resize', () => { | |
| [timelineChart, sourceChart, sentimentChart, gapsChart, networkChart, corrChart, roiChart].forEach(chart => { | |
| chart.resize(); | |
| }); | |
| }); | |
| } | |
| // Update Metrics | |
| function updateMetrics() { | |
| document.getElementById('total-data-points').textContent = '12,847'; | |
| document.getElementById('market-gaps').textContent = '23'; | |
| document.getElementById('avg-sentiment').textContent = '0.68'; | |
| document.getElementById('confidence-score').textContent = '87%'; | |
| } | |
| // Event Listeners | |
| document.getElementById('analyze-btn').addEventListener('click', function() { | |
| const loadingOverlay = document.getElementById('loading-overlay'); | |
| loadingOverlay.classList.remove('hidden'); | |
| setTimeout(() => { | |
| loadingOverlay.classList.add('hidden'); | |
| initCharts(); | |
| updateMetrics(); | |
| }, 3000); | |
| }); | |
| document.getElementById('refresh-btn').addEventListener('click', function() { | |
| location.reload(); | |
| }); | |
| document.getElementById('export-btn').addEventListener('click', function() { | |
| alert('Export functionality would be implemented here'); | |
| }); | |
| // Quick Scan | |
| document.getElementById('quick-scan-btn').addEventListener('click', function() { | |
| const loadingOverlay = document.getElementById('loading-overlay'); | |
| loadingOverlay.classList.remove('hidden'); | |
| setTimeout(() => { | |
| loadingOverlay.classList.add('hidden'); | |
| // Show quick results | |
| updateMetrics(); | |
| }, 1500); | |
| }); | |
| // Initialize | |
| document.addEventListener('DOMContentLoaded', function() { | |
| initCharts(); | |
| updateMetrics(); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |