ApexCharts.js
Modern, Interactive Charts for Your Data Visualization Needs
ApexCharts is a modern JavaScript charting library that helps developers create beautiful, interactive visualizations for web pages. With a focus on smooth animations, responsive design, and advanced features, ApexCharts makes data visualization both powerful and accessible.
In SmartAdmin, ApexCharts is integrated with a custom wrapper (apexchartsWrapper.js
) that ensures visual consistency with the rest of the application and enhances the library with SmartAdmin-specific features.
Installation
ApexCharts is included in the SmartAdmin theme with a custom wrapper. Here's how to set it up:
1. Basic Setup (Already Included)
// The following files are already included in the SmartAdmin theme:
// - apexcharts.esm.js (Original ApexCharts library)
// - apexchartsWrapper.js (SmartAdmin wrapper)
2. Initialize a Chart
// Import the SmartAdmin ApexCharts wrapper
import SmartApexCharts from './pathTo/apexchart/apexchartsWrapper.js';
document.addEventListener('DOMContentLoaded', function() {
// Create a basic bar chart
const options = {
chart: {
type: 'bar',
height: 350
},
series: [{
name: 'Sales',
data: [30, 40, 45, 50, 49, 60, 70, 91, 125]
}],
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']
}
};
const chart = new SmartApexCharts(
document.querySelector('#my-chart'),
options
);
chart.render();
});
HTML Structure
<!-- Basic Chart Container -->
<div id="my-chart"></div>
<!-- Panel-Based Chart Container (Recommended) -->
<div id="panel-1" class="panel">
<div class="panel-hdr">
<h2>Sales <span class="fw-300"><i>Overview</i></span></h2>
<div class="panel-toolbar">
<button class="btn btn-panel" data-action="panel-collapse">
<!-- Panel controls -->
</button>
</div>
</div>
<div class="panel-container show">
<div class="panel-content">
<div id="my-chart"></div>
</div>
</div>
</div>
- Always use the
SmartApexCharts
class from the wrapper instead of the originalApexCharts
to ensure proper integration with SmartAdmin. - The wrapper automatically applies SmartAdmin styling and prevents CSS injection from the original library.
- For more advanced documentation, refer to the official ApexCharts documentation.
SmartAdmin Wrapper
SmartAdmin includes a custom wrapper for ApexCharts that enhances the library with theme-specific features. The wrapper is defined in apexchartsWrapper.js
.
// Excerpt from the ApexCharts wrapper
class SmartApexCharts extends OriginalApexCharts {
// Icon mapping for toolbar
static iconMap = {
'apexcharts-zoomin-icon': 'plus-circle',
'apexcharts-zoomout-icon': 'minus-circle',
'apexcharts-zoom-icon': 'plus',
'apexcharts-pan-icon': 'move',
'apexcharts-reset-icon': 'refresh-ccw',
'apexcharts-menu-icon': 'menu'
};
constructor(el, options) {
// Ensure options object exists
options = options || {};
options.chart = options.chart || {};
// Global styling defaults
const defaults = {
chart: {
fontFamily: 'inherit',
disableCssInjection: true
},
title: {
style: {
color: window.colorMap.bootstrapVars.bodyColor.hex
}
},
// ... additional defaults
};
// Merge options with defaults
options = SmartApexCharts.deepMerge(defaults, options);
// Call parent constructor with merged options
super(el, options);
// Style observer and other enhancements
// ...
}
// Replace toolbar icons with custom sprite system icons
_replaceToolbarIcons(toolbar) {
// ... icon replacement code
}
}
Chart Configuration
ApexCharts offers extensive configuration options. Here are some common chart types and configurations:
Bar Chart
const barOptions = {
chart: {
type: 'bar',
height: 350
},
plotOptions: {
bar: {
horizontal: false,
columnWidth: '55%',
borderRadius: 4
}
},
dataLabels: {
enabled: false
},
stroke: {
show: true,
width: 2,
colors: ['transparent']
},
series: [{
name: 'Net Profit',
data: [44, 55, 57, 56, 61, 58, 63]
}, {
name: 'Revenue',
data: [76, 85, 101, 98, 87, 105, 91]
}],
xaxis: {
categories: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
fill: {
opacity: 1
},
tooltip: {
y: {
formatter: function (val) {
return "$ " + val + " thousands"
}
}
}
};
const barChart = new SmartApexCharts(
document.querySelector('#bar-chart'),
barOptions
);
barChart.render();
Line Chart
const lineOptions = {
chart: {
type: 'line',
height: 350,
zoom: {
enabled: true
}
},
series: [{
name: "Desktops",
data: [10, 41, 35, 51, 49, 62, 69, 91, 148]
}],
title: {
text: 'Product Trends by Month',
align: 'left'
},
grid: {
row: {
colors: ['#f3f3f3', 'transparent'],
opacity: 0.5
}
},
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']
}
};
const lineChart = new SmartApexCharts(
document.querySelector('#line-chart'),
lineOptions
);
lineChart.render();
Area Chart
const areaOptions = {
chart: {
type: 'area',
height: 350,
stacked: true
},
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth'
},
series: [{
name: 'South',
data: [31, 40, 28, 51, 42, 109, 100]
}, {
name: 'North',
data: [11, 32, 45, 32, 34, 52, 41]
}],
xaxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul']
},
tooltip: {
x: {
format: 'dd/MM/yy HH:mm'
}
},
fill: {
type: 'gradient',
gradient: {
shadeIntensity: 1,
opacityFrom: 0.7,
opacityTo: 0.9,
stops: [0, 90, 100]
}
}
};
const areaChart = new SmartApexCharts(
document.querySelector('#area-chart'),
areaOptions
);
areaChart.render();
Pie Chart
const pieOptions = {
chart: {
type: 'pie',
height: 350
},
series: [44, 55, 13, 43, 22],
labels: ['Team A', 'Team B', 'Team C', 'Team D', 'Team E'],
responsive: [{
breakpoint: 480,
options: {
legend: {
position: 'bottom'
}
}
}]
};
const pieChart = new SmartApexCharts(
document.querySelector('#pie-chart'),
pieOptions
);
pieChart.render();
SmartAdmin Integration
For optimal integration with SmartAdmin, consider these tips:
Using Theme Colors
Use SmartAdmin color variables for consistent styling:
// Use SmartAdmin color variables
const options = {
// ... other options
colors: [
'var(--primary-500)',
'var(--success-500)',
'var(--warning-500)',
'var(--danger-500)',
'var(--info-500)'
],
fill: {
colors: [
'var(--primary-300)',
'var(--success-300)',
'var(--warning-300)',
'var(--danger-300)',
'var(--info-300)'
]
}
};
Responsive Configuration
Configure charts to be responsive based on screen size:
const options = {
// ... other options
chart: {
height: 350,
type: 'line',
animations: {
enabled: true,
easing: 'easeinout',
speed: 800
},
toolbar: {
show: true
},
zoom: {
enabled: true
},
responsive: [{
breakpoint: 576,
options: {
chart: {
height: 250,
toolbar: {
show: false
}
},
legend: {
position: 'bottom',
offsetY: 0
}
}
}]
}
};
Dark Mode Compatibility
Make your charts compatible with both light and dark themes:
// Check if dark mode is active
const isDarkMode = document.documentElement.classList.contains('theme-dark');
const options = {
// ... other options
chart: {
foreColor: isDarkMode ? '#ffffff' : '#373a3c'
},
theme: {
mode: isDarkMode ? 'dark' : 'light'
},
tooltip: {
theme: isDarkMode ? 'dark' : 'light'
}
};
// Listen for theme changes if needed
document.addEventListener('themeChanged', function(e) {
const isDark = e.detail.isDark;
chart.updateOptions({
chart: {
foreColor: isDark ? '#ffffff' : '#373a3c'
},
theme: {
mode: isDark ? 'dark' : 'light'
},
tooltip: {
theme: isDark ? 'dark' : 'light'
}
});
});
Advanced Features
API Methods
// Get a reference to the chart
const chart = new SmartApexCharts(element, options);
chart.render();
// Update series data
chart.updateSeries([{
name: 'Sales',
data: [40, 55, 65, 11, 23, 44, 55, 75, 88]
}]);
// Update options
chart.updateOptions({
title: {
text: 'Updated Title'
},
colors: ['var(--danger-500)']
});
// Add data point
chart.appendData([{
data: [20]
}]);
// Toggle series visibility
chart.toggleSeries('Series Name');
// Show/hide specific data point's tooltip
chart.toggleDataPointSelection(2, 0);
// Reset zoom
chart.resetSeries();
// Destroy the chart
chart.destroy();
Dynamic Data Updates
// Create a chart with real-time data updates
const options = {
chart: {
type: 'line',
height: 350,
animations: {
enabled: true,
easing: 'linear',
dynamicAnimation: {
speed: 1000
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
series: [{
name: 'Server Load',
data: [10, 15, 12, 14, 16, 18, 15, 17, 14, 13]
}],
stroke: {
curve: 'smooth',
width: 3
},
xaxis: {
categories: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00']
},
markers: {
size: 0
}
};
const chart = new SmartApexCharts(
document.querySelector('#real-time-chart'),
options
);
chart.render();
// Update data every 1 second
setInterval(function() {
// Generate new data point
const newValue = Math.floor(Math.random() * 10) + 10;
// Get current time for x-axis label
const now = new Date();
const timeLabel = now.getHours() + ':' + (now.getMinutes() < 10 ? '0' : '') + now.getMinutes();
// Update chart
chart.updateSeries([{
data: [...chart.w.globals.series[0].slice(1), newValue]
}]);
chart.updateOptions({
xaxis: {
categories: [...chart.w.globals.xaxis.categories.slice(1), timeLabel]
}
});
}, 1000);
Mixed Chart Types
const mixedOptions = {
chart: {
height: 350,
type: 'line'
},
series: [{
name: 'Website',
type: 'column',
data: [440, 505, 414, 671, 227, 413, 201, 352, 752, 320, 257, 160]
}, {
name: 'Social Media',
type: 'line',
data: [23, 42, 35, 27, 43, 22, 17, 31, 22, 22, 12, 16]
}],
stroke: {
width: [0, 4]
},
title: {
text: 'Traffic Sources'
},
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
xaxis: {
type: 'category'
},
yaxis: [{
title: {
text: 'Website Visits'
}
}, {
opposite: true,
title: {
text: 'Social Media'
}
}]
};
const mixedChart = new SmartApexCharts(
document.querySelector('#mixed-chart'),
mixedOptions
);
mixedChart.render();
Troubleshooting
- Chart not rendering? Ensure the container element exists in the DOM before initializing.
- Colors not applying? Make sure CSS variables are properly defined and accessible.
- Icons missing in toolbar? Verify the SmartApexCharts wrapper is being used instead of the original library.
- Custom styles not working? Check that you're not overriding the wrapper's style management.
Debugging Techniques
// Debug chart initialization
try {
const chart = new SmartApexCharts(
document.querySelector('#chart'),
options
);
chart.render();
} catch (error) {
console.error('Chart initialization error:', error);
}
// Check if container exists
const container = document.querySelector('#chart');
if (!container) {
console.error('Chart container not found');
return;
}
// Verify series data
console.log('Chart series data:', options.series);
// Force explicit dimensions if auto-sizing issues
const options = {
chart: {
height: 350,
width: '100%',
background: '#f8f9fa', // Visible background to check rendering
},
// ...other options
};
Common Error Fixes
// Fix for empty or null data
const validateData = (data) => {
if (!data || !Array.isArray(data)) {
return [0]; // Default fallback value
}
// Replace null/undefined values with 0
return data.map(val => val === null || val === undefined ? 0 : val);
};
const options = {
// ...other options
series: [{
name: 'Sales',
data: validateData(salesData)
}]
};
// Fix for charts in hidden elements (tabs, modals)
document.querySelector('.nav-tabs').addEventListener('shown.bs.tab', function (e) {
// Redraw charts in newly visible tab
const tabId = e.target.getAttribute('href');
const charts = document.querySelectorAll(tabId + ' .apexchart');
charts.forEach(chart => {
if (chart.__smartChart) {
chart.__smartChart.render();
}
});
});
Further Resources
For more advanced usage and detailed API documentation, refer to these resources: