add some fake data to make it look realistic
Browse files
script.js
CHANGED
|
@@ -44,11 +44,14 @@ function setupCharts() {
|
|
| 44 |
userChart = new Chart(userCtx, {
|
| 45 |
type: 'line',
|
| 46 |
data: {
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
| 52 |
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
| 53 |
tension: 0.4,
|
| 54 |
fill: true
|
|
@@ -112,12 +115,13 @@ function setupCharts() {
|
|
| 112 |
{
|
| 113 |
label: 'API Calls',
|
| 114 |
data: Array(24).fill(0).map((_, i) => {
|
| 115 |
-
const
|
| 116 |
-
const
|
| 117 |
-
const
|
| 118 |
-
|
|
|
|
| 119 |
}),
|
| 120 |
-
|
| 121 |
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
| 122 |
tension: 0.3,
|
| 123 |
fill: true
|
|
@@ -127,37 +131,80 @@ function setupCharts() {
|
|
| 127 |
options: chartOptions
|
| 128 |
});
|
| 129 |
}
|
| 130 |
-
|
| 131 |
function startDataUpdates() {
|
| 132 |
// Update metric cards every 3 seconds
|
| 133 |
setInterval(() => {
|
| 134 |
const cards = document.querySelectorAll('metrics-card');
|
|
|
|
|
|
|
| 135 |
|
| 136 |
-
// Active Users
|
| 137 |
-
const
|
| 138 |
-
const
|
|
|
|
| 139 |
cards[0].setAttribute('value', users.toLocaleString());
|
| 140 |
-
cards[0].setAttribute('change', userChange);
|
| 141 |
|
| 142 |
-
// Conversion Rate
|
| 143 |
-
const
|
| 144 |
-
const
|
|
|
|
| 145 |
cards[1].setAttribute('value', conversion + '%');
|
| 146 |
cards[1].setAttribute('change', conversionChange);
|
| 147 |
|
| 148 |
-
// API Latency
|
| 149 |
-
const
|
| 150 |
-
const
|
|
|
|
| 151 |
cards[2].setAttribute('value', latency + 'ms');
|
| 152 |
-
cards[2].setAttribute('change', latencyChange);
|
| 153 |
-
|
| 154 |
-
// Revenue Today
|
| 155 |
-
const revenue = Math.floor(10000 + Math.random() * 5000);
|
| 156 |
-
const revenueChange = Math.floor(Math.random() * 10 - 5);
|
| 157 |
-
cards[3].setAttribute('value', '$' + revenue.toLocaleString());
|
| 158 |
-
cards[3].setAttribute('change', revenueChange);
|
| 159 |
|
| 160 |
-
//
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
updateCharts();
|
| 162 |
}, 3000);
|
| 163 |
}
|
|
|
|
| 44 |
userChart = new Chart(userCtx, {
|
| 45 |
type: 'line',
|
| 46 |
data: {
|
| 47 |
+
labels: Array.from({length: 12}, (_, i) => `${i+1}AM`),
|
| 48 |
+
datasets: [{
|
| 49 |
+
label: 'Active Users',
|
| 50 |
+
data: Array(12).fill(0).map((_,i) => {
|
| 51 |
+
const hourFactor = Math.sin((i / 11) * Math.PI) * 0.5 + 0.7;
|
| 52 |
+
return Math.floor(3000 + (hourFactor * 2000) + Math.random() * 500 - 250);
|
| 53 |
+
}),
|
| 54 |
+
borderColor: '#6366f1',
|
| 55 |
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
| 56 |
tension: 0.4,
|
| 57 |
fill: true
|
|
|
|
| 115 |
{
|
| 116 |
label: 'API Calls',
|
| 117 |
data: Array(24).fill(0).map((_, i) => {
|
| 118 |
+
const isDaytime = i >= 9 && i < 18;
|
| 119 |
+
const base = isDaytime ? 800 : 300;
|
| 120 |
+
const hourFactor = Math.sin((i / 24) * Math.PI * 1.5) * (isDaytime ? 400 : 150);
|
| 121 |
+
const noise = Math.random() * 150 - 75;
|
| 122 |
+
return Math.max(100, base + hourFactor + noise);
|
| 123 |
}),
|
| 124 |
+
borderColor: '#6366f1',
|
| 125 |
backgroundColor: 'rgba(99, 102, 241, 0.1)',
|
| 126 |
tension: 0.3,
|
| 127 |
fill: true
|
|
|
|
| 131 |
options: chartOptions
|
| 132 |
});
|
| 133 |
}
|
|
|
|
| 134 |
function startDataUpdates() {
|
| 135 |
// Update metric cards every 3 seconds
|
| 136 |
setInterval(() => {
|
| 137 |
const cards = document.querySelectorAll('metrics-card');
|
| 138 |
+
const now = new Date();
|
| 139 |
+
const hour = now.getHours();
|
| 140 |
|
| 141 |
+
// Active Users - follows daily pattern with peak around 2PM
|
| 142 |
+
const userBase = hour < 6 ? 2000 : hour < 12 ? 4000 : hour < 18 ? 6000 : 3000;
|
| 143 |
+
const users = userBase + Math.floor(Math.random() * 500 - 250);
|
| 144 |
+
const userChange = (Math.random() > 0.6 ? 1 : -1) * (0.5 + Math.random() * 2);
|
| 145 |
cards[0].setAttribute('value', users.toLocaleString());
|
| 146 |
+
cards[0].setAttribute('change', userChange.toFixed(1));
|
| 147 |
|
| 148 |
+
// Conversion Rate - higher during business hours
|
| 149 |
+
const conversionBase = hour >= 9 && hour < 17 ? 3.5 : 1.8;
|
| 150 |
+
const conversion = (conversionBase + Math.random() * 0.8 - 0.4).toFixed(2);
|
| 151 |
+
const conversionChange = (Math.random() * 0.4 - 0.2).toFixed(2);
|
| 152 |
cards[1].setAttribute('value', conversion + '%');
|
| 153 |
cards[1].setAttribute('change', conversionChange);
|
| 154 |
|
| 155 |
+
// API Latency - degrades slightly during peak hours
|
| 156 |
+
const latencyBase = hour >= 10 && hour < 16 ? 80 : 40;
|
| 157 |
+
const latency = Math.floor(latencyBase + Math.random() * 30);
|
| 158 |
+
const latencyChange = (Math.random() > 0.3 ? 1 : -1) * (1 + Math.random() * 4);
|
| 159 |
cards[2].setAttribute('value', latency + 'ms');
|
| 160 |
+
cards[2].setAttribute('change', latencyChange.toFixed(1));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
|
| 162 |
+
// Revenue Today - follows similar pattern to users but with larger random fluctuations
|
| 163 |
+
const revenueBase = hour < 6 ? 8000 : hour < 12 ? 12000 : hour < 18 ? 15000 : 9000;
|
| 164 |
+
const revenue = revenueBase + Math.floor(Math.random() * 3000 - 1500);
|
| 165 |
+
const revenueChange = (Math.random() > 0.5 ? 1 : -1) * (2 + Math.random() * 5);
|
| 166 |
+
cards[3].setAttribute('value', '// Update charts with new data points
|
| 167 |
+
updateCharts();
|
| 168 |
+
}, 3000);
|
| 169 |
+
}
|
| 170 |
+
|
| 171 |
+
function updateCharts() {
|
| 172 |
+
// User Chart - follows daily pattern with realistic variations
|
| 173 |
+
const userData = userChart.data.datasets[0].data;
|
| 174 |
+
userData.shift();
|
| 175 |
+
const userTrend = hour < 6 ? 0.8 : hour < 12 ? 1.2 : hour < 18 ? 1.5 : 0.9;
|
| 176 |
+
userData.push(Math.max(0, userData[userData.length-1] * (0.98 + Math.random() * 0.04) * userTrend));
|
| 177 |
+
userChart.update();
|
| 178 |
+
|
| 179 |
+
// Revenue Chart - more stable proportions with slight variations
|
| 180 |
+
revenueChart.data.datasets[0].data = [30, 25, 25, 20].map(v => v * (0.95 + Math.random() * 0.1));
|
| 181 |
+
revenueChart.update();
|
| 182 |
+
|
| 183 |
+
// Performance Chart - weekday patterns with better/worse performance
|
| 184 |
+
const weekday = now.getDay();
|
| 185 |
+
const isWeekday = weekday > 0 && weekday < 6;
|
| 186 |
+
performanceChart.data.datasets[0].data = Array(7).fill(0).map((_,i) =>
|
| 187 |
+
isWeekday ? 80 + Math.floor(Math.random() * 120) : 60 + Math.floor(Math.random() * 80));
|
| 188 |
+
performanceChart.data.datasets[1].data = Array(7).fill(0).map((_,i) =>
|
| 189 |
+
isWeekday ? 40 + Math.floor(Math.random() * 70) : 30 + Math.floor(Math.random() * 40));
|
| 190 |
+
performanceChart.update();
|
| 191 |
+
|
| 192 |
+
// Activity Chart - more realistic API call patterns
|
| 193 |
+
const activityData = activityChart.data.datasets[0].data;
|
| 194 |
+
activityData.shift();
|
| 195 |
+
const activityTrend = hour < 6 ? 0.7 : hour < 9 ? 0.9 : hour < 17 ? 1.3 : 1.0;
|
| 196 |
+
const newActivity = Math.max(100, activityData[activityData.length-1] * (0.97 + Math.random() * 0.06) * activityTrend);
|
| 197 |
+
activityData.push(newActivity);
|
| 198 |
+
activityChart.update();
|
| 199 |
+
}
|
| 200 |
+
|
| 201 |
+
// Handle dark mode changes
|
| 202 |
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
| 203 |
+
document.documentElement.classList.toggle('dark', e.matches);
|
| 204 |
+
setupCharts();
|
| 205 |
+
}); + revenue.toLocaleString());
|
| 206 |
+
cards[3].setAttribute('change', revenueChange.toFixed(1));
|
| 207 |
+
// Update charts with new data points
|
| 208 |
updateCharts();
|
| 209 |
}, 3000);
|
| 210 |
}
|