GARR - Servizi Multimediali e Comunicazione
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
min-height: 100vh;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 2rem;
}
.header {
text-align: center;
margin-bottom: 3rem;
color: #2d3748;
}
.header h1 {
font-size: 2.5rem;
font-weight: 300;
margin-bottom: 0.5rem;
}
.header p {
font-size: 1.1rem;
opacity: 0.9;
}
.charts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
gap: 2rem;
}
.chart-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 2rem;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.chart-card:hover {
transform: translateY(-5px);
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15);
}
.chart-header {
text-align: center;
margin-bottom: 1.5rem;
}
.chart-title {
font-size: 1.4rem;
font-weight: 600;
color: #2d3748;
margin-bottom: 0.5rem;
}
.chart-subtitle {
font-size: 0.9rem;
color: #718096;
font-style: italic;
}
.chart-container {
position: relative;
height: 400px;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.download-btn {
padding: 0.5rem 1rem;
border-radius: 8px;
font-size: 0.9rem;
cursor: pointer;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
transition: all 0.3s ease;
}
.download-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
}
.stats-summary {
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
border-radius: 15px;
padding: 1.5rem;
margin-top: 2rem;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
}
.stat-item {
text-align: center;
padding: 1rem;
border-radius: 10px;
background: linear-gradient(135deg, #f7fafc 0%, #edf2f7 100%);
}
.stat-number {
font-size: 1.8rem;
font-weight: 700;
color: #2d3748;
}
.stat-label {
font-size: 0.9rem;
color: #718096;
margin-top: 0.25rem;
}
@media (max-width: 768px) {
.charts-grid {
grid-template-columns: 1fr;
}
.container {
padding: 1rem;
}
}
// Color palette
const colors = {
primary: ['#667eea', '#764ba2', '#3b82f6', '#06b6d4', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#6366f1']
};
// Default options
const defaultOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: {
padding: 20,
usePointStyle: true,
font: {
size: 11,
family: "'Segoe UI', sans-serif"
}
}
},
tooltip: {
backgroundColor: 'rgba(0, 0, 0, 0.8)',
titleColor: 'white',
bodyColor: 'white',
borderColor: 'rgba(255, 255, 255, 0.2)',
borderWidth: 1,
cornerRadius: 8,
padding: 12,
displayColors: true
}
},
animation: {
duration: 1500,
easing: 'easeOutQuart'
}
};
// Line chart options
const lineOptions = {
...defaultOptions,
scales: {
x: {
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
}
},
y: {
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
}
}
}
};
// Bar chart options
const barOptions = {
...defaultOptions,
scales: {
x: {
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
}
},
y: {
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
}
}
}
};
// Dual axis options
const dualAxisOptions = {
...lineOptions,
scales: {
...lineOptions.scales,
y1: {
type: 'linear',
display: true,
position: 'right',
grid: {
drawOnChartArea: false,
},
ticks: {
font: {
size: 11
}
}
}
}
};
// Data
const dataGARRMeet = {
labels: ['2020', '2021', '2022', '2023', '2024'],
datasets: [{
label: 'eduMeet - Picco',
data: [473, 337, 237, 305, 119],
backgroundColor: colors.primary[0],
borderColor: colors.primary[0],
borderWidth: 2
}, {
label: 'eduMeet - Media',
data: [158, 69, 35, 50, 50],
backgroundColor: colors.primary[0] + '80',
borderColor: colors.primary[0],
borderWidth: 2
}, {
label: 'OpenMeet - Picco',
data: [90, 150, 137, 124, 66],
backgroundColor: colors.primary[1],
borderColor: colors.primary[1],
borderWidth: 2
}, {
label: 'OpenMeet - Media',
data: [null, 29, 33, 26, 21],
backgroundColor: colors.primary[1] + '80',
borderColor: colors.primary[1],
borderWidth: 2
}, {
label: 'BlueMeet - Picco',
data: [null, 182, 254, 195, 200],
backgroundColor: colors.primary[2],
borderColor: colors.primary[2],
borderWidth: 2
}, {
label: 'BlueMeet - Media',
data: [null, 26, 30, 22, 26],
backgroundColor: colors.primary[2] + '80',
borderColor: colors.primary[2],
borderWidth: 2
}]
};
const dataMultimedia = {
labels: ['2013', '2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022', '2023', '2024'],
datasets: [{
label: 'Filmati disponibili',
data: [553, 770, 890, 1102, 1271, 1465, 1644, 2161, 2362, 2551, 3074, 3332],
borderColor: colors.primary[0],
backgroundColor: colors.primary[0] + '20',
borderWidth: 3,
fill: true,
tension: 0.4,
pointRadius: 5,
pointHoverRadius: 8,
yAxisID: 'y'
}, {
label: 'Canali',
data: [null, null, null, null, null, null, null, null, null, null, 7, 10],
borderColor: colors.primary[1],
backgroundColor: colors.primary[1] + '20',
borderWidth: 3,
fill: false,
tension: 0.4,
pointRadius: 5,
pointHoverRadius: 8,
yAxisID: 'y1'
}]
};
const dataWebViews = {
labels: ['2020', '2021', '2022', '2023', '2024'],
datasets: [{
label: 'Totale visualizzazioni',
data: [744000, 624000, 726000, 762000, 611000],
borderColor: colors.primary[0],
backgroundColor: colors.primary[0] + '20',
borderWidth: 3,
fill: true,
tension: 0.4,
pointRadius: 6,
pointHoverRadius: 10,
yAxisID: 'y'
}, {
label: 'GARR TV (milioni)',
data: [0, 1.1, 1.5, 1.3, 1.6],
borderColor: colors.primary[1],
backgroundColor: colors.primary[1] + '20',
borderWidth: 3,
fill: false,
tension: 0.4,
pointRadius: 6,
pointHoverRadius: 10,
yAxisID: 'y1'
}]
};
let chartGARRMeet, chartMultimedia, chartWebViews;
// Chart creation functions
function createLineChart(id, data, options = lineOptions) {
const ctx = document.getElementById(id).getContext('2d');
return new Chart(ctx, {
type: 'line',
data: data,
options: options
});
}
function createBarChart(id, data, options = barOptions) {
const ctx = document.getElementById(id).getContext('2d');
return new Chart(ctx, {
type: 'bar',
data: data,
options: options
});
}
function updateStats() {
const statsMultimedia = [
{ label: 'GARR Meet - Picco eduMeet (2020)', value: '473' },
{ label: 'GARR TV - Video 2024', value: '3.332' },
{ label: 'GARR TV - Canali 2024', value: '10' },
{ label: 'Web - Picco Totale (2023)', value: '762.000' },
{ label: 'GARR TV - Visualizzazioni 2024', value: '1,6 M' },
{ label: 'Web - Crescita GARR TV 2021-2024', value: '+45%' }
];
const containerMultimedia = document.getElementById('statsGridMultimedia');
containerMultimedia.innerHTML = statsMultimedia.map(stat => `
${stat.value}
${stat.label}
`).join('');
}
document.addEventListener("DOMContentLoaded", () => {
// Initialize charts
chartGARRMeet = createBarChart("chartGARRMeet", dataGARRMeet);
chartMultimedia = createLineChart("chartMultimedia", dataMultimedia, dualAxisOptions);
chartWebViews = createLineChart("chartWebViews", dataWebViews, {
...lineOptions,
scales: {
x: {
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
}
},
y: {
type: 'linear',
display: true,
position: 'left',
grid: {
color: 'rgba(0, 0, 0, 0.1)'
},
ticks: {
font: {
size: 11
}
},
title: {
display: true,
text: 'Visualizzazioni siti'
}
},
y1: {
type: 'linear',
display: true,
position: 'right',
grid: {
drawOnChartArea: false,
},
ticks: {
font: {
size: 11
}
},
title: {
display: true,
text: 'GARR TV (M)'
}
}
}
});
// Download handlers
document.getElementById("downloadGARRMeet").addEventListener("click", () => {
const link = document.createElement('a');
link.download = 'garr-meet-daily-average.png';
link.href = chartGARRMeet.toBase64Image();
link.click();
});
document.getElementById("downloadMultimedia").addEventListener("click", () => {
const link = document.createElement('a');
link.download = 'garr-tv-videos.png';
link.href = chartMultimedia.toBase64Image();
link.click();
});
document.getElementById("downloadWebViews").addEventListener("click", () => {
const link = document.createElement('a');
link.download = 'garr-web-page-views.png';
link.href = chartWebViews.toBase64Image();
link.click();
});
// Initialize stats
updateStats();
// Add hover effects
document.querySelectorAll('.chart-card').forEach(card => {
card.addEventListener('mouseenter', function() {
this.style.transform = 'translateY(-8px)';
});
card.addEventListener('mouseleave', function() {
this.style.transform = 'translateY(0)';
});
});
});