Back to application components
Charts
Chart components for visualizing trends, comparisons, and breakdowns in dashboards and analytics pages, built with Chart.js.
4/4 Dark Mode Updated: N/ANo commit information available.
<div class="rounded-lg border border-gray-200 bg-white p-6">
<div class="flex items-center justify-between">
<h2 class="text-sm font-medium text-gray-900">Monthly revenue</h2>
<div class="inline-flex rounded-md border border-gray-200 p-0.5 text-xs font-medium">
<button
type="button"
data-revenue-range="6m"
aria-pressed="true"
class="rounded-sm bg-gray-100 px-2 py-1 text-gray-900"
>
6M
</button>
<button
type="button"
data-revenue-range="12m"
aria-pressed="false"
class="rounded-sm px-2 py-1 text-gray-600"
>
12M
</button>
</div>
</div>
<div class="mt-4 h-64">
<canvas
id="revenue-line-chart"
role="img"
aria-label="Line chart showing monthly revenue rising from $28,000 in January to $48,000 in June"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueLineChartCanvas = document.getElementById('revenue-line-chart')
const revenueRangeButtons = document.querySelectorAll('[data-revenue-range]')
const revenueRangesByPeriod = {
'6m': {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
values: [28000, 34000, 31000, 39000, 42000, 48000],
},
'12m': {
labels: ['Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
values: [
19000, 21500, 20000, 23500, 25000, 27000, 28000, 34000, 31000, 39000, 42000, 48000,
],
},
}
const chartCanvasContext = revenueLineChartCanvas.getContext('2d')
const revenueFillGradient = chartCanvasContext.createLinearGradient(0, 0, 0, 256)
revenueFillGradient.addColorStop(0, 'rgba(79, 70, 229, 0.25)')
revenueFillGradient.addColorStop(1, 'rgba(79, 70, 229, 0)')
const revenueLineChart = new Chart(revenueLineChartCanvas, {
type: 'line',
data: {
labels: revenueRangesByPeriod['6m'].labels,
datasets: [
{
label: 'Revenue',
data: revenueRangesByPeriod['6m'].values,
borderColor: '#4f46e5',
backgroundColor: revenueFillGradient,
borderWidth: 2,
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#4f46e5',
pointHoverBorderColor: '#ffffff',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: true,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) => `$${tooltipItem.formattedValue}`,
},
},
},
scales: {
x: {
grid: { display: false },
ticks: { color: '#4b5563' },
},
y: {
beginAtZero: true,
grid: { color: '#e5e7eb' },
ticks: {
color: '#4b5563',
callback: (tickValue) => `$${Number(tickValue) / 1000}k`,
},
},
},
},
})
revenueRangeButtons.forEach((revenueRangeButton) => {
revenueRangeButton.addEventListener('click', () => {
const selectedRange = revenueRangeButton.dataset.revenueRange
revenueRangeButtons.forEach((otherRangeButton) => {
const isSelectedButton = otherRangeButton === revenueRangeButton
otherRangeButton.setAttribute('aria-pressed', String(isSelectedButton))
otherRangeButton.classList.toggle('bg-gray-100', isSelectedButton)
otherRangeButton.classList.toggle('text-gray-900', isSelectedButton)
otherRangeButton.classList.toggle('text-gray-600', !isSelectedButton)
})
revenueLineChart.data.labels = revenueRangesByPeriod[selectedRange].labels
revenueLineChart.data.datasets[0].data = revenueRangesByPeriod[selectedRange].values
revenueLineChart.update()
})
})
</script>Plugins: chart.js
<div class="rounded-lg border border-gray-800 bg-gray-900 p-6">
<div class="flex items-center justify-between">
<h2 class="text-sm font-medium text-white">Monthly revenue</h2>
<div class="inline-flex rounded-md border border-gray-700 p-0.5 text-xs font-medium">
<button
type="button"
data-revenue-range="6m"
aria-pressed="true"
class="rounded-sm bg-gray-800 px-2 py-1 text-white"
>
6M
</button>
<button
type="button"
data-revenue-range="12m"
aria-pressed="false"
class="rounded-sm px-2 py-1 text-gray-400"
>
12M
</button>
</div>
</div>
<div class="mt-4 h-64">
<canvas
id="revenue-line-chart"
role="img"
aria-label="Line chart showing monthly revenue rising from $28,000 in January to $48,000 in June"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueLineChartCanvas = document.getElementById('revenue-line-chart')
const revenueRangeButtons = document.querySelectorAll('[data-revenue-range]')
const revenueRangesByPeriod = {
'6m': {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
values: [28000, 34000, 31000, 39000, 42000, 48000],
},
'12m': {
labels: ['Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
values: [
19000, 21500, 20000, 23500, 25000, 27000, 28000, 34000, 31000, 39000, 42000, 48000,
],
},
}
const chartCanvasContext = revenueLineChartCanvas.getContext('2d')
const revenueFillGradient = chartCanvasContext.createLinearGradient(0, 0, 0, 256)
revenueFillGradient.addColorStop(0, 'rgba(129, 140, 248, 0.3)')
revenueFillGradient.addColorStop(1, 'rgba(129, 140, 248, 0)')
const revenueLineChart = new Chart(revenueLineChartCanvas, {
type: 'line',
data: {
labels: revenueRangesByPeriod['6m'].labels,
datasets: [
{
label: 'Revenue',
data: revenueRangesByPeriod['6m'].values,
borderColor: '#818cf8',
backgroundColor: revenueFillGradient,
borderWidth: 2,
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#818cf8',
pointHoverBorderColor: '#111827',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: true,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) => `$${tooltipItem.formattedValue}`,
},
},
},
scales: {
x: {
grid: { display: false },
ticks: { color: '#9ca3af' },
},
y: {
beginAtZero: true,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: {
color: '#9ca3af',
callback: (tickValue) => `$${Number(tickValue) / 1000}k`,
},
},
},
},
})
revenueRangeButtons.forEach((revenueRangeButton) => {
revenueRangeButton.addEventListener('click', () => {
const selectedRange = revenueRangeButton.dataset.revenueRange
revenueRangeButtons.forEach((otherRangeButton) => {
const isSelectedButton = otherRangeButton === revenueRangeButton
otherRangeButton.setAttribute('aria-pressed', String(isSelectedButton))
otherRangeButton.classList.toggle('bg-gray-800', isSelectedButton)
otherRangeButton.classList.toggle('text-white', isSelectedButton)
otherRangeButton.classList.toggle('text-gray-400', !isSelectedButton)
})
revenueLineChart.data.labels = revenueRangesByPeriod[selectedRange].labels
revenueLineChart.data.datasets[0].data = revenueRangesByPeriod[selectedRange].values
revenueLineChart.update()
})
})
</script>Plugins: chart.js
<div class="rounded-lg border border-gray-200 bg-white p-6">
<h2 class="text-sm font-medium text-gray-900">Orders this week</h2>
<div class="mt-4 h-64">
<canvas
id="weekly-orders-bar-chart"
role="img"
aria-label="Bar chart showing orders per day this week, peaking at 32 orders on Saturday"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const weeklyOrdersBarChartCanvas = document.getElementById('weekly-orders-bar-chart')
new Chart(weeklyOrdersBarChartCanvas, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [
{
label: 'Orders',
data: [12, 19, 14, 22, 27, 32, 18],
backgroundColor: '#6366f1',
hoverBackgroundColor: '#4338ca',
borderRadius: 4,
maxBarThickness: 32,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.formattedValue} orders`,
},
},
},
scales: {
x: {
grid: { display: false },
ticks: { color: '#4b5563' },
},
y: {
beginAtZero: true,
grid: { color: '#e5e7eb' },
ticks: { color: '#4b5563' },
},
},
},
})
</script>Plugins: chart.js
<div class="rounded-lg border border-gray-800 bg-gray-900 p-6">
<h2 class="text-sm font-medium text-white">Orders this week</h2>
<div class="mt-4 h-64">
<canvas
id="weekly-orders-bar-chart"
role="img"
aria-label="Bar chart showing orders per day this week, peaking at 32 orders on Saturday"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const weeklyOrdersBarChartCanvas = document.getElementById('weekly-orders-bar-chart')
new Chart(weeklyOrdersBarChartCanvas, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [
{
label: 'Orders',
data: [12, 19, 14, 22, 27, 32, 18],
backgroundColor: '#818cf8',
hoverBackgroundColor: '#a5b4fc',
borderRadius: 4,
maxBarThickness: 32,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.formattedValue} orders`,
},
},
},
scales: {
x: {
grid: { display: false },
ticks: { color: '#9ca3af' },
},
y: {
beginAtZero: true,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#9ca3af' },
},
},
},
})
</script>Plugins: chart.js
<div class="rounded-lg border border-gray-200 bg-white p-6">
<h2 class="text-sm font-medium text-gray-900">Orders by status</h2>
<div class="mt-4 h-64">
<canvas
id="order-status-donut-chart"
role="img"
aria-label="Donut chart showing 68% of orders paid, 22% pending, and 10% refunded"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const orderStatusDonutChartCanvas = document.getElementById('order-status-donut-chart')
new Chart(orderStatusDonutChartCanvas, {
type: 'doughnut',
data: {
labels: ['Paid', 'Pending', 'Refunded'],
datasets: [
{
data: [68, 22, 10],
backgroundColor: ['#10b981', '#f59e0b', '#f43f5e'],
hoverBackgroundColor: ['#059669', '#d97706', '#e11d48'],
borderColor: '#ffffff',
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.label}: ${tooltipItem.formattedValue}%`,
},
},
},
},
})
</script>Plugins: chart.js
<div class="rounded-lg border border-gray-800 bg-gray-900 p-6">
<h2 class="text-sm font-medium text-white">Orders by status</h2>
<div class="mt-4 h-64">
<canvas
id="order-status-donut-chart"
role="img"
aria-label="Donut chart showing 68% of orders paid, 22% pending, and 10% refunded"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const orderStatusDonutChartCanvas = document.getElementById('order-status-donut-chart')
new Chart(orderStatusDonutChartCanvas, {
type: 'doughnut',
data: {
labels: ['Paid', 'Pending', 'Refunded'],
datasets: [
{
data: [68, 22, 10],
backgroundColor: ['#34d399', '#fbbf24', '#fb7185'],
hoverBackgroundColor: ['#10b981', '#f59e0b', '#f43f5e'],
borderColor: '#111827',
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.label}: ${tooltipItem.formattedValue}%`,
},
},
},
},
})
</script>Plugins: chart.js
<div class="flex items-center justify-between gap-4 rounded-lg border border-gray-200 bg-white p-6">
<div>
<strong class="block text-sm font-medium text-gray-600">Monthly revenue</strong>
<p class="text-2xl font-medium text-gray-900">$48,204</p>
</div>
<div class="h-12 w-24 shrink-0">
<canvas
id="revenue-sparkline-chart"
role="img"
aria-label="Sparkline showing monthly revenue trending upward"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueSparklineChartCanvas = document.getElementById('revenue-sparkline-chart')
new Chart(revenueSparklineChartCanvas, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
data: [28000, 34000, 31000, 39000, 42000, 48000],
borderColor: '#10b981',
borderWidth: 2,
pointRadius: 0,
tension: 0.35,
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { enabled: false },
},
scales: {
x: { display: false },
y: { display: false },
},
},
})
</script>Plugins: chart.js
<div
class="flex items-center justify-between gap-4 rounded-lg border border-gray-800 bg-gray-900 p-6"
>
<div>
<strong class="block text-sm font-medium text-gray-400">Monthly revenue</strong>
<p class="text-2xl font-medium text-white">$48,204</p>
</div>
<div class="h-12 w-24 shrink-0">
<canvas
id="revenue-sparkline-chart"
role="img"
aria-label="Sparkline showing monthly revenue trending upward"
></canvas>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueSparklineChartCanvas = document.getElementById('revenue-sparkline-chart')
new Chart(revenueSparklineChartCanvas, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
data: [28000, 34000, 31000, 39000, 42000, 48000],
borderColor: '#34d399',
borderWidth: 2,
pointRadius: 0,
tension: 0.35,
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: { enabled: false },
},
scales: {
x: { display: false },
y: { display: false },
},
},
})
</script>Plugins: chart.js