What is Larapex?
It is a Laravel package that provides a wrapper to create apexcharts with only PHP.
What we are going to build?
An eloquent example to create charts from eloquent queries
Lets start
First create a project
In valet
laravel new yourproject
With composer
composer create-project --prefer-dist laravel/laravel yourproject
Then add the LarapexChart Package
Go to your app directory and in your console/terminal/cmd/bash type:
composer require arielmejiadev/larapex-charts
About the project.
It will simulate a TODO app with users that creates TODOS, this tutorial will show all commands and code in every file, so just follow the steps.
I will create a TODO model and assign TODOS to users (with default User model from a fresh Laravel installation).
To create a model with migrations, factories and seeders you can use the flag "a" with the make model artisan command:
php artisan make:model Todo -a
The TODO Model file content will look like this:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Todo extends Model
{
protected $fillable = [
'title', 'state', 'user_id'
];
protected $casts = [
'status' => 'boolean',
];
public function user()
{
return $this->belongsTo(User::class);
}
}
The User model file content:
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function todos()
{
return $this->hasMany(Todo::class);
}
}
The TODO migration file content:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateTodosTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('todos', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('title');
$table->boolean('status')->default(false);
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('todos');
}
}
TODO Factory content:
/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\Todo;
use App\User;
use Faker\Generator as Faker;
$factory->define(Todo::class, function (Faker $faker) {
return [
'title' => $faker->title,
'status' => $faker->boolean,
'user_id' => factory(User::class),
];
});
The TODO Seeder content:
use App\User;
use App\Todo;
use Illuminate\Database\Seeder;
class TodoSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$userOne = factory(User::class)->create([
'name' => 'John Doe'
]);
$userTwo = factory(User::class)->create([
'name' => 'Anne Doe'
]);
// TODOS by this month
factory(Todo::class, 15)->create([
'user_id' => $userOne,
'status' => true
]);
factory(Todo::class, 20)->create(['user_id' => $userOne]);
factory(Todo::class, 14)->create([
'user_id' => $userTwo,
'status' => true
]);
factory(Todo::class, 23)->create(['user_id' => $userTwo]);
// TODOS ONE MONTH AGO
factory(Todo::class, 5)->create([
'user_id' => $userOne,
'status' => true,
'created_at' => now()->subMonth()
]);
factory(Todo::class, 10)->create(['user_id' => $userOne, 'created_at' => now()->subMonth()]);
factory(Todo::class, 4)->create([
'user_id' => $userTwo,
'status' => true,
'created_at' => now()->subMonth()
]);
factory(Todo::class, 13)->create(['user_id' => $userTwo, 'created_at' => now()->subMonth()]);
// TODOS TWO MONTHS AGO
factory(Todo::class, 8)->create([
'user_id' => $userOne,
'status' => true,
'created_at' => now()->subMonths(2)
]);
factory(Todo::class, 16)->create(['user_id' => $userOne, 'created_at' => now()->subMonths(2)]);
factory(Todo::class, 14)->create([
'user_id' => $userTwo,
'status' => true,
'created_at' => now()->subMonths(2)
]);
factory(Todo::class, 23)->create(['user_id' => $userTwo, 'created_at' => now()->subMonths(2)]);
}
}
Add Todo seeder
Go to database/seeds/DatabaseSeeders.php and add the Todo seeder in run method as the code below:
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(TodoSeeder::class);
}
}
Now run the migrations
Go to your terminal/console/bash/cmd and type the next commands:
php artisan migrate
php artisan db:seed
Add a route
For this tutorial I will create a controller for charts, executing the artisan command:
php artisan make:controller ChartController
Then go to routes/web.php and add the next route:
Route::get('chart', ChartController::class);
- This controller will only have one method so in Route get method I can pass as second param the controller class and Laravel will load the __invoke method if it exists.
The controller content:
namespace App\Http\Controllers;
use App\Todo;
use App\User;
use ArielMejiaDev\LarapexCharts\Facades\LarapexChart;
use Illuminate\Http\Request;
class ChartController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function __invoke()
{
$user = User::first();
$userTwo = User::find(2);
$todosDone = Todo::where('user_id', $user->id)->whereStatus(true)->count();
$todosNotYet = Todo::where('user_id', $user->id)->whereStatus(false)->count();
$chart = LarapexChart::setTitle('Your Todos Stats')
->setLabels(['Done', 'Not Yet'])
->setDataset([$todosDone, $todosNotYet]);
return view('chart', compact('chart'));
}
}
Create a view file
Next is necesary to create a blade file to render the chart, go to resources/views and create a file called "chart.blade.php"
add the next code to your view:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Todos Chart</title>
</head>
<body>
{!! $chart->container() !!}
<script src="{{ $chart->cdn() }}"></script>
{!! $chart->script() !!}
</body>
</html>
Now open your project
In the browser with your project basepath and "/chart" you will see:
Congrats! now you are implementing apex charts in your Laravel project.
More?
This is a simple example but, maybe you really want to create more complex charts, so go on this.
In your ChartController.php change the last content with this:
namespace App\Http\Controllers;
use App\Todo;
use App\User;
use ArielMejiaDev\LarapexCharts\Facades\LarapexChart;
use Illuminate\Http\Request;
class ChartController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function __invoke()
{
$user = User::first();
$userTwo = User::find(2);
$usercurrentMonthTodos = Todo::where('user_id', $user->id)->whereStatus(true)->whereMonth('created_at', '=', now()->month)->count();
$userTodosAMonthAgo = Todo::where('user_id', $user->id)->whereStatus(true)->whereMonth('created_at', '=', now()->subMonth()->month)->count();
$userTodosTwoMonthAgo = Todo::where('user_id', $user->id)->whereStatus(true)->whereMonth('created_at', '=', now()->subMonths(2)->month)->count();
$userTwocurrentMonthTodos = Todo::where('user_id', $userTwo->id)->whereStatus(true)->whereMonth('created_at', '=', now()->month)->count();
$userTwoTodosAMonthAgo = Todo::where('user_id', $userTwo->id)->whereStatus(true)->whereMonth('created_at', '=', now()->subMonth()->month)->count();
$userTwoTodosTwoMonthAgo = Todo::where('user_id', $userTwo->id)->whereStatus(true)->whereMonth('created_at', '=', now()->subMonths(2)->month)->count();
$chart = LarapexChart::setType('line')
->setLabels([$user->name, $userTwo->name])
->setXAxis(['Now', 'A month ago', '2 months ago'])
->setDataset([
[
'username' => $user->name,
'data' => [
$usercurrentMonthTodos, $userTodosAMonthAgo, $userTodosTwoMonthAgo
]
],
[
'username' => $userTwo->name,
'data' => [
$userTwocurrentMonthTodos, $userTwoTodosAMonthAgo, $userTwoTodosTwoMonthAgo
]
]
]);
return view('chart', compact('chart'));
}
}
This will load a line chart with two different series of data
You can change the value in setType() method to add this types:
- area
- bar
- heatmap
You can even change the colors of the chart by adding the method setColors(), to the chart instance like this:
$chart = LarapexChart::setType('line')
->setLabels([$user->name, $userTwo->name])
->setXAxis(['Now', 'A month ago', '2 months ago'])
->setColors(['#ffc73c', '#f5746f'])
To get more examples and documentation of LarapexCharts go to LarapexCharts Documentation site
Top comments (29)
Hi @arielmejiadev, Thanks for the package, I'm pretty new with Laravel, but managed to get your charts working well with my MSSQL database, the issue I'm trying to overcome or understand is how can we put multiple charts on one view. I have tried to create components and bring them to my main dashboard, but It seems I can only have one at a time displaying, what am I missing here?
PS-I hope you enjoyed the coffee on me.
Hi @lancelotcs hehe thanks! the package allows to use CLI to generate chart classes so you would be able to add multiple charts through the view/js component, you can add an issue in the github repository with your current code so I am going to be able to reproduce it.
Hi, thanks for the quick response, I managed to get it to work, I changed my controller to inject (not sure if correct word) both charts into one function, then sent both charts to the view in the array. My issue was I had 2 functions in 1 controller and 2 routes to same location and controller calling 2 different functions, only one of these would work at any given time.
Is there a list of the return functions in the chart like setTitle(),setSubtitle(),setColors(),setLabels(),etc?
Hi @arielmejiadev. Firstly, thanks for a great package for creating charts. I've used your package in my laravel project and it worked like a breeze, however, I think I have found a bug. Let me demonstrate;
So the thing is, I first created a pie chart exactly like you mentioned and it worked perfectly. However, I then changed the type of the chart from "pie" to "line", but when I changed the type, the method "setLabels()" stopped working. Instead of setting our custom labels for the chart it just states "series-1" and "series-2".
Then I again changed the type from "line" to "bar" and tried setting the labels on that type of chart, but only to find out it again sets the labels on that chart "series-1" and "series-2".
Then I tried to completely remove the labels but again, in vain. The labels don't get removed either, but stay there having the values "series-1" and "series-2".
Please fix this bug.
Thank you.
Hi Haider thanks for using the package... I am currently working on my free time on updating the docs site... I will try to check... if you could add an issue in the package repository would be great.
Are you using the blade integration? or the Vue/Inertia integration?
I would be glad to check this as soon as possible, just take in mind that it is something that I usually check on weekends.
Great work there.
Would you mind if I add the link of Larapex in the main ApexCharts.js repository? I would also like to add an intro page of Larapex to the docs section of the website (similar to apexcharts.com/docs/react-charts/) so that people willing to use ApexCharts with Laravel finds it easily.
Cheers
This is the package repo: github.com/ArielMejiaDev/larapex-c...
In Laravel we use packagist to add packages so here is the packagist docs: packagist.org/packages/arielmejiad...
The official documentation site: arielmejiadev.github.io/LarapexCha...
Let me know if you need something more, thanks for taking the time to check it
Of course it would be awesome it would be very nice
Hi Juned just to tell you that the apexcharts.com site is broken, greetings!
Hi question how can I format it as a thousands separator ? for example I have tried all the php number_format money_format options and I have this number 41598625 and in the graph it only shows me 4.159 or sometimes it doesn't make up a number nothing to do.
I made the query from the DB already brought with the number format that I want but when I pass it to the graph the format disappears.
Hi Ariel,
Great job, greetings from Xela, this package looks very easy to use, i will give it a try and let you know how it goes!
Just for records, the documentation site is broken : arielmejiadev.github.io/LarapexCha...
Best!
Hi yep I was updated the new version of the package and the documentation just today I release the 1.0.5 version, if you give a try now it will load, thanks You are from Guatemala right? please share with other cool Laravel artisans I am from Guatemala too there are Laravel devs?
Good day sir. I was trying to view the documentation but since it is broken at the moment, I will just ask here if it is possible or is there a parameter I can use to add a link on the chart ? thank you. Btw, I really like this package. Great work.
Sorry, a few day ago I release the version 2 of the package and I updated the documentation site the link is now updated, hope you enjoy it!
Hi Ariel,
Thank you for this Larapex... Really appreciate it.
I would like to try the heatmap. Do you have an example for this type of Chart where I can explore in?
Thanks
Here an online example using Larapex & Tailwindcss larapex-chart-example.herokuapp.com/ and for a specific heatmap: here is the package docs with an example of heatmap and other chart types with blade or VueJS components with inertia: larapex-charts.netlify.app/more-ch...
Thanks for the quick reply.
I am sorry for the confusion. I mean, do have sample of chart heatmap overlay a map. Like map of US with number of voters per State, Color coded, with % and figures showing when the mouse is scroll per state. Thanks
Sorry I did not do that before, the package works behind the scenes with apexcharts.js, so you would need to check if there is an example with that but as far as I can remember I never saw something like this, sorry.
Hi Ariel
Brilliant work!
Quick question, is it possible to produce Mixed Charts?
If so, could you point me in the right direction
Many thanks
Sorry at this moment the package only support non mixed charts, because I handle a standard object on the backend and I the mixed charts would have a lot of different structures, it could be something to work on the future, but at this moment the package only has this types:
You're a life saver 💪 💪 💪
Hehe hope it helps!
Hi, Ariel.
This is a good work!
I hope to contribute very soon.
Sure why not, Thanks for taking the time to check the package, please if you have a comment feel free to write about it, do you already use it?
Some comments may only be visible to logged-in visitors. Sign in to view all comments.