June 26, 2015

JavaScript HighCharts in Laravel 5 via Blade

Laravel 5's Blade templating engine is awesome. It can be used to directly inject PHP variables into a HTML5 template to display Eloquent ActiveRecord entities right away to the client. Besides this obvious intended use, escaping those variables can be powerful, as we will see.

HighCharts is a JavaScript library that can be used to display beautiful visualizations of sets of data. If you're here and reading this, you are probably looking for a way to integrate your Laravel PHP app with this JS library.

I started by checking out some HighCharts PHP ports on Packagist, but at the time of this writing, the few such packages have either gone unmaintained into obsolescence, or are overkill for what can be elegantly accomplished with a few lines of code. The trick here is to take advantage of Blade template escaping.

Let's look at the official HighCharts example, as given in its native JavaScript + jQuery:


$(function () { 
    $('#container').highcharts({
        chart: {
            type: 'bar'
        },
        title: {
            text: 'Fruit Consumption'
        },
        xAxis: {
            categories: ['Apples', 'Bananas', 'Oranges']
        },
        yAxis: {
            title: {
                text: 'Fruit eaten'
            }
        },
        series: [{
            name: 'Jane',
            data: [1, 0, 4]
        }, {
            name: 'John',
            data: [5, 7, 3]
        }]
    });
});

The following HTML snippet with the above JS in an HTML page will display a simple chart:


<div id="container" style="width:100%; height:400px;"></div>

That's cool and all, but that's a lot of JS for a PHP app, and it doesn't solve actually getting the database variables to HighCharts, unless we feel like resorting to some funky AJAX hackery... Fear not, there is a better way. Let's start by reconstructing the JSON config structure from the JS HighCharts into a PHP array. Create a controller, say DashboardController and make this method:


public function index() {

    $yourFirstChart["chart"] = array("type" => "bar");
    $yourFirstChart["title"] = array("text" => "Fruit Consumption");
    $yourFirstChart["xAxis"] = array("categories" => ['Apples', 'Bananas', 'Oranges']);
    $yourFirstChart["yAxis"] = array("title" => array("text" => "Fruit eaten"));

    $yourFirstChart["series"] = [
        array("name" => "Jane", "data" => [1,0,4]),
        array("name" => "John", "data" => [5,7,3])
    ];
    return view('finances.dashboard', compact('yourFirstChart'));
}

Now add the route to routes.php:

Route::get('dashboard', 'DashboardController@index');

And finally, create the dashboard.blade.php view itself. Note that you will also need the actual highcharts.js and jQuery libraries (or the stand-alone framework if you don't want to use jQuery!) - in my case they are simply declared in the parent view which is why they aren't included in the dashboard child view below. Anyways, we are now JSON encoding the $yourFirstChart array as passed in from the controller, and escaping the whole thing:


@extends('app')

@section('content')
<div id="container" style="width:100%; height:400px;"></div>
<script type="text/javascript" src="{{ asset('js/highcharts.js') }}"></script>

<script type="text/javascript">
    $(function () {
        $('#container').highcharts(
            {!! json_encode($yourFirstChart) !!}
        );
    })
</script>
@endsection

Your IDE probably won't like the syntax mixture very much, but it will inject a completely valid JSON into the <script>. And the best part is that the JSON is generated from a PHP array that can receive all the usual Eloquent database objects, thus completing the missing data link between HighCharts and Laravel. If all went well you should see the example chart in all its interactive glory like below - go ahead and click the items in the legend!



2 comments :

  1. Replies
    1. You can use Laravel's Eloquent ORM to access your database. Check out their documentation at https://laravel.com/docs/master/eloquent#retrieving-multiple-models. Once you have your model instance, you can do further queries on it to get the data you want, and then start building your Highcharts object like above.

      https://laracasts.com/series/laravel-5-fundamentals/episodes/9 is another good resource series to learn how to access your database.

      Cheers!

      Delete