This Laravel jQuery POS chart reports tutorial wraps up the series with beautiful interactive graphs using ApexCharts to present your data visually.
In this tutorial, you’ll learn how to visualize key business data using ApexCharts—a modern JavaScript charting library that integrates seamlessly with jQuery. We’ll create interactive charts that show total sales, daily trends, top products, and more.
By the end, your POS dashboard will not only be functional but visually insightful—giving store owners and admins a quick overview of performance without needing to open Excel files or read tables.
Table of Contents
Step 1: Import ApexCharts for Laravel jQuery POS Chart Reports
In this step, you will import and configure ApexCharts to power your laravel jquery pos chart reports. This chart library helps you display sales insights, product performance, and daily transactions in a clean and interactive way using jQuery and Ajax inside your Laravel POS system.
Check your JavaScript file resources/js/app.js and make sure you’ve imported ApexCharts into your project. This library will power the interactive charts in your POS dashboard, allowing you to visualize sales and performance data with ease.
// ...
import ApexCharts from 'apexcharts';
window.ApexCharts = ApexCharts;
// ...Step 2: Build the Controller
Next, you will build a controller that prepares the data needed for your laravel jquery pos chart reports. The controller will collect sales records, format the response for jQuery Ajax, and return clean JSON data so ApexCharts can generate dynamic POS chart reports without page reloads.
Replace the contents of app/Http/Controllers/DashboardController.php with the code below. If the file doesn’t exist yet, please create it.
<?php
// Laravel jQuery POS Chart Reports @ https://laravelcenter.com
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Order;
use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
public function __invoke()
{
// Top Products
$top_products = Order::join('order_details', 'order_details.order_id', '=', 'orders.id')
->selectRaw('order_details.description,sum(order_details.qty) AS qty')
->where(DB::raw('DATE_FORMAT(orders.created_at,"%Y-%m-%d")'), DB::raw('DATE_FORMAT(CURDATE(),"%Y-%m-%d")'))
->groupBy('order_details.description')
->orderBy('qty', 'desc')
->take(10)->get();
// Sale by Categories
$sale_categories = Order::join('order_details', 'orders.id', '=', 'order_details.order_id')
->join('product_categories', 'product_categories.id', '=', 'order_details.product_category_id')
->select(
DB::raw("product_categories.name,sum((order_details.qty * order_details.unit_price*order_details.discount/100) + (order_details.qty * order_details.unit_price * (1-order_details.discount/100) * orders.discount/100)) as discount, sum(order_details.qty * order_details.unit_price) as total")
)
->where(DB::raw('DATE_FORMAT(orders.created_at,"%Y-%m-%d")'), DB::raw('DATE_FORMAT(CURDATE(),"%Y-%m-%d")'))
->groupBy(DB::raw('product_categories.name'))
->orderBy('product_categories.name')
->get();
// Last 15 days total sale amount
$days = 15;
$data = Order::select(DB::raw("DATE_FORMAT(created_at,'%Y-%m-%d') AS dd, sum(net_amount) AS total"))
->where(DB::raw('DATE_FORMAT(created_at,"%Y-%m-%d")'), '>=', DB::raw('DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL ' . $days . ' DAY),"%Y-%m-%d")'))
->groupBy('dd')
->orderBy('dd')
->get()->toArray();
$result = [];
for ($i = $days - 1; $i >= 0; $i--) {
$date = date('Y-m-d', strtotime('-' . $i . ' days'));
$total = 0;
foreach ($data as $row) {
if ($row['dd'] == $date) {
$total = $row['total'];
break;
}
}
array_push($result, [
'date' => date('d-M', strtotime($date)),
'total' => $total
]);
}
return view('dashboard', compact('result', 'top_products', 'sale_categories'));
}
}Step 3: Create the View
Here, you will design the view that displays your laravel jquery pos chart reports. The view will include chart placeholders, jQuery Ajax scripts, and ApexCharts configuration so your POS dashboard can render real-time graph reports for sales, orders, and revenue trends.
Replace the contents of resources/views/dashboard.blade.php with the code below. If the file doesn’t exist yet, please create it.
<!-- Laravel jQuery POS Chart Reports @ https://laravelcenter.com -->
<div class="pagetitle">
<h1>Dashboard</h1>
</div>
@php
$total_amount = 0;
$total_discount = 0;
$net_amount = 0;
$pie_labels = [];
$pie_series = [];
if (isset($sale_categories) && $sale_categories->count() > 0) {
foreach ($sale_categories as $value) {
$total_amount += $value->total;
$total_discount += $value->discount;
array_push($pie_labels, $value->name);
array_push($pie_series, $value->total - $value->discount);
}
$net_amount = $total_amount - $total_discount;
}
@endphp
<div class="row">
<div class="col-md-4 mb-4">
<div class="card shadow bg-primary text-white">
<div class="card-body p-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="me-2">
<div class="display-6 text-white">
$ {{ number_format($total_amount, 2) }}
</div>
<div class="card-text fs-6 mt-2">Daily Total Sale</div>
</div>
<div style="color: lightblue"><i class="bi bi-cash-stack display-4"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card shadow bg-danger text-white">
<div class="card-body p-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="me-2">
<div class="display-6 text-white">$ {{ number_format($total_discount, 2) }}</div>
<div class="card-text fs-6 mt-2">Daily Total Disount</div>
</div>
<div style="color: lightgray;"><i class="bi bi-percent display-4"></i></div>
</div>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card shadow bg-success text-white">
<div class="card-body p-4">
<div class="d-flex justify-content-between align-items-center mb-2">
<div class="me-2">
<div class="display-6 text-white">$ {{ number_format($net_amount, 2) }}</div>
<div class="card-text fs-6 mt-2">Daily Net Amount</div>
</div>
<div style="color: lightblue"><i class="bi bi-coin display-4"></i></div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-4">
<div class="card shadow mb-3">
<div class="card-header bg-dark text-white py-2">
<i class="fas fa-chart-area me-1"></i>
Daily Sale Report By Categories
</div>
<div class="card-body py-1">
<div id="pie_chart"></div>
</div>
</div>
</div>
<div class="col-md-6 mb-4">
<table class="table table-hover shadow align-middle bg-white">
<thead>
<tr class="table-dark">
<th style="width: 50px" class="text-center">#</th>
<th>Product Name</th>
<th class="text-center">QTY</th>
</tr>
</thead>
<tbody>
@foreach ($top_products as $index => $value)
<tr>
<td class="text-center">{{ $index + 1 }}</td>
<td>{{ $value->description }}</td>
<td class="text-center">
{{ $value->qty }}
</td>
</tr>
@endforeach
@for ($i = 1; $i <= 10 - $top_products->count(); $i++)
<tr>
<td class="text-center">{{ $top_products->count() + $i }}</td>
<td></td>
<td class="text-center"></td>
</tr>
@endfor
</tbody>
</table>
</div>
</div>
<div class="col mb-5">
<div class="card shadow mb-3">
<div class="card-header bg-dark text-white py-2">
<i class="fas fa-chart-bar me-1"></i>
15 Days Total Sale Amount
</div>
<div class="card-body">
<div id="bar_chart"></div>
</div>
</div>
</div>
<script>
// Pie Chart
var options = {
fill: {
colors: ['#3366cc', '#660066', '#006600', '#cc0066', '#996633', '#006666', '#993399', '#999966',
'#ffcc99', '#33cc33', '#cccc00'
]
},
series: <?php echo json_encode($pie_series); ?>,
chart: {
height: 400,
type: 'pie',
},
labels: <?php echo json_encode($pie_labels); ?>,
legend: {
position: 'bottom'
},
responsive: [{
breakpoint: 480,
options: {
chart: {
width: 200
},
legend: {
position: 'bottom'
}
}
}],
dataLabels: {
enabled: true,
formatter: function(val) {
return val.toFixed(2) + "%"
},
dropShadow: {}
},
tooltip: {
shared: true,
intersect: false,
y: {
formatter: function(value) {
try {
if (typeof value !== "number") {
if (value && !isNaN(value)) {
value = parseFloat(value);
} else {
return value;
}
}
var formatter = new Intl.NumberFormat("en-US", {
style: "decimal",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
return "$" + formatter.format(value);
} catch (ex) {
return "$" + value;
}
}
}
},
};
var chart = new ApexCharts(document.querySelector("#pie_chart"), options);
chart.render();
// Bar Chart
var options = {
series: [{
name: 'Net Amount',
data: <?php echo json_encode(array_column($result, 'total')); ?>
}],
chart: {
height: 350,
type: 'bar',
},
plotOptions: {
bar: {
borderRadius: 10,
dataLabels: {
position: 'top', // top, center, bottom
},
}
},
dataLabels: {
enabled: true,
formatter: function(val) {
return "$" + val;
},
offsetY: -20,
style: {
fontSize: '12px',
colors: ["#304758"]
}
},
xaxis: {
categories: <?php echo json_encode(array_column($result, 'date')); ?>,
position: 'top',
axisBorder: {
show: false
},
axisTicks: {
show: false
},
crosshairs: {
fill: {
type: 'gradient',
gradient: {
colorFrom: '#D8E3F0',
colorTo: '#BED1E6',
stops: [0, 100],
opacityFrom: 0.4,
opacityTo: 0.5,
}
}
},
tooltip: {
enabled: true,
}
},
yaxis: {
axisBorder: {
show: false
},
axisTicks: {
show: false,
},
labels: {
show: false,
formatter: function(val) {
return "$" + val;
}
}
}
};
var chart = new ApexCharts(document.querySelector("#bar_chart"), options);
chart.render();
</script>Running and Testing Your Project
After setting everything up, you will run and test your project to ensure the laravel jquery pos chart reports load correctly. This includes checking Ajax responses, verifying chart rendering, and confirming the POS data updates smoothly inside your reports page.
Open your Terminal/CMD in separate windows, go to the project’s root folder, and then run the command below:
npm run devphp artisan serveWith both commands running in their separate windows, open your web browser to the Laravel address (http://127.0.0.1:8000).

Graph Reports Setup Complete
You have now completed the setup for laravel jquery pos chart reports. Your Laravel POS system can successfully generate interactive charts and visual reports using jQuery, Ajax, and ApexCharts, giving users a clear overview of sales analytics.
With this final feature, your POS app is not only functional but also insightful and professional, ready to help business owners make data-driven decisions with ease.
Thank you for following along this complete Laravel POS with jQuery tutorial series! 🚀
Laravel jQuery POS Tutorial for Beginners Series
This step-by-step series will guide you through building a complete Laravel jQuery POS system from scratch:
- Part 1: Install Laravel and Required Packages
Set up Laravel 12.x, jQuery, Bootstrap, and essential dependencies to get your project started. - Part 2: Integrate NiceAdmin Template into Laravel
Design a clean and responsive UI using the NiceAdmin Bootstrap template. - Part 3: Data Migration and Authentication
Implement user login, logout, and role-based access control. - Part 4: Ajax Menu Navigation and System Data (CRUD)
Create smooth navigation and manage key POS data with simple Ajax-based CRUD features. - Part 5: Build the POS Cart System with jQuery
Add products to cart, adjust quantities, and calculate totals with jQuery. - Part 6: Role-Based Access – Admin vs. Cashier
Create middleware to manage access between different user roles. - Part 7: Generate Reports and Filter Sales Data
Show daily sales, filter by date, and export reports using xlsx-populate. - Part 8: Create Graph Reports with ApexCharts
Visualize sales performance using beautiful charts on the dashboard.







