Exemples Chart.js Library

Exemples complets de Chart.js incluant types de graphiques, options de personnalisation, animations et conceptions responsives

💻 Graphiques de Base Chart.js javascript

🟢 simple ⭐⭐

Graphiques essentiels Chart.js incluant histogrammes, lignes, secteurs et anneaux avec fonctionnalités interactives

⏱️ 20 min 🏷️ chartjs, charts, canvas
Prerequisites: JavaScript, HTML, CSS, Chart.js library
// Chart.js Basic Charts Examples

// 1. Bar Chart
// HTML: <canvas id="barChart"></canvas>
function createBarChart() {
    const ctx = document.getElementById('barChart').getContext('2d');

    const data = {
        labels: ['January', 'February', 'March', 'April', 'May', 'June'],
        datasets: [{
            label: 'Sales 2024',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(78, 121, 167, 0.8)',
                'rgba(242, 142, 44, 0.8)',
                'rgba(225, 87, 89, 0.8)',
                'rgba(118, 183, 178, 0.8)',
                'rgba(89, 161, 79, 0.8)',
                'rgba(237, 201, 73, 0.8)'
            ],
            borderColor: [
                'rgba(78, 121, 167, 1)',
                'rgba(242, 142, 44, 1)',
                'rgba(225, 87, 89, 1)',
                'rgba(118, 183, 178, 1)',
                'rgba(89, 161, 79, 1)',
                'rgba(237, 201, 73, 1)'
            ],
            borderWidth: 2,
            borderRadius: 5,
            borderSkipped: false
        }, {
            label: 'Sales 2023',
            data: [8, 15, 7, 9, 4, 6],
            backgroundColor: 'rgba(175, 122, 161, 0.5)',
            borderColor: 'rgba(175, 122, 161, 1)',
            borderWidth: 2,
            borderRadius: 5
        }]
    };

    const config = {
        type: 'bar',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'top',
                    labels: {
                        padding: 20,
                        font: {
                            size: 14
                        }
                    }
                },
                title: {
                    display: true,
                    text: 'Monthly Sales Comparison',
                    font: {
                        size: 18,
                        weight: 'bold'
                    },
                    padding: {
                        bottom: 20
                    }
                },
                tooltip: {
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    titleFont: {
                        size: 14
                    },
                    bodyFont: {
                        size: 13
                    },
                    padding: 10,
                    cornerRadius: 4,
                    displayColors: true
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    grid: {
                        color: 'rgba(0, 0, 0, 0.1)'
                    },
                    ticks: {
                        font: {
                            size: 12
                        }
                    },
                    title: {
                        display: true,
                        text: 'Sales (in thousands)',
                        font: {
                            size: 14,
                            weight: 'bold'
                        }
                    }
                },
                x: {
                    grid: {
                        display: false
                    },
                    ticks: {
                        font: {
                            size: 12
                        }
                    }
                }
            },
            animation: {
                duration: 1000,
                easing: 'easeInOutQuart'
            },
            interaction: {
                mode: 'index',
                intersect: false
            }
        }
    };

    return new Chart(ctx, config);
}

// 2. Line Chart
// HTML: <canvas id="lineChart"></canvas>
function createLineChart() {
    const ctx = document.getElementById('lineChart').getContext('2d');

    const data = {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [{
            label: 'Revenue',
            data: [30, 45, 42, 55, 48, 62, 58, 72, 68, 75, 80, 85],
            borderColor: 'rgba(78, 121, 167, 1)',
            backgroundColor: 'rgba(78, 121, 167, 0.1)',
            borderWidth: 3,
            pointRadius: 4,
            pointHoverRadius: 6,
            pointBackgroundColor: 'rgba(78, 121, 167, 1)',
            pointBorderColor: '#fff',
                    pointBorderWidth: 2,
            tension: 0.4,
            fill: true
        }, {
            label: 'Expenses',
            data: [20, 28, 35, 40, 32, 45, 42, 48, 52, 55, 58, 60],
            borderColor: 'rgba(242, 142, 44, 1)',
            backgroundColor: 'rgba(242, 142, 44, 0.1)',
            borderWidth: 3,
            pointRadius: 4,
            pointHoverRadius: 6,
            pointBackgroundColor: 'rgba(242, 142, 44, 1)',
            pointBorderColor: '#fff',
            pointBorderWidth: 2,
            tension: 0.4,
            fill: true
        }]
    };

    const config = {
        type: 'line',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'top',
                    labels: {
                        padding: 20,
                        usePointStyle: true,
                        font: {
                            size: 14
                        }
                    }
                },
                title: {
                    display: true,
                    text: 'Financial Performance 2024',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                tooltip: {
                    mode: 'index',
                    intersect: false,
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    titleColor: '#fff',
                    bodyColor: '#fff',
                    borderColor: 'rgba(78, 121, 167, 1)',
                    borderWidth: 1
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    grid: {
                        color: 'rgba(0, 0, 0, 0.1)'
                    },
                    ticks: {
                        font: {
                            size: 12
                        }
                    },
                    title: {
                        display: true,
                        text: 'Amount (in thousands)',
                        font: {
                            size: 14,
                            weight: 'bold'
                        }
                    }
                },
                x: {
                    grid: {
                        display: false
                    },
                    ticks: {
                        font: {
                            size: 12
                        }
                    }
                }
            },
            interaction: {
                mode: 'index',
                intersect: false
            },
            animation: {
                duration: 1500,
                easing: 'easeInOutQuart'
            },
            elements: {
                line: {
                    tension: 0.4
                }
            }
        }
    };

    return new Chart(ctx, config);
}

// 3. Pie Chart
// HTML: <canvas id="pieChart"></canvas>
function createPieChart() {
    const ctx = document.getElementById('pieChart').getContext('2d');

    const data = {
        labels: ['Electronics', 'Clothing', 'Food', 'Books', 'Sports', 'Other'],
        datasets: [{
            data: [25, 20, 18, 12, 15, 10],
            backgroundColor: [
                'rgba(78, 121, 167, 0.8)',
                'rgba(242, 142, 44, 0.8)',
                'rgba(225, 87, 89, 0.8)',
                'rgba(118, 183, 178, 0.8)',
                'rgba(89, 161, 79, 0.8)',
                'rgba(237, 201, 73, 0.8)'
            ],
            borderColor: '#fff',
            borderWidth: 2,
            hoverOffset: 10
        }]
    };

    const config = {
        type: 'pie',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'right',
                    labels: {
                        padding: 15,
                        usePointStyle: true,
                        font: {
                            size: 14
                        },
                        generateLabels: function(chart) {
                            const data = chart.data;
                            if (data.labels.length && data.datasets.length) {
                                return data.labels.map(function(label, i) {
                                    const meta = chart.getDatasetMeta(0);
                                    const total = meta.data.reduce((acc, val) => acc + val, 0);
                                    const value = data.datasets[0].data[i];
                                    const percentage = ((value / total) * 100).toFixed(1);

                                    return {
                                        text: `${label} (${percentage}%)`,
                                        fillStyle: data.datasets[0].backgroundColor[i],
                                        hidden: false,
                                        index: i
                                    };
                                });
                            }
                            return [];
                        }
                    }
                },
                title: {
                    display: true,
                    text: 'Sales by Category',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            const total = context.dataset.data.reduce((acc, val) => acc + val, 0);
                            const percentage = ((context.parsed / total) * 100).toFixed(1);
                            return `${context.label}: ${context.parsed} (${percentage}%)`;
                        }
                    }
                }
            },
            animation: {
                animateRotate: true,
                animateScale: true,
                duration: 1000,
                easing: 'easeInOutQuart'
            }
        }
    };

    return new Chart(ctx, config);
}

// 4. Doughnut Chart
// HTML: <canvas id="doughnutChart"></canvas>
function createDoughnutChart() {
    const ctx = document.getElementById('doughnutChart').getContext('2d');

    const data = {
        labels: ['Completed', 'In Progress', 'Pending', 'Cancelled'],
        datasets: [{
            data: [45, 25, 20, 10],
            backgroundColor: [
                'rgba(89, 161, 79, 0.8)',
                'rgba(78, 121, 167, 0.8)',
                'rgba(242, 142, 44, 0.8)',
                'rgba(225, 87, 89, 0.8)'
            ],
            borderColor: '#fff',
            borderWidth: 2,
            hoverOffset: 8
        }]
    };

    const config = {
        type: 'doughnut',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            cutout: '60%',
            plugins: {
                legend: {
                    position: 'bottom',
                    labels: {
                        padding: 20,
                        usePointStyle: true,
                        font: {
                            size: 14
                        }
                    }
                },
                title: {
                    display: true,
                    text: 'Project Status',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            const total = context.dataset.data.reduce((acc, val) => acc + val, 0);
                            const percentage = ((context.parsed / total) * 100).toFixed(1);
                            return `${context.label}: ${context.parsed} (${percentage}%)`;
                        }
                    }
                }
            },
            animation: {
                animateRotate: true,
                animateScale: true,
                duration: 1200,
                easing: 'easeInOutQuart'
            }
        }
    };

    return new Chart(ctx, config);
}

// 5. Radar Chart
// HTML: <canvas id="radarChart"></canvas>
function createRadarChart() {
    const ctx = document.getElementById('radarChart').getContext('2d');

    const data = {
        labels: ['Product Quality', 'Customer Service', 'Price', 'Delivery Speed', 'User Experience', 'Support'],
        datasets: [{
            label: 'Company A',
            data: [85, 90, 70, 88, 92, 78],
            borderColor: 'rgba(78, 121, 167, 1)',
            backgroundColor: 'rgba(78, 121, 167, 0.2)',
            borderWidth: 2,
            pointBackgroundColor: 'rgba(78, 121, 167, 1)',
            pointBorderColor: '#fff',
            pointHoverBackgroundColor: '#fff',
            pointHoverBorderColor: 'rgba(78, 121, 167, 1)',
            pointRadius: 4,
            pointHoverRadius: 6
        }, {
            label: 'Company B',
            data: [75, 85, 90, 70, 80, 88],
            borderColor: 'rgba(242, 142, 44, 1)',
            backgroundColor: 'rgba(242, 142, 44, 0.2)',
            borderWidth: 2,
            pointBackgroundColor: 'rgba(242, 142, 44, 1)',
            pointBorderColor: '#fff',
            pointHoverBackgroundColor: '#fff',
            pointHoverBorderColor: 'rgba(242, 142, 44, 1)',
            pointRadius: 4,
            pointHoverRadius: 6
        }]
    };

    const config = {
        type: 'radar',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'top',
                    labels: {
                        padding: 20,
                        usePointStyle: true,
                        font: {
                            size: 14
                        }
                    }
                },
                title: {
                    display: true,
                    text: 'Company Comparison',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                }
            },
            scales: {
                r: {
                    beginAtZero: true,
                    max: 100,
                    ticks: {
                        stepSize: 20,
                        font: {
                            size: 12
                        }
                    },
                    grid: {
                        color: 'rgba(0, 0, 0, 0.1)'
                    },
                    pointLabels: {
                        font: {
                            size: 13,
                            weight: 'bold'
                        }
                    }
                }
            },
            animation: {
                duration: 1000,
                easing: 'easeInOutQuart'
            },
            elements: {
                line: {
                    borderWidth: 2
                }
            }
        }
    };

    return new Chart(ctx, config);
}

// Initialize all charts
document.addEventListener('DOMContentLoaded', function() {
    // Set default chart styles
    Chart.defaults.font.family = 'Arial, sans-serif';
    Chart.defaults.color = '#333';

    // Create charts
    const barChart = createBarChart();
    const lineChart = createLineChart();
    const pieChart = createPieChart();
    const doughnutChart = createDoughnutChart();
    const radarChart = createRadarChart();

    // Store chart instances for later reference
    window.charts = {
        bar: barChart,
        line: lineChart,
        pie: pieChart,
        doughnut: doughnutChart,
        radar: radarChart
    };
});

💻 Personnalisation Avancée Chart.js javascript

🟡 intermediate ⭐⭐⭐

Fonctionnalités avancées Chart.js incluant graphiques mixtes, plugins personnalisés, animations et conceptions responsives

⏱️ 35 min 🏷️ chartjs, advanced, plugins, real-time
Prerequisites: Advanced JavaScript, Chart.js, Canvas API, CSS animations
// Chart.js Advanced Customization Examples

// 1. Mixed Chart (Bar + Line)
// HTML: <canvas id="mixedChart"></canvas>
function createMixedChart() {
    const ctx = document.getElementById('mixedChart').getContext('2d');

    const data = {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [{
            type: 'bar',
            label: 'Revenue',
            data: [12000, 19000, 15000, 25000, 22000, 30000, 28000, 35000, 32000, 38000, 42000, 45000],
            backgroundColor: 'rgba(78, 121, 167, 0.8)',
            borderColor: 'rgba(78, 121, 167, 1)',
            borderWidth: 2,
            borderRadius: 5,
            yAxisID: 'y'
        }, {
            type: 'line',
            label: 'Growth Rate %',
            data: [10, 15, 8, 25, 18, 30, 22, 35, 28, 32, 38, 40],
            borderColor: 'rgba(242, 142, 44, 1)',
            backgroundColor: 'rgba(242, 142, 44, 0.1)',
            borderWidth: 3,
            pointRadius: 5,
            pointHoverRadius: 7,
            tension: 0.4,
            yAxisID: 'y1',
            fill: true
        }]
    };

    const config = {
        type: 'bar', // Base type
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            interaction: {
                mode: 'index',
                intersect: false
            },
            plugins: {
                title: {
                    display: true,
                    text: 'Revenue vs Growth Rate',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                legend: {
                    position: 'top',
                    labels: {
                        usePointStyle: true,
                        padding: 20
                    }
                },
                tooltip: {
                    mode: 'index',
                    intersect: false,
                    backgroundColor: 'rgba(0, 0, 0, 0.8)',
                    titleColor: '#fff',
                    bodyColor: '#fff',
                    borderColor: 'rgba(78, 121, 167, 1)',
                    borderWidth: 1
                }
            },
            scales: {
                y: {
                    type: 'linear',
                    display: true,
                    position: 'left',
                    title: {
                        display: true,
                        text: 'Revenue ($)',
                        font: {
                            weight: 'bold'
                        }
                    },
                    grid: {
                        color: 'rgba(0, 0, 0, 0.1)'
                    }
                },
                y1: {
                    type: 'linear',
                    display: true,
                    position: 'right',
                    title: {
                        display: true,
                        text: 'Growth Rate (%)',
                        font: {
                            weight: 'bold'
                        }
                    },
                    grid: {
                        drawOnChartArea: false
                    }
                },
                x: {
                    grid: {
                        display: false
                    }
                }
            },
            animation: {
                duration: 2000,
                easing: 'easeInOutQuart'
            }
        }
    };

    return new Chart(ctx, config);
}

// 2. Bubble Chart
// HTML: <canvas id="bubbleChart"></canvas>
function createBubbleChart() {
    const ctx = document.getElementById('bubbleChart').getContext('2d');

    const data = {
        datasets: [{
            label: 'Technology Companies',
            data: [
                { x: 20, y: 30, r: 15, company: 'Apple', marketCap: 2000 },
                { x: 40, y: 45, r: 25, company: 'Microsoft', marketCap: 1800 },
                { x: 30, y: 25, r: 20, company: 'Google', marketCap: 1600 },
                { x: 35, y: 35, r: 18, company: 'Amazon', marketCap: 1500 },
                { x: 25, y: 40, r: 12, company: 'Meta', marketCap: 800 },
                { x: 45, y: 50, r: 10, company: 'Tesla', marketCap: 700 }
            ],
            backgroundColor: [
                'rgba(78, 121, 167, 0.6)',
                'rgba(242, 142, 44, 0.6)',
                'rgba(225, 87, 89, 0.6)',
                'rgba(118, 183, 178, 0.6)',
                'rgba(89, 161, 79, 0.6)',
                'rgba(237, 201, 73, 0.6)'
            ],
            borderColor: [
                'rgba(78, 121, 167, 1)',
                'rgba(242, 142, 44, 1)',
                'rgba(225, 87, 89, 1)',
                'rgba(118, 183, 178, 1)',
                'rgba(89, 161, 79, 1)',
                'rgba(237, 201, 73, 1)'
            ],
            borderWidth: 2
        }, {
            label: 'Banks',
            data: [
                { x: 50, y: 20, r: 20, company: 'JP Morgan', marketCap: 450 },
                { x: 55, y: 25, r: 18, company: 'Bank of America', marketCap: 280 },
                { x: 48, y: 15, r: 15, company: 'Wells Fargo', marketCap: 220 },
                { x: 52, y: 30, r: 14, company: 'Citigroup', marketCap: 180 }
            ],
            backgroundColor: 'rgba(175, 122, 161, 0.6)',
            borderColor: 'rgba(175, 122, 161, 1)',
            borderWidth: 2
        }]
    };

    const config = {
        type: 'bubble',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                title: {
                    display: true,
                    text: 'Company Analysis',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                legend: {
                    position: 'top'
                },
                tooltip: {
                    callbacks: {
                        label: function(context) {
                            const item = context.raw;
                            return [
                                `${item.company}`,
                                `Revenue Growth: ${item.x}%`,
                                `Profit Margin: ${item.y}%`,
                                `Market Cap: $${item.marketCap}B`,
                                `Employees: ${item.r}K`
                            ];
                        }
                    }
                }
            },
            scales: {
                x: {
                    title: {
                        display: true,
                        text: 'Revenue Growth (%)',
                        font: {
                            weight: 'bold'
                        }
                    },
                    min: 0,
                    max: 60
                },
                y: {
                    title: {
                        display: true,
                        text: 'Profit Margin (%)',
                        font: {
                            weight: 'bold'
                        }
                    },
                    min: 0,
                    max: 60
                }
            },
            animation: {
                duration: 1500,
                easing: 'easeInOutQuart'
            }
        }
    };

    return new Chart(ctx, config);
}

// 3. Custom Plugin Example - Trend Line
// HTML: <canvas id="trendChart"></canvas>
function createTrendChart() {
    // Custom plugin to draw trend line
    const trendLinePlugin = {
        id: 'trendLine',
        beforeDraw: (chart) => {
            const ctx = chart.ctx;
            const xAxis = chart.scales.x;
            const yAxis = chart.scales.y;

            const dataset = chart.data.datasets[0];
            const data = dataset.data;

            // Calculate linear regression
            const n = data.length;
            const sumX = data.reduce((sum, point, index) => sum + index, 0);
            const sumY = data.reduce((sum, point) => sum + point, 0);
            const sumXY = data.reduce((sum, point, index) => sum + index * point, 0);
            const sumX2 = data.reduce((sum, point, index) => sum + index * index, 0);

            const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
            const intercept = (sumY - slope * sumX) / n;

            // Draw trend line
            ctx.save();
            ctx.beginPath();
            ctx.strokeStyle = 'rgba(242, 142, 44, 0.8)';
            ctx.lineWidth = 2;
            ctx.setLineDash([5, 5]);

            const startX = xAxis.getPixelForValue(0);
            const startY = yAxis.getPixelForValue(intercept);
            const endX = xAxis.getPixelForValue(n - 1);
            const endY = yAxis.getPixelForValue(slope * (n - 1) + intercept);

            ctx.moveTo(startX, startY);
            ctx.lineTo(endX, endY);
            ctx.stroke();

            // Add trend line label
            ctx.setLineDash([]);
            ctx.fillStyle = 'rgba(242, 142, 44, 1)';
            ctx.font = '14px Arial';
            ctx.fillText('Trend Line', endX - 50, endY - 10);

            ctx.restore();
        }
    };

    const ctx = document.getElementById('trendChart').getContext('2d');

    const data = {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [{
            label: 'Sales',
            data: [30, 45, 42, 55, 48, 62, 58, 72, 68, 75, 80, 85],
            borderColor: 'rgba(78, 121, 167, 1)',
            backgroundColor: 'rgba(78, 121, 167, 0.1)',
            borderWidth: 3,
            tension: 0.4,
            fill: true
        }]
    };

    const config = {
        type: 'line',
        data: data,
        plugins: [trendLinePlugin],
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                title: {
                    display: true,
                    text: 'Sales with Trend Analysis',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                legend: {
                    display: true,
                    position: 'top'
                }
            },
            scales: {
                y: {
                    beginAtZero: true
                }
            },
            animation: {
                duration: 2000,
                easing: 'easeInOutQuart'
            }
        }
    };

    return new Chart(ctx, config);
}

// 4. Real-time Chart
// HTML: <canvas id="realtimeChart"></canvas>
function createRealtimeChart() {
    const ctx = document.getElementById('realtimeChart').getContext('2d');

    const initialData = Array.from({ length: 20 }, () => Math.random() * 100);
    const labels = Array.from({ length: 20 }, (_, i) => `T-${i}`);

    const data = {
        labels: labels,
        datasets: [{
            label: 'CPU Usage (%)',
            data: initialData,
            borderColor: 'rgba(78, 121, 167, 1)',
            backgroundColor: 'rgba(78, 121, 167, 0.1)',
            borderWidth: 2,
            tension: 0.4,
            fill: true
        }, {
            label: 'Memory Usage (%)',
            data: initialData.map(() => Math.random() * 100),
            borderColor: 'rgba(242, 142, 44, 1)',
            backgroundColor: 'rgba(242, 142, 44, 0.1)',
            borderWidth: 2,
            tension: 0.4,
            fill: true
        }]
    };

    const config = {
        type: 'line',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: {
                duration: 0 // Disable animation for real-time updates
            },
            plugins: {
                title: {
                    display: true,
                    text: 'Real-time System Monitoring',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                },
                legend: {
                    display: true,
                    position: 'top'
                }
            },
            scales: {
                y: {
                    beginAtZero: true,
                    max: 100,
                    title: {
                        display: true,
                        text: 'Usage (%)',
                        font: {
                            weight: 'bold'
                        }
                    }
                },
                x: {
                    title: {
                        display: true,
                        text: 'Time',
                        font: {
                            weight: 'bold'
                        }
                    }
                }
            },
            interaction: {
                mode: 'index',
                intersect: false
            }
        }
    };

    const chart = new Chart(ctx, config);

    // Update chart with real-time data
    setInterval(() => {
        chart.data.datasets[0].data.push(Math.random() * 100);
        chart.data.datasets[0].data.shift();
        chart.data.datasets[1].data.push(Math.random() * 100);
        chart.data.datasets[1].data.shift();

        chart.data.labels.push(`T-${Date.now() % 100}`);
        chart.data.labels.shift();

        chart.update('none'); // Update without animation
    }, 1000);

    return chart;
}

// 5. Responsive Chart Configuration
function createResponsiveCharts() {
    // Common responsive options
    const responsiveOptions = {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
            legend: {
                labels: {
                    boxWidth: 15,
                    padding: 20,
                    font: {
                        size: 12
                    }
                }
            },
            tooltip: {
                titleFont: {
                    size: 14
                },
                bodyFont: {
                    size: 12
                },
                padding: 10,
                cornerRadius: 4
            }
        }
    };

    // Font size adjustments based on screen size
    const getFontSize = (baseSize) => {
        return window.innerWidth < 768 ? baseSize * 0.8 : baseSize;
    };

    // Apply responsive configuration
    Chart.defaults.font.family = 'Arial, sans-serif';
    Chart.defaults.font.size = getFontSize(12);

    return responsiveOptions;
}

// 6. Custom Animation Example
function createAnimatedChart() {
    const ctx = document.getElementById('animatedChart').getContext('2d');

    const data = {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
        datasets: [{
            label: 'Monthly Sales',
            data: [0, 0, 0, 0, 0, 0], // Start with zeros
            backgroundColor: 'rgba(78, 121, 167, 0.8)',
            borderColor: 'rgba(78, 121, 167, 1)',
            borderWidth: 2,
            borderRadius: 5
        }]
    };

    const config = {
        type: 'bar',
        data: data,
        options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: {
                onComplete: () => {
                    console.log('Animation completed!');
                },
                delay: (context) => {
                    let delay = 0;
                    if (context.type === 'data' && context.mode === 'default') {
                        delay = context.dataIndex * 200 + context.datasetIndex * 100;
                    }
                    return delay;
                },
                duration: 1000,
                easing: 'easeInOutQuart'
            },
            plugins: {
                title: {
                    display: true,
                    text: 'Animated Bar Chart',
                    font: {
                        size: 18,
                        weight: 'bold'
                    }
                }
            }
        }
    };

    const chart = new Chart(ctx, config);

    // Animate data after a delay
    setTimeout(() => {
        chart.data.datasets[0].data = [65, 59, 80, 81, 56, 55];
        chart.update();
    }, 500);

    return chart;
}

// Initialize all advanced charts
document.addEventListener('DOMContentLoaded', function() {
    // Apply responsive configuration
    createResponsiveCharts();

    // Create advanced charts
    const mixedChart = createMixedChart();
    const bubbleChart = createBubbleChart();
    const trendChart = createTrendChart();
    const realtimeChart = createRealtimeChart();
    const animatedChart = createAnimatedChart();

    // Store chart instances
    window.advancedCharts = {
        mixed: mixedChart,
        bubble: bubbleChart,
        trend: trendChart,
        realtime: realtimeChart,
        animated: animatedChart
    };
});

💻 Tableau de Bord Interactif Chart.js javascript

🔴 complex ⭐⭐⭐⭐

Tableau de bord complet avec plusieurs graphiques, mises à jour en temps réel, filtres et synchronisation de données

⏱️ 60 min 🏷️ chartjs, dashboard, real-time, interactive
Prerequisites: Advanced JavaScript, Chart.js, CSS Grid/Flexbox, Data visualization concepts
// Chart.js Interactive Dashboard with Real-time Updates

// Dashboard configuration and data management
class ChartDashboard {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.charts = {};
        this.filters = {
            dateRange: 'month',
            category: 'all',
            region: 'all'
        };
        this.realTimeData = [];
        this.updateInterval = null;

        this.init();
    }

    init() {
        this.createLayout();
        this.createControls();
        this.createCharts();
        this.setupEventListeners();
        this.startRealTimeUpdates();
    }

    createLayout() {
        // Main dashboard container
        this.container.innerHTML = `
            <div class="dashboard-header">
                <h1>Sales Analytics Dashboard</h1>
                <div class="header-stats">
                    <div class="stat-card">
                        <h3>Total Revenue</h3>
                        <span class="stat-value" id="totalRevenue">$0</span>
                    </div>
                    <div class="stat-card">
                        <h3>Total Orders</h3>
                        <span class="stat-value" id="totalOrders">0</span>
                    </div>
                    <div class="stat-card">
                        <h3>Average Order Value</h3>
                        <span class="stat-value" id="avgOrderValue">$0</span>
                    </div>
                    <div class="stat-card">
                        <h3>Conversion Rate</h3>
                        <span class="stat-value" id="conversionRate">0%</span>
                    </div>
                </div>
            </div>

            <div class="dashboard-filters">
                <select id="dateRange" class="filter-select">
                    <option value="week">Last Week</option>
                    <option value="month" selected>Last Month</option>
                    <option value="quarter">Last Quarter</option>
                    <option value="year">Last Year</option>
                </select>

                <select id="category" class="filter-select">
                    <option value="all">All Categories</option>
                    <option value="electronics">Electronics</option>
                    <option value="clothing">Clothing</option>
                    <option value="food">Food</option>
                    <option value="books">Books</option>
                </select>

                <select id="region" class="filter-select">
                    <option value="all">All Regions</option>
                    <option value="north">North</option>
                    <option value="south">South</option>
                    <option value="east">East</option>
                    <option value="west">West</option>
                </select>

                <button id="exportBtn" class="export-btn">Export Data</button>
            </div>

            <div class="dashboard-content">
                <div class="chart-container">
                    <h3>Revenue Trend</h3>
                    <canvas id="revenueChart"></canvas>
                </div>

                <div class="chart-container">
                    <h3>Category Distribution</h3>
                    <canvas id="categoryChart"></canvas>
                </div>

                <div class="chart-container">
                    <h3>Regional Performance</h3>
                    <canvas id="regionalChart"></canvas>
                </div>

                <div class="chart-container">
                    <h3>Real-time Metrics</h3>
                    <canvas id="realtimeChart"></canvas>
                </div>
            </div>
        `;

        // Add CSS styles
        const style = document.createElement('style');
        style.textContent = `
            .dashboard {
                font-family: 'Arial', sans-serif;
                padding: 20px;
                background: #f8f9fa;
            }

            .dashboard-header {
                margin-bottom: 30px;
                text-align: center;
            }

            .dashboard-header h1 {
                color: #333;
                margin: 0 0 20px 0;
            }

            .header-stats {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
                gap: 20px;
                margin-bottom: 20px;
            }

            .stat-card {
                background: white;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                text-align: center;
            }

            .stat-card h3 {
                color: #666;
                margin: 0 0 10px 0;
                font-size: 14px;
            }

            .stat-value {
                font-size: 24px;
                font-weight: bold;
                color: #4e79a7;
            }

            .dashboard-filters {
                display: flex;
                gap: 15px;
                margin-bottom: 30px;
                flex-wrap: wrap;
                align-items: center;
                padding: 20px;
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }

            .filter-select {
                padding: 10px 15px;
                border: 1px solid #ddd;
                border-radius: 4px;
                font-size: 14px;
            }

            .export-btn {
                padding: 10px 20px;
                background: #4e79a7;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
            }

            .export-btn:hover {
                background: #3a5a8c;
            }

            .dashboard-content {
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
                gap: 20px;
            }

            .chart-container {
                background: white;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }

            .chart-container h3 {
                margin: 0 0 20px 0;
                color: #333;
            }

            canvas {
                max-height: 300px;
            }

            @media (max-width: 768px) {
                .header-stats {
                    grid-template-columns: repeat(2, 1fr);
                }

                .dashboard-content {
                    grid-template-columns: 1fr;
                }
            }
        `;
        document.head.appendChild(style);
    }

    createControls() {
        // Export functionality
        document.getElementById('exportBtn').addEventListener('click', () => {
            this.exportData();
        });
    }

    createCharts() {
        // Revenue trend chart
        this.charts.revenue = this.createRevenueChart();

        // Category distribution chart
        this.charts.category = this.createCategoryChart();

        // Regional performance chart
        this.charts.regional = this.createRegionalChart();

        // Real-time metrics chart
        this.charts.realtime = this.createRealtimeChart();
    }

    createRevenueChart() {
        const ctx = document.getElementById('revenueChart').getContext('2d');

        const data = this.generateRevenueData();

        return new Chart(ctx, {
            type: 'line',
            data: data,
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        display: true,
                        position: 'top'
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: 'Revenue ($)'
                        }
                    }
                },
                interaction: {
                    mode: 'index',
                    intersect: false
                },
                animation: {
                    duration: 1000
                }
            }
        });
    }

    createCategoryChart() {
        const ctx = document.getElementById('categoryChart').getContext('2d');

        const data = this.generateCategoryData();

        return new Chart(ctx, {
            type: 'doughnut',
            data: data,
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        position: 'bottom'
                    },
                    tooltip: {
                        callbacks: {
                            label: function(context) {
                                const total = context.dataset.data.reduce((a, b) => a + b, 0);
                                const percentage = ((context.parsed / total) * 100).toFixed(1);
                                return `${context.label}: ${percentage}%`;
                            }
                        }
                    }
                },
                animation: {
                    animateRotate: true,
                    animateScale: true,
                    duration: 1000
                }
            }
        });
    }

    createRegionalChart() {
        const ctx = document.getElementById('regionalChart').getContext('2d');

        const data = this.generateRegionalData();

        return new Chart(ctx, {
            type: 'bar',
            data: data,
            options: {
                responsive: true,
                maintainAspectRatio: false,
                indexAxis: 'y',
                plugins: {
                    legend: {
                        display: false
                    }
                },
                scales: {
                    x: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: 'Revenue ($)'
                        }
                    }
                },
                animation: {
                    duration: 1000
                }
            }
        });
    }

    createRealtimeChart() {
        const ctx = document.getElementById('realtimeChart').getContext('2d');

        const initialData = this.generateRealtimeData();

        return new Chart(ctx, {
            type: 'line',
            data: initialData,
            options: {
                responsive: true,
                maintainAspectRatio: false,
                animation: {
                    duration: 0 // Disable animations for real-time updates
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        max: 100
                    }
                },
                plugins: {
                    legend: {
                        display: true,
                        position: 'top'
                    }
                }
            }
        });
    }

    generateRevenueData() {
        const labels = this.getDateLabels();
        const datasets = [{
            label: 'Revenue',
            data: labels.map(() => Math.random() * 50000 + 10000),
            borderColor: '#4e79a7',
            backgroundColor: 'rgba(78, 121, 167, 0.1)',
            borderWidth: 2,
            tension: 0.4,
            fill: true
        }, {
            label: 'Target',
            data: labels.map(() => 40000),
            borderColor: '#f28e2c',
            backgroundColor: 'rgba(242, 142, 44, 0.1)',
            borderWidth: 2,
            borderDash: [5, 5],
            tension: 0,
            fill: false
        }];

        return { labels, datasets };
    }

    generateCategoryData() {
        const categories = ['Electronics', 'Clothing', 'Food', 'Books', 'Other'];
        const data = categories.map(() => Math.random() * 10000 + 5000);

        return {
            labels: categories,
            datasets: [{
                data: data,
                backgroundColor: [
                    '#4e79a7',
                    '#f28e2c',
                    '#e15759',
                    '#76b7b2',
                    '#59a14f'
                ],
                borderWidth: 2,
                borderColor: '#fff'
            }]
        };
    }

    generateRegionalData() {
        const regions = ['North', 'South', 'East', 'West'];
        const datasets = [{
            label: 'This Month',
            data: regions.map(() => Math.random() * 50000 + 10000),
            backgroundColor: '#4e79a7'
        }, {
            label: 'Last Month',
            data: regions.map(() => Math.random() * 50000 + 10000),
            backgroundColor: '#76b7b2'
        }];

        return {
            labels: regions,
            datasets: datasets
        };
    }

    generateRealtimeData() {
        const labels = Array.from({ length: 20 }, (_, i) => `${i}s ago`);
        const datasets = [{
            label: 'Active Users',
            data: Array.from({ length: 20 }, () => Math.random() * 100 + 50),
            borderColor: '#e15759',
            backgroundColor: 'rgba(225, 87, 89, 0.1)',
            borderWidth: 2,
            tension: 0.4,
            fill: true
        }, {
            label: 'Server Load',
            data: Array.from({ length: 20 }, () => Math.random() * 100),
            borderColor: '#59a14f',
            backgroundColor: 'rgba(89, 161, 79, 0.1)',
            borderWidth: 2,
            tension: 0.4,
            fill: true
        }];

        return { labels, datasets };
    }

    getDateLabels() {
        const dateRange = this.filters.dateRange;
        const count = this.getDateRangeCount(dateRange);
        const labels = [];

        for (let i = count - 1; i >= 0; i--) {
            const date = new Date();
            switch (dateRange) {
                case 'week':
                    date.setDate(date.getDate() - i);
                    labels.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }));
                    break;
                case 'month':
                    date.setDate(date.getDate() - i);
                    labels.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }));
                    break;
                case 'quarter':
                    date.setDate(date.getDate() - (i * 7));
                    labels.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }));
                    break;
                case 'year':
                    date.setMonth(date.getMonth() - i);
                    labels.push(date.toLocaleDateString('en-US', { month: 'short' }));
                    break;
            }
        }

        return labels;
    }

    getDateRangeCount(dateRange) {
        switch (dateRange) {
            case 'week': return 7;
            case 'month': return 30;
            case 'quarter': return 13;
            case 'year': return 12;
            default: return 30;
        }
    }

    setupEventListeners() {
        // Date range filter
        document.getElementById('dateRange').addEventListener('change', (e) => {
            this.filters.dateRange = e.target.value;
            this.updateCharts();
        });

        // Category filter
        document.getElementById('category').addEventListener('change', (e) => {
            this.filters.category = e.target.value;
            this.updateCharts();
        });

        // Region filter
        document.getElementById('region').addEventListener('change', (e) => {
            this.filters.region = e.target.value;
            this.updateCharts();
        });

        // Window resize handler
        window.addEventListener('resize', () => {
            Object.values(this.charts).forEach(chart => {
                chart.resize();
            });
        });
    }

    updateCharts() {
        // Update revenue chart
        const revenueData = this.generateRevenueData();
        this.charts.revenue.data = revenueData;
        this.charts.revenue.update();

        // Update category chart
        const categoryData = this.generateCategoryData();
        this.charts.category.data = categoryData;
        this.charts.category.update();

        // Update regional chart
        const regionalData = this.generateRegionalData();
        this.charts.regional.data = regionalData;
        this.charts.regional.update();

        // Update KPIs
        this.updateKPIs();
    }

    updateKPIs() {
        const revenue = Math.random() * 1000000 + 500000;
        const orders = Math.floor(Math.random() * 10000 + 5000);
        const avgOrder = revenue / orders;
        const conversionRate = Math.random() * 10 + 2;

        document.getElementById('totalRevenue').textContent = `$${revenue.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`;
        document.getElementById('totalOrders').textContent = orders.toLocaleString();
        document.getElementById('avgOrderValue').textContent = `$${avgOrder.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",")}`;
        document.getElementById('conversionRate').textContent = `${conversionRate.toFixed(1)}%`;
    }

    startRealTimeUpdates() {
        this.updateInterval = setInterval(() => {
            this.updateRealtimeChart();
        }, 2000);
    }

    updateRealtimeChart() {
        const chart = this.charts.realtime;

        // Shift data
        chart.data.labels.shift();
        chart.data.labels.push('Now');

        chart.data.datasets.forEach(dataset => {
            dataset.data.shift();
            dataset.data.push(Math.random() * 100 + 50);
        });

        chart.update('none'); // Update without animation
    }

    exportData() {
        const data = {
            dateRange: this.filters.dateRange,
            category: this.filters.category,
            region: this.filters.region,
            timestamp: new Date().toISOString(),
            charts: {
                revenue: this.charts.revenue.data,
                category: this.charts.category.data,
                regional: this.charts.regional.data,
                realtime: this.charts.realtime.data
            }
        };

        // Create CSV
        const csv = this.convertToCSV(data);

        // Download CSV
        const blob = new Blob([csv], { type: 'text/csv' });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = `dashboard-export-${Date.now()}.csv`;
        a.click();
        window.URL.revokeObjectURL(url);
    }

    convertToCSV(data) {
        let csv = 'Dashboard Export\n';
        csv += `Export Date: ${data.timestamp}\n\n`;

        // Add filters
        csv += 'Filters:\n';
        csv += `Date Range: ${data.dateRange}\n`;
        csv += `Category: ${data.category}\n`;
        csv += `Region: ${data.region}\n\n`;

        // Add chart data
        Object.entries(data.charts).forEach(([chartName, chartData]) => {
            csv += `${chartName.toUpperCase()} Data:\n`;

            if (chartData.labels) {
                csv += 'Labels,' + chartData.labels.join(',') + '\n';
            }

            if (chartData.datasets) {
                chartData.datasets.forEach((dataset, index) => {
                    csv += `${dataset.label || `Dataset ${index}`},`;
                    csv += dataset.data.join(',') + '\n';
                });
            }

            csv += '\n';
        });

        return csv;
    }

    destroy() {
        // Clear update interval
        if (this.updateInterval) {
            clearInterval(this.updateInterval);
        }

        // Destroy charts
        Object.values(this.charts).forEach(chart => {
            chart.destroy();
        });

        // Clear container
        this.container.innerHTML = '';
    }
}

// Initialize dashboard
document.addEventListener('DOMContentLoaded', function() {
    // Set default Chart.js options
    Chart.defaults.font.family = 'Arial, sans-serif';
    Chart.defaults.color = '#333';

    // Create dashboard
    window.dashboard = new ChartDashboard('dashboard');

    // Make dashboard globally accessible for debugging
    console.log('Dashboard initialized:', window.dashboard);
});