Download script.js from alejandro-ao/pulsefaker-analytics-dash: direct link, hf CLI and curl.
- Browser
- Download file 9.75 kB
-
https://huggingface.co/spaces/alejandro-ao/pulsefaker-analytics-dash/resolve/main/script.js
- Command line
-
hf download hf://spaces/alejandro-ao/pulsefaker-analytics-dash/script.js
-
curl -L -o script.js https://huggingface.co/spaces/alejandro-ao/pulsefaker-analytics-dash/resolve/main/script.js
9.75 kB
| // Initialize charts | |
| let userChart, revenueChart, performanceChart, activityChart; | |
| document.addEventListener('DOMContentLoaded', () => { | |
| setupCharts(); | |
| startDataUpdates(); | |
| }); | |
| function setupCharts() { | |
| const chartOptions = { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| legend: { | |
| position: 'top', | |
| labels: { | |
| color: window.matchMedia('(prefers-color-scheme: dark)').matches ? '#fff' : '#000' | |
| } | |
| } | |
| }, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| grid: { | |
| color: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)' | |
| }, | |
| ticks: { | |
| color: window.matchMedia('(prefers-color-scheme: dark)').matches ? '#fff' : '#000' | |
| } | |
| }, | |
| x: { | |
| grid: { | |
| color: window.matchMedia('(prefers-color-scheme: dark)').matches ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)' | |
| }, | |
| ticks: { | |
| color: window.matchMedia('(prefers-color-scheme: dark)').matches ? '#fff' : '#000' | |
| } | |
| } | |
| } | |
| }; | |
| // User Growth Chart | |
| const userCtx = document.getElementById('userChart').getContext('2d'); | |
| userChart = new Chart(userCtx, { | |
| type: 'line', | |
| data: { | |
| labels: Array.from({length: 12}, (_, i) => `${i+1}AM`), | |
| datasets: [{ | |
| label: 'Active Users', | |
| data: Array(12).fill(0).map((_,i) => { | |
| const hourFactor = Math.sin((i / 11) * Math.PI) * 0.5 + 0.7; | |
| return Math.floor(3000 + (hourFactor * 2000) + Math.random() * 500 - 250); | |
| }), | |
| borderColor: '#6366f1', | |
| backgroundColor: 'rgba(99, 102, 241, 0.1)', | |
| tension: 0.4, | |
| fill: true | |
| }] | |
| }, | |
| options: chartOptions | |
| }); | |
| // Revenue Chart | |
| const revenueCtx = document.getElementById('revenueChart').getContext('2d'); | |
| revenueChart = new Chart(revenueCtx, { | |
| type: 'doughnut', | |
| data: { | |
| labels: ['Subscriptions', 'Ads', 'Merchandise', 'Services'], | |
| datasets: [{ | |
| data: [35, 25, 20, 20].map(v => v + Math.floor(Math.random() * 10 - 5)), | |
| backgroundColor: [ | |
| '#6366f1', | |
| '#8b5cf6', | |
| '#ec4899', | |
| '#f43f5e' | |
| ], | |
| borderWidth: 0 | |
| }] | |
| }, | |
| options: { | |
| ...chartOptions, | |
| cutout: '70%' | |
| } | |
| }); | |
| // Performance Chart | |
| const performanceCtx = document.getElementById('performanceChart').getContext('2d'); | |
| performanceChart = new Chart(performanceCtx, { | |
| type: 'bar', | |
| data: { | |
| labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | |
| datasets: [ | |
| { | |
| label: 'Page Load (ms)', | |
| data: Array(7).fill(0).map(() => 100 + Math.floor(Math.random() * 300)), | |
| backgroundColor: '#6366f1' | |
| }, | |
| { | |
| label: 'API Response (ms)', | |
| data: Array(7).fill(0).map(() => 50 + Math.floor(Math.random() * 150)), | |
| backgroundColor: '#8b5cf6' | |
| } | |
| ] | |
| }, | |
| options: chartOptions | |
| }); | |
| // Activity Chart | |
| const activityCtx = document.getElementById('activityChart').getContext('2d'); | |
| activityChart = new Chart(activityCtx, { | |
| type: 'line', | |
| data: { | |
| labels: Array.from({length: 24}, (_, i) => i), | |
| datasets: [ | |
| { | |
| label: 'API Calls', | |
| data: Array(24).fill(0).map((_, i) => { | |
| const isDaytime = i >= 9 && i < 18; | |
| const base = isDaytime ? 800 : 300; | |
| const hourFactor = Math.sin((i / 24) * Math.PI * 1.5) * (isDaytime ? 400 : 150); | |
| const noise = Math.random() * 150 - 75; | |
| return Math.max(100, base + hourFactor + noise); | |
| }), | |
| borderColor: '#6366f1', | |
| backgroundColor: 'rgba(99, 102, 241, 0.1)', | |
| tension: 0.3, | |
| fill: true | |
| } | |
| ] | |
| }, | |
| options: chartOptions | |
| }); | |
| } | |
| function startDataUpdates() { | |
| // Update metric cards every 3 seconds | |
| setInterval(() => { | |
| const cards = document.querySelectorAll('metrics-card'); | |
| const now = new Date(); | |
| const hour = now.getHours(); | |
| // Active Users - follows daily pattern with peak around 2PM | |
| const userBase = hour < 6 ? 2000 : hour < 12 ? 4000 : hour < 18 ? 6000 : 3000; | |
| const users = userBase + Math.floor(Math.random() * 500 - 250); | |
| const userChange = (Math.random() > 0.6 ? 1 : -1) * (0.5 + Math.random() * 2); | |
| cards[0].setAttribute('value', users.toLocaleString()); | |
| cards[0].setAttribute('change', userChange.toFixed(1)); | |
| // Conversion Rate - higher during business hours | |
| const conversionBase = hour >= 9 && hour < 17 ? 3.5 : 1.8; | |
| const conversion = (conversionBase + Math.random() * 0.8 - 0.4).toFixed(2); | |
| const conversionChange = (Math.random() * 0.4 - 0.2).toFixed(2); | |
| cards[1].setAttribute('value', conversion + '%'); | |
| cards[1].setAttribute('change', conversionChange); | |
| // API Latency - degrades slightly during peak hours | |
| const latencyBase = hour >= 10 && hour < 16 ? 80 : 40; | |
| const latency = Math.floor(latencyBase + Math.random() * 30); | |
| const latencyChange = (Math.random() > 0.3 ? 1 : -1) * (1 + Math.random() * 4); | |
| cards[2].setAttribute('value', latency + 'ms'); | |
| cards[2].setAttribute('change', latencyChange.toFixed(1)); | |
| // Revenue Today - follows similar pattern to users but with larger random fluctuations | |
| const revenueBase = hour < 6 ? 8000 : hour < 12 ? 12000 : hour < 18 ? 15000 : 9000; | |
| const revenue = revenueBase + Math.floor(Math.random() * 3000 - 1500); | |
| const revenueChange = (Math.random() > 0.5 ? 1 : -1) * (2 + Math.random() * 5); | |
| cards[3].setAttribute('value', '// Update charts with new data points | |
| updateCharts(); | |
| }, 3000); | |
| } | |
| function updateCharts() { | |
| // User Chart - follows daily pattern with realistic variations | |
| const userData = userChart.data.datasets[0].data; | |
| userData.shift(); | |
| const userTrend = hour < 6 ? 0.8 : hour < 12 ? 1.2 : hour < 18 ? 1.5 : 0.9; | |
| userData.push(Math.max(0, userData[userData.length-1] * (0.98 + Math.random() * 0.04) * userTrend)); | |
| userChart.update(); | |
| // Revenue Chart - more stable proportions with slight variations | |
| revenueChart.data.datasets[0].data = [30, 25, 25, 20].map(v => v * (0.95 + Math.random() * 0.1)); | |
| revenueChart.update(); | |
| // Performance Chart - weekday patterns with better/worse performance | |
| const weekday = now.getDay(); | |
| const isWeekday = weekday > 0 && weekday < 6; | |
| performanceChart.data.datasets[0].data = Array(7).fill(0).map((_,i) => | |
| isWeekday ? 80 + Math.floor(Math.random() * 120) : 60 + Math.floor(Math.random() * 80)); | |
| performanceChart.data.datasets[1].data = Array(7).fill(0).map((_,i) => | |
| isWeekday ? 40 + Math.floor(Math.random() * 70) : 30 + Math.floor(Math.random() * 40)); | |
| performanceChart.update(); | |
| // Activity Chart - more realistic API call patterns | |
| const activityData = activityChart.data.datasets[0].data; | |
| activityData.shift(); | |
| const activityTrend = hour < 6 ? 0.7 : hour < 9 ? 0.9 : hour < 17 ? 1.3 : 1.0; | |
| const newActivity = Math.max(100, activityData[activityData.length-1] * (0.97 + Math.random() * 0.06) * activityTrend); | |
| activityData.push(newActivity); | |
| activityChart.update(); | |
| } | |
| // Handle dark mode changes | |
| window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { | |
| document.documentElement.classList.toggle('dark', e.matches); | |
| setupCharts(); | |
| }); + revenue.toLocaleString()); | |
| cards[3].setAttribute('change', revenueChange.toFixed(1)); | |
| // Update charts with new data points | |
| updateCharts(); | |
| }, 3000); | |
| } | |
| function updateCharts() { | |
| // User Chart - add new point and remove oldest | |
| const userData = userChart.data.datasets[0].data; | |
| userData.shift(); | |
| userData.push(Math.floor(Math.random() * 5000)); | |
| userChart.update(); | |
| // Revenue Chart - update values with slight variations | |
| revenueChart.data.datasets[0].data = [35, 25, 20, 20].map(v => v + Math.floor(Math.random() * 10 - 5)); | |
| revenueChart.update(); | |
| // Performance Chart - update with new random values | |
| performanceChart.data.datasets[0].data = Array(7).fill(0).map(() => 100 + Math.floor(Math.random() * 300)); | |
| performanceChart.data.datasets[1].data = Array(7).fill(0).map(() => 50 + Math.floor(Math.random() * 150)); | |
| performanceChart.update(); | |
| // Activity Chart - shift data and add new point | |
| const activityData = activityChart.data.datasets[0].data; | |
| activityData.shift(); | |
| const lastValue = activityData[activityData.length - 1]; | |
| activityData.push(Math.max(0, lastValue + (Math.random() * 100 - 50))); | |
| activityChart.update(); | |
| } | |
| // Handle dark mode changes | |
| window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => { | |
| document.documentElement.classList.toggle('dark', e.matches); | |
| setupCharts(); | |
| }); |