Spaces:
Running
Running
Bar chart
Browse files- index.html +84 -27
index.html
CHANGED
|
@@ -205,19 +205,21 @@
|
|
| 205 |
<div class="bg-gray-800 bg-opacity-70 backdrop-blur-sm rounded-xl p-6 mb-12">
|
| 206 |
<div class="flex justify-between items-center mb-6">
|
| 207 |
<h4 class="text-2xl font-bold">Age Range Distribution</h4>
|
| 208 |
-
<div class="flex
|
| 209 |
-
<button class="bg-
|
| 210 |
<button class="bg-pink-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-pink-800 transition" id="age-18-25">18-25</button>
|
| 211 |
<button class="bg-purple-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-purple-800 transition" id="age-25-35">25-35</button>
|
| 212 |
<button class="bg-blue-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-blue-800 transition" id="age-35-45">35-45</button>
|
| 213 |
</div>
|
| 214 |
</div>
|
| 215 |
-
<div class="h-64 w-full"
|
| 216 |
-
<
|
|
|
|
|
|
|
|
|
|
| 217 |
</div>
|
| 218 |
</div>
|
| 219 |
-
|
| 220 |
-
<!-- Music Genre Pie Chart -->
|
| 221 |
<div class="bg-gray-800 bg-opacity-70 backdrop-blur-sm rounded-xl p-6">
|
| 222 |
<div class="flex justify-between items-center mb-6">
|
| 223 |
<h4 class="text-2xl font-bold">Music Genre Popularity</h4>
|
|
@@ -367,35 +369,55 @@
|
|
| 367 |
label: 'Percentage of Visitors',
|
| 368 |
data: [42, 38, 15, 5],
|
| 369 |
backgroundColor: [
|
| 370 |
-
'rgba(
|
| 371 |
-
'rgba(
|
| 372 |
-
'rgba(
|
| 373 |
-
'rgba(156, 163, 175, 0.
|
| 374 |
],
|
| 375 |
borderColor: [
|
| 376 |
-
'rgba(
|
| 377 |
-
'rgba(
|
| 378 |
-
'rgba(
|
| 379 |
'rgba(156, 163, 175, 1)'
|
| 380 |
],
|
| 381 |
-
borderWidth:
|
|
|
|
|
|
|
| 382 |
}]
|
| 383 |
},
|
| 384 |
options: {
|
| 385 |
responsive: true,
|
|
|
|
| 386 |
scales: {
|
| 387 |
y: {
|
| 388 |
beginAtZero: true,
|
| 389 |
-
max:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 390 |
title: {
|
| 391 |
display: true,
|
| 392 |
-
text: 'Percentage (%)'
|
|
|
|
| 393 |
}
|
| 394 |
},
|
| 395 |
x: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 396 |
title: {
|
| 397 |
display: true,
|
| 398 |
-
text: 'Age Range'
|
|
|
|
| 399 |
}
|
| 400 |
}
|
| 401 |
},
|
|
@@ -403,18 +425,27 @@
|
|
| 403 |
legend: {
|
| 404 |
display: false
|
| 405 |
},
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 411 |
}
|
| 412 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
}
|
| 414 |
}
|
| 415 |
});
|
| 416 |
-
|
| 417 |
-
// Music Genre Pie Chart
|
| 418 |
const genreCtx = document.getElementById('genreChart').querySelector('div').getContext('2d');
|
| 419 |
const genreChart = new Chart(genreCtx, {
|
| 420 |
type: 'pie',
|
|
@@ -463,21 +494,47 @@
|
|
| 463 |
}
|
| 464 |
});
|
| 465 |
// Filter buttons functionality
|
|
|
|
| 466 |
document.querySelectorAll('#age-all, #age-18-25, #age-25-35, #age-35-45').forEach(btn => {
|
| 467 |
btn.addEventListener('click', function() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 468 |
const filter = this.id.split('-').pop();
|
|
|
|
|
|
|
| 469 |
if (filter === 'all') {
|
|
|
|
| 470 |
ageChart.data.datasets[0].data = [42, 38, 15, 5];
|
|
|
|
| 471 |
} else {
|
| 472 |
-
ageChart.data.datasets[0].data = [0, 0, 0, 0];
|
| 473 |
const index = ['18-25', '25-35', '35-45', '45+'].indexOf(filter.replace(/(\d+)-(\d+)/, '$1-$2'));
|
| 474 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 475 |
}
|
|
|
|
| 476 |
ageChart.update();
|
| 477 |
});
|
| 478 |
});
|
| 479 |
|
| 480 |
-
|
|
|
|
|
|
|
| 481 |
btn.addEventListener('click', function() {
|
| 482 |
const filter = this.id.split('-').pop();
|
| 483 |
if (filter === 'all') {
|
|
|
|
| 205 |
<div class="bg-gray-800 bg-opacity-70 backdrop-blur-sm rounded-xl p-6 mb-12">
|
| 206 |
<div class="flex justify-between items-center mb-6">
|
| 207 |
<h4 class="text-2xl font-bold">Age Range Distribution</h4>
|
| 208 |
+
<div class="flex flex-wrap gap-2">
|
| 209 |
+
<button class="bg-pink-600 text-white px-4 py-2 rounded-lg text-sm hover:bg-pink-700 transition active" id="age-all">All</button>
|
| 210 |
<button class="bg-pink-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-pink-800 transition" id="age-18-25">18-25</button>
|
| 211 |
<button class="bg-purple-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-purple-800 transition" id="age-25-35">25-35</button>
|
| 212 |
<button class="bg-blue-900 text-white px-4 py-2 rounded-lg text-sm hover:bg-blue-800 transition" id="age-35-45">35-45</button>
|
| 213 |
</div>
|
| 214 |
</div>
|
| 215 |
+
<div class="relative h-64 w-full">
|
| 216 |
+
<canvas id="ageChart"></canvas>
|
| 217 |
+
<div class="absolute top-0 left-0 w-full h-full flex items-center justify-center pointer-events-none" id="noDataMessage" style="display: none;">
|
| 218 |
+
<p class="text-gray-400 bg-black bg-opacity-70 px-4 py-2 rounded-lg">No data available for selected filter</p>
|
| 219 |
+
</div>
|
| 220 |
</div>
|
| 221 |
</div>
|
| 222 |
+
<!-- Music Genre Pie Chart -->
|
|
|
|
| 223 |
<div class="bg-gray-800 bg-opacity-70 backdrop-blur-sm rounded-xl p-6">
|
| 224 |
<div class="flex justify-between items-center mb-6">
|
| 225 |
<h4 class="text-2xl font-bold">Music Genre Popularity</h4>
|
|
|
|
| 369 |
label: 'Percentage of Visitors',
|
| 370 |
data: [42, 38, 15, 5],
|
| 371 |
backgroundColor: [
|
| 372 |
+
'rgba(236, 72, 153, 0.8)',
|
| 373 |
+
'rgba(167, 139, 250, 0.8)',
|
| 374 |
+
'rgba(99, 102, 241, 0.8)',
|
| 375 |
+
'rgba(156, 163, 175, 0.8)'
|
| 376 |
],
|
| 377 |
borderColor: [
|
| 378 |
+
'rgba(236, 72, 153, 1)',
|
| 379 |
+
'rgba(167, 139, 250, 1)',
|
| 380 |
+
'rgba(99, 102, 241, 1)',
|
| 381 |
'rgba(156, 163, 175, 1)'
|
| 382 |
],
|
| 383 |
+
borderWidth: 2,
|
| 384 |
+
borderRadius: 4,
|
| 385 |
+
borderSkipped: false
|
| 386 |
}]
|
| 387 |
},
|
| 388 |
options: {
|
| 389 |
responsive: true,
|
| 390 |
+
maintainAspectRatio: false,
|
| 391 |
scales: {
|
| 392 |
y: {
|
| 393 |
beginAtZero: true,
|
| 394 |
+
max: 50,
|
| 395 |
+
grid: {
|
| 396 |
+
color: 'rgba(255, 255, 255, 0.1)'
|
| 397 |
+
},
|
| 398 |
+
ticks: {
|
| 399 |
+
color: 'rgba(255, 255, 255, 0.7)',
|
| 400 |
+
callback: function(value) {
|
| 401 |
+
return value + '%';
|
| 402 |
+
}
|
| 403 |
+
},
|
| 404 |
title: {
|
| 405 |
display: true,
|
| 406 |
+
text: 'Percentage (%)',
|
| 407 |
+
color: 'rgba(255, 255, 255, 0.7)'
|
| 408 |
}
|
| 409 |
},
|
| 410 |
x: {
|
| 411 |
+
grid: {
|
| 412 |
+
display: false
|
| 413 |
+
},
|
| 414 |
+
ticks: {
|
| 415 |
+
color: 'rgba(255, 255, 255, 0.7)'
|
| 416 |
+
},
|
| 417 |
title: {
|
| 418 |
display: true,
|
| 419 |
+
text: 'Age Range',
|
| 420 |
+
color: 'rgba(255, 255, 255, 0.7)'
|
| 421 |
}
|
| 422 |
}
|
| 423 |
},
|
|
|
|
| 425 |
legend: {
|
| 426 |
display: false
|
| 427 |
},
|
| 428 |
+
tooltip: {
|
| 429 |
+
backgroundColor: 'rgba(17, 24, 39, 0.9)',
|
| 430 |
+
titleColor: 'white',
|
| 431 |
+
bodyColor: 'white',
|
| 432 |
+
borderColor: 'rgba(255, 255, 255, 0.1)',
|
| 433 |
+
borderWidth: 1,
|
| 434 |
+
padding: 12,
|
| 435 |
+
callbacks: {
|
| 436 |
+
label: function(context) {
|
| 437 |
+
return context.parsed.y + '%';
|
| 438 |
+
}
|
| 439 |
}
|
| 440 |
}
|
| 441 |
+
},
|
| 442 |
+
animation: {
|
| 443 |
+
duration: 1000,
|
| 444 |
+
easing: 'easeOutQuart'
|
| 445 |
}
|
| 446 |
}
|
| 447 |
});
|
| 448 |
+
// Music Genre Pie Chart
|
|
|
|
| 449 |
const genreCtx = document.getElementById('genreChart').querySelector('div').getContext('2d');
|
| 450 |
const genreChart = new Chart(genreCtx, {
|
| 451 |
type: 'pie',
|
|
|
|
| 494 |
}
|
| 495 |
});
|
| 496 |
// Filter buttons functionality
|
| 497 |
+
// Filter buttons functionality
|
| 498 |
document.querySelectorAll('#age-all, #age-18-25, #age-25-35, #age-35-45').forEach(btn => {
|
| 499 |
btn.addEventListener('click', function() {
|
| 500 |
+
// Remove active class from all buttons
|
| 501 |
+
document.querySelectorAll('#age-all, #age-18-25, #age-25-35, #age-35-45').forEach(b => {
|
| 502 |
+
b.classList.remove('active', 'bg-pink-600');
|
| 503 |
+
b.classList.add('bg-opacity-70');
|
| 504 |
+
});
|
| 505 |
+
|
| 506 |
+
// Add active class to clicked button
|
| 507 |
+
this.classList.add('active', 'bg-pink-600');
|
| 508 |
+
this.classList.remove('bg-opacity-70');
|
| 509 |
+
|
| 510 |
const filter = this.id.split('-').pop();
|
| 511 |
+
const noDataMsg = document.getElementById('noDataMessage');
|
| 512 |
+
|
| 513 |
if (filter === 'all') {
|
| 514 |
+
noDataMsg.style.display = 'none';
|
| 515 |
ageChart.data.datasets[0].data = [42, 38, 15, 5];
|
| 516 |
+
ageChart.options.scales.y.max = 50;
|
| 517 |
} else {
|
|
|
|
| 518 |
const index = ['18-25', '25-35', '35-45', '45+'].indexOf(filter.replace(/(\d+)-(\d+)/, '$1-$2'));
|
| 519 |
+
|
| 520 |
+
if (index === 3) { // 45+ has very little data
|
| 521 |
+
noDataMsg.style.display = 'flex';
|
| 522 |
+
ageChart.data.datasets[0].data = [0, 0, 0, 0];
|
| 523 |
+
} else {
|
| 524 |
+
noDataMsg.style.display = 'none';
|
| 525 |
+
ageChart.data.datasets[0].data = [0, 0, 0, 0];
|
| 526 |
+
ageChart.data.datasets[0].data[index] = [42, 38, 15, 5][index];
|
| 527 |
+
ageChart.options.scales.y.max = 50;
|
| 528 |
+
}
|
| 529 |
}
|
| 530 |
+
|
| 531 |
ageChart.update();
|
| 532 |
});
|
| 533 |
});
|
| 534 |
|
| 535 |
+
// Initialize first button as active
|
| 536 |
+
document.getElementById('age-all').classList.add('active', 'bg-pink-600');
|
| 537 |
+
document.querySelectorAll('#genre-all, #genre-edm, #genre-rock, #genre-hiphop').forEach(btn => {
|
| 538 |
btn.addEventListener('click', function() {
|
| 539 |
const filter = this.id.split('-').pop();
|
| 540 |
if (filter === 'all') {
|