Back to application components
Charts
Chart components for visualizing trends, comparisons, and breakdowns in dashboards and analytics pages, built with Chart.js.
11/11 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="Monthly revenue, line chart"
></canvas>
</div>
<table id="revenue-line-chart-table" class="sr-only" aria-live="polite">
<caption>
Monthly revenue by month
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody></tbody>
</table>
</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 revenueLineChartTableBody = document.querySelector('#revenue-line-chart-table tbody')
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`,
},
},
},
},
})
function renderRevenueTableRows(selectedRange) {
const { labels, values } = revenueRangesByPeriod[selectedRange]
revenueLineChartTableBody.innerHTML = labels
.map(
(monthLabel, monthIndex) => `
<tr>
<th scope="row">${monthLabel}</th>
<td>$${values[monthIndex].toLocaleString()}</td>
</tr>
`,
)
.join('')
}
renderRevenueTableRows('6m')
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()
renderRevenueTableRows(selectedRange)
})
})
</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="Monthly revenue, line chart"
></canvas>
</div>
<table id="revenue-line-chart-table" class="sr-only" aria-live="polite">
<caption>
Monthly revenue by month
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody></tbody>
</table>
</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 revenueLineChartTableBody = document.querySelector('#revenue-line-chart-table tbody')
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="Orders this week, bar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Orders per day this week
</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Orders</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Mon</th>
<td>12</td>
</tr>
<tr>
<th scope="row">Tue</th>
<td>19</td>
</tr>
<tr>
<th scope="row">Wed</th>
<td>14</td>
</tr>
<tr>
<th scope="row">Thu</th>
<td>22</td>
</tr>
<tr>
<th scope="row">Fri</th>
<td>27</td>
</tr>
<tr>
<th scope="row">Sat</th>
<td>32</td>
</tr>
<tr>
<th scope="row">Sun</th>
<td>18</td>
</tr>
</tbody>
</table>
</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="Orders this week, bar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Orders per day this week
</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Orders</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Mon</th>
<td>12</td>
</tr>
<tr>
<th scope="row">Tue</th>
<td>19</td>
</tr>
<tr>
<th scope="row">Wed</th>
<td>14</td>
</tr>
<tr>
<th scope="row">Thu</th>
<td>22</td>
</tr>
<tr>
<th scope="row">Fri</th>
<td>27</td>
</tr>
<tr>
<th scope="row">Sat</th>
<td>32</td>
</tr>
<tr>
<th scope="row">Sun</th>
<td>18</td>
</tr>
</tbody>
</table>
</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="Orders by status, donut chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Orders by status
</caption>
<thead>
<tr>
<th scope="col">Status</th>
<th scope="col">Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Paid</th>
<td>68%</td>
</tr>
<tr>
<th scope="row">Pending</th>
<td>22%</td>
</tr>
<tr>
<th scope="row">Refunded</th>
<td>10%</td>
</tr>
</tbody>
</table>
</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="Orders by status, donut chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Orders by status
</caption>
<thead>
<tr>
<th scope="col">Status</th>
<th scope="col">Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Paid</th>
<td>68%</td>
</tr>
<tr>
<th scope="row">Pending</th>
<td>22%</td>
</tr>
<tr>
<th scope="row">Refunded</th>
<td>10%</td>
</tr>
</tbody>
</table>
</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="Monthly revenue trend, sparkline chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue by month
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
</tr>
</tbody>
</table>
</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="Monthly revenue trend, sparkline chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue by month
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
</tr>
</tbody>
</table>
</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
<div class="rounded-lg border border-gray-200 bg-white p-6">
<h2 class="text-sm font-medium text-gray-900">Traffic by channel</h2>
<div class="mt-4 h-64">
<canvas
id="channel-traffic-stacked-bar-chart"
role="img"
aria-label="Traffic by channel, stacked bar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Website traffic by channel, per day
</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Organic</th>
<th scope="col">Paid</th>
<th scope="col">Referral</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Mon</th>
<td>120</td>
<td>80</td>
<td>40</td>
</tr>
<tr>
<th scope="row">Tue</th>
<td>132</td>
<td>95</td>
<td>35</td>
</tr>
<tr>
<th scope="row">Wed</th>
<td>101</td>
<td>70</td>
<td>45</td>
</tr>
<tr>
<th scope="row">Thu</th>
<td>134</td>
<td>110</td>
<td>38</td>
</tr>
<tr>
<th scope="row">Fri</th>
<td>90</td>
<td>60</td>
<td>42</td>
</tr>
<tr>
<th scope="row">Sat</th>
<td>230</td>
<td>120</td>
<td>55</td>
</tr>
<tr>
<th scope="row">Sun</th>
<td>210</td>
<td>95</td>
<td>48</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const channelTrafficStackedBarChartCanvas = document.getElementById(
'channel-traffic-stacked-bar-chart',
)
new Chart(channelTrafficStackedBarChartCanvas, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [
{
label: 'Organic',
data: [120, 132, 101, 134, 90, 230, 210],
backgroundColor: '#4f46e5',
hoverBackgroundColor: '#4338ca',
borderColor: '#ffffff',
borderWidth: 2,
maxBarThickness: 32,
},
{
label: 'Paid',
data: [80, 95, 70, 110, 60, 120, 95],
backgroundColor: '#10b981',
hoverBackgroundColor: '#059669',
borderColor: '#ffffff',
borderWidth: 2,
maxBarThickness: 32,
},
{
label: 'Referral',
data: [40, 35, 45, 38, 42, 55, 48],
backgroundColor: '#f59e0b',
hoverBackgroundColor: '#d97706',
borderColor: '#ffffff',
borderWidth: 2,
maxBarThickness: 32,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: ${tooltipItem.formattedValue}`,
},
},
},
scales: {
x: {
stacked: true,
grid: { display: false },
ticks: { color: '#4b5563' },
},
y: {
stacked: true,
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">Traffic by channel</h2>
<div class="mt-4 h-64">
<canvas
id="channel-traffic-stacked-bar-chart"
role="img"
aria-label="Traffic by channel, stacked bar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Website traffic by channel, per day
</caption>
<thead>
<tr>
<th scope="col">Day</th>
<th scope="col">Organic</th>
<th scope="col">Paid</th>
<th scope="col">Referral</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Mon</th>
<td>120</td>
<td>80</td>
<td>40</td>
</tr>
<tr>
<th scope="row">Tue</th>
<td>132</td>
<td>95</td>
<td>35</td>
</tr>
<tr>
<th scope="row">Wed</th>
<td>101</td>
<td>70</td>
<td>45</td>
</tr>
<tr>
<th scope="row">Thu</th>
<td>134</td>
<td>110</td>
<td>38</td>
</tr>
<tr>
<th scope="row">Fri</th>
<td>90</td>
<td>60</td>
<td>42</td>
</tr>
<tr>
<th scope="row">Sat</th>
<td>230</td>
<td>120</td>
<td>55</td>
</tr>
<tr>
<th scope="row">Sun</th>
<td>210</td>
<td>95</td>
<td>48</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const channelTrafficStackedBarChartCanvas = document.getElementById(
'channel-traffic-stacked-bar-chart',
)
new Chart(channelTrafficStackedBarChartCanvas, {
type: 'bar',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [
{
label: 'Organic',
data: [120, 132, 101, 134, 90, 230, 210],
backgroundColor: '#818cf8',
hoverBackgroundColor: '#a5b4fc',
borderColor: '#111827',
borderWidth: 2,
maxBarThickness: 32,
},
{
label: 'Paid',
data: [80, 95, 70, 110, 60, 120, 95],
backgroundColor: '#34d399',
hoverBackgroundColor: '#6ee7b7',
borderColor: '#111827',
borderWidth: 2,
maxBarThickness: 32,
},
{
label: 'Referral',
data: [40, 35, 45, 38, 42, 55, 48],
backgroundColor: '#fbbf24',
hoverBackgroundColor: '#fcd34d',
borderColor: '#111827',
borderWidth: 2,
maxBarThickness: 32,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: ${tooltipItem.formattedValue}`,
},
},
},
scales: {
x: {
stacked: true,
grid: { display: false },
ticks: { color: '#9ca3af' },
},
y: {
stacked: true,
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">Revenue vs target</h2>
<div class="mt-4 h-64">
<canvas
id="revenue-target-combo-chart"
role="img"
aria-label="Revenue vs target, combo chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue against quarterly target
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
<th scope="col">Target</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
<td>$40,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
<td>$40,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
<td>$40,000</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueTargetComboChartCanvas = document.getElementById('revenue-target-combo-chart')
new Chart(revenueTargetComboChartCanvas, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
type: 'bar',
label: 'Revenue',
data: [28000, 34000, 31000, 39000, 42000, 48000],
backgroundColor: '#4f46e5',
hoverBackgroundColor: '#4338ca',
borderRadius: 4,
maxBarThickness: 32,
order: 2,
},
{
type: 'line',
label: 'Target',
data: [32000, 32000, 32000, 40000, 40000, 40000],
borderColor: '#f59e0b',
backgroundColor: '#f59e0b',
borderWidth: 2,
borderDash: [6, 4],
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#f59e0b',
pointHoverBorderColor: '#ffffff',
pointHoverBorderWidth: 2,
tension: 0,
fill: false,
order: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${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`,
},
},
},
},
})
</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">Revenue vs target</h2>
<div class="mt-4 h-64">
<canvas
id="revenue-target-combo-chart"
role="img"
aria-label="Revenue vs target, combo chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue against quarterly target
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">Revenue</th>
<th scope="col">Target</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
<td>$32,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
<td>$40,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
<td>$40,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
<td>$40,000</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const revenueTargetComboChartCanvas = document.getElementById('revenue-target-combo-chart')
new Chart(revenueTargetComboChartCanvas, {
type: 'bar',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
type: 'bar',
label: 'Revenue',
data: [28000, 34000, 31000, 39000, 42000, 48000],
backgroundColor: '#818cf8',
hoverBackgroundColor: '#a5b4fc',
borderRadius: 4,
maxBarThickness: 32,
order: 2,
},
{
type: 'line',
label: 'Target',
data: [32000, 32000, 32000, 40000, 40000, 40000],
borderColor: '#fbbf24',
backgroundColor: '#fbbf24',
borderWidth: 2,
borderDash: [6, 4],
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#fbbf24',
pointHoverBorderColor: '#111827',
pointHoverBorderWidth: 2,
tension: 0,
fill: false,
order: 1,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${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`,
},
},
},
},
})
</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">Revenue: this year vs last year</h2>
<div class="mt-4 h-64">
<canvas
id="yearly-revenue-comparison-line-chart"
role="img"
aria-label="Revenue this year vs last year, line chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue, this year vs last year
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">This year</th>
<th scope="col">Last year</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
<td>$22,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
<td>$25,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
<td>$24,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
<td>$29,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
<td>$31,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
<td>$35,000</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const yearlyRevenueComparisonLineChartCanvas = document.getElementById(
'yearly-revenue-comparison-line-chart',
)
new Chart(yearlyRevenueComparisonLineChartCanvas, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
label: 'This year',
data: [28000, 34000, 31000, 39000, 42000, 48000],
borderColor: '#4f46e5',
backgroundColor: 'transparent',
borderWidth: 2,
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#4f46e5',
pointHoverBorderColor: '#ffffff',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: false,
},
{
label: 'Last year',
data: [22000, 25000, 24000, 29000, 31000, 35000],
borderColor: '#9ca3af',
backgroundColor: 'transparent',
borderWidth: 2,
borderDash: [6, 4],
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#9ca3af',
pointHoverBorderColor: '#ffffff',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${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`,
},
},
},
},
})
</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">Revenue: this year vs last year</h2>
<div class="mt-4 h-64">
<canvas
id="yearly-revenue-comparison-line-chart"
role="img"
aria-label="Revenue this year vs last year, line chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Monthly revenue, this year vs last year
</caption>
<thead>
<tr>
<th scope="col">Month</th>
<th scope="col">This year</th>
<th scope="col">Last year</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Jan</th>
<td>$28,000</td>
<td>$22,000</td>
</tr>
<tr>
<th scope="row">Feb</th>
<td>$34,000</td>
<td>$25,000</td>
</tr>
<tr>
<th scope="row">Mar</th>
<td>$31,000</td>
<td>$24,000</td>
</tr>
<tr>
<th scope="row">Apr</th>
<td>$39,000</td>
<td>$29,000</td>
</tr>
<tr>
<th scope="row">May</th>
<td>$42,000</td>
<td>$31,000</td>
</tr>
<tr>
<th scope="row">Jun</th>
<td>$48,000</td>
<td>$35,000</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const yearlyRevenueComparisonLineChartCanvas = document.getElementById(
'yearly-revenue-comparison-line-chart',
)
new Chart(yearlyRevenueComparisonLineChartCanvas, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'],
datasets: [
{
label: 'This year',
data: [28000, 34000, 31000, 39000, 42000, 48000],
borderColor: '#818cf8',
backgroundColor: 'transparent',
borderWidth: 2,
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#818cf8',
pointHoverBorderColor: '#111827',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: false,
},
{
label: 'Last year',
data: [22000, 25000, 24000, 29000, 31000, 35000],
borderColor: '#9ca3af',
backgroundColor: 'transparent',
borderWidth: 2,
borderDash: [6, 4],
pointRadius: 0,
pointHoverRadius: 5,
pointHoverBackgroundColor: '#9ca3af',
pointHoverBorderColor: '#111827',
pointHoverBorderWidth: 2,
tension: 0.35,
fill: false,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${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`,
},
},
},
},
})
</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">Team performance</h2>
<div class="mt-4 h-64">
<canvas
id="team-performance-radar-chart"
role="img"
aria-label="Team performance, radar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Team performance by metric
</caption>
<thead>
<tr>
<th scope="col">Metric</th>
<th scope="col">Team A</th>
<th scope="col">Team B</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Speed</th>
<td>80</td>
<td>65</td>
</tr>
<tr>
<th scope="row">Quality</th>
<td>90</td>
<td>75</td>
</tr>
<tr>
<th scope="row">Collaboration</th>
<td>70</td>
<td>88</td>
</tr>
<tr>
<th scope="row">Innovation</th>
<td>60</td>
<td>92</td>
</tr>
<tr>
<th scope="row">Reliability</th>
<td>85</td>
<td>70</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const teamPerformanceRadarChartCanvas = document.getElementById(
'team-performance-radar-chart',
)
new Chart(teamPerformanceRadarChartCanvas, {
type: 'radar',
data: {
labels: ['Speed', 'Quality', 'Collaboration', 'Innovation', 'Reliability'],
datasets: [
{
label: 'Team A',
data: [80, 90, 70, 60, 85],
borderColor: '#4f46e5',
backgroundColor: 'rgba(79, 70, 229, 0.2)',
pointBackgroundColor: '#4f46e5',
pointBorderColor: '#ffffff',
pointHoverRadius: 5,
borderWidth: 2,
},
{
label: 'Team B',
data: [65, 75, 88, 92, 70],
borderColor: '#10b981',
backgroundColor: 'rgba(16, 185, 129, 0.2)',
pointBackgroundColor: '#10b981',
pointBorderColor: '#ffffff',
pointHoverRadius: 5,
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: ${tooltipItem.formattedValue}`,
},
},
},
scales: {
r: {
beginAtZero: true,
max: 100,
angleLines: { color: '#e5e7eb' },
grid: { color: '#e5e7eb' },
pointLabels: { color: '#4b5563', font: { size: 11 } },
ticks: { display: false },
},
},
},
})
</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">Team performance</h2>
<div class="mt-4 h-64">
<canvas
id="team-performance-radar-chart"
role="img"
aria-label="Team performance, radar chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Team performance by metric
</caption>
<thead>
<tr>
<th scope="col">Metric</th>
<th scope="col">Team A</th>
<th scope="col">Team B</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Speed</th>
<td>80</td>
<td>65</td>
</tr>
<tr>
<th scope="row">Quality</th>
<td>90</td>
<td>75</td>
</tr>
<tr>
<th scope="row">Collaboration</th>
<td>70</td>
<td>88</td>
</tr>
<tr>
<th scope="row">Innovation</th>
<td>60</td>
<td>92</td>
</tr>
<tr>
<th scope="row">Reliability</th>
<td>85</td>
<td>70</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const teamPerformanceRadarChartCanvas = document.getElementById(
'team-performance-radar-chart',
)
new Chart(teamPerformanceRadarChartCanvas, {
type: 'radar',
data: {
labels: ['Speed', 'Quality', 'Collaboration', 'Innovation', 'Reliability'],
datasets: [
{
label: 'Team A',
data: [80, 90, 70, 60, 85],
borderColor: '#818cf8',
backgroundColor: 'rgba(129, 140, 248, 0.25)',
pointBackgroundColor: '#818cf8',
pointBorderColor: '#111827',
pointHoverRadius: 5,
borderWidth: 2,
},
{
label: 'Team B',
data: [65, 75, 88, 92, 70],
borderColor: '#34d399',
backgroundColor: 'rgba(52, 211, 153, 0.25)',
pointBackgroundColor: '#34d399',
pointBorderColor: '#111827',
pointHoverRadius: 5,
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: ${tooltipItem.formattedValue}`,
},
},
},
scales: {
r: {
beginAtZero: true,
max: 100,
angleLines: { color: 'rgba(255, 255, 255, 0.1)' },
grid: { color: 'rgba(255, 255, 255, 0.1)' },
pointLabels: { color: '#9ca3af', font: { size: 11 } },
ticks: { display: false },
},
},
},
})
</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">Traffic sources</h2>
<div class="mt-4 h-64">
<canvas
id="traffic-sources-polar-area-chart"
role="img"
aria-label="Traffic sources, polar area chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Traffic by source
</caption>
<thead>
<tr>
<th scope="col">Source</th>
<th scope="col">Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Organic</th>
<td>45%</td>
</tr>
<tr>
<th scope="row">Paid</th>
<td>25%</td>
</tr>
<tr>
<th scope="row">Referral</th>
<td>18%</td>
</tr>
<tr>
<th scope="row">Direct</th>
<td>12%</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const trafficSourcesPolarAreaChartCanvas = document.getElementById(
'traffic-sources-polar-area-chart',
)
new Chart(trafficSourcesPolarAreaChartCanvas, {
type: 'polarArea',
data: {
labels: ['Organic', 'Paid', 'Referral', 'Direct'],
datasets: [
{
data: [45, 25, 18, 12],
backgroundColor: [
'rgba(79, 70, 229, 0.7)',
'rgba(16, 185, 129, 0.7)',
'rgba(245, 158, 11, 0.7)',
'rgba(244, 63, 94, 0.7)',
],
hoverBackgroundColor: ['#4f46e5', '#10b981', '#f59e0b', '#f43f5e'],
borderColor: '#ffffff',
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.label}: ${tooltipItem.formattedValue}%`,
},
},
},
scales: {
r: {
beginAtZero: true,
angleLines: { color: '#e5e7eb' },
grid: { color: '#e5e7eb' },
ticks: { display: false },
},
},
},
})
</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">Traffic sources</h2>
<div class="mt-4 h-64">
<canvas
id="traffic-sources-polar-area-chart"
role="img"
aria-label="Traffic sources, polar area chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Traffic by source
</caption>
<thead>
<tr>
<th scope="col">Source</th>
<th scope="col">Percentage</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Organic</th>
<td>45%</td>
</tr>
<tr>
<th scope="row">Paid</th>
<td>25%</td>
</tr>
<tr>
<th scope="row">Referral</th>
<td>18%</td>
</tr>
<tr>
<th scope="row">Direct</th>
<td>12%</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const trafficSourcesPolarAreaChartCanvas = document.getElementById(
'traffic-sources-polar-area-chart',
)
new Chart(trafficSourcesPolarAreaChartCanvas, {
type: 'polarArea',
data: {
labels: ['Organic', 'Paid', 'Referral', 'Direct'],
datasets: [
{
data: [45, 25, 18, 12],
backgroundColor: [
'rgba(129, 140, 248, 0.7)',
'rgba(52, 211, 153, 0.7)',
'rgba(251, 191, 36, 0.7)',
'rgba(251, 113, 133, 0.7)',
],
hoverBackgroundColor: ['#818cf8', '#34d399', '#fbbf24', '#fb7185'],
borderColor: '#111827',
borderWidth: 2,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) => `${tooltipItem.label}: ${tooltipItem.formattedValue}%`,
},
},
},
scales: {
r: {
beginAtZero: true,
angleLines: { color: 'rgba(255, 255, 255, 0.1)' },
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { display: false },
},
},
},
})
</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">Ad spend vs conversions</h2>
<div class="mt-4 h-64">
<canvas
id="ad-spend-conversions-scatter-chart"
role="img"
aria-label="Ad spend vs conversions, scatter chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Ad spend and conversions per campaign
</caption>
<thead>
<tr>
<th scope="col">Spend ($)</th>
<th scope="col">Conversions</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">90</th>
<td>8</td>
</tr>
<tr>
<th scope="row">120</th>
<td>12</td>
</tr>
<tr>
<th scope="row">140</th>
<td>14</td>
</tr>
<tr>
<th scope="row">150</th>
<td>15</td>
</tr>
<tr>
<th scope="row">180</th>
<td>18</td>
</tr>
<tr>
<th scope="row">200</th>
<td>22</td>
</tr>
<tr>
<th scope="row">220</th>
<td>25</td>
</tr>
<tr>
<th scope="row">260</th>
<td>30</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const adSpendConversionsScatterChartCanvas = document.getElementById(
'ad-spend-conversions-scatter-chart',
)
new Chart(adSpendConversionsScatterChartCanvas, {
type: 'scatter',
data: {
datasets: [
{
label: 'Campaigns',
data: [
{ x: 90, y: 8 },
{ x: 120, y: 12 },
{ x: 140, y: 14 },
{ x: 150, y: 15 },
{ x: 180, y: 18 },
{ x: 200, y: 22 },
{ x: 220, y: 25 },
{ x: 260, y: 30 },
],
backgroundColor: '#4f46e5',
hoverBackgroundColor: '#4338ca',
pointRadius: 5,
pointHoverRadius: 7,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) =>
`$${tooltipItem.raw.x} spend → ${tooltipItem.raw.y} conversions`,
},
},
},
scales: {
x: {
title: { display: true, text: 'Spend ($)', color: '#4b5563' },
grid: { color: '#e5e7eb' },
ticks: { color: '#4b5563' },
},
y: {
title: { display: true, text: 'Conversions', color: '#4b5563' },
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">Ad spend vs conversions</h2>
<div class="mt-4 h-64">
<canvas
id="ad-spend-conversions-scatter-chart"
role="img"
aria-label="Ad spend vs conversions, scatter chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Ad spend and conversions per campaign
</caption>
<thead>
<tr>
<th scope="col">Spend ($)</th>
<th scope="col">Conversions</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">90</th>
<td>8</td>
</tr>
<tr>
<th scope="row">120</th>
<td>12</td>
</tr>
<tr>
<th scope="row">140</th>
<td>14</td>
</tr>
<tr>
<th scope="row">150</th>
<td>15</td>
</tr>
<tr>
<th scope="row">180</th>
<td>18</td>
</tr>
<tr>
<th scope="row">200</th>
<td>22</td>
</tr>
<tr>
<th scope="row">220</th>
<td>25</td>
</tr>
<tr>
<th scope="row">260</th>
<td>30</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const adSpendConversionsScatterChartCanvas = document.getElementById(
'ad-spend-conversions-scatter-chart',
)
new Chart(adSpendConversionsScatterChartCanvas, {
type: 'scatter',
data: {
datasets: [
{
label: 'Campaigns',
data: [
{ x: 90, y: 8 },
{ x: 120, y: 12 },
{ x: 140, y: 14 },
{ x: 150, y: 15 },
{ x: 180, y: 18 },
{ x: 200, y: 22 },
{ x: 220, y: 25 },
{ x: 260, y: 30 },
],
backgroundColor: '#818cf8',
hoverBackgroundColor: '#a5b4fc',
pointRadius: 5,
pointHoverRadius: 7,
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: (tooltipItem) =>
`$${tooltipItem.raw.x} spend → ${tooltipItem.raw.y} conversions`,
},
},
},
scales: {
x: {
title: { display: true, text: 'Spend ($)', color: '#9ca3af' },
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#9ca3af' },
},
y: {
title: { display: true, text: 'Conversions', color: '#9ca3af' },
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">Campaign performance</h2>
<div class="mt-4 h-64">
<canvas
id="campaign-performance-bubble-chart"
role="img"
aria-label="Campaign performance, bubble chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Campaign spend, conversions, and reach
</caption>
<thead>
<tr>
<th scope="col">Campaign</th>
<th scope="col">Spend ($)</th>
<th scope="col">Conversions</th>
<th scope="col">Reach index</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Search</th>
<td>3,200</td>
<td>18,000</td>
<td>22</td>
</tr>
<tr>
<th scope="row">Social</th>
<td>2,400</td>
<td>9,500</td>
<td>16</td>
</tr>
<tr>
<th scope="row">Display</th>
<td>1,800</td>
<td>5,200</td>
<td>12</td>
</tr>
<tr>
<th scope="row">Email</th>
<td>900</td>
<td>7,800</td>
<td>14</td>
</tr>
<tr>
<th scope="row">Video</th>
<td>2,600</td>
<td>6,100</td>
<td>18</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const campaignPerformanceBubbleChartCanvas = document.getElementById(
'campaign-performance-bubble-chart',
)
new Chart(campaignPerformanceBubbleChartCanvas, {
type: 'bubble',
data: {
datasets: [
{
label: 'Search',
data: [{ x: 3200, y: 18000, r: 22 }],
backgroundColor: 'rgba(79, 70, 229, 0.7)',
hoverBackgroundColor: '#4f46e5',
},
{
label: 'Social',
data: [{ x: 2400, y: 9500, r: 16 }],
backgroundColor: 'rgba(16, 185, 129, 0.7)',
hoverBackgroundColor: '#10b981',
},
{
label: 'Display',
data: [{ x: 1800, y: 5200, r: 12 }],
backgroundColor: 'rgba(245, 158, 11, 0.7)',
hoverBackgroundColor: '#f59e0b',
},
{
label: 'Email',
data: [{ x: 900, y: 7800, r: 14 }],
backgroundColor: 'rgba(244, 63, 94, 0.7)',
hoverBackgroundColor: '#f43f5e',
},
{
label: 'Video',
data: [{ x: 2600, y: 6100, r: 18 }],
backgroundColor: 'rgba(14, 165, 233, 0.7)',
hoverBackgroundColor: '#0ea5e9',
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#4b5563' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${tooltipItem.raw.x} spend, ${tooltipItem.raw.y} conversions`,
},
},
},
scales: {
x: {
title: { display: true, text: 'Spend ($)', color: '#4b5563' },
grid: { color: '#e5e7eb' },
ticks: { color: '#4b5563' },
},
y: {
title: { display: true, text: 'Conversions', color: '#4b5563' },
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">Campaign performance</h2>
<div class="mt-4 h-64">
<canvas
id="campaign-performance-bubble-chart"
role="img"
aria-label="Campaign performance, bubble chart"
></canvas>
</div>
<table class="sr-only">
<caption>
Campaign spend, conversions, and reach
</caption>
<thead>
<tr>
<th scope="col">Campaign</th>
<th scope="col">Spend ($)</th>
<th scope="col">Conversions</th>
<th scope="col">Reach index</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Search</th>
<td>3,200</td>
<td>18,000</td>
<td>22</td>
</tr>
<tr>
<th scope="row">Social</th>
<td>2,400</td>
<td>9,500</td>
<td>16</td>
</tr>
<tr>
<th scope="row">Display</th>
<td>1,800</td>
<td>5,200</td>
<td>12</td>
</tr>
<tr>
<th scope="row">Email</th>
<td>900</td>
<td>7,800</td>
<td>14</td>
</tr>
<tr>
<th scope="row">Video</th>
<td>2,600</td>
<td>6,100</td>
<td>18</td>
</tr>
</tbody>
</table>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js"></script>
<script>
const campaignPerformanceBubbleChartCanvas = document.getElementById(
'campaign-performance-bubble-chart',
)
new Chart(campaignPerformanceBubbleChartCanvas, {
type: 'bubble',
data: {
datasets: [
{
label: 'Search',
data: [{ x: 3200, y: 18000, r: 22 }],
backgroundColor: 'rgba(129, 140, 248, 0.7)',
hoverBackgroundColor: '#818cf8',
},
{
label: 'Social',
data: [{ x: 2400, y: 9500, r: 16 }],
backgroundColor: 'rgba(52, 211, 153, 0.7)',
hoverBackgroundColor: '#34d399',
},
{
label: 'Display',
data: [{ x: 1800, y: 5200, r: 12 }],
backgroundColor: 'rgba(251, 191, 36, 0.7)',
hoverBackgroundColor: '#fbbf24',
},
{
label: 'Email',
data: [{ x: 900, y: 7800, r: 14 }],
backgroundColor: 'rgba(251, 113, 133, 0.7)',
hoverBackgroundColor: '#fb7185',
},
{
label: 'Video',
data: [{ x: 2600, y: 6100, r: 18 }],
backgroundColor: 'rgba(56, 189, 248, 0.7)',
hoverBackgroundColor: '#38bdf8',
},
],
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom',
labels: { color: '#9ca3af' },
},
tooltip: {
callbacks: {
label: (tooltipItem) =>
`${tooltipItem.dataset.label}: $${tooltipItem.raw.x} spend, ${tooltipItem.raw.y} conversions`,
},
},
},
scales: {
x: {
title: { display: true, text: 'Spend ($)', color: '#9ca3af' },
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#9ca3af' },
},
y: {
title: { display: true, text: 'Conversions', color: '#9ca3af' },
beginAtZero: true,
grid: { color: 'rgba(255, 255, 255, 0.1)' },
ticks: { color: '#9ca3af' },
},
},
},
})
</script>Plugins: chart.js