Pie, Donut and Polar Area in JavaScript
Using ApexCharts with JavaScript
This Pie, Donut and Polar Area example uses ApexCharts.js directly in JavaScript, with no wrapper component.
Install it with npm install apexcharts, then mount the chart with new ApexCharts(element, options).render().
// Shared by the vanilla-js, React and Vue builds.
//
// Every channel's figure is the whole and one device's is the part. A pick
// is an ordinary update of highlightFilter.data, one value per slice; null
// clears it.
var CHANNELS = ['Organic', 'Paid search', 'Social', 'Email', 'Referral']
// Sums: a channel's sessions and orders are its devices' added up, so a
// device's part always fits inside the channel's slice.
var SESSIONS = [4200, 2600, 1900, 1100, 700]
var SESSIONS_BY_DEVICE = {
mobile: [2500, 1300, 1500, 400, 300],
desktop: [1400, 1100, 300, 600, 330],
tablet: [300, 200, 100, 100, 70],
}
var ORDERS = [300, 240, 160, 180, 120]
var ORDERS_BY_DEVICE = {
mobile: [140, 100, 100, 60, 45],
desktop: [130, 120, 45, 100, 60],
tablet: [30, 20, 15, 20, 15],
}
// Averages: a channel's average order value is its devices' revenue over
// their orders, so a device that spends more per order sits above it.
var ORDER_VALUE = [66, 85, 49, 76, 95]
var ORDER_VALUE_BY_DEVICE = {
mobile: [52, 70, 41, 60, 76],
desktop: [81, 98, 66, 84, 109],
tablet: [70, 85, 55, 80, 95],
}
function pickDevice(device) {
document.querySelectorAll('[data-device]').forEach(function (b) {
b.classList.toggle('active', b.getAttribute('data-device') === device)
})
// A pick is an ordinary update; null clears it.
ApexCharts.getChartByID('sessions').updateOptions({
highlightFilter: { data: device ? SESSIONS_BY_DEVICE[device] : null },
})
ApexCharts.getChartByID('orders').updateOptions({
highlightFilter: { data: device ? ORDERS_BY_DEVICE[device] : null },
})
ApexCharts.getChartByID('order-value').updateOptions({
highlightFilter: { data: device ? ORDER_VALUE_BY_DEVICE[device] : null },
})
}
function wireDevices() {
document.querySelectorAll('[data-device]').forEach(function (b) {
b.addEventListener('click', function () {
pickDevice(b.getAttribute('data-device'))
})
})
}
var options = {
series: SESSIONS,
chart: {
id: 'sessions',
type: 'donut',
height: 360,
toolbar: { show: false },
},
labels: CHANNELS,
colors: ['#0284c7', '#0f766e', '#f59e0b', '#e11d48', '#64748b'],
plotOptions: {
pie: {
donut: {
size: '58%',
labels: {
show: true,
value: {
formatter: function (v) {
return Number(v).toLocaleString()
},
},
total: {
show: true,
label: 'Sessions',
formatter: function (w) {
return w.globals.seriesTotals
.reduce(function (a, b) {
return a + b
}, 0)
.toLocaleString()
},
},
},
},
},
},
// No slice borders: the faded tints alone keep the slices apart.
stroke: { width: 0 },
dataLabels: { enabled: true },
legend: { position: 'bottom' },
title: { text: 'Sessions by channel', style: { fontSize: '13px' } },
tooltip: {
y: {
formatter: function (v) {
return Number(v).toLocaleString()
},
},
},
highlightFilter: { data: SESSIONS_BY_DEVICE.mobile },
}
var chart = new ApexCharts(document.querySelector('#chart'), options)
chart.render()
var options1 = {
series: ORDERS,
chart: {
id: 'orders',
type: 'polarArea',
height: 360,
toolbar: { show: false },
},
labels: CHANNELS,
colors: ['#0284c7', '#0f766e', '#f59e0b', '#e11d48', '#64748b'],
fill: { opacity: 0.85 },
stroke: { width: 0 },
legend: { position: 'bottom' },
title: { text: 'Orders by channel', style: { fontSize: '13px' } },
highlightFilter: { data: ORDERS_BY_DEVICE.mobile },
}
var chart1 = new ApexCharts(document.querySelector('#chart2'), options1)
chart1.render()
var options2 = {
series: ORDER_VALUE,
chart: {
id: 'order-value',
type: 'polarArea',
height: 360,
toolbar: { show: false },
},
labels: CHANNELS,
colors: ['#0284c7', '#0f766e', '#f59e0b', '#e11d48', '#64748b'],
fill: { opacity: 0.85 },
stroke: { width: 0 },
yaxis: {
labels: {
formatter: function (v) {
return '$' + v
},
},
},
legend: { position: 'bottom' },
title: {
text: 'Average order value by channel',
style: { fontSize: '13px' },
},
tooltip: {
y: {
formatter: function (v) {
return '$' + v
},
},
},
highlightFilter: { data: ORDER_VALUE_BY_DEVICE.mobile },
}
var chart2 = new ApexCharts(document.querySelector('#chart3'), options2)
chart2.render()
wireDevices()