For bigger web-project with a lot of data we usually have to build a reporting system – with export to PDF/Excel, charts and graphs. There are many ways to do it, let’s look at the most popular ones.


Update: in February 2019 we released our own small Laravel package to generate simple charts.


JavaScript libraries

We won’t start with Laravel, first things first: generally, charts on the web are created with JavaScript. There are quite a few popular libraries for this:

And others. Most of them work in a way that there’s a <canvas> or <div> element which then gets filled with JavaScript “magic” – lines, colors, labels etc.

Here’s a simple example of Chart.js:

<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});
</script>

As you can see, it’s pretty simple, you just need to know the parameters – variables, labels, datasets, axes options etc. And every JavaScript library has some special sauce – different chart types, more/less parameters or better/worse documentation. So the choice is yours.

The main point – it is possible to draw charts just in JavaScript/jQuery, without Laravel packages, just getting data from database via Eloquent and passing it to Blade within JavaScript, like this:

  ...
  data: [{{ implode(',', $data }}],
  ...

But what if we want to do it more Laravel-way? We don’t want to mess with JavaScript and their parameters? There are two packages we can use.


ConsoleTVs/Charts

Creator of this package describes it: “Multi-library chart package to create interactive charts using Laravel”. And actually – the multi-library part is really important – this package can draw a chart using any of JavaScript libraries mentioned above, and even more.

Basically, it’s a wrapper for the front-end code, but you would write only back-end Laravel code and wouldn’t have to worry about JavaScript.

Here’s a sample Blade file from their documentation:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>My Charts</title>

        {!! Charts::styles() !!}

    </head>
    <body>
        <!-- Main Application (Can be VueJS or other JS framework) -->
        <div class="app">
            <center>
                {!! $chart->html() !!}
            </center>
        </div>
        <!-- End Of Main Application -->
        {!! Charts::scripts() !!}
        {!! $chart->script() !!}
    </body>
</html>

And then you’re passing the $chart variable from Controller, like this:

$chart = Charts::multi('bar', 'material')
    ->title("My Cool Chart")
    ->dimensions(0, 400) // Width x Height
    ->template("material")
    ->dataset('Element 1', [5,20,100])
    ->dataset('Element 2', [15,30,80])
    ->dataset('Element 3', [25,10,40])
    ->labels(['One', 'Two', 'Three']);

return view('test', ['chart' => $chart]);

Looks much more familiar in Laravel, right?
Also, you can define a lot of options in config/charts.php file, which is also a well-known structure.

So, I can recommend this package, URL again: https://github.com/ConsoleTVs/Charts

There are a few more Laravel packages related to charts, but in comparison, their functions are pretty limited – they are wrappers of one particular JS library, or similar.


Laravel Report Generator

From what I read online, terms “reports” and “charts” are sometimes used mixing those together. But in reality, chart is a visual representation of data, and report is more like a table or list of data.

So we have one strong package that will help you with your reports and forming PDF/Excel versions of them.

Meet https://github.com/Jimmy-JS/laravel-report-generator

It is a wrapper over Laravel-Dompdf and Laravel-Excel packages, utilizing them to form the reports like this:

To be honest, there’s quite a lot of code to write, to get such (or similar) report:

use PdfReport;

public function displayReport(Request $request) {
    // Retrieve any filters
    $fromDate = $request->input('from_date');
    $toDate = $request->input('to_date');
    $sortBy = $request->input('sort_by');

    // Report title
    $title = 'Registered User Report';

    // For displaying filters description on header
    $meta = [
        'Registered on' => $fromDate . ' To ' . $toDate,
        'Sort By' => $sortBy
    ];

    // Do some querying..
    $queryBuilder = User::select(['name', 'balance', 'registered_at'])
                        ->whereBetween('registered_at', [$fromDate, $toDate])
                        ->orderBy($sortBy);

    // Set Column to be displayed
    $columns = [
        'Name' => 'name',
        'Registered At', 
        'Total Balance' => 'balance',
        'Status' => function($result) { 
            return ($result->balance > 100000) ? 'Rich Man' : 'Normal Guy';
        }
    ];

    return PdfReport::of($title, $meta, $queryBuilder, $columns)
                    ->editColumn('Registered At', [
                        'displayAs' => function($result) {
                            return $result->registered_at->format('d M Y');
                        }
                    ])
                    ->editColumn('Total Balance', [
                        'displayAs' => function($result) {
                            return thousandSeparator($result->balance);
                        }
                    ])
                    ->editColumns(['Total Balance', 'Status'], [
                        'class' => 'right bold'
                    ])
                    ->showTotal([
                        'Total Balance' => 'point' // if you want to show dollar sign ($) then use 'Total Balance' => '$'
                    ])
                    ->limit(20)
                    ->stream(); // or download('filename here..') to download pdf
}

Still, it’s much more convenient than building PDF one line after another, or from HTML code.

Link to the package again: https://github.com/Jimmy-JS/laravel-report-generator


So, these are two of my favorites. Anything to add?

Final note: in our QuickAdminPanel module called Reports generator, we use simple Chart.js library, here’s a short video about how it works.