Để tạo báo cáo với biểu đồ trực quan, chúng ta sẽ sử dụng thư viện rất mạnh về biểu đồ là ChartJS

Step 1: download thư viện và tích hợp vào dự án

ChartJS

assets
├───vendor
│ └───Chart.jS
│ │ * -> các file css, js của thư viện Chart.JS
assets ├───vendor │ └───Chart.jS │ │ * -> các file css, js của thư viện Chart.JS
assets
├───vendor
│   └───Chart.jS
│       │       * -> các file css, js của thư viện Chart.JS
 

Step 2: viết file logic xử lý Trang Dashboard

  • Tạo file backend/pages/dashboard.php
<?php
// Include file cấu hình ban đầu của `Twig`
require_once __DIR__.'/../../bootstrap.php';
// Yêu cầu `Twig` vẽ giao diện được viết trong file `backend/pages/dashboard.html.twig`
echo $twig->render('backend/pages/dashboard.html.twig');
<?php // Include file cấu hình ban đầu của `Twig` require_once __DIR__.'/../../bootstrap.php'; // Yêu cầu `Twig` vẽ giao diện được viết trong file `backend/pages/dashboard.html.twig` echo $twig->render('backend/pages/dashboard.html.twig');
<?php
// Include file cấu hình ban đầu của `Twig`
require_once __DIR__.'/../../bootstrap.php';

// Yêu cầu `Twig` vẽ giao diện được viết trong file `backend/pages/dashboard.html.twig`
echo $twig->render('backend/pages/dashboard.html.twig');

Step 3: tạo file template Trang Dashboard

  • Tạo file templates/backend/pages/dashboard.php
{# Kế thừa layout backend #}
{% extends "backend/layouts/layout.html.twig" %}
{% block title %}
Bảng tin Dashboard
{% endblock %}
{# Nội dung trong block content #}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-primary mb-2">
<div class="card-body pb-0">
<div class="text-value" id="baocaoSanPham_quantity">
<h1>0</h1>
</div>
<div>Tổng số mặt hàng</div>
</div>
</div>
<button class="btn btn-primary btn-sm form-control" id="refreshBaoCaoSanPham">Refresh dữ liệu</button>
</div> <!-- Tổng số mặt hàng -->
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-success mb-2">
<div class="card-body pb-0">
<div class="text-value" id="baocaoKhachHang_quantity">
<h1>0</h1>
</div>
<div>Tổng số khách hàng</div>
</div>
</div>
<button class="btn btn-success btn-sm form-control" id="refreshBaoCaoKhachHang">Refresh dữ liệu</button>
</div> <!-- Tổng số khách hàng -->
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-warning mb-2">
<div class="card-body pb-0">
<div class="text-value" id="baocaoDonHang_quantity">
<h1>0</h1>
</div>
<div>Tổng số đơn hàng</div>
</div>
</div>
<button class="btn btn-warning btn-sm form-control" id="refreshBaoCaoDonHang">Refresh dữ liệu</button>
</div> <!-- Tổng số đơn hàng -->
<div class="col-sm-6 col-lg-3">
<div class="card text-white bg-danger mb-2">
<div class="card-body pb-0">
<div class="text-value" id="baocaoGopY_quantity">
<h1>0</h1>
</div>
<div>Tổng số góp ý</div>
</div>
</div>
<button class="btn btn-danger btn-sm form-control" id="refreshBaoCaoGopY">Refresh dữ liệu</button>
</div> <!-- Tổng số góp ý -->
<div id="ketqua"></div>
</div><!-- row -->
<div class="row">
<!-- Biểu đồ thống kê loại sản phẩm -->
<div class="col-sm-6 col-lg-6">
<canvas id="chartOfobjChartThongKeLoaiSanPham"></canvas>
<button class="btn btn-outline-primary btn-sm form-control" id="refreshThongKeLoaiSanPham">Refresh dữ liệu</button>
</div><!-- col -->
</div><!-- row -->
</div>
{% endblock %}
{# End Nội dung trong block content #}
{% block customscripts %}
<script src="/project-nentang/assets/vendor/Chart.js/Chart.min.js"></script>
<script>
$(document).ready(function() {
function getDuLieuBaoCaoTongSoMatHang() {
$.ajax('/project-nentang/backend/ajax/baocao-tongsomathang-ajax.php', {
success: function (data) {
var dataObj = JSON.parse(data);
var htmlString = `<h1>${dataObj.quantity}</h1>`;
$('#baocaoSanPham_quantity').html(htmlString);
},
error: function () {
var htmlString = `<h1>Không thể xử lý</h1>`;
$('#baocaoSanPham_quantity').html(htmlString);
}
});
}
$('#refreshBaoCaoSanPham').click(function(event) {
event.preventDefault();
getDuLieuBaoCaoTongSoMatHang();
});
// Mới mở web
getDuLieuBaoCaoTongSoMatHang();
// ----------------- Tổng số khách hàng --------------------------
function getDuLieuBaoCaoTongSoKhachHang() {
$.ajax('/project-nentang/backend/ajax/baocao-tongsokhachhang-ajax.php', {
success: function (data) {
var dataObj = JSON.parse(data);
var htmlString = `<h1>${dataObj.quantity}</h1>`;
$('#baocaoKhachHang_quantity').html(htmlString);
},
error: function () {
var htmlString = `<h1>Không thể xử lý</h1>`;
$('#baocaoKhachHang_quantity').html(htmlString);
}
});
}
$('#refreshBaoCaoKhachHang').click(function(event) {
event.preventDefault();
getDuLieuBaoCaoTongSoKhachHang();
});
// Mới mở web
getDuLieuBaoCaoTongSoKhachHang();
// ------------------ Vẽ biểu đồ thống kê Loại sản phẩm -----------------
// Vẽ biểu đổ Thống kê Loại sản phẩm sử dụng ChartJS
var $objChartThongKeLoaiSanPham;
var $chartOfobjChartThongKeLoaiSanPham = document.getElementById("chartOfobjChartThongKeLoaiSanPham").getContext(
"2d");
function renderChartThongKeLoaiSanPham() {
$.ajax({
url: '/project-nentang/backend/ajax/baocao-thongkeloaisanpham-ajax.php',
type: "GET",
success: function (response) {
debugger;
var data = JSON.parse(response);
var myLabels = [];
var myData = [];
$(data).each(function () {
myLabels.push((this.TenLoaiSanPham));
myData.push(this.quantity);
});
myData.push(0); // tạo dòng số liệu 0
if (typeof $objChartThongKeLoaiSanPham !== "undefined") {
$objChartThongKeLoaiSanPham.destroy();
}
$objChartThongKeLoaiSanPham = new Chart($chartOfobjChartThongKeLoaiSanPham, {
// Kiểu biểu đồ muốn vẽ. Các bạn xem thêm trên trang ChartJS
type: "bar",
data: {
labels: myLabels,
datasets: [{
data: myData,
borderColor: "#9ad0f5",
backgroundColor: "#9ad0f5",
borderWidth: 1
}]
},
// Cấu hình dành cho biểu đồ của ChartJS
options: {
legend: {
display: false
},
title: {
display: true,
text: "Thống kê Loại sản phẩm"
},
responsive: true
}
});
}
});
};
$('#refreshThongKeLoaiSanPham').click(function (event) {
event.preventDefault();
renderChartThongKeLoaiSanPham();
});
});
</script>
{% endblock %}
{# Kế thừa layout backend #} {% extends "backend/layouts/layout.html.twig" %} {% block title %} Bảng tin Dashboard {% endblock %} {# Nội dung trong block content #} {% block content %} <div class="container-fluid"> <div class="row"> <div class="col-sm-6 col-lg-3"> <div class="card text-white bg-primary mb-2"> <div class="card-body pb-0"> <div class="text-value" id="baocaoSanPham_quantity"> <h1>0</h1> </div> <div>Tổng số mặt hàng</div> </div> </div> <button class="btn btn-primary btn-sm form-control" id="refreshBaoCaoSanPham">Refresh dữ liệu</button> </div> <!-- Tổng số mặt hàng --> <div class="col-sm-6 col-lg-3"> <div class="card text-white bg-success mb-2"> <div class="card-body pb-0"> <div class="text-value" id="baocaoKhachHang_quantity"> <h1>0</h1> </div> <div>Tổng số khách hàng</div> </div> </div> <button class="btn btn-success btn-sm form-control" id="refreshBaoCaoKhachHang">Refresh dữ liệu</button> </div> <!-- Tổng số khách hàng --> <div class="col-sm-6 col-lg-3"> <div class="card text-white bg-warning mb-2"> <div class="card-body pb-0"> <div class="text-value" id="baocaoDonHang_quantity"> <h1>0</h1> </div> <div>Tổng số đơn hàng</div> </div> </div> <button class="btn btn-warning btn-sm form-control" id="refreshBaoCaoDonHang">Refresh dữ liệu</button> </div> <!-- Tổng số đơn hàng --> <div class="col-sm-6 col-lg-3"> <div class="card text-white bg-danger mb-2"> <div class="card-body pb-0"> <div class="text-value" id="baocaoGopY_quantity"> <h1>0</h1> </div> <div>Tổng số góp ý</div> </div> </div> <button class="btn btn-danger btn-sm form-control" id="refreshBaoCaoGopY">Refresh dữ liệu</button> </div> <!-- Tổng số góp ý --> <div id="ketqua"></div> </div><!-- row --> <div class="row"> <!-- Biểu đồ thống kê loại sản phẩm --> <div class="col-sm-6 col-lg-6"> <canvas id="chartOfobjChartThongKeLoaiSanPham"></canvas> <button class="btn btn-outline-primary btn-sm form-control" id="refreshThongKeLoaiSanPham">Refresh dữ liệu</button> </div><!-- col --> </div><!-- row --> </div> {% endblock %} {# End Nội dung trong block content #} {% block customscripts %} <script src="/project-nentang/assets/vendor/Chart.js/Chart.min.js"></script> <script> $(document).ready(function() { function getDuLieuBaoCaoTongSoMatHang() { $.ajax('/project-nentang/backend/ajax/baocao-tongsomathang-ajax.php', { success: function (data) { var dataObj = JSON.parse(data); var htmlString = `<h1>${dataObj.quantity}</h1>`; $('#baocaoSanPham_quantity').html(htmlString); }, error: function () { var htmlString = `<h1>Không thể xử lý</h1>`; $('#baocaoSanPham_quantity').html(htmlString); } }); } $('#refreshBaoCaoSanPham').click(function(event) { event.preventDefault(); getDuLieuBaoCaoTongSoMatHang(); }); // Mới mở web getDuLieuBaoCaoTongSoMatHang(); // ----------------- Tổng số khách hàng -------------------------- function getDuLieuBaoCaoTongSoKhachHang() { $.ajax('/project-nentang/backend/ajax/baocao-tongsokhachhang-ajax.php', { success: function (data) { var dataObj = JSON.parse(data); var htmlString = `<h1>${dataObj.quantity}</h1>`; $('#baocaoKhachHang_quantity').html(htmlString); }, error: function () { var htmlString = `<h1>Không thể xử lý</h1>`; $('#baocaoKhachHang_quantity').html(htmlString); } }); } $('#refreshBaoCaoKhachHang').click(function(event) { event.preventDefault(); getDuLieuBaoCaoTongSoKhachHang(); }); // Mới mở web getDuLieuBaoCaoTongSoKhachHang(); // ------------------ Vẽ biểu đồ thống kê Loại sản phẩm ----------------- // Vẽ biểu đổ Thống kê Loại sản phẩm sử dụng ChartJS var $objChartThongKeLoaiSanPham; var $chartOfobjChartThongKeLoaiSanPham = document.getElementById("chartOfobjChartThongKeLoaiSanPham").getContext( "2d"); function renderChartThongKeLoaiSanPham() { $.ajax({ url: '/project-nentang/backend/ajax/baocao-thongkeloaisanpham-ajax.php', type: "GET", success: function (response) { debugger; var data = JSON.parse(response); var myLabels = []; var myData = []; $(data).each(function () { myLabels.push((this.TenLoaiSanPham)); myData.push(this.quantity); }); myData.push(0); // tạo dòng số liệu 0 if (typeof $objChartThongKeLoaiSanPham !== "undefined") { $objChartThongKeLoaiSanPham.destroy(); } $objChartThongKeLoaiSanPham = new Chart($chartOfobjChartThongKeLoaiSanPham, { // Kiểu biểu đồ muốn vẽ. Các bạn xem thêm trên trang ChartJS type: "bar", data: { labels: myLabels, datasets: [{ data: myData, borderColor: "#9ad0f5", backgroundColor: "#9ad0f5", borderWidth: 1 }] }, // Cấu hình dành cho biểu đồ của ChartJS options: { legend: { display: false }, title: { display: true, text: "Thống kê Loại sản phẩm" }, responsive: true } }); } }); }; $('#refreshThongKeLoaiSanPham').click(function (event) { event.preventDefault(); renderChartThongKeLoaiSanPham(); }); }); </script> {% endblock %}
{# Kế thừa layout backend #}
{% extends "backend/layouts/layout.html.twig" %}

{% block title %}
Bảng tin Dashboard
{% endblock %}


{# Nội dung trong block content #}
{% block content %}
<div class="container-fluid">
    <div class="row">
        <div class="col-sm-6 col-lg-3">
            <div class="card text-white bg-primary mb-2">
                <div class="card-body pb-0">
                    <div class="text-value" id="baocaoSanPham_quantity">
                        <h1>0</h1>
                    </div>
                    <div>Tổng số mặt hàng</div>
                </div>
            </div>
            <button class="btn btn-primary btn-sm form-control" id="refreshBaoCaoSanPham">Refresh dữ liệu</button>
        </div> <!-- Tổng số mặt hàng -->

        <div class="col-sm-6 col-lg-3">
            <div class="card text-white bg-success mb-2">
                <div class="card-body pb-0">
                    <div class="text-value" id="baocaoKhachHang_quantity">
                        <h1>0</h1>
                    </div>
                    <div>Tổng số khách hàng</div>
                </div>
            </div>
            <button class="btn btn-success btn-sm form-control" id="refreshBaoCaoKhachHang">Refresh dữ liệu</button>
        </div> <!-- Tổng số khách hàng -->

        <div class="col-sm-6 col-lg-3">
            <div class="card text-white bg-warning mb-2">
                <div class="card-body pb-0">
                    <div class="text-value" id="baocaoDonHang_quantity">
                        <h1>0</h1>
                    </div>
                    <div>Tổng số đơn hàng</div>
                </div>
            </div>
            <button class="btn btn-warning btn-sm form-control" id="refreshBaoCaoDonHang">Refresh dữ liệu</button>
        </div> <!-- Tổng số đơn hàng -->

        <div class="col-sm-6 col-lg-3">
            <div class="card text-white bg-danger mb-2">
                <div class="card-body pb-0">
                    <div class="text-value" id="baocaoGopY_quantity">
                        <h1>0</h1>
                    </div>
                    <div>Tổng số góp ý</div>
                </div>
            </div>
            <button class="btn btn-danger btn-sm form-control" id="refreshBaoCaoGopY">Refresh dữ liệu</button>
        </div> <!-- Tổng số góp ý -->

        <div id="ketqua"></div>
    </div><!-- row -->

    <div class="row">
        <!-- Biểu đồ thống kê loại sản phẩm -->
        <div class="col-sm-6 col-lg-6">
            <canvas id="chartOfobjChartThongKeLoaiSanPham"></canvas>
            <button class="btn btn-outline-primary btn-sm form-control" id="refreshThongKeLoaiSanPham">Refresh dữ liệu</button>
        </div><!-- col -->

        
    </div><!-- row -->
</div>


{% endblock %}
{# End Nội dung trong block content #}

{% block customscripts %}
<script src="/project-nentang/assets/vendor/Chart.js/Chart.min.js"></script>
<script>
    $(document).ready(function() {

        function getDuLieuBaoCaoTongSoMatHang() {
            $.ajax('/project-nentang/backend/ajax/baocao-tongsomathang-ajax.php', {
                success: function (data) {
                    var dataObj = JSON.parse(data);
                    var htmlString = `<h1>${dataObj.quantity}</h1>`;
                    $('#baocaoSanPham_quantity').html(htmlString);
                },
                error: function () {
                    var htmlString = `<h1>Không thể xử lý</h1>`;
                    $('#baocaoSanPham_quantity').html(htmlString);
                }
            });
        }

        $('#refreshBaoCaoSanPham').click(function(event) {
            event.preventDefault();

            getDuLieuBaoCaoTongSoMatHang();
        });

        // Mới mở web
        getDuLieuBaoCaoTongSoMatHang();

        // ----------------- Tổng số khách hàng --------------------------
        function getDuLieuBaoCaoTongSoKhachHang() {
            $.ajax('/project-nentang/backend/ajax/baocao-tongsokhachhang-ajax.php', {
                success: function (data) {
                    var dataObj = JSON.parse(data);
                    var htmlString = `<h1>${dataObj.quantity}</h1>`;
                    $('#baocaoKhachHang_quantity').html(htmlString);
                },
                error: function () {
                    var htmlString = `<h1>Không thể xử lý</h1>`;
                    $('#baocaoKhachHang_quantity').html(htmlString);
                }
            });
        }

        $('#refreshBaoCaoKhachHang').click(function(event) {
            event.preventDefault();

            getDuLieuBaoCaoTongSoKhachHang();
        });

        // Mới mở web
        getDuLieuBaoCaoTongSoKhachHang();
        

        // ------------------ Vẽ biểu đồ thống kê Loại sản phẩm -----------------
        // Vẽ biểu đổ Thống kê Loại sản phẩm sử dụng ChartJS
        var $objChartThongKeLoaiSanPham;
        var $chartOfobjChartThongKeLoaiSanPham = document.getElementById("chartOfobjChartThongKeLoaiSanPham").getContext(
            "2d");
        function renderChartThongKeLoaiSanPham() {
            $.ajax({
                url: '/project-nentang/backend/ajax/baocao-thongkeloaisanpham-ajax.php',
                type: "GET",
                success: function (response) {
                    debugger;
                    var data = JSON.parse(response);
                    var myLabels = [];
                    var myData = [];
                    $(data).each(function () {
                        myLabels.push((this.TenLoaiSanPham));
                        myData.push(this.quantity);
                    });
                    myData.push(0); // tạo dòng số liệu 0
                    if (typeof $objChartThongKeLoaiSanPham !== "undefined") {
                        $objChartThongKeLoaiSanPham.destroy();
                    }
                    $objChartThongKeLoaiSanPham = new Chart($chartOfobjChartThongKeLoaiSanPham, {
                        // Kiểu biểu đồ muốn vẽ. Các bạn xem thêm trên trang ChartJS
                        type: "bar",
                        data: {
                            labels: myLabels,
                            datasets: [{
                                data: myData,
                                borderColor: "#9ad0f5",
                                backgroundColor: "#9ad0f5",
                                borderWidth: 1
                            }]
                        },
                        // Cấu hình dành cho biểu đồ của ChartJS
                        options: {
                            legend: {
                                display: false
                            },
                            title: {
                                display: true,
                                text: "Thống kê Loại sản phẩm"
                            },
                            responsive: true
                        }
                    });
                }
            });
        };
        $('#refreshThongKeLoaiSanPham').click(function (event) {
            event.preventDefault();
            renderChartThongKeLoaiSanPham();
        });
    });
</script>
{% endblock %}