Embed Analytics Using the Google Analtyics API

Mar 7, 2012
JavaScript PHP
169 Shares
By

Google Analtyics gives so much data that sometimes it becomes hard to digest. For larger sites it is easy to become so overwhelmed that you can’t find the time to look up the analtyics for each page.

Or maybe you have many editors for a site who don’t have access to your Google Analtyics account and you want to provide them with data so they can see how well their pages are performing.

With the Google Analytics API we can easily display some basic analytics right in each page.  Google offers many libraries for exporting your data or you can use a community developed library like the GAPI PHP library created by Stig Manning which I’ll be using in this example.

The final result will be a nice graph and data that tells us some useful information about how well each page is performing:

Final result Google Charts with Google Analtyics

Starting off, pulling the data

Download the latest version of GAPI and extract it to a location in your site folder. Open your page template file and find where you want to place your analtyics and then include the class you just extracted:

require('gapi.class.php');

In order to connect to Google Analytics we have to supply login information and the profile id of the specific account profile we want to connect to. While we’re defining variables, let’s also define the page URL that we want to retrieve analytics for.

$ga_email = '[email protected]';
$ga_password = 'yourpassword';
$ga_profile_id = '12345678';
$ga_url = $_SERVER['REQUEST_URI'];

I’m not a fan of hardcoding login information into my code, but this method prevents other users from needing login access to your account to retrieve the data.

To find the profile id in Google Analytics, go to the settings page of your profile (gear icon in top right) then click on the Profile Settings tab and you will see the profile id.

Google Analtyics Profile ID

Now let’s use the GAPI class to create a query and pull five metrics: pageviews, unique pageviews, exit rate, average time on page and the bounce rate. All of these metrics will be based upon the page we’re viewing. The GAPI documentation shows how to structure the query using the requestReportData() function:

requestReportData($report_id, $dimensions, $metrics, $sort_metric=null, $filter=null, $start_date=null, $end_date=null, $start_index=1, $max_results=30)

So here’s our query which we’ll save the results to the $results variable:

$ga = new gapi($ga_email,$ga_password);
$ga->requestReportData($ga_profile_id, 'pagePath', array('pageviews', 'uniquePageviews', 'exitRate', 'avgTimeOnPage', 'entranceBounceRate'), null, 'pagePath == '.$ga_url);
$results = $ga->getResults();

If no start and end date are given, GAPI will  return the results for the last 30 days by default.

Displaying the data

Before we display these results let’s create a function to convert seconds into minutes. This will be useful for displaying the average time on page, which by default returns the result in seconds.

function secondMinute($seconds) {
  $minResult = floor($seconds/60);
  if($minResult < 10){$minResult = 0 . $minResult;}
  $secResult = ($seconds/60 - $minResult)*60;
  if($secResult < 10){$secResult = 0 . round($secResult);}
  else { $secResult = round($secResult); }
  return $minResult.":".$secResult;
}

Now it’s just a matter of parsing through the results and displaying them however you want.

echo '<div id="page-analtyics">';
foreach($results as $result) {
  echo '<div><span>Pageviews</span><br /><strong>'.number_format($result->getPageviews()).'</strong></div>';
  echo '<div><span>Unique pageviews</span><br /><strong>'.number_format($result->getUniquepageviews()).'</strong></div>';
  echo '<div><span>Avg time on page</span><br /><strong>'.secondMinute($result->getAvgtimeonpage()).'</strong></div>';
  echo '<div><span>Bounce rate</span><br /><strong>'.round($result->getEntrancebouncerate(), 2).'%</strong></div>';
  echo '<div><span>Exit rate</span><br /><strong>'.round($result->getExitrate(), 2).'%</strong></div>';
  echo '<div style="clear: left;"></div>';
}
echo '</div>';

GAPI gives easy to use functions for pulling metrics like:

getPageviews() and getAvgtimeonpage()

Now we are going to want to add some CSS. Of course you can make up your own and customize it to blend in with your site.

<style type="text/css">
#page-analtyics {
  clear: left;
}
#page-analtyics .metric {
  background: #fefefe; /* Old browsers */
    background: -moz-linear-gradient(top, #fefefe 0%, #f2f3f2 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fefefe), color-stop(100%,#f2f3f2)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* IE10+ */
    background: linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefefe', endColorstr='#f2f3f2',GradientType=0 ); /* IE6-9 */
  border: 1px solid #ccc;
  float: left;
  font-size: 12px;
  margin: -4px 0 1em -1px;
  padding: 10px;
  width: 105px;
}
#page-analtyics .metric:hover {
  background: #fff;
  border-bottom-color: #b1b1b1;
}
#page-analtyics .metric .legend {
  background-color: #058DC7;
  border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
  font-size: 0;
  margin-right: 5px;
  padding: 10px 5px 0;
}
#page-analtyics .metric strong {
  font-size: 16px;
  font-weight: bold;
}
#page-analtyics .range {
  color: #686868;
  font-size: 11px;
  margin-bottom: 7px;
  width: 100%;
}
</style>

This is how things should look so far:

Analytics preview

Adding a chart

Most people who use Google Analytics are familiar with the big blue charts that display pageviews or visits. Using the Google Charts API in combination with the Google Analtyics API we can add a visually similar chart to our in page analytics that displays the number of pageviews over the last 30 days. I won’t breakdown the Charts API to a great amount of detail but if you want to learn more Google offers some excellent documentation for it.

Continuing from the example abov,e we can reuse the $ga and $ga_url variables to create a new GAPI request. However, instead of retrieving the total results over a span of time we need to get individual results for each day so we can feed this data to the chart. The trick to this is to setup the query to use both a dimension and filter of ‘date’. This will return the number of pageviews for every day in the last 30 days.

$ga->requestReportData($ga_profile_id, array('date'),array('pageviews'), 'date', 'pagePath == '.$ga_url);           
$results = $ga->getResults();

Next, setup a spot in your page template that will contain the chart, this will initially be an empty div that will later be modified by the Google Charts API.

<div id="chart"></div>

Include the Google Charts API

<script type="text/javascript" src="https://www.google.com/jsapi"></script>

In this case we will use a bit of JavaScript to create a new chart populated by the data we retrieved. Load the Google Charts API and tell it to use a function we will create called drawChart().

<script type="text/javascript"> 
google.load("visualization", "1", {packages:["corechart"]}); 
google.setOnLoadCallback(drawChart);

Now it’s time to create the function drawChart(). This function will start off by defining the columns of data that will be used in the chart. You can think of the columns as being each axis of a graph.

function drawChart() {   
  var data = new google.visualization.DataTable();       
  data.addColumn('string', 'Day');   
  data.addColumn('number', 'Pageviews');

Once the data structure for the chart is setup it can accept the data pulled from GAPI. Google Charts uses the function addRows() that can accept comma separated arrays of data.

Each of these arrays will contain one day and the number of pageviews for that day.

data.addRows([     
  <?php     
  foreach($results as $result) {         
    echo '["'.date('M j',strtotime($result->getDate())).'", '.$result->getPageviews().'],';     
  }
  ?>   
]);

Finally, create a chart and pass it the data we just set up. You will see there are several variables in this section which can be adjusted to fit your template such as width, height and title. The specific chart in use is the Google’s Area Chart in case you want to look up additional options.

  var chart = new google.visualization.AreaChart(document.getElementById('chart'));   
  chart.draw(data, {width: 630, height: 180, title: '<?php echo date('M j, Y',strtotime('-30 day')).' - '.date('M j, Y'); ?>',                     
    colors:['#058dc7','#e6f4fa'],                     
    areaOpacity: 0.1,                     
    hAxis: {textPosition: 'in', showTextEvery: 5, slantedText: false, textStyle: { color: '#058dc7', fontSize: 10 } },                     
    pointSize: 5,                       
    legend: 'none',                     
    chartArea:{left:0,top:30,width:"100%",height:"100%"}   
  }); 
} // End of drawChart()
</script>

That’s it! You should now have a working chart. You can even hover your mouse over each point and it will tell you the exact number of pageviews for that day.

Analytics chart

Full example

Below, you can see what the code looks like when everything is put together. If you would like to see it in action, simply modify the email, password and Google id in the code below to match your individual credentials.

<style type="text/css">
/* IN PAGE ANALYTICS */
#page-analtyics {
    clear: left;
}
#page-analtyics .metric {
    background: #fefefe; /* Old browsers */
        background: -moz-linear-gradient(top, #fefefe 0%, #f2f3f2 100%); /* FF3.6+ */
        background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#fefefe), color-stop(100%,#f2f3f2)); /* Chrome,Safari4+ */
        background: -webkit-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* Chrome10+,Safari5.1+ */
        background: -o-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* Opera 11.10+ */
        background: -ms-linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* IE10+ */
        background: linear-gradient(top, #fefefe 0%,#f2f3f2 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fefefe', endColorstr='#f2f3f2',GradientType=0 ); /* IE6-9 */
    border: 1px solid #ccc;
    float: left;
    font-size: 12px;
    margin: -4px 0 1em -1px;
    padding: 10px;
    width: 105px;
}
#page-analtyics .metric:hover {
    background: #fff;
    border-bottom-color: #b1b1b1;
}
#page-analtyics .metric .legend {
    background-color: #058DC7;
    border-radius: 5px;
        -moz-border-radius: 5px;
        -webkit-border-radius: 5px;
    font-size: 0;
    margin-right: 5px;
    padding: 10px 5px 0;
}
#page-analtyics .metric strong {
    font-size: 16px;
    font-weight: bold;
}
#page-analtyics .range {
    color: #686868;
    font-size: 11px;
    margin-bottom: 7px;
    width: 100%;
}
</style>
<?php
require('gapi.class.php');

/* Define variables */
$ga_email       = '[email protected]';
$ga_password    = 'yourpassword';
$ga_profile_id  = '12345678';
$ga_url         = $_SERVER['REQUEST_URI'];

/* Create a new Google Analytics request and pull the results */
$ga = new gapi($ga_email,$ga_password);
$ga->requestReportData($ga_profile_id, array('date'),array('pageviews'), 'date', 'pagePath == '.$ga_url);    

$results = $ga->getResults();
?>   

<!-- Create an empty div that will be filled using the Google Charts API and the data pulled from Google -->
<div id="chart"></div>

<!-- Include the Google Charts API -->
<script type="text/javascript" src="https://www.google.com/jsapi"></script>

<!-- Create a new chart and plot the pageviews for each day -->
<script type="text/javascript">
  google.load("visualization", "1", {packages:["corechart"]});
  google.setOnLoadCallback(drawChart);
  function drawChart() {
    var data = new google.visualization.DataTable();

    <!-- Create the data table -->
    data.addColumn('string', 'Day');
    data.addColumn('number', 'Pageviews');

    <!-- Fill the chart with the data pulled from Analtyics. Each row matches the order setup by the columns: day then pageviews -->
    data.addRows([
      <?php
      foreach($results as $result) {
          echo '["'.date('M j',strtotime($result->getDate())).'", '.$result->getPageviews().'],';
      }
      ?>
    ]);

    var chart = new google.visualization.AreaChart(document.getElementById('chart'));
    chart.draw(data, {width: 630, height: 180, title: '<?php echo date('M j, Y',strtotime('-30 day')).' - '.date('M j, Y'); ?>',
                      colors:['#058dc7','#e6f4fa'],
                      areaOpacity: 0.1,
                      hAxis: {textPosition: 'in', showTextEvery: 5, slantedText: false, textStyle: { color: '#058dc7', fontSize: 10 } },
                      pointSize: 5,
                      legend: 'none',
                      chartArea:{left:0,top:30,width:"100%",height:"100%"}
    });
  }
</script>

<?php
$ga->requestReportData($ga_profile_id, 'pagePath', array('pageviews', 'uniquePageviews', 'exitRate', 'avgTimeOnPage', 'entranceBounceRate'), null, 'pagePath == '.$ga_url);
$results = $ga->getResults();

function secondMinute($seconds) {
    $minResult = floor($seconds/60);
    if($minResult < 10){$minResult = 0 . $minResult;}
    $secResult = ($seconds/60 - $minResult)*60;
    if($secResult < 10){$secResult = 0 . round($secResult);}
    else { $secResult = round($secResult); }
    return $minResult.":".$secResult;
}
echo '<div id="page-analtyics">';
foreach($results as $result) {
    echo '<div class="metric"><span class="label">Pageviews</span><br /><strong>'.number_format($result->getPageviews()).'</strong></div>';
    echo '<div class="metric"><span class="label">Unique pageviews</span><br /><strong>'.number_format($result->getUniquepageviews()).'</strong></div>';
    echo '<div class="metric"><span class="label">Avg time on page</span><br /><strong>'.secondMinute($result->getAvgtimeonpage()).'</strong></div>';
    echo '<div class="metric"><span class="label">Bounce rate</span><br /><strong>'.round($result->getEntrancebouncerate(), 2).'%</strong></div>';
    echo '<div class="metric"><span class="label">Exit rate</span><br /><strong>'.round($result->getExitrate(), 2).'%</strong></div>';
    echo '<div style="clear: left;"></div>';
}
echo '</div>';
?>

Additional thoughts

  • Try using your CMS to only show these analytics based upon user roles. In WordPress you could use is_admin().
  • Consider seperating this code from your template. You could put it in a seperate file like show_analytics.php and then (in WordPress) use get_template_part(‘show_analytics’).
  • Adding the chart does add a decent amount of additional load time.
Author: Seth Stevenson
Seth is a web developer based in Des Moines, IA. He focuses on PHP, WordPress and UI. Seth is currently the web developer for Des Moines University.
  • http://www.facebook.com/profile.php?id=763899195 Waylon Fourie

    This is great! Been scouring the web for the last few days looking for just this. Many thanks!

    • http://twitter.com/SethStevenson Seth Stevenson

      Hopefully it works well for you. I’ve been using it on a larger site for a while and my editors love it. Mainly it helps me see pages that are preforming poorly.

  • http://twitter.com/e11world Eddie11

    This example works in WP only? I tried it but didn’t work (my credentials are correct) so any thoughts on this?

    • http://twitter.com/SethStevenson Seth Stevenson

      Nothing WP specific in the code. It should work on any page.

  • ssh22

    It’s not working at me. I’m getting this error:
    Fatal error: Uncaught exception ‘Exception’ with message ‘GAPI: Failed to request report data. Error: “No start-date specified in URI”‘ in /var/www/public_html/lib/Google/gapi.class.php:218

    • Justin

      Same here, Did you ever get it to work? If so, what was the issue?

  • Samuel Goodwin

    excellent post. Have added it into my cms admin, so when clients go to edit the page, they can see how the page is tracking.

    • http://www.facebook.com/profile.php?id=1388697568 John-Paul de Rooij

      Can you maybe help me with my problem?

      Thank you very much!:)

  • http://twitter.com/mattritter M. Ritter

    Awesome! This is extremely useful.

  • http://twitter.com/networkaaron Aaron Kahlhamer

    I’m not a PHP expert but I removed references to

    $ga_url = $_SERVER['REQUEST_URI'];

    and added array(‘date’) to

    $ga->requestReportData($ga_profile_id, array(‘date’),array(‘pageviews’, ‘uniquePageviews’, ‘exitRate’, ‘avgTimeOnPage’, ‘entranceBounceRate’, ‘newVisits’), ‘date’);
    $results = $ga->getResults();

    and now it’s working on my server.

    Great tutorial. I’m looking for more of these because when googling this subject I’m mainly getting tutorials from the years 08 and 09.

    • rudra

      this works..
      thanks man u saved my life

    • toto

      thanks a lot man, it works now with your code changes.

  • http://www.mobifreaks.com Munawar Ahmed Mohammed

    Great post, its like a rain in the desert for me.
    i was searching for this, never thought it was nearly close to my subsciptions

  • http://www.facebook.com/profile.php?id=1388697568 John-Paul de Rooij

    Hello i have install it and it works fine but my line only going straight from the left to the right? and there are no ammounts inside it? It says 0 pageviews on every date?

    • hunt

      I have the same problem, any fixes?

  • Eawade

    Hello,
    Not sure if this thread is still alive but I have a question. I did everything according to the instructions above. However, the chart does not appear. The data shows up perfectly fine, but the chart never appears. Any suggestions?

  • Sarafandee

    Hello Guys,

    I am receving empty page views. I placed all the code in a shortcode function in WordPress. Any help would be appreciated, thank you.

  • John72atki

    Brillaint thank you to Developer

    How can i add onto addrows?

    code:

    data.addRows([
    getDate())).'", '.$result->getNewVisits().'],';
    —> add for getVisits()
    }?>]);

    I have tried to added but no display :-(

    • Excelia

      anyone know how to add new visitor and visits?

  • Johnmartinsep

    thk u for ur useful coding

  • Johnmartinsep

    how to change bar chart.

    • GA lover

      change this code :
      var chart = new google.visualization.AreaChart
      to
      var chart = new google.visualization.*******
      On the * marks you place your type of visualization.
      Example : var chart = new google.visualization.BarChart

      More information : https://developers.google.com/chart/interactive/docs/gallery

  • Justin

    Hello, Thanks for the example and explanation but I cannot seem to make this work for me. I am getting this error and I’m not sure why, maybe you can help.

    Fatal error: Uncaught exception ‘Exception’ with message ‘GAPI:
    Failed to request report data. Error: “GDatainvalidInvalid Value”‘ in
    /var/www/site/public/sales/gapi.class.php:218
    Stack trace:
    #0 /var/www/site/public/sales/googleapitest.php(57):
    gapi->requestReportData(‘123456′, Array, Array, ‘date’, ‘pagePath ==
    ‘)
    #1 {main}
    thrown in /var/www/site/public/sales/gapi.class.php on line 218

  • simplyamazin

    Wow.. it works! tried Aaron Kahlhamer suggestion and i got it working.
    Thanks!

  • GA Lover

    Great source. I got one problem. For every day i get the information ( pageviews, unique pageviews, bounce rate etc ). This is a big table (30 records) Im searching for a single row with the totals of pageviews, unique pageviews etc. What do i have to change?

    @Aaron Kahlhamer : you’re source addition rocks !

  • Emanuel

    Hi! This tutorial helps me a lot. So many thanks :)

    Is possible to draw/export the chart and data boxes in a pdf?

  • Ratan Thapa

    Hi there,

    I am getting such error in http://localhost

    Fatal error: Uncaught exception ‘Exception’ with message ‘GAPI:
    Failed to authenticate user. Error: “Request failed, fopen provides no
    further information”‘ in C:xampphtdocsgapi-1.3gapi.class.php:418
    Stack trace:
    #0 C:xampphtdocsgapi-1.3gapi.class.php(62):
    gapi->authenticateUser(‘[email protected]….’, ‘1234567890’)
    #1 C:xampphtdocsgapi-1.3index.php(12):
    gapi->__construct(‘[email protected]….’, ‘1234567890’)
    #2 {main}
    thrown in C:xampphtdocsgapi-1.3gapi.class.php on line 418

    • Excelia

      I have this same problem too, I look up for it and it might be your extension=php_curl.dll is commented inside your php.ini but the thing is I already uncomment that, but still doesn’t work for me. Anyone can help, please…

  • http://twitter.com/kevingmichaud Kevin Michaud

    Nice code. I can’t make it work. I only got a blank page. Can you help me out ?

  • Marco Jay

    An excellent starting point! Thanks

  • Xeyal

    Hello, can you anyone give me the source code of this project please?

  • Agile

    Hi not show current date in graph

  • Webteam Amsterdam

    Thanks for this tutorial! I did have a problem (error) on IE8. IE8 has trouble with an extra comma at the end of a javascript array. This foreach loop generates an extra comma:

    —-code——-
    foreach($results as $result) {
    echo ‘["'.strftime('%e %B',strtotime($result->getDate())).'", '.$result->getPageviews().'],';
    }
    —-code——-

    To get it working on IE8, you can use the php funtion rtrim(). I changed the above code to:

    —–code———
    ob_start();
    foreach($results as $result) {
    echo ‘["'.strftime('%e %B',strtotime($result->getDate())).'", '.$result->getPageviews().'],';
    }
    $output = ob_get_clean();

    data.addRows([]);

    ——–code———

  • thomas

    i get this error

    Fatal error: Uncaught exception ‘Exception’ with message ‘GAPI:
    Failed to request report data. Error: “GDatainsufficientPermissionsUser
    does not have sufficient permissions for this profile.”‘ in
    /home/udprojec/public_html/google/gapi.class.php:218
    Stack trace:
    #0 /home/udprojec/public_html/google/google.php(57):
    gapi->requestReportData(‘20745845′, Array, Array, ‘date’, ‘pagePath
    == ‘)
    #1 {main}
    thrown in /home/udprojec/public_html/google/gapi.class.php on line 218

    • Rafique Mohammed

      I have posted a solution. Hope it will works for you :-)
      http://stackoverflow.com/a/21283681/2165382

      • sonia

        hello the code is working but l’m not getting the pie chart for new visitors and returning visitos

  • VikrantKumbhar

    Showing page blank. Please suggest.

  • webfirstpro
  • harry

    how to use it in wordpress . plz the complete code

  • Mako

    A quick note on something that has just bitten me very badly. If you’re using something like “echo number_format($result->getUniquepageviews())” inside “data.addRows([” function in JavaScript, you need to be very, very careful about it, since if the result is in the thousands (like 1 600 for example) or more, it will be outputted as:

    —–code—–
    data.addRows([
    1,
    600,
    —–code—–

    To deal with this, you need to alter the “number_format()” function like this:

    —–code—–
    number_format($value->getPageviews(), 0, ‘.’, ”)
    —–code—–

    This will remove the thousands’ separator and make it valid number for JavaScript again. See the documentation for more info.
    I know, it’s not a bug, but more of a caveat I should’ve foreseen :) I hope this will save a little bit of somebody’s time.

    Cheers

  • http://www.artur.es aMirabet

    In the ” secondMinute($seconds) ” function you need to round $secResult before the condition that adds the “0” to avoid weird behaiviour in some cases:

    function secondMinute($seconds) {
    $minResult = floor($seconds/60);
    if($minResult HERE WE ROUND BEFORE THE CONDITION
    if($secResult IF NOT ROUNDED SOMETIMES I$secResult != 10 BUT THEN ROUNDED TO 10 SO WE GET 01:010 (For example)
    return $minResult.”:”.$secResult;
    }

    Sorry for my english, hope I explained it well…

  • titi

    Hello an thank you for that great Tutorial. I am receving empty page views. I placed all the code in a shortcode function in WordPress. Any help would be appreciated, thank you.