Skip to content

Chart.js Chart Styling and Customization

Chart.js provides rich styling customization options, allowing developers to create charts that match brand styles and design requirements. This chapter will detail how to customize style and appearance of Chart.js charts.

Global Style Configuration

1. Global Default Configuration

You can set global default styles by modifying Chart.defaults:

javascript
// Set global default configuration
Chart.defaults.borderColor = '#ccc';
Chart.defaults.color = '#666';
Chart.defaults.font.family = 'Arial, sans-serif';
Chart.defaults.font.size = 14;
Chart.defaults.font.weight = 'normal';
Chart.defaults.responsive = true;
Chart.defaults.maintainAspectRatio = false;

// Charts will use these global default values when created
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    }
    // Unspecified configurations in options will use global defaults
});

2. Chart-level Configuration

When creating a chart, you can configure styles through options parameter:

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        // Chart-level style configuration
        responsive: true,
        maintainAspectRatio: false,
        backgroundColor: '#f8f9fa',
        borderColor: '#dee2e6',
        borderWidth: 1,

        // Font configuration
        font: {
            family: 'Arial, sans-serif',
            size: 14,
            weight: 'normal',
            lineHeight: 1.2
        },

        // Layout configuration
        layout: {
            padding: {
                top: 20,
                right: 20,
                bottom: 20,
                left: 20
            }
        }
    }
});

Color Customization

1. Dataset Colors

You can set different colors for each dataset:

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June'],
        datasets: [{
            label: 'Sales',
            data: [12, 19, 3, 5, 2, 3],
            // Background colors
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 205, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            // Border colors
            borderColor: [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 205, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            // Border width
            borderWidth: 2
        }]
    }
});

2. Gradient Colors

You can use Canvas gradient function to create gradient color effects:

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ['January', 'February', 'March', 'April', 'May', 'June'],
        datasets: [{
            label: 'Sales',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: function(context) {
                const chart = context.chart;
                const {ctx, chartArea} = chart;

                if (!chartArea) {
                    // If chart area is undefined, return default color
                    return 'rgba(54, 162, 235, 0.2)';
                }

                // Create linear gradient
                const gradient = ctx.createLinearGradient(0, chartArea.top, 0, chartArea.bottom);
                gradient.addColorStop(0, 'rgba(54, 162, 235, 0.8)');
                gradient.addColorStop(1, 'rgba(54, 162, 235, 0.2)');

                return gradient;
            },
            borderColor: 'rgba(54, 162, 235, 1)',
            borderWidth: 2
        }]
    }
});

Font and Text Styles

1. Title Styles

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        plugins: {
            title: {
                display: true,
                text: 'Monthly Sales Data',
                font: {
                    family: 'Arial, sans-serif',
                    size: 18,
                    weight: 'bold',
                    style: 'normal'
                },
                color: '#333',
                padding: {
                    top: 10,
                    bottom: 20
                }
            }
        }
    }
});

2. Legend Styles

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        plugins: {
            legend: {
                display: true,
                position: 'top',
                align: 'center',
                labels: {
                    font: {
                        family: 'Arial, sans-serif',
                        size: 14,
                        weight: 'normal'
                    },
                    color: '#666',
                    padding: 10,
                    usePointStyle: true, // Use point style instead of square
                    pointStyle: 'circle'
                }
            }
        }
    }
});

3. Tooltip Styles

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        plugins: {
            tooltip: {
                enabled: true,
                backgroundColor: 'rgba(0, 0, 0, 0.8)',
                titleColor: '#fff',
                bodyColor: '#fff',
                borderColor: '#333',
                borderWidth: 1,
                cornerRadius: 6,
                displayColors: true,
                font: {
                    family: 'Arial, sans-serif',
                    size: 12,
                    weight: 'normal'
                },
                padding: 10,
                callbacks: {
                    title: function(tooltipItems) {
                        return 'Month: ' + tooltipItems[0].label;
                    },
                    label: function(context) {
                        return context.dataset.label + ': ' + context.parsed.y + ' ten thousand';
                    }
                }
            }
        }
    }
});

Axis Styles

1. Basic Axis Configuration

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        scales: {
            x: {
                // X-axis title
                title: {
                    display: true,
                    text: 'Month',
                    color: '#666',
                    font: {
                        family: 'Arial, sans-serif',
                        size: 14,
                        weight: 'bold'
                    }
                },
                // Tick marks
                ticks: {
                    color: '#999',
                    font: {
                        family: 'Arial, sans-serif',
                        size: 12
                    },
                    callback: function(value, index, values) {
                        // Customize tick labels
                        return value + '月';
                    }
                },
                // Grid lines
                grid: {
                    color: 'rgba(0, 0, 0, 0.1)',
                    lineWidth: 1
                }
            },
            y: {
                // Y-axis title
                title: {
                    display: true,
                    text: 'Sales (ten thousand)',
                    color: '#666',
                    font: {
                        family: 'Arial, sans-serif',
                        size: 14,
                        weight: 'bold'
                    }
                },
                // Tick marks
                ticks: {
                    color: '#999',
                    font: {
                        family: 'Arial, sans-serif',
                        size: 12
                    },
                    beginAtZero: true,
                    callback: function(value, index, values) {
                        // Add unit
                        return value + '万';
                    }
                },
                // Grid lines
                grid: {
                    color: 'rgba(0, 0, 0, 0.1)',
                    lineWidth: 1
                }
            }
        }
    }
});

2. Axis Position and Display

javascript
const myChart = new Chart(ctx, {
    type: 'line',
    data: {
        // ... data configuration
    },
    options: {
        scales: {
            x: {
                position: 'bottom', // 'top', 'bottom'
                display: true,      // Whether to display axis
                reverse: false,     // Whether to reverse axis
            },
            y: {
                position: 'left',   // 'left', 'right'
                display: true,
                min: 0,            // Minimum value
                max: 100,          // Maximum value
                ticks: {
                    stepSize: 10   // Tick step size
                }
            },
            // Second Y-axis
            y1: {
                position: 'right',
                display: true,
                grid: {
                    drawOnChartArea: false // Don't draw grid lines in chart area
                }
            }
        }
    }
});

Animation Effects

1. Basic Animation Configuration

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        animation: {
            duration: 1000,        // Animation duration (milliseconds)
            easing: 'easeInOutQuart', // Easing function
            delay: 0,              // Delay time
            loop: false            // Whether to loop

            // Animation property configuration
            // colors: {
            //     duration: 1000,
            //     easing: 'easeInOutQuart'
            // },
            // numbers: {
            //     duration: 1000,
            //     easing: 'easeInOutQuart'
            // }
        }
    }
});

2. Custom Animation

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        animation: {
            duration: 2000,
            easing: 'linear',
            onProgress: function(animation) {
                // Callback during animation
                console.log('Animation progress:', animation.currentStep / animation.numSteps);
            },
            onComplete: function(animation) {
                // Callback when animation completes
                console.log('Animation completed');
            }
        }
    }
});

Responsive Design

1. Basic Responsive Configuration

javascript
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        responsive: true,           // Enable responsive
        maintainAspectRatio: true,  // Maintain aspect ratio
        aspectRatio: 2,            // Aspect ratio

        // Responsive events
        onResize: function(chart, size) {
            console.log('Chart resized:', size);
        }
    }
});

2. Media Query Styles

javascript
// Set different configurations based on screen size
const config = {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        responsive: true,
        plugins: {
            legend: {
                position: window.innerWidth < 768 ? 'bottom' : 'top'
            }
        },
        scales: {
            x: {
                ticks: {
                    font: {
                        size: window.innerWidth < 768 ? 10 : 12
                    }
                }
            }
        }
    }
};

const myChart = new Chart(ctx, config);

// Listen to window size changes
window.addEventListener('resize', function() {
    // Update chart configuration
    myChart.options.plugins.legend.position = window.innerWidth < 768 ? 'bottom' : 'top';
    myChart.options.scales.x.ticks.font.size = window.innerWidth < 768 ? 10 : 12;
    myChart.update();
});

Themes and Style Variants

1. Create Custom Theme

javascript
// Define theme configuration
const darkTheme = {
    backgroundColor: '#222',
    borderColor: '#444',
    color: '#eee',
    font: {
        family: 'Arial, sans-serif',
        size: 14,
        weight: 'normal'
    },
    plugins: {
        title: {
            color: '#fff',
            font: {
                size: 18,
                weight: 'bold'
            }
        },
        legend: {
            labels: {
                color: '#ccc'
            }
        },
        tooltip: {
            backgroundColor: 'rgba(50, 50, 50, 0.9)',
            titleColor: '#fff',
            bodyColor: '#eee',
            borderColor: '#666'
        }
    },
    scales: {
        x: {
            ticks: {
                color: '#ccc'
            },
            grid: {
                color: 'rgba(255, 255, 255, 0.1)'
            }
        },
        y: {
            ticks: {
                color: '#ccc'
            },
            grid: {
                color: 'rgba(255, 255, 255, 0.1)'
            }
        }
    }
};

// Apply theme
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        ...darkTheme,
        responsive: true,
        scales: {
            y: {
                beginAtZero: true,
                ...darkTheme.scales.y
            },
            x: {
                ...darkTheme.scales.x
            }
        }
    }
});

2. Dynamic Theme Switching

javascript
// Define multiple themes
const themes = {
    light: {
        backgroundColor: '#fff',
        color: '#333',
        // ... other configurations
    },
    dark: {
        backgroundColor: '#222',
        color: '#eee',
        // ... other configurations
    }
};

// Use default theme when creating chart
let currentTheme = 'light';
const myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        // ... data configuration
    },
    options: {
        ...themes[currentTheme],
        responsive: true
    }
});

// Function to switch theme
function switchTheme(themeName) {
    currentTheme = themeName;
    Object.assign(myChart.options, themes[themeName]);
    myChart.update();
}

// Usage example
// switchTheme('dark'); // Switch to dark theme

Complete Example

Following is a complete example showing multiple style customization effects:

html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chart.js Style Customization Example</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .chart-container {
            position: relative;
            height: 400px;
            margin: 20px 0;
        }
        .controls {
            text-align: center;
            margin: 20px 0;
        }
        button {
            margin: 5px;
            padding: 10px 20px;
            background-color: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #0056b3;
        }
        .theme-selector {
            margin: 20px 0;
            text-align: center;
        }
        select {
            padding: 8px 12px;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1 style="text-align: center;">Chart.js Style Customization Example</h1>

        <div class="theme-selector">
            <label for="themeSelect">Select Theme: </label>
            <select id="themeSelect">
                <option value="default">Default Theme</option>
                <option value="dark">Dark Theme</option>
                <option value="colorful">Colorful Theme</option>
            </select>
        </div>

        <div class="controls">
            <button onclick="toggleAnimation()">Toggle Animation</button>
            <button onclick="changeColors()">Change Colors</button>
        </div>

        <div class="chart-container">
            <canvas id="myChart"></canvas>
        </div>
    </div>

    <script>
        // Define theme configurations
        const themes = {
            default: {
                backgroundColor: '#fff',
                color: '#333',
                plugins: {
                    title: {
                        color: '#333',
                        font: {
                            size: 18,
                            weight: 'bold'
                        }
                    },
                    legend: {
                        labels: {
                            color: '#666',
                            font: {
                                size: 14
                            }
                        }
                    },
                    tooltip: {
                        backgroundColor: 'rgba(0, 0, 0, 0.8)',
                        titleColor: '#fff',
                        bodyColor: '#fff'
                    }
                },
                scales: {
                    x: {
                        ticks: {
                            color: '#666'
                        },
                        grid: {
                            color: 'rgba(0, 0, 0, 0.1)'
                        }
                    },
                    y: {
                        ticks: {
                            color: '#666'
                        },
                        grid: {
                            color: 'rgba(0, 0, 0, 0.1)'
                        }
                    }
                }
            },
            dark: {
                backgroundColor: '#222',
                color: '#eee',
                plugins: {
                    title: {
                        color: '#fff',
                        font: {
                            size: 18,
                            weight: 'bold'
                        }
                    },
                    legend: {
                        labels: {
                            color: '#ccc',
                            font: {
                                size: 14
                            }
                        }
                    },
                    tooltip: {
                        backgroundColor: 'rgba(50, 50, 50, 0.9)',
                        titleColor: '#fff',
                        bodyColor: '#eee',
                        borderColor: '#666'
                    }
                },
                scales: {
                    x: {
                        ticks: {
                            color: '#ccc'
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.1)'
                        }
                    },
                    y: {
                        ticks: {
                            color: '#ccc'
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.1)'
                        }
                    }
                }
            },
            colorful: {
                backgroundColor: '#f8f9fa',
                color: '#333',
                plugins: {
                    title: {
                        color: '#e74c3c',
                        font: {
                            size: 18,
                            weight: 'bold'
                        }
                    },
                    legend: {
                        labels: {
                            color: '#3498db',
                            font: {
                                size: 14
                            }
                        }
                    },
                    tooltip: {
                        backgroundColor: 'rgba(52, 152, 219, 0.9)',
                        titleColor: '#fff',
                        bodyColor: '#fff',
                        borderColor: '#2980b9'
                    }
                },
                scales: {
                    x: {
                        ticks: {
                            color: '#27ae60'
                        },
                        grid: {
                            color: 'rgba(39, 174, 96, 0.2)'
                        }
                    },
                    y: {
                        ticks: {
                            color: '#27ae60'
                        },
                        grid: {
                            color: 'rgba(39, 174, 96, 0.2)'
                        }
                    }
                }
            }
        };

        // Create chart
        const ctx = document.getElementById('myChart').getContext('2d');
        let myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ['January', 'February', 'March', 'April', 'May', 'June'],
                datasets: [{
                    label: 'Product A Sales',
                    data: [12, 19, 3, 5, 2, 3],
                    backgroundColor: 'rgba(255, 99, 132, 0.2)',
                    borderColor: 'rgba(255, 99, 132, 1)',
                    borderWidth: 2
                }, {
                    label: 'Product B Sales',
                    data: [8, 15, 7, 12, 9, 6],
                    backgroundColor: 'rgba(54, 162, 235, 0.2)',
                    borderColor: 'rgba(54, 162, 235, 1)',
                    borderWidth: 2
                }]
            },
            options: {
                ...themes.default,
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    title: {
                        display: true,
                        text: 'Product Sales Data Chart'
                    },
                    legend: {
                        position: 'top'
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        title: {
                            display: true,
                            text: 'Sales (ten thousand)'
                        }
                    },
                    x: {
                        title: {
                            display: true,
                            text: 'Month'
                        }
                    }
                },
                animation: {
                    duration: 1000,
                    easing: 'easeInOutQuart'
                }
            }
        });

        // Theme switching
        document.getElementById('themeSelect').addEventListener('change', function() {
            const selectedTheme = this.value;
            Object.assign(myChart.options, themes[selectedTheme]);
            myChart.update();
        });

        // Toggle animation
        let animationEnabled = true;
        function toggleAnimation() {
            animationEnabled = !animationEnabled;
            myChart.options.animation.duration = animationEnabled ? 1000 : 0;
            myChart.update();
        }

        // Change colors
        function changeColors() {
            const colors = [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 205, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ];

            const borderColors = [
                'rgba(255, 99, 132, 1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 205, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ];

            // Randomly shuffle color arrays
            shuffleArray(colors);
            shuffleArray(borderColors);

            myChart.data.datasets[0].backgroundColor = colors[0];
            myChart.data.datasets[0].borderColor = borderColors[0];
            myChart.data.datasets[1].backgroundColor = colors[1];
            myChart.data.datasets[1].borderColor = borderColors[1];

            myChart.update();
        }

        // Array random shuffle function
        function shuffleArray(array) {
            for (let i = array.length - 1; i > 0; i--) {
                const j = Math.floor(Math.random() * (i + 1));
                [array[i], array[j]] = [array[j], array[i]];
            }
        }
    </script>
</body>
</html>

Through this chapter's learning, you should have mastered how to customize Chart.js chart styles and appearance. In next chapter, we will explore Chart.js advanced features.

Content is for learning and research only.