CodeIgniter 4 Apexcharts Example Tutorial

             ApexCharts is a powerful JavaScript library designed to create interactive and visually appealing charts. It supports bar, line, pie charts, and more, offering customization, animation, and filtering options for enhanced data visualization. This guide will help you create a dynamic bar chart in CodeIgniter and explore various charts with CodeIgniter.

Codeigniter 4 ApexCharts: Create Dynamic Charts with Filter Options in ApexCharts

Table Of Content

1 Prerequisites

1.) PHP version of >= 8.2
2.) Composer
3.) Mysql

2 Introduction

In this tutorial, we will explore how to create a dynamic bar chart in CodeIgniter and visualize user data dynamically. Additionally, we will cover how to implement filter options for better user interaction.

3 How to Integrate ApexChart with Filter Options in CodeIgniter 4

3.1 Install Codeigniter 4 Project

Make sure Composer is installed, then run:

composer create-project codeigniter4/appstarter ci-4-chart-app

Then, navigate to your project directory:

cd ci-4-chart-app

3.2 Configure Environment and MySql Database

Rename the env file to .env and set the development mode in the .env file also configure mysql:

# CI_ENVIRONMENT = production
CI_ENVIRONMENT = development


DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ci4_charts
DB_USERNAME=root
DB_PASSWORD=

4 Create Migration and Model

Create a migration for the users table and a model to manage data:

php spark make:model User

Edit app/Models/User.php to configure the model:

<?php
namespace App\Models;

use CodeIgniter\Model;

class Event extends Model
{
    protected $table = 'users';
    protected $primaryKey = 'id';
    protected $allowedFields = ['name','email', 'created_at','updated_at'];
}

Create a migration file for the users table:

php spark make:migration AddUser

Define the table structure and migrate:
    
<?php
namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddUser extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type' => 'BIGINT',
                'constraint' => 255,
                'unsigned' => true,
                'auto_increment' => true
            ],
            'name' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
            'email' => [
                'type' => 'longtext'
            ],
            'created_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
            'updated_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
        ]);
        $this->forge->addPrimaryKey('id');
        $this->forge->createTable('users');
    }

    public function down()
    {
        $this->forge->dropTable('users');
    }
}

Run the migration:

php spark migrate

5 Create Database Seeder

For seeding test data in the users table, use the Seeder class:

php spark make:seeder UserSeeder

Inside the UserSeeder.php file, use the Faker library to generate fake data:

<?php
namespace App\Database\Seeds;

use CodeIgniter\Database\Seeder;
use CodeIgniter\I18n\Time;
use App\Models\User;
class UserSeeder extends Seeder
{
    public function run()
    {
        $user = new User;
        $faker = \Faker\Factory::create();

        for ($i = 0; $i < 100; $i++) {
          $user->save(
                [
                    'name'        =>    $faker->name,
                    'email'       =>    $faker->email,
                    'created_at'  =>    Time::createFromTimestamp($faker->unixTime()),
                    'updated_at'  =>    Time::now()
                ]
            );
        }
    }
}


Run this below command to insert the data.

php spark db:seed UserSeeder

6 Create New Controller - UserController

Handle chart logic in UserController:

php spark make:controller UserController

In app/Controllers/UserController.php, define the index and filterData function:

<?php
namespace App\Controllers;

use App\Controllers\BaseController;
use CodeIgniter\HTTP\ResponseInterface;
use App\Models\User;


class UserController extends BaseController
{
    public function __construct()
    {
        $this->userModel = new User();
    }
    public function index() {

        $charts=$this->userModel->select("DATE_FORMAT(created_at,'%m') as month,count(*) as sum")->where("DATE_FORMAT(created_at,'%Y')","2024")->groupBy("month")->findAll();
        $chart_data=array();
        foreach($charts as $chart)
            {
                $temp=array();
                $temp['x']='2024-'.$chart['month'];
                $temp['y']=$chart['sum'];
                $chart_data[]=$temp;
            }
            $data['charts']=$chart_data;
        return view('index', $data);
    }
   function filterData()
   {

   $year=$this->request->getPost('year');
    $charts=$this->userModel->select("DATE_FORMAT(created_at,'%m') as month,count(*) as sum")->where("DATE_FORMAT(created_at,'%Y')",$year)->groupBy("month")->findAll();
   
    $chart_data=array();
    foreach($charts as $chart)
        {
            $temp=array();
            $temp['x']=$year.'-'.$chart['month'];
            $temp['y']=$chart['sum'];
            $chart_data[]=$temp;
        }
       $data['charts']=$chart_data;
        echo  json_encode($data);
   }
}
?>

7 Create Views for Dynamic Charts

In app/Views/index.php :

   <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ApexChat with Filter in CodeIgniter 4</title>
     <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.1/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.datatables.net/1.11.4/css/dataTables.bootstrap5.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<style>
  .showLeft {
  background-color: white !important;
  border: 1px solid white !important;
  text-shadow: white !important;
  color: black !important;
  padding: 10px;
}
.icons li {
  background: none repeat scroll 0 0 black;
  height: 7px;
  width: 7px;
  line-height: 0;
  list-style: none outside none;
  margin-right: 15px;
  margin-top: 3px;
  vertical-align: top;
  border-radius: 50%;
  pointer-events: none;
}
.btn-left {
  left: 0.4em;
}
.btn-right {
  right: 0.4em;
}
.btn-left,
.btn-right {
  position: absolute;
  top: 0.24em;
}
.dropbtn {
  background-color: #4caf50;
  position: fixed;
  color: white;
  font-size: 16px;
  border: none;
  cursor: pointer;
}
.dropbtn:hover,
.dropbtn:focus {
  background-color: #3e8e41;
}
.dropdown {
  position: absolute;
  display: inline-block;
  right: 0.4em;
}
.dropdown-content {
  display: none;
  position: relative;
  margin-top: 60px;
  background-color: #f9f9f9;
  min-width: 160px;
  overflow: auto;
  box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
  z-index: 1;
}

.dropdown-content a {
  color: black;
  padding: 12px 16px;
  text-decoration: none;
  display: block;
}

.dropdown a:hover {
  background-color: #f1f1f1;
}

.show {
  display: block;
}

</style>
</head>
<body>
    <div class="container">
      <!-- three dot menu -->
  <div class="dropdown">
    <!-- three dots -->
    <ul class="dropbtn icons btn-right showLeft" onclick="showDropdown()">
      <li></li>
      <li></li>
      <li></li>
    </ul>
    <!-- menu -->
    <div id="myDropdown" class="dropdown-content">
      <a href="javascript:void(0)" class="chart_filter" data-value="2024">This Year</a>
      <a  href="javascript:void(0)" class="chart_filter" data-value="2023">Last Year</a>
    </div>
  </div>
       <div id="chart"></div>
    </div>

    <script>
     

function showDropdown() {
  document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown if the user clicks outside of it
window.onclick = function(event) {
  if (!event.target.matches(".dropbtn")) {
    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains("show")) {
        openDropdown.classList.remove("show");
      }
    }
  }
};

        $(document).ready(function() {
          
            var options = {
          series: [{
          name: 'Profile Created',
          data: [44, 55, 41, 67, 22, 43]
        }],
          chart: {
          type: 'bar',
          height: 350,
          stacked: true,
          toolbar: {
            show: true
          },
          zoom: {
            enabled: true
          }
        },
        responsive: [{
          breakpoint: 480,
          options: {
            legend: {
              position: 'bottom',
              offsetX: -10,
              offsetY: 0
            }
          }
        }],
        plotOptions: {
          bar: {
            horizontal: false,
            borderRadius: 10,
            borderRadiusApplication: 'end', // 'around', 'end'
            borderRadiusWhenStacked: 'last', // 'all', 'last'
            dataLabels: {
              total: {
                enabled: true,
                style: {
                  fontSize: '13px',
                  fontWeight: 900
                }
              }
            }
          },
        },
        xaxis: {
          type: 'datetime',
          categories: ['01/01/2024 GMT', '01/02/2024 GMT', '01/03/2024 GMT', '01/04/2024 GMT',
            '01/05/2024 GMT', '01/06/2024 GMT'
          ],
        },
        legend: {
          position: 'right',
          offsetY: 40
        },
        fill: {
          opacity: 1
        }
        };

        var chart = new ApexCharts(document.querySelector("#chart"), options);
        chart.render();
        chart.updateSeries([{
												data: <?php echo json_encode($charts);?>
											}]);

    $(".chart_filter").on("click", function(){
	  
     $.ajax({
                url: "search",
                method: 'POST',
                data: {'year':$(this).data("value")},
                dataType: 'json',
                success: function(response) {
                  chart.updateSeries([{
												data: response.charts
											}]);
       
                }
          });

    });
                   
        });

       
    </script>
</body>
</html>


8 Define a Route

In app/Config/Routes.php:


use CodeIgniter\Router\RouteCollection;

/**
 * @var RouteCollection $routes
 */
$routes->get('/', 'Home::index');
$routes->get('users', 'UserController::index');
$routes->post('search', 'UserController::filterData');

9 Folder Structure

10 Run Web Server to Test the App

Serve the project:

php spark serve

Access it in your browser: http://localhost:8080/users

11 Conclusion

You’ve successfully learned how to integrate a dynamic bar chart in CodeIgniter using ApexCharts and implemented filter options to enhance visualization. These charts with CodeIgniter provide interactive, customizable solutions for displaying data efficiently.

Tags