#167 JS development of hashchange-dependant tabbing mechanism, and of Rickshaw graphs with separate legends.
#167 JS development of hashchange-dependant tabbing mechanism, and of Rickshaw graphs with separate legends.

--- a/ckanext/ga_report/public/css/ga_report.css
+++ b/ckanext/ga_report/public/css/ga_report.css
@@ -16,16 +16,8 @@
   bottom: 0;
 }
 .rickshaw_legend {
-  position: absolute;
-  right: 0;
-  top: 0;
-  margin-left: 15px;
-  padding: 0 5px;
   background: transparent;
-  max-width: 150px;
-  overflow: hidden;
-  background: rgba(0,0,0,0.05);
-  border-radius:5px;
+  width: 100%;
 }
 .rickshaw_y_axis {
   position: absolute;

--- a/ckanext/ga_report/public/scripts/ckanext_ga_reports.js
+++ b/ckanext/ga_report/public/scripts/ckanext_ga_reports.js
@@ -3,6 +3,9 @@
 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();
@@ -39,4 +42,73 @@
     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'); }
+  });
+});
+

--- a/ckanext/ga_report/templates/ga_report/ga_util.html
+++ b/ckanext/ga_report/templates/ga_report/ga_util.html
@@ -34,7 +34,6 @@
   <div id="chart_container_$id" class="rickshaw_chart_container">
     <div id="y_axis_$id" class="rickshaw_y_axis"></div>
     <div id="chart_$id" class="rickshaw_chart"></div>
-    <div id="legend_$id" class="rickshaw_legend"></div>
     <script type="text/javascript">
       $(function() {
           CKAN.GA_Reports.render_rickshaw('$id', $items_json, '$mode', '$colorscheme');

--- a/ckanext/ga_report/templates/ga_report/site/index.html
+++ b/ckanext/ga_report/templates/ga_report/site/index.html
@@ -24,6 +24,12 @@
           <a class="btn button btn-primary" href="${h.url_for(controller='ckanext.ga_report.controller:GaReport',action='csv',month=c.month or 'all')}">Download as CSV</a></center>
       </p>
     </li>
+    <li class="widget-container boxed widget_text">
+      <h4>Graph Legend</h4>
+      <div id="graph-legend-container">
+        <div id="legend_none">(No graph loaded)</div>
+      </div>
+    </li>
     <xi:include href="../notes.html" />
 
   </py:match>
@@ -43,38 +49,36 @@
 
     <div class="tabbable">
       <ul class="nav nav-tabs">
-        <li class="active"><a href="#totals" data-toggle="tab">Totals</a></li>
+        <li><a href="#totals" data-toggle="hashchange">Totals</a></li>
         <li class="dropdown">
-            <a href="#browsers" class="dropdown-toggle" data-toggle="dropdown">Browsers
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Browsers
                 <b class="caret"></b></a>
             <ul class="dropdown-menu">
-                <li><a href="#browsers_names" data-toggle="tab">Browsers</a></li>
-                <li><a href="#browsers_versions" data-toggle="tab">Versions</a></li>
+                <li><a href="#browsers_names" data-toggle="hashchange">Browsers</a></li>
+                <li><a href="#browsers_versions" data-toggle="hashchange">Versions</a></li>
             </ul>
         </li>
         <li class="dropdown">
-            <a href="#browsers" class="dropdown-toggle" data-toggle="dropdown">Operating<br/>Systems
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Operating Systems
                 <b class="caret"></b></a>
             <ul class="dropdown-menu">
-                <li><a href="#os" data-toggle="tab">Operating Systems</a></li>
-                <li><a href="#os_versions" data-toggle="tab">Versions</a></li>
+                <li><a href="#os" data-toggle="hashchange">Operating Systems</a></li>
+                <li><a href="#os_versions" data-toggle="hashchange">Versions</a></li>
             </ul>
         </li>
         <li class="dropdown">
-            <a href="#browsers" class="dropdown-toggle" data-toggle="dropdown">Social Networks
+            <a href="#" class="dropdown-toggle" data-toggle="dropdown">Social
                 <b class="caret"></b></a>
             <ul class="dropdown-menu">
-                <li><a href="#social_networks" data-toggle="tab">All networks</a></li>
-                <li><a href="#social_referrals_totals" data-toggle="tab">Referral links</a></li>
+                <li><a href="#social_networks" data-toggle="hashchange">All networks</a></li>
+                <li><a href="#social_referrals_totals" data-toggle="hashchange">Referral links</a></li>
             </ul>
         </li>
-
-        <li><a href="#social_networks" data-toggle="tab"></a></li>
-        <li><a href="#languages" data-toggle="tab">Languages</a></li>
-        <li><a href="#country" data-toggle="tab">Country</a></li>
+        <li><a href="#languages" data-toggle="hashchange">Languages</a></li>
+        <li><a href="#country" data-toggle="hashchange">Country</a></li>
       </ul>
       <div class="tab-content">
-        <div class="tab-pane active" id="totals">
+        <div class="tab-pane" id="totals">
              <table class="table table-condensed table-bordered table-striped">
             	 <tr>
             	   <th>Name</th>
@@ -136,20 +140,9 @@
   <py:def function="optional_footer">
     <script type="text/javascript">
       $(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_sparklines();
+        CKAN.GA_Reports.bind_sidebar();
+        $(window).trigger('hashchange');
       });  
     </script>
   </py:def>