pChart Revisited with Google Analytics

Back in December, SitePoint published an introductory article I wrote on pChart, a PHP library that creates eye-catching anti-aliased charts. A reader suggested that other articles might follow with further examples, and so I decided to write this one with a handy device for visually checking website statistics with the help of Google Analytics.

Google Analytics’ API

As most people know, Analytics is Google’s tracking tool that gathers such data like the number of visitors, unique visitor, pages per visit, and country of visitors for your website. Adding Analytics requires only the creation of an account, a profile for each website, and the addition of some JavaScript code in the page(s) you want to track. If you are new to all this then please visit Google Analytics’ Help Center to learn more about setting up your accounts and getting the tracking code. Once the tracking has been deployed for a short while, you can visit the Analytics website and view the current stats for your site(s).

Also, Google Analytics has an API which your script can invoke from a GET request and receive a JSON string as response. This string, once decoded, supplies data that can be manipulated by a server-side language like PHP. For example, if you want to check the traffic statistics often and regularly for several of your sites, you can build a personal dashboard in PHP that captures the required data through the Analytics API and display it.

While the tracking code is quite straightforward to set up and use, the API is a bit more complex. Fortunately, Google and other developers provide a number of client libraries, like GAPI, the Google Analytics PHP5 Interface which is simple to use:

<?php
$ga = new gapi(USERNAME, PASSWORD);
$ga->requestReportData(REPORT_ID, DIMENSIONS, METRICS);

The first line above creates a gapi object and with it a connection to the API. The email and password required is the same you used to login and create your Analytics account. The second line invokes the method that grabs data proper. It has three mandatory arguments: the profile ID, the dimensions, and the metrics. The profile ID can be obtained from Analytics’ control panel, the same one you used to create the account. Click on the set-up icon at the right side of the menu bar, the choose the profile and click on “Profile Settings”. The profile ID is under the General Information header.

Dimensions specify the kind of report you want. For example, the dimension “date” will breakdown all of the results by date. Metrics is the information you’re after, in this case, “visitors” and “newvisits”, the latter being the percentage of first time visitors with respect to the total visitation. See the API documentation for a complete list of dimensions and metrics.

Graphing Visits

Let’s assume I want to track three websites: castleofargh.com, knightsofni.com and thecamelotfollies.com. Assuming tracking has been set up for each site, we begin to create the dashboard application by grabbing GAPI’s latest version from their download page and extracting the contents of the zipped file onto the server that will host the dashboard. Once this is done, I can write the script, which is made even simpler thanks to pChart.

Let’s start be including the necessary third-party code:

<?php
session_start();
define("PCHART_PATH", "/srv/www/lib/pChart");
define("GAPI_PATH", "/srv/www/lib/gapi");

set_include_path(get_include_path() . PATH_SEPARATOR . PCHART_PATH);
set_include_path(get_include_path() . PATH_SEPARATOR . GAPI_PATH);
require_once "class/pData.class.php";
require_once "class/pDraw.class.php";
require_once "class/pImage.class.php";
require_once "class/pPie.class.php";
require_once "gapi.class.php";

Note that pChart must be included after the session has been opened and before anything is sent to the browser otherwise “headers already sent by…” errors will arise.

Afterward, we’ll need to set up some configuration data and initialize some useful arrays. I’ve started with an array which holds the names and profile IDs of the three websites we’ll be displaying information for, and then initialized arrays to store the names of the domains, the number of visits, and the number of new visitors.

<?php
$trackedDomains = array(
    "castleofargh.com" => "56400824",
    "knightsofni.com" => "56418404",
    "thecamelotfollies.com" => "56417539");
$domainNames = array_keys($trackedDomains);
$domainVisits = array();
$domainNewVisits = array();

Since we’re keeping an eye on three sites, we’d be better off wrapping the data gathering logic in a loop:

<?php
$ga = new gapi(USERNAME, PASSWORD);
$startDate = $endDate = strftime("%Y-%m-%d");
foreach ($trackedDomains as $domainName => $profileID) {
    $ga->requestReportData($profileID, array("date"),
        array("visits", "newvisits"), null, null,
        $startDate, $endDate);
    foreach($ga->getResults() as $result) {
      $domainVisits[] = $result->getVisits();
      $domainNewVisits[] = $result->getNewVisits();
    }
}

The line above queries the API for all visits and new visitors figures for today. The two null parameters are for filtering and sorting formats and are required here only because they come before the date limits in the function’s definition statement.

reportRequestData() returns an object with one array for each day of the report. Since we’re interested only in a single date (the $startDate and $endDate values are the same), the inner loop will run only once.

At this point we have all three arrays filled with the relevant data. We’ll comes the fun part of using pChart to create a pie chart to show the percentage each of the three websites have in the day’s gross visitation.

The subsequent lines define the “points” of the graph – which for the pie chart are expressed as the angle of each sector of its circle – and the names of each website, that will be displayed as labels. Note that though the figures are presented as absolute values, pChart will later be instructed to display them as percentages.

<?php
$myPieData = new pData();
$myPieData->addPoints($domainVisits, "Visits");
$myPieData->addPoints($domainNames, "Names");
$myPieData->setAbscissa("Names");

This last instruction is necessary to use the domain names as labels.

The chart object can be thought of as a transparent canvas where we can write and plot data, and is created and given a visible boundary by like so:

<?php
$myPiePicture = new pImage(700,490, $myPieData);
$myPiePicture->drawRectangle(1,1, 699,489,
    array("R" => 0, "G" => 0, "B" => 0));
$myPiePicture->setGraphArea(50,50, 650,440);

The canvas has been specified as 700 pixels wide by 490 pixels high and will data from the dataset $myPieData will be plotted to it. The boundary is placed one pixel inside the canvas. The graph area proper was defined with a 50px margin with respect to the image object canvas.

Next, create a string to hold the picture’s title and generate the corresponding text:

<?php
$title = "Visitation Distribution Among Websites - " . 
    strftime("%m/%d/%Y", strtotime($today));
$myPiePicture->drawText(350,3, $title, array(
    "R" => 0, "G" => 0, "B" => 0,
    "FontName" => PCHART_PATH . "/fonts/calibri.ttf",
    "FontSize" => 15,
    "Align" => TEXT_ALIGN_TOPMIDDLE));
$myPiePicture->drawFilledRectangle(50,50, 650,440, 
    array("R" => 200, "G" => 200,"B" => 200));

The drawText() method places a rectangular box “pinned” to the canvas at x pixels from the left and y from the top side of the chart object area. The position on the box where it will be pinned is given by the align attribute. Above, the text area with the plot descriptor ($title) has the middle point of its top border placed at a point 350 px from the left and 3px from the top border of the canvas. I also added a grayish background rectangle with borders 50px away from the canvas’ limits.

Now let’s define a nice font and create the pie chart object. Later it will be rendered as a PNG image:

<?php
$myPiePicture->setFontProperties(array(
    "FontName" => PCHART_PATH . "/fonts/calibri.ttf",
    "FontSize" => 11));
$myPieChart = new pPie($myPiePicture, $myPieData);

pChart allows us to define the colors of the pie slices. Let’s make them red, green and blue:

<?php
$myPieChart->setSliceColor(0, array("R" => 128, "G" => 0, "B" => 0));
$myPieChart->setSliceColor(1, array("R" => 0, "G" => 128, "B" => 0));
$myPieChart->setSliceColor(2,array("R" => 0, "G" => 0,"B" => 128));

The method draw3DPie will make $myPieChart to be rendered like a 3d slanted pie. Here I used a radius of 200 pixels, which will create a rather large graph:

<?php
$myPieChart->draw3DPie(350,245, array("Radius"=>200,
    "DrawLabels" => true,"Border" => true,
    "WriteValues" => PIE_VALUE_PERCENTAGE));

All we have to do now is to render the picture with the pie chart:

<?php
$myPiePicture->Render("myPieChart.png");

In addition to the pie chart, I want a stacked bar chart to visually show the number of new visitors with respect to the total of visits. The following lines should be easy to understand but please notice that now we have 2 data series, one for visits (as for the pie chart) and another for new visitors:

<?php
$myBarData = new pData();
$myBarData->addPoints($domainVisits, "Visits");
$myBarData->addPoints($domainNewVisits, "New Visits");
$myBarData->addPoints($domainNames, "Names");
$myBarData->setAbscissa("Names");
$myBarPicture = new pImage(700,490, $myBarData);
$myBarPicture->drawRectangle(1,1, 699,489,
    array("R" => 0,"G" => 0, "B" => 0));
$myBarPicture->setGraphArea(50,50, 650,440);
$title = "Visits and New Visits - " . 
    strftime("%m/%d/%Y", strtotime($today));
$myBarPicture->drawText(350,3, $title, 
    array("R" => 0, "G" => 0, "B" => 0, 
    "FontName" => PCHART_PATH . "/fonts/calibri.ttf",
    "FontSize" => 15,
    "Align" => TEXT_ALIGN_TOPMIDDLE));
$myBarPicture->drawFilledRectangle(50,50, 650,440,
    array("R" => 200,"G" => 200, "B"=>200));
$myBarPicture->setFontProperties(array(
    "FontName" => PCHART_PATH . "/fonts/calibri.ttf",
    "FontSize" => 11));
$myBarPicture->drawScale(array("DrawSubTicks" => false,
    "Mode" => SCALE_MODE_ADDALL));

Here we create the stacked bar chart and its legend, which will be taken from the definition of the series with addPoints():

<?php
$myBarPicture->drawStackedBarChart(array("DisplayValues" => true,
    "DisplayColor" => DISPLAY_AUTO, "Rounded" => true,
    "Surrounding" => 60));
$myBarPicture->drawLegend(510,205, array("FontSize" => 12,
    "Mode" => LEGEND_HORIZONTAL));

Again, all we have to do now is to render the bar chart and…

<?php
$myBarPicture->Render("myBarChart.png");

Summary

Demo code for this article is available on GitHub for you to play with and experiment. pChart can be used for creating application as simple as these but also a full-fledged dashboard for controlling any sort of process that can be measured and presented via an API. Use any sort of refresh mechanism (such as a JavaScript reload or a meta refresh) and the script you produce can continuously display updated statistics.

Image via Alaris/ Shutterstock

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • http://www.designaeon.com raman

    Tnxxxxxxxxx

  • http://www.johnmcbride.com John

    So what I am doing wrong??

    PHP Warning: require_once(class/pData.class.php) [function.require-once]: failed to open stream: No such file or directory in C:Inetpubwwwrootgoogle_analyticsstats.php on line 11 PHP Fatal error: require_once() [function.require]: Failed opening required ‘class/pData.class.php’ (include_path=’.;C:php5pear;/srv/www/lib/pChart;/srv/www/lib/gapi’) in C:Inetpubwwwrootgoogle_analyticsstats.php on line 11

    • http://zaemis.blogspot.com Timothy Boronczyk

      It looks like your paths are not correct. The lines:
      define(“PCHART_PATH”, “/srv/www/lib/pChart”);
      define(“GAPI_PATH”, “/srv/www/lib/gapi”);
      need to be changed to point to where you’ve put the pChart and GAPI libraries on your system.

  • http://Dadlitraders.com Curtis

    Lovely, I could do alot with this

  • http://jeungun.wordpress.com Jeune

    Interesting library! How do the charts render in html?

    • J Armando Jeronymo

      Hi Jeune,
      what exactly do you mean?

      • http://jeungun.wordpress.com Jeune

        I meant, what happens under the hood of the render method? Does it somehow make an image out of the values given to it and then display the image or does it render it in HTML5/SVG?

        • J Armando Jeronymo

          pChart renders a PNG image and saves it on the PHP server. The browser can display it with an tag. I hope this helps.

          • http://jeungun.wordpress.com Jose Asuncion

            Thanks Armando! All makes sense now.