Wissen

KNOW-HOW FÜR FORTSCHRITT

In diesem Artikel geht es um die Benutzung der Google Analytics Embed API, um Daten eigener Analytics-Konten, beispielsweise auf Webseiten, anzuzeigen. In diesem Zusammenhang ist ein eigenständiges Modul – ngAnalytics – mit verschiedenen Direktiven entstanden, welches den Umgang mit der API ein wenig vereinfachen soll. Zu Beginn des Beitrags werden die Grundlagen der API erklärt und im Anschluss das Angular-Modul vorgestellt.

Voraussetzung

Vorbereitung

Wie bei jeder Nutzung einer Google API muss diese erst eingerichtet und aktiviert werden. Für die Google Analytics API müssen folgenden Schritte durchgeführt werden.

  1. Google Entwickler Konsole aufrufen
  2. Projekt anlegen oder vorhandenes öffnen
  3. In der Seitennavigation APIs auswählen
  4. Analytics API suchen und aktivieren
  5. In der Seitennavigation Zugangsdaten auswählen
  6. OAuth Client ID erzeugen, falls noch nicht vorhanden
  7. Client-ID wird später zu Authentifizierung benötigt

Einstieg in die API

Ein einfaches Beispiel zur normalen Benutzung der API kann unter https://ga-dev-tools.appspot.com gefunden werden. Hier werden auch die zwei grundlegenden Schritte deutlich.

  1. Embed API einbinden
  2. Authentifizierung/Autorisierung
  3. Inhalt erstellen/anzeigen

Embed API einbinden

Als ersten Schritt muss natürlich der Google-Code geladen werden, damit die API genutzt werden kann.

<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>

Danach kann ein eigener Skrip-Inhalt definiert werden. Es sollte jedoch drauf gewartet werden, dass die Google-API auch fertig geladen ist.

<script>
gapi.analytics.ready(function() {
// Google API ist bereit und kann benutzt werden.
});
</script>

Authentifizierung/Autorisierung

Google bindet hier automatisch einen Button ein, falls man nicht autorisiert ist. Andernfalls erscheint die E-Mail-Adresse des Google-Accounts.
Dazu benötigt Google einen DOM-Knoten, worin dieser Inhalt angezeigt wird.

<div id="embed-api-auth-container"></div>

Nun wird die erstellte Client-ID benötigt.

gapi.analytics.auth.authorize({
container: 'embed-api-auth-container', // id des DOM-Knoten
clientid: 'CLIENT ID',
});

Inhalt erstellen/anzeigen

Nach der Autorisierung können dann die Goolge Analytics Inhalte, wie Diagramme, View-Selektoren oder Daten-Reports angezeigt werden.

  • Diagramm – DataChart – Diagramm mit konfigurierbaren Inhalten
  • View-Selektor – ViewSelector – DropDown-Auswahl von verschiedenen Ansichten und Webseiten
  • Report-Data – ReportData – Anfrage zu bestimmten Daten

DataChart

Ein DataChart ist im allgemeinen ein Diagramm, welches aufbereitete Daten anzeigt. Auch hier vereinfacht Google den Umgang und übernimmt das Anzeigen dieser Komponente. Die einzige Schwierigkeit ist, die richtige Konfiguration zu finden. Es lassen sich einfach Torten-, Linien- und Säulen-Diagramme erzeugen. Damit Google weiß, wo das Diagramm dargestellt werden soll, wird auch hier wieder ein extra DOM-Knoten benötigt.

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

Nach dem Authentifizieren kann nun ein Diagramm erstellt werden, welches mit dem DOM-Knoten verknüpft wird.

// Diagramm erzeugen
var dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
ids: 'VIEWIDS' // View IDs eintragen
metrics: 'ga:sessions',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'chart-container', // Diagramm DOM-Knoten
type: 'LINE',
options: {
width: '100%'
}
}
});
// Diagramm anzeigen
dataChart.execute();

Im Quellcode zur Diagrammerzeugung gibt es einen Schlüssel mit dem Namen ids. Hier wird eine (oder mehrere) View-Id eingetragen. Eine View kann wie folgt konfiguriert oder angesehen werden: Im Analytics-Konto auf Verwalten wechseln, ein Konto auswählen, im Abschnitt Datenansicht kann eine View erstellt, konfiguriert, gelöscht oder angesehen werden. Unter Einstellungen der Berichtdatenansicht kann die ID der View gefunden werden. Ein Diagramm muss immer mit mindestens einer View verknüpft werden.

ViewSelector

Ein ViewSelector ist nichts anderes als ein bestimmte Anzahl von Auswahllisten zur Filterung von Daten, beispielsweise nach Konto und/oder View. Wie bei den anderen Komponenten auch wird hier ein DOM-Knoten benötigt, in dem Google den Inhalt anzeigt.

<div id="view-selector-container"></div>

Danach kann der ViewSelector erzeugt und angezeigt werden.

// Erzeugt ViewSelector
var viewSelector = new gapi.analytics.ViewSelector({
container: 'view-selector-container' // DOM-Knoten ID
});
// ViewSelector anzeigen
viewSelector.execute();

Verknüpfung von DataChart und ViewSelector

Natürlich ist der reine ViewSelector, wie er jetzt zu sehen ist, unbrauchbar. Die Auswahllisten sind sicht- und änderbar, aber eine Veränderung hat keinen Effekt. Aus diesem Grund bietet Google die Möglichkeit Diagramme (aber auch andere Komponenten) mit einem ViewSelector zu verknüpfen.

Als Beispiel wird jetzt das DataChart aus 4.3.1 mit dem ViewSelector aus 4.3.2 verknüpft. Als ersten Schritt wird der ‚ids‘ Schlüssel aus dem Diagramm-Options-Objekt entfernt und verhindert, dass es angezeigt wird. Bliebe die Anzeige bestehen, würde Google einne Fehler zurückgeben, da Google den Schlüsser ‚ids‘ zur Anzeige erwartet.

// Diagramm erzeugen
var dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
// keine View IDs mehr
metrics: 'ga:sessions',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'chart-container',
type: 'LINE',
options: {
width: '100%'
}
}
});
// Diagramm nicht mehr anzeigen
Durch die Verknüpfung mit dem ViewSelector müssen die nun fehlenden Daten gesetzt und die Anzeige des Diagramms angestoßen werden. Dafür bietet der ViewSelector verschiedene Events auf die reagiert werden kann. Für dieses Beispiel soll darauf reagiert werden, wenn sich die Auswahl im ViewSelector ändert.
// Höre auf Änderungen im ViewSelector
viewSelector.on('change', function (ids) {
// auf ids stehen die zutreffenden/ausgewählten View IDs
// Setzt die IDs und zeigt das Diagramm an 
dataChart.set({query: {ids: ids}}).execute();
});

ReportData

ReportDatas sind eine zusätzliche Möglichkeit, Daten von der Google-Schnittstelle zu einer View zu erhalten. Dabei wird jedoch kein Inhalt angezeigt. Stattdessen funktioniert es wie eine einfache Anfrage, die Daten in JSON-Form zurückliefert. Im folgenden ein kleines Beispiel dafür.

// Report-Anfrage erstellen
var data = new gapi.analytics.report.Data({
query: {
ids: 'ga:VIEWID', // View IDs
metrics: 'ga:sessions',
dimensions: 'ga:city'
}
});
// Erfolgsfall
report.on('success', function(response) {
console.log(response);
});
// Fehlerfall
report.on('error', function(response) {
console.log(response);
});
// Report-Anfrage absenden.
report.execute();

4.3.5 Verknüpfung von ReportData und ViewSelector

Die Verknüpfung folgt im Grunde genau dem gleichen Prinzip, wie das Verknüpfen von Diagramm und ViewSelector. Die ‚ids‘ werden nicht direkt gesetzt und der Report auch nicht ausgeführt. Erst wenn sich der ViewSelector ändert, werden die Ids gesetzt und dann die Anfragen abgesendet.

Implementierung in AngularJS

Die normale Vorgehensweise zur Benutzung der Google Analytics API ist für AngularJS oder generell für den App-Kontext (ob nun Web- oder Mobile App) sehr umständlich und bietet wenig Flexibilität. Es beginnt mit der festen Einbindung des Analytics-Scripts, über die Erzeugung von generischen Diagrammen bis hin zur Verknüpfung dieser mit ViewSelektoren.

Vorbetrachtung

Bevor programmiert wird, kommen diverse Fragen auf, die vorher geklärt werden müssen.

  • Modularer Einsatz? – Ja!
  • Wie wird es Modular? – Ein eigenes Module mit verschiedenen Directives!
  • Wie können diese miteinander interagieren (siehe 4.3.3, 4.3.5)? – Ein Service!
  • Welche der vorgestellten Funktionen sollen abgebildet werden? – Möglichst alle!

Daraus leitet sich im Grunde der Implementierungsablauf ab.

Ablauf

  1. Ein Modul
  2. Ein Service zu Autorisierung und Verknüpfung der Komponenten
  3. Direktiven für Reports, ViewSelectors, DataCharts

Implementierung

Das Modul

Schlicht und einfach eine normale AngularJS Module-Deklaration.

angular.module("ngAnalytics", [])

Der Service

Hier stellt sich die Frage, was der Service alles können muss.

  • Client ID speichern -> Getter und Setter
  • Speichern, ob bereits autorisiert
  • Speichern, ob Analytics geladen ist
app.service('ngAnalyticsService', [
function() {
var clientId; // Speichert Client ID
this.ga = null; // Wrapper für Analytics
this.setClientId = function(id) { // Setter für ClientId
clientId = id;
return id;
};
this.getClientId = function() { // Getter für ClientId
return clientId;
};
this.authorize = function(container) { // Autorisierung
this.ga.auth.authorize({
container: container,
clientid: clientId,
userInfoLabel: this.authLabel // Anzeige, wenn eingeloggt
});
};
this.viewSelectors = {}; // Objekt von View Selektoren
this.isReady = false; // Flag, ob Analytics API geladen
this.authLabel = undefined; // Label
this.authorized = false; // Flag, ob autorisiert
}
]);

API Code einbinden

Damit mit der API gearbeitet werden kann, muss diese natürlich erstmal irgendwie eingebunden werden. Ein geeigneter Zeitpunkt wäre direkt nach dem eigentlich späteren App-Start. Dafür bietet sich in Angular der sogenannte run-Block an. Dort muss das Google-Analytics-Skript eingebunden, geladen werden und die entsprechenden Service-Flags gesetzt werden.

app.run([
'$timeout',
'ngAnalyticsService',
function($timeout, ngAnalyticsService) {
// Erzeugt einen Script-Tag und setzt dort den Analytics Code ein und fügt den DOM-Knoten an das Ende der Seite.
var gaCode = document.createTextNode("(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'));");
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.appendChild(gaCode);
document.body.appendChild(scriptTag);
// Wenn Analytics geladen wurde wird, wird es auf dem Wrapper gespeichert und das isReady Flag gesetzt.
gapi.analytics.ready(function() {
$timeout(function() {
ngAnalyticsService.ga = gapi.analytics;
ngAnalyticsService.isReady = true;
}, 0);
});
}
]);

Die Direktiven

Die Direktiven sind im Grunde das Kernstück des Moduls. Um den Rahmen nicht zu sprengen, werden im folgenden Kontext die Funktionsweisen dieser nur wörtlich erklärt.

Autorisierung

Diese Direktive kümmert sich darum den Autorisierungsbutton oder falls eingeloggt – und gewünscht – einen Hinweis dazu anzuzeigen. Daraus ergeben sich folgende Konfigurationsparameter für die Direktive:

  • authContainer – Zeichenkette mit der ID des zu erstellenden DOM-Knotens
  • label – optionaler Text, falls man eingeloggt ist
  • hideOnAuth – optionaler Parameter (‚true|false‘), ob Hinweis über eingeloggten Account angezeigt werden soll

Aus diesen Parametern lässt sich die Autorisierung möglichst flexibel erstellen. Des Weiteren hört die Direktive darauf, ob Google Analytics bereit ist, setzt daraufhin die Autorisierungsoptionen und erstellt den benötigten DOM-Knoten.

ViewSelector

Hier sollen einfach ViewSelectors erstellt werden können ohne etwas über die nötigen Strukturen von diesen zu wissen. Auch hier wird wieder ein DOM-Knoten benötigt und der Selector darf erst angezeigt (ausgeführt) werden, wenn die Autorisierung bei Google geklappt hat. Dadurch wird auch eine Verknüpfung zur Autorisierung benötigt.

  • viewSelectorContainer – ID des zu erzeugenden DOM-Knoten für den ViewSelector
  • authContainer – ID des zu verknüpfenden Autorisierungsknotens

Wird ein ViewSelector erzeugt, wird dieser im Service gespeichert, um später andere Komponenten mit diesem zu verbinden.

DataChart

Ein Diagramm benötigt wieder die Verknüpfung mit dem Autorisierungsknoten und die Konfigurationsparameter eines Google-Diagramms (DOM-Knoten, Achsen, Daten, …). Zusätzlich kann es mit einem ViewSelector verbunden werden. Daraus ergeben sich wieder folgende Attribute.

  • viewSelectorContainer – ID des ViewSelectors
  • authContainer – ID des Autorisierungsknotens
  • chart – das Konfigurationsobject

Dadurch ist die Direktive in der Lage auf Änderungen des möglicherweise verbundenen ViewSelectors zu reagieren und sich zu aktualisieren. Um so flexibel, wie möglich zu bleiben, hört das Diagramm darauf, wann der ViewSelector erstellt wurde und verbindet sich danach mit ihm.

ReportData

Dies geschieht im Grunde wie bei DataCharts. Jedoch benötigen Reports keinen eigenen DOM-Knoten, können aber auch mit ViewSelectors verbunden werden. Ein Report kann aus einem oder mehreren Anfragen an die API bestehen. Aus diesem Grund wird noch eine Liste von Anfrage-Objekten benötigt.

  • viewSelectorContainer – ID des ViewSelectors
  • authContainer – ID des Autorisierungsknotens
  • queries – Liste von Anfrage-Objekten

Da es jetzt kein visuelles Feedback gibt, wird trotzdem ein leerer DOM-Knoten erstellt und mit dem Report verknüpft. Außerdem wirft die Direktive zwei Events:

  • $gaReportSuccess – Report-Anfragen erfolgreich – enthält die Antworten von Google und den verbunden DOM-Knoten
  • $gaReportError – eine Anfrage ist fehlgeschlagen – enthält die Fehler-Antworten von Google und den verbunden DOM-Knoten

Dadurch besteht die Möglichkeit die erhaltenen Daten weiter zu verarbeiten und im DOM anzuzeigen.

Template/DOM-Knoten der Direktiven

Für die Erstellung der benötigten DOM-Knoten werden ganz normale Templates benutzt, welche über den Angular $templateCache im run-Block bekannt gemacht werden.

app.run([
'$templateCache',
'$timeout',
'ngAnalyticsService',
function($templateCache, $timeout, ngAnalyticsService) {
// Erzeugt einen Script-Tag und setzt dort den Analytics Code ein und fügt den DOM-Knoten an das Ende der Seite.
var gaCode = document.createTextNode("(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'));");
var scriptTag = document.createElement('script');
scriptTag.type = 'text/javascript';
scriptTag.appendChild(gaCode);
document.body.appendChild(scriptTag);
// if ga is ready -> inform service
gapi.analytics.ready(function() {
$timeout(function() {
ngAnalyticsService.ga = gapi.analytics;
ngAnalyticsService.isReady = true;
}, 0);
});
// Wenn Analytics geladen wurde wird, wird es auf dem Wrapper gespeichert und das isReady Flag gesetzt.
$templateCache.put('ngAnalytics-auth/template.html', '<div id="{{authContainer}}" ng-hide="hide"></div>');
$templateCache.put('ngAnalytics-chart/template.html', '<div id="{{chart.chart.container}}"></div>');
$templateCache.put('ngAnalytics-view/template.html', '<div id="{{viewSelectorContainer}}"></div>');
}
]);

Benutzung

Die Benutzung teilt sich in verschiedene Schritte.

    1. Modul laden:
      %MINIFYHTMLc98ec188211f91b841a40a3ae07835d13%
    2. Module in eigene App einbinden:
      var myAppModule = angular.module('gaTest', ['ngAnalytics']);
    3. ClientID setzen:
      myAppModule.run(['ngAnalyticsService', function (ngAnalyticsService) {
      ngAnalyticsService.setClientId('CLIENT_ID');
      }]);
    4. Direktiven einbinden: zum Beispiel
      <ng-analytics-auth label="Hallo:&nbsp;" hide-on-auth="true" auth-container="embed-api-auth-container"></ng-analytics-auth>

Ein vollständiges Beispiel dazu findet sich auf der Demo-Seite.

Fazit

Die Google-Analytics Embed API ist ein weiterer toller Service von Google. Sie ist schnell einzurichten und die Nutzung für normale Webseiten ist einfach. In die eher modulare und flexible Struktur einer AngularJS-App fügt sie sich eher weniger gut ein. Aus diesem Grund nimmt ngAnalytics dem Programmierer viel Arbeit ab, da er sich voll und ganz auf die Konfiguration für die Anzeige der Komponenten, wie Diagramm oder Report, konzentrieren kann. Verknüpfungen und die Komponenten selbst werden von dem Modul erstellt und verwaltet. Darüber hinaus wird versucht die von AngularJS vorgeschriebene Struktur einer App einzuhalten. Beispielsweise laufen DOM-Manipulationen Dank der Verwendung einzelner Direktiven nur in begrenzten Scopes ab und Daten werden über Events und Services mit anderen Scopes (und Controllers) geteilt.

Wir freuen uns über eine Bewertung, um ein Feedback zu erhalten:

Durchschnittlich 4.4 Sterne aus 8 Meinungen.