ChartJS Reporting in Your Laravel Project

I am addicted to analytics. My wife reminds me of this every time she sees me looking at Google Analytics, Tweet metrics, etc. So of course I have put a little analytics in to Linuxphile.  I wanted to get an idea of how many views and comments were coming in.  I have limited my scope to the top 10 posts.  I looked around at the Javascript libraries available, (d3, ChartJs, Chartist, etc).  I settled on ChartJS because it looked fairly simple to implement and my requirements, at this time, are minimal. I wanted a pie chart, a bar chart, and I wanted the data to be fed using AJAX calls with JSON data returned. 

To get started you'll need to head over to http://www.chartjs.org/ and grab the latest version of the library.  I have placed the library in the public/js folder.  To begin the process I created a ReportsController to handle the data requests and delegate to a dashboard view.  There are two methods in the ReportsController at this point:

 

 /**
     * Retrieve and return the posts view/comments metrics 
     *
     * @return JSON
     */
    public function postMetrics( ) {
        $views = Posts::orderBy('views', 'desc')->take(10)->get();
        $labels = array();
        $viewDataset = array();
        $commentDataset = array();
        foreach ($views as $view) {

            array_push($labels, $view->title);
            array_push($viewDataset, $view->views);
            array_push($commentDataset, $view->comments->count());
        }

        $viewData = array('labels'=>$labels, 'datasets'=> array (
            array('label'=> "Post Views",
                'fillColor'=> "rgba(231,35,55,0.5)",
                'strokeColor'=> "rgba(220,220,220,0.8)",
                'highlightFill'=> "rgba(179,151,161,0.75)",
                'highlightStroke'=> "rgba(220,220,220,1)",
                'data'=>$viewDataset),
            array('label'=> "Post Comments",
                'fillColor'=> "rgba(220,220,220,0.5)",
                'strokeColor'=> "rgba(220,220,220,0.8)",
                'highlightFill'=> "rgba(220,220,220,0.75)",
                'highlightStroke'=> "rgba(220,220,220,1)",
                'data'=>$commentDataset)

        ));
        return (json_encode($viewData)   );
    }
    /**
     * Show the application dashboard to the user.
     *
     * @return Response
     */
    public function dashboard() {

        return view('reports.dashboard');
    }

The dashboard method is self explanatory, so we will gloss over that. Focusing on the postMetrics method we start by grabbing the posts. You will notice we order by views, a field that is incremented each time a non-admin user views the posts. Notice also that we are taking only the first 10. This should ensure we get only the most active posts. There are three arrays following the posts retrieval: labels, viewsDataSet, commentDataSet. All three are initialized and then populated within the foreach loop beneath. We are doing it this way to present a JSON object that ChartJS can accept immediately and without modification. Instead of building this within your controller you could easily do this within the Javascript that will present/build the chart, however, I prefer to put the processing on the server side rather than the client. In the foreach we grab the title of each posts, the total views, and the count of comments on that post each pushed into the appropriate array. Once we've built out the three arrays we can then build the object that will be passed back to ChartJS. You'll notice we have 2 data sets defined here along with the labels array.


$viewData = array('labels'=>$labels, 'datasets'=> array (
            array('label'=> "Post Views",
                'fillColor'=> "rgba(231,35,55,0.5)",
                'strokeColor'=> "rgba(220,220,220,0.8)",
                'highlightFill'=> "rgba(179,151,161,0.75)",
                'highlightStroke'=> "rgba(220,220,220,1)",
                'data'=>$viewDataset),
            array('label'=> "Post Comments",
                'fillColor'=> "rgba(220,220,220,0.5)",
                'strokeColor'=> "rgba(220,220,220,0.8)",
                'highlightFill'=> "rgba(220,220,220,0.75)",
                'highlightStroke'=> "rgba(220,220,220,1)",
                'data'=>$commentDataset)

        ));

In each of the datasets we provide a label for the set, the color options, and finally the array of data to be presented. I am desgine retarded so you'll have to figure our the RGB color options for each of the variables.

Now might be a good time to go ahead and create the routes for both these methods.


Route::any('/postmetrics', ['as'=>'post.metrics', 'middleware'=>'auth', 'uses'=>'ReportsController@postMetrics']);
Route::any('/admin/dashboard', ['as'=>'admin.dashboard', 'middleware'=>'auth', 'uses'=>'ReportsController@dashboard']);
 

Now on to the reports.dashboard view where we will define the canvas element and Javascript required to present the chart.


    <script src="/js/Chart.min.js"></script>
    <script>
        $(document).on('ready', function() {

            $.ajax({
                url: "/postmetrics",
                data: {_token: "{!!csrf_token()!!}"},
                dataType: 'json',
                method: "post"


            }).done(function (data) {
                var ctx = document.getElementById("myChart").getContext("2d");
                var myBarChart = new Chart(ctx).Bar(data);
            });

        });

    </script>
    <div class="container">
    <div class="panel panel-default">
        <div class="panel-heading"><h2>Views and Comments</h2></div>
        <div class="panel-body text-centered">
            <canvas id="myChart" width="400" height="400"></canvas>
        </div>
    </div>
    </div>

Most of the magic here is within the Javascript, however, you will need an HTML5 canvas element to handle the rendered chart. Go ahead and create a canvas element, remembering to note the id you provide. In my case I am using postMetrics. With the canvas element defined and the ChartJS library imported we get to the good stuff. We have created a document ready function that uses an AJAX call to the /postmetrics route and once complete passes that data to the ChartJS initiatlization. Because we built the JSON just as ChartJS expects we do not have to implement any special processing of the data such as cutting out only the elements from the JSON object that are required for ChartJS.

The end result I have (don't judge these lowly metrics) are:

chartjssample.png

I hope you have found this quick tutorial and helpful. If you have please post a comment below and let me know what you think. Let me know also if you any improvements.

0 Comments



Post Comment