#167 JS development of hashchange-dependant tabbing mechanism, and of Rickshaw graphs with separate legends.
[ckanext-ga-report.git] / ckanext / ga_report / public / scripts / ckanext_ga_reports.js
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
 
var CKAN = CKAN || {};
CKAN.GA_Reports = {};
 
CKAN.GA_Reports.render_rickshaw = function( css_name, data, mode, colorscheme ) {
    var graphLegends = $('#graph-legend-container');
    var myLegend = $('<div id="legend_'+css_name+'"/>').appendTo(graphLegends);
 
    var palette = new Rickshaw.Color.Palette( { scheme: colorscheme } );
    $.each(data, function(i, object) {
        object['color'] = palette.color();
    });
 
    var graphElement =  document.querySelector("#chart_"+css_name);
 
    var graph = new Rickshaw.Graph( {
        element: document.querySelector("#chart_"+css_name),
        renderer: mode,
        series: data ,
        height: 328
    });
    var x_axis = new Rickshaw.Graph.Axis.Time( { graph: graph } );
    var y_axis = new Rickshaw.Graph.Axis.Y( {
        graph: graph,
        orientation: 'left',
        tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
        element: document.getElementById('y_axis_'+css_name),
    } );
    var legend = new Rickshaw.Graph.Legend( {
        element: document.querySelector('#legend_'+css_name),
        graph: graph
    } );
    var hoverDetail = new Rickshaw.Graph.HoverDetail( {
      graph: graph,
      formatter: function(series, x, y) {
        var date = '<span class="date">' + new Date(x * 1000).toUTCString() + '</span>';
        var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
        var content = swatch + series.name + ": " + parseInt(y) + '<br>' + date;
        return content;
      }
    } );
    graph.render();
};
 
CKAN.GA_Reports.bind_sparklines = function() {
  /* 
   * Bind to the 'totals' tab being on screen, when the 
   * Sparkline graphs should be drawn.
   * Note that they cannot be drawn sooner.
   */
  $('a[href="#totals"]').on(
    'shown', 
    function() {
      var sparkOptions = {
        enableTagOptions: true,
        type: 'line',
        width: 100,
        height: 26,
        chartRangeMin: 0,
        spotColor: '',
        maxSpotColor: '',
        minSpotColor: '',
        highlightSpotColor: '000000',
        lineColor: '3F8E6D',
        fillColor: 'B7E66B'
      };
      $('.sparkline').sparkline('html',sparkOptions);
    }
  );
};
 
CKAN.GA_Reports.bind_sidebar = function() {
  /* 
   * Bind to changes in the tab behaviour: 
   * Show the correct rickshaw graph in the sidebar. 
   * Not to be called before all graphs load.
   */
  $('a[data-toggle="hashchange"]').on(
    'shown',
    function(e) {
      var href = $(e.target).attr('href');
      var pane = $(href);
      if (!pane.length) { console.err('bad href',href); return; }
      var legend_name = "none";
      var graph = pane.find('.rickshaw_chart');
      if (graph.length) {
        legend_name = graph.attr('id').replace('chart_','');
      }
      legend_name = '#legend_'+legend_name;
      $('#graph-legend-container > *').hide();
      $(legend_name).show();
    }
  );
};
 
/* 
 * Custom bootstrap plugin for handling data-toggle="hashchange".
 * Behaves like data-toggle="tab" but I respond to the hashchange.
 * Page state is memo-ized in the URL this way. Why doesn't Bootstrap do this?
 */
$(function() {
  var mapping = {};
  $('a[data-toggle="hashchange"]').each(
    function(i,link) {
      link = $(link);
      mapping[link.attr('href')] = link;
    }
  );
  $(window).hashchange(function() {
    var link = mapping[window.location.hash];
    if (link) { link.tab('show'); }
  });
});