Charts
Charts drawn with ApexCharts. Import the components from @/afcl, see AdminForth Components Library.
Bar Chart
Under the hood AdminForth uses MIT-licensed ApexCharts. It has very rich variety of options, you can pass
any of native settings to options prop. Here we will only show some basics.
color of a series is optional: series without it take the chart palette colors in order, so several bar charts on one page stay consistent.
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
}"
/>
Y-axis labels
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
yaxis: {
stepSize: 1, // needed if your data is integer
labels: {
show: true,
style: {
fontFamily: 'Inter, sans-serif',
cssClass: 'text-xs font-normal fill-gray-500 dark:fill-gray-400'
}
}
}
}"
/>
X-axis labels and formatting labels
import { BarChart } from '@/afcl'
import dayjs from 'dayjs'
<BarChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
xaxis: {
labels: {
show: true,
formatter: function (value) {
return dayjs(value).format('DD MMM');
},
style: {
fontFamily: 'Inter, sans-serif',
cssClass: 'text-xs font-normal fill-gray-500 dark:fill-gray-400'
}
}
}
}"
/>
Grid
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
grid: {
show: true,
borderColor: 'rgba(0, 0, 0, 0.1)',
strokeDashArray: 4,
position: 'back',
xaxis: {
lines: {
show: true
}
},
yaxis: {
lines: {
show: true
}
}
}
}"
/>
Data labels
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
dataLabels: {
formatter: function (value) {
return `⬆️ ${value}`;
},
enabled: true,
style: {
fontSize: '12px',
fontFamily: 'Inter, sans-serif',
}
}
}"
/>
Stacked bars and legend
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ countCars: 2, countBikes: 3, x: '02 Jun 2025'},
{ countCars: 5, countBikes: 1, x: '03 Jun 2025'},
{ countCars: 3, countBikes: 4, x: '04 Jun 2025'},
{ countCars: 4, countBikes: 2, x: '05 Jun 2025'},
{ countCars: 2, countBikes: 3, x: '06 Jun 2025'},
]"
:series="[
{
name: $t('Cars'),
fieldName: 'countCars',
color: '#4E79A7',
},
{
name: $t('Bikes'),
fieldName: 'countBikes',
color: '#F28E2B',
}
]"
:options="{
chart: {
height: 250,
stacked: true,
},
legend: {
show: true,
},
}"
/>
Horizontal bars
import { BarChart } from '@/afcl'
<BarChart
:data="[
{ countCars: 2, countBikes: 3, x: '02 Jun 2025'},
{ countCars: 5, countBikes: 1, x: '03 Jun 2025'},
{ countCars: 3, countBikes: 4, x: '04 Jun 2025'},
{ countCars: 4, countBikes: 2, x: '05 Jun 2025'},
{ countCars: 2, countBikes: 3, x: '06 Jun 2025'},
]"
:series="[
{
name: $t('Cars'),
fieldName: 'countCars',
color: '#4E79A7',
},
{
name: $t('Bikes'),
fieldName: 'countBikes',
color: '#F28E2B',
}
]"
:options="{
chart: {
height: 250,
type: 'bar',
},
plotOptions: {
bar: {
horizontal: true,
}
},
legend: {
show: true,
},
}"
/>
Area Chart
import { AreaChart } from '@/afcl'
<AreaChart
:data="[
{ count: 1, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[{
name: $t('Added apartments'),
fieldName: 'count',
color: '#4E79A7',
}]"
:options="{
chart: {
height: 250,
},
}"
/>
Multiple lines
import { AreaChart } from '@/afcl'
<AreaChart
:data="[
{ countCars: 2, countBikes: 3, x: '02 Jun 2025'},
{ countCars: 5, countBikes: 1, x: '03 Jun 2025'},
{ countCars: 3, countBikes: 4, x: '04 Jun 2025'},
{ countCars: 4, countBikes: 2, x: '05 Jun 2025'},
{ countCars: 2, countBikes: 3, x: '06 Jun 2025'},
]"
:series="[
{
name: $t('Cars'),
fieldName: 'countCars',
color: '#4E79A7',
},
{
name: $t('Bikes'),
fieldName: 'countBikes',
color: '#F28E2B',
}
]"
:options="{
chart: {
height: 250,
},
}"
/>
Stacked area
import { AreaChart } from '@/afcl'
<AreaChart
:data="[
{ countCars: 2, countBikes: 3, x: '02 Jun 2025'},
{ countCars: 5, countBikes: 1, x: '03 Jun 2025'},
{ countCars: 3, countBikes: 4, x: '04 Jun 2025'},
{ countCars: 4, countBikes: 2, x: '05 Jun 2025'},
{ countCars: 2, countBikes: 3, x: '06 Jun 2025'},
]"
:series="[
{
name: $t('Cars'),
fieldName: 'countCars',
color: '#4E79A7',
},
{
name: $t('Bikes'),
fieldName: 'countBikes',
color: '#F28E2B',
}
]"
:options="{
chart: {
height: 250,
stacked: true,
},
}"
/>
Data labels
import { AreaChart } from '@/afcl'
<AreaChart
:data="[
{ count: 2, x: '02 Jun 2025'},
{ count: 5, x: '03 Jun 2025'},
{ count: 3, x: '04 Jun 2025'},
{ count: 4, x: '05 Jun 2025'},
{ count: 2, x: '06 Jun 2025'},
]"
:series="[
{
name: $t('Cars'),
fieldName: 'count',
color: '#4E79A7',
},
]"
:options="{
chart: {
height: 250,
},
dataLabels: {
enabled: true,
style: {
fontSize: '12px',
fontFamily: 'Inter, sans-serif',
}
},
grid: {
padding: {
left: 10, // to fit the labels
right: 10,
},
},
}"
/>
Grid, x-axis and y-axis labels
See Bar Chart for details, the config is the same.
Pie Chart
Basic
import { PieChart } from '@/afcl'
<PieChart
:data="[
{ amount: 5, label: 'Cars'},
{ amount: 3, label: 'Bikes'},
{ amount: 2, label: 'Trucks'},
{ amount: 1, label: 'Boats'},
]"
:options="{
chart: {
height: 250,
},
}"
/>
Pie with data labels
import { PieChart } from '@/afcl'
<PieChart
:data="[
{ amount: 5, label: 'Cars'},
{ amount: 3, label: 'Bikes'},
{ amount: 2, label: 'Trucks'},
{ amount: 1, label: 'Boats'},
]"
:options="{
chart: {
height: 250,
},
dataLabels: {
enabled: true,
},
plotOptions: {
pie: {
dataLabels: {
offset: -10, // Moves labels closer to or further from the slices
minAngleToShowLabel: 10, // Ensures that small slices don't show labels
},
expandOnClick: true,
},
},
}"
/>
Donut Chart
import { PieChart } from '@/afcl'
<PieChart
:data="[
{ amount: 5, label: 'Cars'},
{ amount: 3, label: 'Bikes'},
{ amount: 2, label: 'Trucks'},
{ amount: 1, label: 'Boats'},
]"
:options="{
chart: {
height: 250,
type: 'donut',
},
}"
/>
Fill donut with total info
import { PieChart } from '@/afcl'
<PieChart
:data="[
{ amount: 5, label: 'Cars'},
{ amount: 3, label: 'Bikes'},
{ amount: 2, label: 'Trucks'},
{ amount: 1, label: 'Boats'},
]"
:options="{
chart: {
height: 250,
type: 'donut',
},
plotOptions: {
pie: {
donut: {
labels: {
total: {
show: true,
label: $t('Total wheels'),
formatter: () => `11`,
},
},
},
},
},
}"
/>
Radial bar chart
import { PieChart } from '@/afcl'
<PieChart
:data="[
{ amount: 80, label: 'Cars'},
{ amount: 50, label: 'Bikes'},
{ amount: 30, label: 'Trucks'},
{ amount: 70, label: 'Boats'},
]"
:options="{
chart: {
height: '300px',
width: '100%',
type: 'radialBar',
sparkline: {
enabled: true,
},
},
plotOptions: {
radialBar: {
track: {
background: '#E5E7EB',
},
dataLabels: {
name: {
offsetY: -10
},
value: {
offsetY: 2,
}
},
hollow: {
margin: 0,
size: '32%',
}
},
},
legend: {
show: true,
position: 'bottom',
},
}"
/>
Treemap Chart
This example is based on the ApexCharts treemap demo “color range”.
import { TreeMapChart } from '@/afcl'
const deltaToColor = (delta: number) => {
if (delta < -10) return '#B91C1C' // bright red
if (delta < 0) return '#EF4444' // red
if (delta <= 10) return '#22C55E' // green
return '#15803D' // very green
}
const formatDelta = (delta: number) => (delta > 0 ? `+${delta}%` : `${delta}%`)
const data = [
{ x: 'New Delhi', value: 218, delta: 12 },
{ x: 'Kolkata', value: 149, delta: -4 },
{ x: 'Mumbai', value: 184, delta: -14 },
{ x: 'Ahmedabad', value: 55, delta: 6 },
{ x: 'Bangalore', value: 84, delta: 9 },
{ x: 'Pune', value: 31, delta: -2 },
{ x: 'Chennai', value: 70, delta: 0 }
]
// Optional: precompute per-point color using delta
const dataWithColors = data.map((item) => ({
...item,
fillColor: deltaToColor(item.delta),
}))
const series = [
{ name: 'Desktops', fieldName: 'value' },
]
<TreeMapChart
:data="dataWithColors"
:series="series"
:options="{
chart: { height: 350 },
dataLabels: {
formatter: (text, { seriesIndex, dataPointIndex, w }) => {
const point = w?.config?.series?.[seriesIndex]?.data?.[dataPointIndex]
if (!point) return text
return `${text} ${formatDelta(point.delta)}`
},
},
plotOptions: {
treemap: {
distributed: false,
enableShades: false,
},
},
tooltip: {
y: {
formatter: (value, { seriesIndex, dataPointIndex, w }) => {
const point = w?.config?.series?.[seriesIndex]?.data?.[dataPointIndex]
if (!point) return value
return `${point.value} (${formatDelta(point.delta)})`
},
},
},
}"
/>
Mixed Chart
Basic
import { MixedChart } from '@/afcl'
<MixedChart
:data="[
{ x: '02 Jun 2025', avgPrice: 100, listedPrice: 100, unlistedPrice: 100},
{ x: '03 Jun 2025', avgPrice: 280, listedPrice: 130, unlistedPrice: 200},
{ x: '04 Jun 2025', avgPrice: 150, listedPrice: 90, unlistedPrice: 60},
{ x: '05 Jun 2025', avgPrice: 100, listedPrice: 100, unlistedPrice: 100},
{ x: '06 Jun 2025', avgPrice: 200, listedPrice: 290, unlistedPrice: 180},
{ x: '07 Jun 2025', avgPrice: 100, listedPrice: 100, unlistedPrice: 100},
]"
:series="[
{ name: $t('Avg Price'), fieldName: 'avgPrice', type: 'line', color: '#4E79A7' },
{ name: $t('Listed Price'), fieldName: 'listedPrice', type: 'column', color: '#F28E2B' },
{ name: $t('Unlisted Price'), fieldName: 'unlistedPrice', type: 'area', color: '#59A14F' },
]"
:options="{
chart: {
height: 350,
},
stroke: {
width: [6, 0, 6], // Line: 6px, Column: 0px (no border), Area: 6px
},
fill: {
opacity: [1, 0.85, 0.25], // Line: 1, Column: 0.85, Area: 0.25
},
}"
/>