Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
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.
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;
// ...
In your controller, create methods that prepare and return chart data in JSON format. You’ll calculate sales totals, daily trends, or top products—ready for ApexCharts to consume and display.
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'));
}
}
Inside your Blade view, design the chart layout and initialize ApexCharts. You’ll connect it to the data and render dynamic charts directly within your dashboard, giving users clear visual insights.
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>
Run the following command to compile your assets:
npm run dev
Use <strong>npm run build</strong>
for production.
Once compiled, visit:
http://laravel-jquery-pos
Fantastic job! 🎉 You’ve successfully enhanced your Laravel POS with jQuery system by adding powerful graph reports using ApexCharts. Now your users can visualize sales trends, top products, and key metrics through beautiful, interactive charts—all right inside the dashboard.
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! 🚀