CodeIgniter 4 Apexcharts Example Tutorial

             ApexCharts is loaded with powerful features to fulfill your data-visualization needs.

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

Inside this article, we will see the concept of CodeIgniter 4 Apex Chart Integration

3 Create / Install a Codeigniter 4 Project

3.1 Install Codeigniter 4 Project

First, make sure your computer has a composer.
Use the following command to install new Codeigniter Project.

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 events 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

Edit the migration file to define the table structure:
    
<?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 events 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

Create a controller to handle Chart process:

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 a View

Create the index.php view file in app/Views/ to generate the dynamic Apexchart:

   <!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, define routes for the FullCalenderController controller:


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

Use the following command to Test the App.

php spark serve

Visit the URL http://localhost:8080/users

11 Conclusion

This guide walked you through How to Create Dynamic Charts with Filter Options in ApexCharts Using CodeIgniter 4.

Tags