Laravel 11 Apexcharts Example Tutorial

             ApexCharts is a JavaScript library used for creating interactive and visually appealing charts on websites. It supports various chart types like bar, line, and pie, and provides options to customize their appearance, add animations, and enable interactivity. With its user-friendly design, ApexCharts makes data visualization straightforward and aesthetically pleasing.

Laravel 11 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 guide, we'll demonstrate how to integrate ApexChart with filter options in Laravel 11. You'll learn to create dummy user records and display a dynamic line chart featuring the months of the current year. Follow these steps to add powerful chart functionality to your Laravel 11 application.

3 Create / Install a Laravel Project

3.1 Install Laravel Project

Ensure Composer is installed and use the command:

composer create-project laravel/laravel laravel11-chart-app

Navigate to your project directory:

cd laravel11-chart-app

3.2 Configure MySql Database

Open the .env file to include database credentials:

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

4 Create Migration

Generate a migration for the users table:

    php artisan make:migration create_users_table

Edit the migration file to define the table structure, then run:
    
<?php
se Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

        Schema::create('password_reset_tokens', function (Blueprint $table) {
            $table->string('email')->primary();
            $table->string('token');
            $table->timestamp('created_at')->nullable();
        });

        Schema::create('sessions', function (Blueprint $table) {
            $table->string('id')->primary();
            $table->foreignId('user_id')->nullable()->index();
            $table->string('ip_address', 45)->nullable();
            $table->text('user_agent')->nullable();
            $table->longText('payload');
            $table->integer('last_activity')->index();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('users');
        Schema::dropIfExists('password_reset_tokens');
        Schema::dropIfExists('sessions');
    }
};


Run the migration:

php artisan migrate

5 Create Model

Define the User model in app/Models/User.php. Use this model to work with the users table.
    
<?php
namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    /** @use HasFactory<\Database\Factories\UserFactory> */
    use HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var list
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var list
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array
     */
    protected function casts(): array
    {
        return [
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
        ];
    }
}


6 Create Factory Class

Create a factory class:

php artisan make:factory UserFactory

Update the factory to generate sample data and seed the database:
    
<?php
namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use Illuminate\Support\Carbon;


/**
 * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
 */
class UserFactory extends Factory
{
    /**
     * The current password being used by the factory.
     */
    protected static ?string $password;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition(): array
    {
        return [
            'name' => fake()->name(),
            'email' => fake()->unique()->safeEmail(),
            'email_verified_at' => now(),
            'password' => static::$password ??= Hash::make('password'),
            'remember_token' => Str::random(10),
            'created_at'  =>    Carbon::createFromTimestamp(fake()->unixTime()),
        ];
    }

    /**
     * Indicate that the model's email address should be unverified.
     */
    public function unverified(): static
    {
        return $this->state(fn (array $attributes) => [
            'email_verified_at' => null,
        ]);
    }
}

To generate 100 dummy records, use:

php artisan tinker


User::factory()->count(100)->create()

7 Create Controller (UserController)

Create a UserController for chart data handling:

php artisan make:controller UserController

In the controller, implement index and filterData methods to populate the charts dynamically. This allows you to explore how to create dynamic charts with filter options in ApexCharts using Laravel 11.

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class UserController extends Controller
{
    public function index(Request $request)
    {
        $charts_data = User::selectRaw('count(id) AS data,MONTH(created_at) AS month')->whereYear('created_at',"2024")->groupBy('month')->get();
       
        $chart_data=array();
        foreach($charts_data as $chart)
            {
                $temp=array();
                $temp['x']='2024-'.$chart['month'];
                $temp['y']=$chart['data'];
                $chart_data[]=$temp;
            }
         $charts=$chart_data;   
        return view('index', compact('charts'));
    }
    function filterData(Request $request)
   {

   $year=$request->input('year');
    $charts=User::selectRaw('count(id) AS data,MONTH(created_at) AS month')->whereYear('created_at',$year)->groupBy('month')->get();
   
    $chart_data=array();
    foreach($charts as $chart)
        {
            $temp=array();
            $temp['x']=$year.'-'.$chart['month'];
            $temp['y']=$chart['data'];
            $chart_data[]=$temp;
        }
        $data['charts']=$chart_data;
        return $data;
   }
}
?>

8 Create view (Blade)

Create resources/views/index.blade.php to render the chart. Use ApexCharts for visualizing user data interactively.
    
   <!DOCTYPE html>
<html>
<head>
    <title>ApexChat with Filter in Laravel 11 : A Step-by-Step Tutorial - getsamplecode.com</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>

       
</body>
       
<script type="text/javascript">
     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"), "_token": "{{ csrf_token() }}",},
                     dataType: 'json',
                     success: function(response) {
                       chart.updateSeries([{
                                                     data: response.charts
                                                 }]);
            
                     }
               });
     
         });
                        
             });
     
            
         
</script>
</html>

    

9 Define Routes

Add routes in routes/web.php for loading and filtering chart data.

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;


Route::get('/', function () {
    return view('welcome');
});

Route::get('users',[UserController::class,'index'])->name('users.index');
Route::post('search',[UserController::class,'filterData'])->name('users.search');

10 Folder Structure

11 Run Laravel Server to Test the App

Start the Laravel server:

php artisan serve

Visit the app to view dynamic charts with filter options integrated seamlessly.

12 Conclusion

You've now learned how to integrate ApexChart with filter options in Laravel 11 and create dynamic charts using this powerful JavaScript library. Implementing these features allows your application to offer enhanced data visualization capabilities.

Tags