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.

Pro Tip: SmartAdmin's ApexCharts wrapper prevents CSS injection from the original library, ensuring that only your theme's styles are used, and adds custom icon support using the SmartAdmin icon system.

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>
Important:
  • Always use the SmartApexCharts class from the wrapper instead of the original ApexCharts 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
    }
}
Pro Tip: The SmartAdmin wrapper ensures that charts automatically adapt to your theme's color scheme and maintains a consistent UI across your application.

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

Common Issues:
  • 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: