Die Google-Analytics API spricht mit dir 0

Posted by fwoeck
on Saturday, May 02

Kurz nach der Veröffentlichung der neuen Google-Analytics-API gibt es jetzt das gem garb, welches die Kommunikation damit erheblich vereinfacht. In diesem Beispiel frage ich die Werte visits, pageviews, etc. für den letzten Monat ab und übergebe sie dem jQuery-Plugin flot, das diese Daten auf eine recht hübsche interaktive Weise darstellt:

Hier folgen die Ergänzungen zu einer leeren Rails-2.3.2-Instanz. Das gesamte Projekt habe ich zum Clonen und Spielen auf Github eingestellt (s.u.).

Die Umgebung

Das gem wird aufgerufen (> 0.2), aus einem YAML-File werden die Accountinformationen eingelesen und eine Session mit Google etabliert.

In config/environment.rb:

1
2
3
4
5
6
7
8
9
10
...
Rails::Initializer.run do |config|
...
  config.gem "vigetlabs-garb", :lib => "garb"
...
end

google_path = File.join(RAILS_ROOT,"config","google.yml")
@@google_config = YAML.load(File.read(google_path))[RAILS_ENV]
Garb::Session.login(@@google_config['login'], @@google_config['password'])

Anmeldedaten

Das File config/google.yml enthält die Domaindaten:

1
2
3
4
5
6
7
8
9
development:
  domain: rnotes.bm.net
  login: me@bm.net
  password: p4ssw0rd

production:
  domain: rnotes.bm.net
  login: me@bm.net
  password: p4ssw0rd

Controller-Code

Wenn der Welcome-Index aufgerufen wird, wird die Datenabfrage im Controller assembliert und aufgerufen. Einer sauberen MVC-Kultur folgend, sollte man dies in einem richtigen Projekt vielleicht in ein Modell geben.

app/controllers/welcome_controller.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class WelcomeController < ApplicationController

  def index
    profile = Garb::Profile.all.select {|p| p.title == 
                              @@google_config['domain']}.first
    report = Garb::Report.new(profile, :start_date => 
                              4.weeks.ago, :end_date => Time.now )

    report.metrics :pageviews, :visits, :visitors, :new_visits
    report.dimensions :date
    report.sort :date
    result = report.results

    @visitors = result.map(&:visitors)
    @visits = result.map(&:visits)
    @newvisits = result.map(&:new_visits)
    @pageviews = result.map(&:pageviews)
    @dates = result.map {|d| d.date.to_time.to_i * 1000 }
    @domain = @@google_config['domain']
  end

end

Hier ist bemerkenswert, wie die Datumsformate “CCYYMMDD”, die von Google als String kommen in Javascript-Timestamps umgerechnet werden, wie flot sie erwartet.

Die Diagrammdarstellung

Im Index werden die Ergebnisse ein ein Javascript eingefügt, das letztlich flot benutzt. Weitere Beispiele mit verschiedenen Optionen findet man auf der Website des Plugins.

Das app/views/welcome/index.html.erb-File:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
<h1><%= @domain -%></h1>

<p><br /></p>

<div id="placeholder" style="width:600px;height:300px"></div>
<div id="overview" style="margin-left:200px;margin-top:20px;
                                           width:400px;height:50px"></div>

<script id="source" language="javascript" type="text/javascript">
$(function () {
    var d1 = [<%= i = -1; @visitors.map {|v| i += 1; 
                        "[#{@dates[i]}, #{v}]" }.join(", ") -%>];
    var d2 = [<%= i = -1; @visits.map {|v| i += 1; 
                        "[#{@dates[i]}, #{v}]" }.join(", ") -%>];
    var d3 = [<%= i = -1; @pageviews.map {|v| i += 1; 
                        "[#{@dates[i]}, #{v}]" }.join(", ") -%>];
    var d4 = [<%= i = -1; @newvisits.map {|v| i += 1; 
                        "[#{@dates[i]}, #{v}]" }.join(", ") -%>];
    var d = [ { label: 'Visitors', data: d1 }, { label: 'Visits', data: d2 }, 
        { label: 'Pageviews', data: d3 },  { label: 'New visits', data: d4 } ];

    // helper for returning the weekends in a period
    function weekendAreas(axes) {
        var markings = [];
        var d = new Date(axes.xaxis.min);
        // go to the first Saturday
        d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
        d.setUTCSeconds(0);
        d.setUTCMinutes(0);
        d.setUTCHours(0);
        var i = d.getTime();
        do {
            // when we don't set yaxis the rectangle automatically
            // extends to infinity upwards and downwards
            markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } });
            i += 7 * 24 * 60 * 60 * 1000;
        } while (i < axes.xaxis.max);

        return markings;
    }
    
    var options = {
        xaxis: { mode: "time" },
        selection: { mode: "x" },
        legend: { position: 'sw' },
        points: { show: true },
        lines: { show: true },
        grid: { markings: weekendAreas }
    };

    var plot = $.plot($("#placeholder"), d, options);

    var overview = $.plot($("#overview"), [d1, d2, d3, d4], {
        lines: { show: true, lineWidth: 1 },
        shadowSize: 0,
        xaxis: { ticks: [], mode: "time" },
        selection: { mode: "x" }
    });

    $("#placeholder").bind("plotselected", function (event, ranges) {
        // do the zooming
        plot = $.plot($("#placeholder"), d,
                      $.extend(true, {}, options, {
                          xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to }
                      }));

        // don't fire event on the overview to prevent eternal loop
        overview.setSelection(ranges, true);
    });

    $("#overview").bind("plotselected", function (event, ranges) {
        plot.setSelection(ranges);
    });
});
</script>

Javascripts und JRails

flot selbst benötigt jQuery. Eine elegante und schnelle Art der Einbettung ist es, das jRails-plugin zu installieren – es bringt jQuery mit:

script/plugin install http://ennerchi.googlecode.com/svn/trunk/plugins/jrails

Das fügt die rechten Files in public/javascripts ein. Es fehlt nur noch das jquery.flot.js:

  1. jrails.js
  2. jquery-ui.js
  3. jquery.flot.js
  4. jquery.js

das html-Layout

Zum Schluss müssen die Scripte im Layout aktivert werden – app/views/layouts/application.html.erb:

1
2
3
4
...
  <%= javascript_include_tag :defaults %>
  <%= javascript_include_tag 'jquery.flot' %>
...

Weblinks

  1. github.com/fwoeck/analytics
  2. introducing-garb-access-the-google-analytics-data-export-api-with-ruby
  3. github.com/vigetlabs/garb
  4. code.google.com/p/flot
  5. code.google.com/gdataReferenceDimensionsMetrics
Comments

Leave a response

Comment