Chart.js Chart Library Samples
Comprehensive Chart.js examples including various chart types, customization options, animations, and responsive designs
Key Facts
- Category
- Data Visualization
- Items
- 3
- Format Families
- sample
Sample Overview
Comprehensive Chart.js examples including various chart types, customization options, animations, and responsive designs This sample set belongs to Data Visualization and can be used to test related workflows inside Elysia Tools.
💻 Chart.js Basic Charts javascript
🟢 simple
⭐⭐
Essential Chart.js charts including bar, line, pie, doughnut, and radar charts with customization
⏱️ 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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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
};
});
💻 Chart.js Advanced Customization javascript
🟡 intermediate
⭐⭐⭐
Advanced Chart.js features including mixed charts, custom plugins, animations, and responsive designs
⏱️ 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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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
};
});
💻 Chart.js Interactive Dashboard javascript
🔴 complex
⭐⭐⭐⭐
Complete dashboard with multiple charts, real-time updates, filters, and data synchronization
⏱️ 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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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');
if (!ctx) throw new Error('Canvas element not found');
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);
});