Embed API

Working with Custom Components

Demo Overview

The built-in components that ship with the Embed API are very nice, but sometimes you need to do more. This example shows how you can extend the Embed API to use your own custom components.

The two components used in this dashboard are DateRangeSelector and ViewSelector2.

Date range selector component

The date range selector component allows you to pick various start and end dates. Whenever a new date is chosen, a "change" event is emitted and the date values can be passed to a query component (e.g. DateChart).

Enhanced view selector component

The built in view selector is pretty nice, but it only gives you the ids property when you change views. If you want to get any additional information (like the name of the view or the account it belongs to) you're out of luck. The ViewSelector2 component extends the functionality of the native ViewSelector to offer these additional features.

In the demo below, when you change views, the dashboard title is updated with the new view and property name.

Select a View

Comparing sessions from last week to this week

How it works

You can recreate the demo above by copy and pasting the following code into an HTML file running on a web server. Feel free to add some CSS to spice it up a bit!

To learn how to build your own component, check out the creating custom components developer guide. For general information about the Embed API, check out the documentation on our developers site.

Step 1: Load the Embed API library.

<script>
(function(w,d,s,g,js,fs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
  js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
</script>

Step 2: Add HTML containers to host the dashboard components.

<div id="embed-api-auth-container"></div>
<div id="view-selector-container"></div>
<div id="data-chart-1-container"></div>
<div id="date-range-selector-1-container"></div>
<div id="data-chart-2-container"></div>
<div id="date-range-selector-2-container"></div>

Step 3: Load the components and their dependencies.

<!-- Include the ViewSelector2 component script. -->
<script src="/public/javascript/embed-api/components/view-selector2.js"></script>

<!-- Include the DateRangeSelector component script. -->
<script src="/public/javascript/embed-api/components/date-range-selector.js"></script>

Note: custom component files create new constructor functions on the gapi.analytics.ext object, so in this case once these scripts are loaded the components can be found at gapi.analytics.ext.ViewSelector2 and gapi.analytics.ext.DateRangeSelector.

Step 4: Write the dashboard code.

<script>

gapi.analytics.ready(function() {

  /**
   * Authorize the user immediately if the user has already granted access.
   * If no access has been created, render an authorize button inside the
   * element with the ID "embed-api-auth-container".
   */
  gapi.analytics.auth.authorize({
    container: 'embed-api-auth-container',
    clientid: 'REPLACE WITH YOUR CLIENT ID'
  });


  /**
   * Store a set of common DataChart config options since they're shared by
   * both of the charts we're about to make.
   */
  var commonConfig = {
    query: {
      metrics: 'ga:sessions',
      dimensions: 'ga:date'
    },
    chart: {
      type: 'LINE',
      options: {
        width: '100%'
      }
    }
  };


  /**
   * Query params representing the first chart's date range.
   */
  var dateRange1 = {
    'start-date': '14daysAgo',
    'end-date': '8daysAgo'
  };


  /**
   * Query params representing the second chart's date range.
   */
  var dateRange2 = {
    'start-date': '7daysAgo',
    'end-date': 'yesterday'
  };


  /**
   * Create a new ViewSelector2 instance to be rendered inside of an
   * element with the id "view-selector-container".
   */
  var viewSelector = new gapi.analytics.ext.ViewSelector2({
    container: 'view-selector-container',
  }).execute();


  /**
   * Create a new DateRangeSelector instance to be rendered inside of an
   * element with the id "date-range-selector-1-container", set its date range
   * and then render it to the page.
   */
  var dateRangeSelector1 = new gapi.analytics.ext.DateRangeSelector({
    container: 'date-range-selector-1-container'
  })
  .set(dateRange1)
  .execute();


  /**
   * Create a new DateRangeSelector instance to be rendered inside of an
   * element with the id "date-range-selector-2-container", set its date range
   * and then render it to the page.
   */
  var dateRangeSelector2 = new gapi.analytics.ext.DateRangeSelector({
    container: 'date-range-selector-2-container'
  })
  .set(dateRange2)
  .execute();


  /**
   * Create a new DataChart instance with the given query parameters
   * and Google chart options. It will be rendered inside an element
   * with the id "data-chart-1-container".
   */
  var dataChart1 = new gapi.analytics.googleCharts.DataChart(commonConfig)
      .set({query: dateRange1})
      .set({chart: {container: 'data-chart-1-container'}});


  /**
   * Create a new DataChart instance with the given query parameters
   * and Google chart options. It will be rendered inside an element
   * with the id "data-chart-2-container".
   */
  var dataChart2 = new gapi.analytics.googleCharts.DataChart(commonConfig)
      .set({query: dateRange2})
      .set({chart: {container: 'data-chart-2-container'}});


  /**
   * Register a handler to run whenever the user changes the view.
   * The handler will update both dataCharts as well as updating the title
   * of the dashboard.
   */
  viewSelector.on('viewChange', function(data) {
    dataChart1.set({query: {ids: data.ids}}).execute();
    dataChart2.set({query: {ids: data.ids}}).execute();

    var title = document.getElementById('view-name');
    title.textContent = data.property.name + ' (' + data.view.name + ')';
  });


  /**
   * Register a handler to run whenever the user changes the date range from
   * the first datepicker. The handler will update the first dataChart
   * instance as well as change the dashboard subtitle to reflect the range.
   */
  dateRangeSelector1.on('change', function(data) {
    dataChart1.set({query: data}).execute();

    // Update the "from" dates text.
    var datefield = document.getElementById('from-dates');
    datefield.textContent = data['start-date'] + '&mdash;' + data['end-date'];
  });


  /**
   * Register a handler to run whenever the user changes the date range from
   * the second datepicker. The handler will update the second dataChart
   * instance as well as change the dashboard subtitle to reflect the range.
   */
  dateRangeSelector2.on('change', function(data) {
    dataChart2.set({query: data}).execute();

    // Update the "to" dates text.
    var datefield = document.getElementById('to-dates');
    datefield.textContent = data['start-date'] + '&mdash;' + data['end-date'];
  });

});
</script>