updated documentation - reportable - Fork of reportable required by WarVox, from hdm/reportable.
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit 1166ac66c5e5c75af0ca808ffc5b43e3deaeef6b
 (DIR) parent 0d6bd917f144d7985057e52b89da00aa42b5603b
 (HTM) Author: Marco Otte-Witte <marco.otte-witte@simplabs.com>
       Date:   Wed, 29 Apr 2009 19:34:12 +0200
       
       updated documentation
       
       Diffstat:
         M README.rdoc                         |      48 ++++++++++++++-----------------
         M doc/classes/Simplabs/ReportsAsSpar… |      79 ++++++++++++++++---------------
         M doc/classes/Simplabs/ReportsAsSpar… |      21 +++++++++++++--------
         D doc/classes/Simplabs/ReportsAsSpar… |     192 -------------------------------
         M doc/classes/Simplabs/ReportsAsSpar… |      91 ++++++++++++++++---------------
         A doc/classes/Simplabs/ReportsAsSpar… |     124 +++++++++++++++++++++++++++++++
         D doc/classes/Simplabs/ReportsAsSpar… |     327 -------------------------------
         M doc/classes/Simplabs/ReportsAsSpar… |      12 +++++++-----
         M doc/coverage/index.html             |      14 +++++++-------
         M doc/coverage/lib-simplabs-reports_… |      92 ++++++++++++++++----------------
         M doc/coverage/lib-simplabs-reports_… |     238 +++++++++++++++----------------
         M doc/coverage/lib-simplabs-reports_… |     202 ++++++++++++++++---------------
         M doc/coverage/lib-simplabs-reports_… |     240 ++++++++++++++++----------------
         M doc/coverage/lib-simplabs-reports_… |     207 ++++++++++++++-----------------
         M doc/coverage/lib-simplabs-reports_… |       8 ++++----
         M doc/coverage/lib-simplabs-reports_… |      75 ++++++++++++++++---------------
         M doc/created.rid                     |       2 +-
         M doc/files/README_rdoc.html          |     101 ++++++++++++++++---------------
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/files/lib/simplabs/reports_as_… |       2 +-
         M doc/fr_class_index.html             |       3 +--
         M doc/fr_method_index.html            |      11 ++---------
         M doc/spec.html                       |       2 +-
         M lib/simplabs/reports_as_sparkline.… |      21 +++++++++++----------
         M lib/simplabs/reports_as_sparkline/… |       8 ++++----
         M lib/simplabs/reports_as_sparkline/… |       8 ++------
         M lib/simplabs/reports_as_sparkline/… |      26 +++++++++++++-------------
         M lib/simplabs/reports_as_sparkline/… |       6 ++++--
         M lib/simplabs/reports_as_sparkline/… |      25 +++++--------------------
         M lib/simplabs/reports_as_sparkline/… |       6 +++---
       
       35 files changed, 891 insertions(+), 1312 deletions(-)
       ---
 (DIR) diff --git a/README.rdoc b/README.rdoc
       @@ -1,21 +1,20 @@
        = ReportsAsSparkline
        
       -ReportsAsSparkline enables you to generate reports and sparklines from your model's data with very little effort.
       +ReportsAsSparkline enables you to generate sparkline reports from your model's data with very little effort.
        
        == Usage
        
        If you hace a +User+ model with +created_at+ and +activated_at+ columns, you can just add +reports_as_sparkline+
        to it with the following options:
        
       -* :date_column - The name of the date column on that the records are aggregated
       -* :value_column - The name of the column that holds the value to sum for aggregation :sum
       -* :aggregation - The aggregation to use (one of :count, :sum, :minimum, :maximum or :average); when using anything other than :count, :value_column must also be specified (<b>If you really want to e.g. sumon the 'id' column, you have to explicitely say so.</b>)
       -* :grouping - The period records are grouped on (:hour, :day, :week, :month); <b>Beware that reports_as_sparkline treats weeks as starting on monday!</b>
       -* :limit - The number of periods to get (see :grouping)
       -* :conditions - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -* :cumulate - Sets whether to cumulate the numbers (instead of [1, 2, 3] returns [1, 3, 6])
       -* :live_data - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -* :end_date - When specified, the report will only include data for the periods before this date.
       +* <tt>:date_column</tt> - The name of the date column over that the records are aggregated (defaults to <tt>created_at</tt>)
       +* <tt>:value_column</tt> - The name of the column that holds the values to sum up when using aggregation <tt>:sum</tt>
       +* <tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>, <tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>); when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must also be specified (<b>If you really want to e.g. sum up the values in the <tt>id</tt> column, you have to explicitely say so.</b>); (defaults to <tt>:count</tt>)
       +* <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
       +* <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       +* <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +* <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
       +* <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
        
        <b>Example:</b>
        
       @@ -33,30 +32,28 @@ This will add the following class methods to your User model:
        
        When invoking the report, you can override some of the options you specified for +reports_as_sparkline+:
        
       -* :grouping - The period records are grouped on (:hour, :day, :week, :month)
       -* :limit - The number of periods to get (see :grouping)
       -* :conditions - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -* :live_data - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -* :end_date - When specified, the report will be for the periods before this date.
       +* <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
       +* <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       +* <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +* <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
       +* <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
        
        <b>Example:</b>
        
          User.registrations_report(:conditions => ['last_name LIKE 'A%'])
          User.activations_report(:grouping => :week, :limit => 5)
        
       -<b>Beware that when specifying conditions on invocation of the report, the cache will not be used!</b>
       -
        You can than render sparklines for these reports with sparkline_tag in your view:
        
          <%= sparkline_tag(User.registrations_report) %>
        
        The +sparkline_tag+ helper takes the following parameters:
        
       -* width - The width of the generated image
       -* height - The height of the generated image
       -* line_color - The line color of the sparkline (hex code)
       -* fill_color - The color to fill the area below the sparkline with (hex code)
       -* labes - The axes to render lables for (Array of :x, :y, :r, :t; this is x axis, y axis, right, top)
       +* <tt>width</tt> - The width of the generated image
       +* <tt>height</tt> - The height of the generated image
       +* <tt>line_color</tt> - The line color of the sparkline (hex code)
       +* <tt>fill_color</tt> - The color to fill the area below the sparkline with (hex code)
       +* <tt>labels</tt> - The axes to render lables for (Array of <tt>:x</tt>, <tt>:y+</tt>, <tt>:r</tt>, <tt>:t</tt>; this is x axis, y axis, right, top)
        
        == Installation
        
       @@ -64,11 +61,11 @@ Installation requires 3 simple steps:
        
        <b>get the plugin</b>
        
       -From your RAILS_ROOT in Rails &gt;= 2.1, do
       +From your RAILS_ROOT in Rails >= 2.1, do
        
          ./script/plugin install git://github.com/marcoow/reports_as_sparkline.git
        
       -If you are on Rails &lt; 2.1, do this from your RAILS_ROOT
       +If you are on Rails < 2.1, do this from your RAILS_ROOT
        
          git clone git://github.com/marcoow/reports_as_sparkline.git vendor/plugins/reports_as_sparkline
        
       @@ -97,7 +94,6 @@ If you are on PostgreSQL, you should add functional indices:
        == TODOs/ future plans
        
        * support for Oracle and DB2 (and others?) missing
       -* Implement data ranges in arguments
        * Limit number of data points to maximum that the google chart api allows
        * Make graph styling configurable
        
       @@ -109,4 +105,4 @@ If you want to suggest any new features or report bugs, do so at http://github.c
        
        == Author
        
       -© 2008-2009 Marco Otte-Witte (http://simplabs.com/#projects), Martin Kavalar, released under the MIT license
       +© 2008-2009 Marco Otte-Witte (http://simplabs.com), Martin Kavalar, released under the MIT license
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/ClassMethods.html b/doc/classes/Simplabs/ReportsAsSparkline/ClassMethods.html
       @@ -114,53 +114,57 @@
                <div class="method-description">
                  <p>
        Generates a report on a model. That report can then be executed via the new
       -method &lt;name&gt;_report (see documentation of <a
       -href="Report.html#M000014">Simplabs::ReportsAsSparkline::Report#run</a>).
       +method <tt>&lt;name&gt;_report</tt> (see documentation of <a
       +href="Report.html#M000007">Simplabs::ReportsAsSparkline::Report#run</a>).
        </p>
        <h4>Parameters</h4>
        <ul>
        <li><tt>name</tt> - The name of the report, defines the name of the generated
       -report method (&lt;name&gt;_report)
       +report method (<tt>&lt;name&gt;_report</tt>)
        
        </li>
        </ul>
        <h4>Options</h4>
        <ul>
       -<li><tt>:date_column</tt> - The name of the date column on that the records are
       -aggregated
       +<li><tt>:date_column</tt> - The name of the date column over that the records
       +are aggregated (defaults to <tt>created_at</tt>)
        
        </li>
       -<li><tt>:value_column</tt> - The name of the column that holds the value to sum
       -for aggregation :sum
       +<li><tt>:value_column</tt> - The name of the column that holds the values to
       +sum up when using aggregation <tt>:sum</tt>
        
        </li>
       -<li><tt>:aggregation</tt> - The aggregation to use (one of :count, :sum,
       -:minimum, :maximum or :average); when using anything other than :count,
       -:value_column must also be specified (<b>If you really want to e.g. sumon
       -the &#8216;id&#8217; column, you have to explicitely say so.</b>)
       +<li><tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>,
       +<tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>);
       +when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must
       +also be specified (<b>If you really want to e.g. sum up the values in the
       +<tt>id</tt> column, you have to explicitely say so.</b>); (defaults to
       +<tt>:count</tt>)
        
        </li>
       -<li><tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week,
       -:month); <b>Beware that <a
       -href="ClassMethods.html#M000002">reports_as_sparkline</a> treats weeks as
       -starting on monday!</b>
       +<li><tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>,
       +<tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt><a
       +href="ClassMethods.html#M000002">reports_as_sparkline</a></tt> treats weeks
       +as starting on monday!</b>
        
        </li>
       -<li><tt>:limit</tt> - The number of periods to get (see :grouping)
       +<li><tt>:limit</tt> - The number of reporting periods to get (see
       +<tt>:grouping</tt>), (defaults to 100)
        
        </li>
       -<li><tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only
       -records that match there conditions are reported on
       +<li><tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>;
       +only records that match the conditions are reported; <b>Beware that when
       +conditions are specified, caching is disabled!</b>
        
        </li>
       -<li><tt>:live_data</tt> - Specified whether data for the current reporting
       -period is read; if :live_data is true, you will experience a performance
       -hit since the request cannot be satisfied from the cache only (defaults to
       -false)
       +<li><tt>:live_data</tt> - Specifies whether data for the current reporting
       +period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will
       +experience a performance hit since the request cannot be satisfied from the
       +cache only (defaults to <tt>false</tt>)</b>
        
        </li>
        <li><tt>:end_date</tt> - When specified, the report will only include data for
       -the periods before this date.
       +the <tt>:limit</tt> reporting periods until this date.
        
        </li>
        </ul>
       @@ -170,6 +174,7 @@ the periods before this date.
           reports_as_sparkline :games_per_day
           reports_as_sparkline :games_played_total, :cumulate =&gt; true
         end
       +
         class User &lt; ActiveRecord::Base
           reports_as_sparkline :registrations, :aggregation =&gt; :count
           reports_as_sparkline :activations,   :aggregation =&gt; :count, :date_column =&gt; :activated_at
       @@ -181,20 +186,20 @@ the periods before this date.
                    onclick="toggleCode('M000002-source');return false;">[Source]</a></p>
                  <div class="method-source-code" id="M000002-source">
        <pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline.rb, line 40</span>
       -40:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">reports_as_sparkline</span>(<span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
       -41:         (<span class="ruby-keyword kw">class</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">end</span>).<span class="ruby-identifier">instance_eval</span> <span class="ruby-keyword kw">do</span>
       -42:           <span class="ruby-identifier">define_method</span> <span class="ruby-node">&quot;#{name.to_s}_report&quot;</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-operator">*</span><span class="ruby-identifier">args</span><span class="ruby-operator">|</span>
       -43:             <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:cumulate</span>)
       -44:               <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">CumulatedReport</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
       -45:             <span class="ruby-keyword kw">else</span>
       -46:               <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">Report</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
       -47:             <span class="ruby-keyword kw">end</span>
       -48:             <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>].<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>))
       -49:             <span class="ruby-identifier">report</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> {} <span class="ruby-operator">:</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>])
       -50:           <span class="ruby-keyword kw">end</span>
       -51:         <span class="ruby-keyword kw">end</span>
       -52:       <span class="ruby-keyword kw">end</span>
       +    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline.rb, line 41</span>
       +41:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">reports_as_sparkline</span>(<span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
       +42:         (<span class="ruby-keyword kw">class</span> <span class="ruby-operator">&lt;&lt;</span> <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">self</span>; <span class="ruby-keyword kw">end</span>).<span class="ruby-identifier">instance_eval</span> <span class="ruby-keyword kw">do</span>
       +43:           <span class="ruby-identifier">define_method</span> <span class="ruby-node">&quot;#{name.to_s}_report&quot;</span>.<span class="ruby-identifier">to_sym</span> <span class="ruby-keyword kw">do</span> <span class="ruby-operator">|</span><span class="ruby-operator">*</span><span class="ruby-identifier">args</span><span class="ruby-operator">|</span>
       +44:             <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">options</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">:cumulate</span>)
       +45:               <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">CumulatedReport</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
       +46:             <span class="ruby-keyword kw">else</span>
       +47:               <span class="ruby-identifier">report</span> = <span class="ruby-constant">Simplabs</span><span class="ruby-operator">::</span><span class="ruby-constant">ReportsAsSparkline</span><span class="ruby-operator">::</span><span class="ruby-constant">Report</span>.<span class="ruby-identifier">new</span>(<span class="ruby-keyword kw">self</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span>)
       +48:             <span class="ruby-keyword kw">end</span>
       +49:             <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword kw">unless</span> <span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">1</span> <span class="ruby-operator">&amp;&amp;</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>].<span class="ruby-identifier">is_a?</span>(<span class="ruby-constant">Hash</span>))
       +50:             <span class="ruby-identifier">report</span>.<span class="ruby-identifier">run</span>(<span class="ruby-identifier">args</span>.<span class="ruby-identifier">length</span> <span class="ruby-operator">==</span> <span class="ruby-value">0</span> <span class="ruby-operator">?</span> {} <span class="ruby-operator">:</span> <span class="ruby-identifier">args</span>[<span class="ruby-value">0</span>])
       +51:           <span class="ruby-keyword kw">end</span>
       +52:         <span class="ruby-keyword kw">end</span>
       +53:       <span class="ruby-keyword kw">end</span>
        </pre>
                  </div>
                </div>
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/CumulatedReport.html b/doc/classes/Simplabs/ReportsAsSparkline/CumulatedReport.html
       @@ -86,14 +86,19 @@ A special report class that cumulates all data (see <a
        href="Report.html">Simplabs::ReportsAsSparkline::Report</a>)
        </p>
        <h4>Examples</h4>
       +<p>
       +When <a href="Report.html">Simplabs::ReportsAsSparkline::Report</a> returns
       +</p>
        <pre>
       - When Simplabs::ReportsAsSparkline::Report returns
       -
       -   [[&lt;DateTime today&gt;, 1], [&lt;DateTime yesterday&gt;, 2], etc.]
       -
       - Simplabs::ReportsAsSparkline::CumulatedReport returns
       -
       -   [[&lt;DateTime today&gt;, 3], [&lt;DateTime yesterday&gt;, 2], etc.]
       + [[&lt;DateTime today&gt;, 1], [&lt;DateTime yesterday&gt;, 2], etc.]
       +</pre>
       +<p>
       +<a
       +href="CumulatedReport.html">Simplabs::ReportsAsSparkline::CumulatedReport</a>
       +returns
       +</p>
       +<pre>
       + [[&lt;DateTime today&gt;, 3], [&lt;DateTime yesterday&gt;, 2], etc.]
        </pre>
        
            </div>
       @@ -141,7 +146,7 @@ href="Report.html">Simplabs::ReportsAsSparkline::Report</a>)
                <div class="method-description">
                  <p>
        Runs the report (see <a
       -href="Report.html#M000014">Simplabs::ReportsAsSparkline::Report#run</a>)
       +href="Report.html#M000007">Simplabs::ReportsAsSparkline::Report#run</a>)
        </p>
                  <p><a class="source-toggle" href="#"
                    onclick="toggleCode('M000003-source');return false;">[Source]</a></p>
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/Grouping.html b/doc/classes/Simplabs/ReportsAsSparkline/Grouping.html
       @@ -1,191 +0,0 @@
       -<?xml version="1.0" encoding="iso-8859-1"?>
       -<!DOCTYPE html 
       -     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       -     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       -
       -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
       -<head>
       -  <title>Class: Simplabs::ReportsAsSparkline::Grouping</title>
       -  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
       -  <meta http-equiv="Content-Script-Type" content="text/javascript" />
       -  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
       -  <script type="text/javascript">
       -  // <![CDATA[
       -
       -  function popupCode( url ) {
       -    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
       -  }
       -
       -  function toggleCode( id ) {
       -    if ( document.getElementById )
       -      elem = document.getElementById( id );
       -    else if ( document.all )
       -      elem = eval( "document.all." + id );
       -    else
       -      return false;
       -
       -    elemStyle = elem.style;
       -    
       -    if ( elemStyle.display != "block" ) {
       -      elemStyle.display = "block"
       -    } else {
       -      elemStyle.display = "none"
       -    }
       -
       -    return true;
       -  }
       -  
       -  // Make codeblocks hidden by default
       -  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
       -  
       -  // ]]>
       -  </script>
       -
       -</head>
       -<body>
       -
       -
       -
       -    <div id="classHeader">
       -        <table class="header-table">
       -        <tr class="top-aligned-row">
       -          <td><strong>Class</strong></td>
       -          <td class="class-name-in-header">Simplabs::ReportsAsSparkline::Grouping</td>
       -        </tr>
       -        <tr class="top-aligned-row">
       -            <td><strong>In:</strong></td>
       -            <td>
       -                <a href="../../../files/lib/simplabs/reports_as_sparkline/grouping_rb.html">
       -                lib/simplabs/reports_as_sparkline/grouping.rb
       -                </a>
       -        <br />
       -            </td>
       -        </tr>
       -
       -        <tr class="top-aligned-row">
       -            <td><strong>Parent:</strong></td>
       -            <td>
       -                Object
       -            </td>
       -        </tr>
       -        </table>
       -    </div>
       -  <!-- banner header -->
       -
       -  <div id="bodyContent">
       -
       -
       -
       -  <div id="contextContent">
       -
       -    <div id="description">
       -      <p>
       -This is the grouping a report uses to group records in the database
       -</p>
       -
       -    </div>
       -
       -
       -   </div>
       -
       -    <div id="method-list">
       -      <h3 class="section-bar">Methods</h3>
       -
       -      <div class="name-list">
       -      <a href="#M000007">identifier</a>&nbsp;&nbsp;
       -      <a href="#M000006">new</a>&nbsp;&nbsp;
       -      </div>
       -    </div>
       -
       -  </div>
       -
       -
       -    <!-- if includes -->
       -
       -    <div id="section">
       -
       -
       -
       -
       -
       -      
       -
       -
       -    <!-- if method_list -->
       -    <div id="methods">
       -      <h3 class="section-bar">Public Class methods</h3>
       -
       -      <div id="method-M000006" class="method-detail">
       -        <a name="M000006"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000006" class="method-signature">
       -          <span class="method-name">new</span><span class="method-args">(identifier)</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <h4>Parameters</h4>
       -<ul>
       -<li><tt><a href="Grouping.html#M000007">identifier</a></tt> - The <a
       -href="Grouping.html#M000007">identifier</a> of the grouping - one of :hour,
       -:day, :week or :month
       -
       -</li>
       -</ul>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000006-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/grouping.rb, line 10</span>
       -10:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">identifier</span>)
       -11:         <span class="ruby-identifier">raise</span> <span class="ruby-constant">ArgumentError</span>.<span class="ruby-identifier">new</span>(<span class="ruby-node">&quot;Invalid grouping #{identifier}&quot;</span>) <span class="ruby-keyword kw">unless</span> [<span class="ruby-identifier">:hour</span>, <span class="ruby-identifier">:day</span>, <span class="ruby-identifier">:week</span>, <span class="ruby-identifier">:month</span>].<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">identifier</span>)
       -12:         <span class="ruby-ivar">@identifier</span> = <span class="ruby-identifier">identifier</span>
       -13:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -      <h3 class="section-bar">Public Instance methods</h3>
       -
       -      <div id="method-M000007" class="method-detail">
       -        <a name="M000007"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000007" class="method-signature">
       -          <span class="method-name">identifier</span><span class="method-args">()</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <p>
       -Returns the <a href="Grouping.html">Grouping</a>&#8216;s <a
       -href="Grouping.html#M000007">identifier</a>
       -</p>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000007-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/grouping.rb, line 16</span>
       -16:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">identifier</span>
       -17:         <span class="ruby-ivar">@identifier</span>
       -18:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -
       -    </div>
       -
       -
       -  </div>
       -
       -
       -<div id="validator-badges">
       -  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
       -</div>
       -
       -</body>
       -</html>
       -\ No newline at end of file
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/Report.html b/doc/classes/Simplabs/ReportsAsSparkline/Report.html
       @@ -93,8 +93,8 @@ and calculations
              <h3 class="section-bar">Methods</h3>
        
              <div class="name-list">
       -      <a href="#M000013">new</a>&nbsp;&nbsp;
       -      <a href="#M000014">run</a>&nbsp;&nbsp;
       +      <a href="#M000006">new</a>&nbsp;&nbsp;
       +      <a href="#M000007">run</a>&nbsp;&nbsp;
              </div>
            </div>
        
       @@ -154,11 +154,11 @@ and calculations
            <div id="methods">
              <h3 class="section-bar">Public Class methods</h3>
        
       -      <div id="method-M000013" class="method-detail">
       -        <a name="M000013"></a>
       +      <div id="method-M000006" class="method-detail">
       +        <a name="M000006"></a>
        
                <div class="method-heading">
       -          <a href="#M000013" class="method-signature">
       +          <a href="#M000006" class="method-signature">
                  <span class="method-name">new</span><span class="method-args">(klass, name, options = {})</span>
                  </a>
                </div>
       @@ -179,46 +179,50 @@ href="ClassMethods.html#M000002">Simplabs::ReportsAsSparkline::ClassMethods#repo
        </ul>
        <h4>Options</h4>
        <ul>
       -<li><tt>:date_column</tt> - The name of the date column on that the records are
       -aggregated
       +<li><tt>:date_column</tt> - The name of the date column over that the records
       +are aggregated (defaults to <tt>created_at</tt>)
        
        </li>
       -<li><tt>:value_column</tt> - The name of the column that holds the value to sum
       -for aggregation :sum
       +<li><tt>:value_column</tt> - The name of the column that holds the values to
       +sum up when using aggregation <tt>:sum</tt>
        
        </li>
       -<li><tt>:aggregation</tt> - The aggregation to use (one of :count, :sum,
       -:minimum, :maximum or :average); when using anything other than :count,
       -:value_column must also be specified (<b>If you really want to e.g. sumon
       -the &#8216;id&#8217; column, you have to explicitely say so.</b>)
       +<li><tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>,
       +<tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>);
       +when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must
       +also be specified (<b>If you really want to e.g. sum up the values in the
       +<tt>id</tt> column, you have to explicitely say so.</b>); (defaults to
       +<tt>:count</tt>)
        
        </li>
       -<li><tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week,
       -:month); <b>Beware that reports_as_sparkline treats weeks as starting on
       -monday!</b>
       +<li><tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>,
       +<tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that
       +<tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
        
        </li>
       -<li><tt>:limit</tt> - The number of periods to get (see :grouping)
       +<li><tt>:limit</tt> - The number of reporting periods to get (see
       +<tt>:grouping</tt>), (defaults to 100)
        
        </li>
       -<li><tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only
       -records that match there conditions are reported on
       +<li><tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>;
       +only records that match the conditions are reported; <b>Beware that when
       +conditions are specified, caching is disabled!</b>
        
        </li>
       -<li><tt>:live_data</tt> - Specified whether data for the current reporting
       -period is read; if :live_data is true, you will experience a performance
       -hit since the request cannot be satisfied from the cache only (defaults to
       -false)
       +<li><tt>:live_data</tt> - Specifies whether data for the current reporting
       +period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will
       +experience a performance hit since the request cannot be satisfied from the
       +cache only (defaults to <tt>false</tt>)</b>
        
        </li>
        <li><tt>:end_date</tt> - When specified, the report will only include data for
       -the periods before this date.
       +the <tt>:limit</tt> reporting periods until this date.
        
        </li>
        </ul>
                  <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000013-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000013-source">
       +            onclick="toggleCode('M000006-source');return false;">[Source]</a></p>
       +          <div class="method-source-code" id="M000006-source">
        <pre>
            <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/report.rb, line 24</span>
        24:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">klass</span>, <span class="ruby-identifier">name</span>, <span class="ruby-identifier">options</span> = {})
       @@ -245,11 +249,11 @@ the periods before this date.
        
              <h3 class="section-bar">Public Instance methods</h3>
        
       -      <div id="method-M000014" class="method-detail">
       -        <a name="M000014"></a>
       +      <div id="method-M000007" class="method-detail">
       +        <a name="M000007"></a>
        
                <div class="method-heading">
       -          <a href="#M000014" class="method-signature">
       +          <a href="#M000007" class="method-signature">
                  <span class="method-name">run</span><span class="method-args">(options = {})</span>
                  </a>
                </div>
       @@ -260,33 +264,34 @@ Runs the report and returns an array of array of DateTimes and Floats
        </p>
        <h4>Options</h4>
        <ul>
       -<li><tt>:limit</tt> - The number of periods to get
       +<li><tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>,
       +<tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that
       +<tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
        
        </li>
       -<li><tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only
       -records that match there conditions are reported on (<b>Beware that when
       -you specify conditions here, caching will be disabled</b>)
       +<li><tt>:limit</tt> - The number of reporting periods to get (see
       +<tt>:grouping</tt>), (defaults to 100)
        
        </li>
       -<li><tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week,
       -:month); <b>Beware that reports_as_sparkline treats weeks as starting on
       -monday!</b>
       +<li><tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>;
       +only records that match the conditions are reported; <b>Beware that when
       +conditions are specified, caching is disabled!</b>
        
        </li>
       -<li><tt>:live_data</tt> - Specified whether data for the current reporting
       -period is read; if :live_data is true, you will experience a performance
       -hit since the request cannot be satisfied from the cache only (defaults to
       -false)
       +<li><tt>:live_data</tt> - Specifies whether data for the current reporting
       +period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will
       +experience a performance hit since the request cannot be satisfied from the
       +cache only (defaults to <tt>false</tt>)</b>
        
        </li>
        <li><tt>:end_date</tt> - When specified, the report will only include data for
       -the periods before this date.
       +the <tt>:limit</tt> reporting periods until this date.
        
        </li>
        </ul>
                  <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000014-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000014-source">
       +            onclick="toggleCode('M000007-source');return false;">[Source]</a></p>
       +          <div class="method-source-code" id="M000007-source">
        <pre>
            <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/report.rb, line 50</span>
        50:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">run</span>(<span class="ruby-identifier">options</span> = {})
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/ReportCache.html b/doc/classes/Simplabs/ReportsAsSparkline/ReportCache.html
       @@ -0,0 +1,123 @@
       +<?xml version="1.0" encoding="iso-8859-1"?>
       +<!DOCTYPE html 
       +     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       +     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       +
       +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
       +<head>
       +  <title>Class: Simplabs::ReportsAsSparkline::ReportCache</title>
       +  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
       +  <meta http-equiv="Content-Script-Type" content="text/javascript" />
       +  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
       +  <script type="text/javascript">
       +  // <![CDATA[
       +
       +  function popupCode( url ) {
       +    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
       +  }
       +
       +  function toggleCode( id ) {
       +    if ( document.getElementById )
       +      elem = document.getElementById( id );
       +    else if ( document.all )
       +      elem = eval( "document.all." + id );
       +    else
       +      return false;
       +
       +    elemStyle = elem.style;
       +    
       +    if ( elemStyle.display != "block" ) {
       +      elemStyle.display = "block"
       +    } else {
       +      elemStyle.display = "none"
       +    }
       +
       +    return true;
       +  }
       +  
       +  // Make codeblocks hidden by default
       +  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
       +  
       +  // ]]>
       +  </script>
       +
       +</head>
       +<body>
       +
       +
       +
       +    <div id="classHeader">
       +        <table class="header-table">
       +        <tr class="top-aligned-row">
       +          <td><strong>Class</strong></td>
       +          <td class="class-name-in-header">Simplabs::ReportsAsSparkline::ReportCache</td>
       +        </tr>
       +        <tr class="top-aligned-row">
       +            <td><strong>In:</strong></td>
       +            <td>
       +                <a href="../../../files/lib/simplabs/reports_as_sparkline/report_cache_rb.html">
       +                lib/simplabs/reports_as_sparkline/report_cache.rb
       +                </a>
       +        <br />
       +            </td>
       +        </tr>
       +
       +        <tr class="top-aligned-row">
       +            <td><strong>Parent:</strong></td>
       +            <td>
       +                ActiveRecord::Base
       +            </td>
       +        </tr>
       +        </table>
       +    </div>
       +  <!-- banner header -->
       +
       +  <div id="bodyContent">
       +
       +
       +
       +  <div id="contextContent">
       +
       +    <div id="description">
       +      <p>
       +The <a href="ReportCache.html">ReportCache</a> class is a regular
       +<tt>ActiveRecord</tt> model and represents cached results for single
       +reporting periods (table name is <tt>reports_as_sparkline_cache</tt>) <a
       +href="ReportCache.html">ReportCache</a> instances are identified by the
       +combination of <tt>model_name</tt>, <tt>report_name</tt>,
       +<tt>grouping</tt>, <tt>aggregation</tt>, <tt>reporting_period</tt>,
       +<tt>run_limit</tt>
       +</p>
       +
       +    </div>
       +
       +
       +   </div>
       +
       +
       +  </div>
       +
       +
       +    <!-- if includes -->
       +
       +    <div id="section">
       +
       +
       +
       +
       +
       +      
       +
       +
       +    <!-- if method_list -->
       +
       +
       +  </div>
       +
       +
       +<div id="validator-badges">
       +  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
       +</div>
       +
       +</body>
       +</html>
       +\ No newline at end of file
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html b/doc/classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html
       @@ -1,326 +0,0 @@
       -<?xml version="1.0" encoding="iso-8859-1"?>
       -<!DOCTYPE html 
       -     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       -     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
       -
       -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
       -<head>
       -  <title>Class: Simplabs::ReportsAsSparkline::ReportingPeriod</title>
       -  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
       -  <meta http-equiv="Content-Script-Type" content="text/javascript" />
       -  <link rel="stylesheet" href="../../.././rdoc-style.css" type="text/css" media="screen" />
       -  <script type="text/javascript">
       -  // <![CDATA[
       -
       -  function popupCode( url ) {
       -    window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
       -  }
       -
       -  function toggleCode( id ) {
       -    if ( document.getElementById )
       -      elem = document.getElementById( id );
       -    else if ( document.all )
       -      elem = eval( "document.all." + id );
       -    else
       -      return false;
       -
       -    elemStyle = elem.style;
       -    
       -    if ( elemStyle.display != "block" ) {
       -      elemStyle.display = "block"
       -    } else {
       -      elemStyle.display = "none"
       -    }
       -
       -    return true;
       -  }
       -  
       -  // Make codeblocks hidden by default
       -  document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
       -  
       -  // ]]>
       -  </script>
       -
       -</head>
       -<body>
       -
       -
       -
       -    <div id="classHeader">
       -        <table class="header-table">
       -        <tr class="top-aligned-row">
       -          <td><strong>Class</strong></td>
       -          <td class="class-name-in-header">Simplabs::ReportsAsSparkline::ReportingPeriod</td>
       -        </tr>
       -        <tr class="top-aligned-row">
       -            <td><strong>In:</strong></td>
       -            <td>
       -                <a href="../../../files/lib/simplabs/reports_as_sparkline/reporting_period_rb.html">
       -                lib/simplabs/reports_as_sparkline/reporting_period.rb
       -                </a>
       -        <br />
       -            </td>
       -        </tr>
       -
       -        <tr class="top-aligned-row">
       -            <td><strong>Parent:</strong></td>
       -            <td>
       -                Object
       -            </td>
       -        </tr>
       -        </table>
       -    </div>
       -  <!-- banner header -->
       -
       -  <div id="bodyContent">
       -
       -
       -
       -  <div id="contextContent">
       -
       -    <div id="description">
       -      <p>
       -A <a href="ReportingPeriod.html">ReportingPeriod</a> is - depending on the
       -<a href="Grouping.html">Grouping</a> - either a specific hour, a day, a
       -month or a year. All records falling into this period will be grouped
       -together.
       -</p>
       -
       -    </div>
       -
       -
       -   </div>
       -
       -    <div id="method-list">
       -      <h3 class="section-bar">Methods</h3>
       -
       -      <div class="name-list">
       -      <a href="#M000009">first</a>&nbsp;&nbsp;
       -      <a href="#M000008">new</a>&nbsp;&nbsp;
       -      <a href="#M000010">next</a>&nbsp;&nbsp;
       -      <a href="#M000012">offset</a>&nbsp;&nbsp;
       -      <a href="#M000011">previous</a>&nbsp;&nbsp;
       -      </div>
       -    </div>
       -
       -  </div>
       -
       -
       -    <!-- if includes -->
       -
       -    <div id="section">
       -
       -
       -
       -
       -
       -    <div id="attribute-list">
       -      <h3 class="section-bar">Attributes</h3>
       -
       -      <div class="name-list">
       -        <table>
       -        <tr class="top-aligned-row context-row">
       -          <td class="context-item-name">date_time</td>
       -          <td class="context-item-value">&nbsp;[R]&nbsp;</td>
       -          <td class="context-item-desc"></td>
       -        </tr>
       -        <tr class="top-aligned-row context-row">
       -          <td class="context-item-name">grouping</td>
       -          <td class="context-item-value">&nbsp;[R]&nbsp;</td>
       -          <td class="context-item-desc"></td>
       -        </tr>
       -        </table>
       -      </div>
       -    </div>
       -      
       -
       -
       -    <!-- if method_list -->
       -    <div id="methods">
       -      <h3 class="section-bar">Public Class methods</h3>
       -
       -      <div id="method-M000009" class="method-detail">
       -        <a name="M000009"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000009" class="method-signature">
       -          <span class="method-name">first</span><span class="method-args">(grouping, limit, end_date = nil)</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <p>
       -Returns the <a href="ReportingPeriod.html#M000009">first</a> reporting
       -period for a grouping and a limit; e.g. the <a
       -href="ReportingPeriod.html#M000009">first</a> reporting period for <a
       -href="Grouping.html">Grouping</a> :day and limit 2 would be Time.now -
       -2.days
       -</p>
       -<h4>Parameters</h4>
       -<ul>
       -<li><tt>grouping</tt> - The <a
       -href="Grouping.html">Simplabs::ReportsAsSparkline::Grouping</a> of the
       -reporting period
       -
       -</li>
       -<li><tt>limit</tt> - The number of reporting periods until the <a
       -href="ReportingPeriod.html#M000009">first</a> one
       -
       -</li>
       -</ul>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000009-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000009-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/reporting_period.rb, line 23</span>
       -23:       <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">first</span>(<span class="ruby-identifier">grouping</span>, <span class="ruby-identifier">limit</span>, <span class="ruby-identifier">end_date</span> = <span class="ruby-keyword kw">nil</span>)
       -24:         <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">grouping</span>, <span class="ruby-identifier">end_date</span>).<span class="ruby-identifier">offset</span>(<span class="ruby-operator">-</span><span class="ruby-identifier">limit</span>)
       -25:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -      <div id="method-M000008" class="method-detail">
       -        <a name="M000008"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000008" class="method-signature">
       -          <span class="method-name">new</span><span class="method-args">(grouping, date_time = nil)</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <h4>Parameters</h4>
       -<ul>
       -<li><tt>grouping</tt> - The <a
       -href="Grouping.html">Simplabs::ReportsAsSparkline::Grouping</a> of the
       -reporting period
       -
       -</li>
       -<li><tt>date_time</tt> - The DateTime that reporting period is created for
       -
       -</li>
       -</ul>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000008-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000008-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/reporting_period.rb, line 13</span>
       -13:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">initialize</span>(<span class="ruby-identifier">grouping</span>, <span class="ruby-identifier">date_time</span> = <span class="ruby-keyword kw">nil</span>)
       -14:         <span class="ruby-ivar">@grouping</span>  = <span class="ruby-identifier">grouping</span>
       -15:         <span class="ruby-ivar">@date_time</span> = <span class="ruby-identifier">parse_date_time</span>(<span class="ruby-identifier">date_time</span> <span class="ruby-operator">||</span> <span class="ruby-constant">DateTime</span>.<span class="ruby-identifier">now</span>)
       -16:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -      <h3 class="section-bar">Public Instance methods</h3>
       -
       -      <div id="method-M000010" class="method-detail">
       -        <a name="M000010"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000010" class="method-signature">
       -          <span class="method-name">next</span><span class="method-args">()</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <p>
       -Returns the <a href="ReportingPeriod.html#M000010">next</a> reporting
       -period (that is <a href="ReportingPeriod.html#M000010">next</a>
       -hour/day/month/year)
       -</p>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000010-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000010-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/reporting_period.rb, line 43</span>
       -43:       <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">next</span>
       -44:         <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">offset</span>(<span class="ruby-value">1</span>)
       -45:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -      <div id="method-M000012" class="method-detail">
       -        <a name="M000012"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000012" class="method-signature">
       -          <span class="method-name">offset</span><span class="method-args">(offset)</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <p>
       -Returns the reporting period with the specified <a
       -href="ReportingPeriod.html#M000012">offset</a> from the current
       -</p>
       -<h4>Parameters</h4>
       -<ul>
       -<li><tt><a href="ReportingPeriod.html#M000012">offset</a></tt> - The <a
       -href="ReportingPeriod.html#M000012">offset</a> to return the reporting
       -period for (specifies the <a href="ReportingPeriod.html#M000012">offset</a>
       -in hours/days/months/years), depending on the reporting period&#8216;s
       -grouping
       -
       -</li>
       -</ul>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000012-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000012-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/reporting_period.rb, line 56</span>
       -56:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">offset</span>(<span class="ruby-identifier">offset</span>)
       -57:         <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">class</span>.<span class="ruby-identifier">new</span>(<span class="ruby-ivar">@grouping</span>, <span class="ruby-ivar">@date_time</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">offset</span>.<span class="ruby-identifier">send</span>(<span class="ruby-ivar">@grouping</span>.<span class="ruby-identifier">identifier</span>))
       -58:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -      <div id="method-M000011" class="method-detail">
       -        <a name="M000011"></a>
       -
       -        <div class="method-heading">
       -          <a href="#M000011" class="method-signature">
       -          <span class="method-name">previous</span><span class="method-args">()</span>
       -          </a>
       -        </div>
       -      
       -        <div class="method-description">
       -          <p>
       -Returns the <a href="ReportingPeriod.html#M000011">previous</a> reporting
       -period (that is <a href="ReportingPeriod.html#M000010">next</a>
       -hour/day/month/year)
       -</p>
       -          <p><a class="source-toggle" href="#"
       -            onclick="toggleCode('M000011-source');return false;">[Source]</a></p>
       -          <div class="method-source-code" id="M000011-source">
       -<pre>
       -    <span class="ruby-comment cmt"># File lib/simplabs/reports_as_sparkline/reporting_period.rb, line 48</span>
       -48:       <span class="ruby-keyword kw">def</span> <span class="ruby-identifier">previous</span>
       -49:         <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">offset</span>(<span class="ruby-value">-1</span>)
       -50:       <span class="ruby-keyword kw">end</span>
       -</pre>
       -          </div>
       -        </div>
       -      </div>
       -
       -
       -    </div>
       -
       -
       -  </div>
       -
       -
       -<div id="validator-badges">
       -  <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
       -</div>
       -
       -</body>
       -</html>
       -\ No newline at end of file
 (DIR) diff --git a/doc/classes/Simplabs/ReportsAsSparkline/SparklineTagHelper.html b/doc/classes/Simplabs/ReportsAsSparkline/SparklineTagHelper.html
       @@ -117,7 +117,8 @@ Renders a sparkline with the given data.
        </p>
        <h4>Parameters</h4>
        <ul>
       -<li><tt>data</tt> - The data to render the sparkline for
       +<li><tt>data</tt> - The data to render the sparkline for, is retrieved from a
       +report like <tt>User.registration_report</tt>
        
        </li>
        </ul>
       @@ -136,16 +137,17 @@ Renders a sparkline with the given data.
        (hex code)
        
        </li>
       -<li><tt>labels</tt> - The axes to render lables for (Array of :x, :y, :r, :t;
       -this is x axis, y axis, right, top)
       +<li><tt>labels</tt> - The axes to render lables for (Array of <tt>:x</tt>,
       +<tt>:y+</tt>, <tt>:r</tt>, <tt>:t</tt>; this is x axis, y axis, right, top)
        
        </li>
        </ul>
        <h4>Example</h4>
        <p>
       -&lt;%= <a
       +<tt>&lt;%= <a
        href="SparklineTagHelper.html#M000001">sparkline_tag</a>(User.registrations_report,
       -:width =&gt; 200, :height =&gt; 100, :color =&gt; &#8216;000&#8217;) %&gt;
       +:width =&gt; 200, :height =&gt; 100, :color =&gt; &#8216;000&#8217;)
       +%&gt;</tt>
        </p>
                  <p><a class="source-toggle" href="#"
                    onclick="toggleCode('M000001-source');return false;">[Source]</a></p>
 (DIR) diff --git a/doc/coverage/index.html b/doc/coverage/index.html
       @@ -148,7 +148,7 @@ table.report tr.dark {
        </script>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:07 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <table class='report'><thead><tr><td class='heading'>Name</td>
       @@ -159,7 +159,7 @@ table.report tr.dark {
              </tr>
            </thead>
          <tbody><tr class='light'><td>TOTAL</td>
       -      <td class='lines_total'><tt>586</tt>
       +      <td class='lines_total'><tt>570</tt>
                </td>
              <td class='lines_code'><tt>404</tt>
                </td>
       @@ -186,7 +186,7 @@ table.report tr.dark {
              </tr>
            <tr class='dark'><td><a href='lib-simplabs-reports_as_sparkline_rb.html'>lib/simplabs/reports_as_sparkline.rb</a>
                </td>
       -      <td class='lines_total'><tt>58</tt>
       +      <td class='lines_total'><tt>59</tt>
                </td>
              <td class='lines_code'><tt>22</tt>
                </td>
       @@ -240,7 +240,7 @@ table.report tr.dark {
              </tr>
            <tr class='dark'><td><a href='lib-simplabs-reports_as_sparkline-grouping_rb.html'>lib/simplabs/reports_as_sparkline/grouping.rb</a>
                </td>
       -      <td class='lines_total'><tt>119</tt>
       +      <td class='lines_total'><tt>115</tt>
                </td>
              <td class='lines_code'><tt>99</tt>
                </td>
       @@ -294,7 +294,7 @@ table.report tr.dark {
              </tr>
            <tr class='dark'><td><a href='lib-simplabs-reports_as_sparkline-report_cache_rb.html'>lib/simplabs/reports_as_sparkline/report_cache.rb</a>
                </td>
       -      <td class='lines_total'><tt>98</tt>
       +      <td class='lines_total'><tt>100</tt>
                </td>
              <td class='lines_code'><tt>83</tt>
                </td>
       @@ -321,11 +321,11 @@ table.report tr.dark {
              </tr>
            <tr class='light'><td><a href='lib-simplabs-reports_as_sparkline-reporting_period_rb.html'>lib/simplabs/reports_as_sparkline/reporting_period.rb</a>
                </td>
       -      <td class='lines_total'><tt>108</tt>
       +      <td class='lines_total'><tt>93</tt>
                </td>
              <td class='lines_code'><tt>76</tt>
                </td>
       -      <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>96.3%</tt>
       +      <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>95.7%</tt>
                      &nbsp;</td>
                    <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='96'/>
                          <td class='uncovered' width='4'/>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-cumulated_report_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-cumulated_report_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:07 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -598,51 +598,51 @@ span.run100 {
              </tr>
            </tbody>
          </table>
       -<pre><span class="marked1"><a name="line1"></a> 1 module Simplabs #:nodoc:
       -</span><span class="inferred0"><a name="line2"></a> 2 
       -</span><span class="marked1"><a name="line3"></a> 3   module ReportsAsSparkline #:nodoc:
       -</span><span class="inferred0"><a name="line4"></a> 4 
       -</span><span class="inferred1"><a name="line5"></a> 5     # A special report class that cumulates all data (see Simplabs::ReportsAsSparkline::Report)
       -</span><span class="inferred0"><a name="line6"></a> 6     #
       -</span><span class="inferred1"><a name="line7"></a> 7     # ==== Examples
       -</span><span class="inferred0"><a name="line8"></a> 8     #
       -</span><span class="inferred1"><a name="line9"></a> 9     #  When Simplabs::ReportsAsSparkline::Report returns
       -</span><span class="inferred0"><a name="line10"></a>10     #
       -</span><span class="inferred1"><a name="line11"></a>11     #    [[&lt;DateTime today&gt;, 1], [&lt;DateTime yesterday&gt;, 2], etc.]
       -</span><span class="inferred0"><a name="line12"></a>12     #
       -</span><span class="inferred1"><a name="line13"></a>13     #  Simplabs::ReportsAsSparkline::CumulatedReport returns
       -</span><span class="inferred0"><a name="line14"></a>14     #
       -</span><span class="inferred1"><a name="line15"></a>15     #    [[&lt;DateTime today&gt;, 3], [&lt;DateTime yesterday&gt;, 2], etc.]
       -</span><span class="marked0"><a name="line16"></a>16     class CumulatedReport &lt; Report
       -</span><span class="inferred1"><a name="line17"></a>17 
       -</span><span class="inferred0"><a name="line18"></a>18       # Runs the report (see Simplabs::ReportsAsSparkline::Report#run)
       -</span><span class="marked1"><a name="line19"></a>19       def run(options = {})
       -</span><span class="marked0"><a name="line20"></a>20         cumulate(super, options_for_run(options))
       -</span><span class="marked1"><a name="line21"></a>21       end
       -</span><span class="inferred0"><a name="line22"></a>22 
       -</span><span class="marked1"><a name="line23"></a>23       protected
       -</span><span class="inferred0"><a name="line24"></a>24 
       -</span><span class="marked1"><a name="line25"></a>25         def cumulate(data, options)
       -</span><span class="marked0"><a name="line26"></a>26           first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
       -</span><span class="marked1"><a name="line27"></a>27           acc = initial_cumulative_value(first_reporting_period.date_time, options)
       -</span><span class="marked0"><a name="line28"></a>28           result = []
       -</span><span class="marked1"><a name="line29"></a>29           data.each do |element|
       -</span><span class="marked0"><a name="line30"></a>30             acc += element[1].to_f
       -</span><span class="marked1"><a name="line31"></a>31             result &lt;&lt; [element[0], acc]
       -</span><span class="inferred0"><a name="line32"></a>32           end
       -</span><span class="marked1"><a name="line33"></a>33           result
       -</span><span class="inferred0"><a name="line34"></a>34         end
       -</span><span class="inferred1"><a name="line35"></a>35 
       -</span><span class="marked0"><a name="line36"></a>36         def initial_cumulative_value(date, options)
       -</span><span class="marked1"><a name="line37"></a>37           conditions = setup_conditions(nil, date, options[:conditions])
       -</span><span class="marked0"><a name="line38"></a>38           @klass.send(@aggregation, @value_column, :conditions =&gt; conditions)
       -</span><span class="inferred1"><a name="line39"></a>39         end
       -</span><span class="inferred0"><a name="line40"></a>40 
       -</span><span class="inferred1"><a name="line41"></a>41     end
       -</span><span class="inferred0"><a name="line42"></a>42 
       -</span><span class="inferred1"><a name="line43"></a>43   end
       -</span><span class="inferred0"><a name="line44"></a>44 
       -</span><span class="inferred1"><a name="line45"></a>45 end
       +<pre><span class="marked0"><a name="line1"></a> 1 module Simplabs #:nodoc:
       +</span><span class="inferred1"><a name="line2"></a> 2 
       +</span><span class="marked0"><a name="line3"></a> 3   module ReportsAsSparkline #:nodoc:
       +</span><span class="inferred1"><a name="line4"></a> 4 
       +</span><span class="inferred0"><a name="line5"></a> 5     # A special report class that cumulates all data (see Simplabs::ReportsAsSparkline::Report)
       +</span><span class="inferred1"><a name="line6"></a> 6     #
       +</span><span class="inferred0"><a name="line7"></a> 7     # ==== Examples
       +</span><span class="inferred1"><a name="line8"></a> 8     #
       +</span><span class="inferred0"><a name="line9"></a> 9     # When Simplabs::ReportsAsSparkline::Report returns
       +</span><span class="inferred1"><a name="line10"></a>10     #
       +</span><span class="inferred0"><a name="line11"></a>11     #  [[&lt;DateTime today&gt;, 1], [&lt;DateTime yesterday&gt;, 2], etc.]
       +</span><span class="inferred1"><a name="line12"></a>12     #
       +</span><span class="inferred0"><a name="line13"></a>13     # Simplabs::ReportsAsSparkline::CumulatedReport returns
       +</span><span class="inferred1"><a name="line14"></a>14     #
       +</span><span class="inferred0"><a name="line15"></a>15     #  [[&lt;DateTime today&gt;, 3], [&lt;DateTime yesterday&gt;, 2], etc.]
       +</span><span class="marked1"><a name="line16"></a>16     class CumulatedReport &lt; Report
       +</span><span class="inferred0"><a name="line17"></a>17 
       +</span><span class="inferred1"><a name="line18"></a>18       # Runs the report (see Simplabs::ReportsAsSparkline::Report#run)
       +</span><span class="marked0"><a name="line19"></a>19       def run(options = {})
       +</span><span class="marked1"><a name="line20"></a>20         cumulate(super, options_for_run(options))
       +</span><span class="marked0"><a name="line21"></a>21       end
       +</span><span class="inferred1"><a name="line22"></a>22 
       +</span><span class="marked0"><a name="line23"></a>23       protected
       +</span><span class="inferred1"><a name="line24"></a>24 
       +</span><span class="marked0"><a name="line25"></a>25         def cumulate(data, options)
       +</span><span class="marked1"><a name="line26"></a>26           first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date])
       +</span><span class="marked0"><a name="line27"></a>27           acc = initial_cumulative_value(first_reporting_period.date_time, options)
       +</span><span class="marked1"><a name="line28"></a>28           result = []
       +</span><span class="marked0"><a name="line29"></a>29           data.each do |element|
       +</span><span class="marked1"><a name="line30"></a>30             acc += element[1].to_f
       +</span><span class="marked0"><a name="line31"></a>31             result &lt;&lt; [element[0], acc]
       +</span><span class="inferred1"><a name="line32"></a>32           end
       +</span><span class="marked0"><a name="line33"></a>33           result
       +</span><span class="inferred1"><a name="line34"></a>34         end
       +</span><span class="inferred0"><a name="line35"></a>35 
       +</span><span class="marked1"><a name="line36"></a>36         def initial_cumulative_value(date, options)
       +</span><span class="marked0"><a name="line37"></a>37           conditions = setup_conditions(nil, date, options[:conditions])
       +</span><span class="marked1"><a name="line38"></a>38           @klass.send(@aggregation, @value_column, :conditions =&gt; conditions)
       +</span><span class="inferred0"><a name="line39"></a>39         end
       +</span><span class="inferred1"><a name="line40"></a>40 
       +</span><span class="inferred0"><a name="line41"></a>41     end
       +</span><span class="inferred1"><a name="line42"></a>42 
       +</span><span class="inferred0"><a name="line43"></a>43   end
       +</span><span class="inferred1"><a name="line44"></a>44 
       +</span><span class="inferred0"><a name="line45"></a>45 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-grouping_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-grouping_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:07 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -571,7 +571,7 @@ span.run100 {
            </thead>
          <tbody><tr class='light'><td><a href='lib-simplabs-reports_as_sparkline-grouping_rb.html'>lib/simplabs/reports_as_sparkline/grouping.rb</a>
                </td>
       -      <td class='lines_total'><tt>119</tt>
       +      <td class='lines_total'><tt>115</tt>
                </td>
              <td class='lines_code'><tt>99</tt>
                </td>
       @@ -598,125 +598,121 @@ span.run100 {
              </tr>
            </tbody>
          </table>
       -<pre><span class="marked0"><a name="line1"></a>  1 module Simplabs #:nodoc:
       -</span><span class="inferred1"><a name="line2"></a>  2 
       -</span><span class="marked0"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       -</span><span class="inferred1"><a name="line4"></a>  4 
       -</span><span class="inferred0"><a name="line5"></a>  5     # This is the grouping a report uses to group records in the database
       -</span><span class="marked1"><a name="line6"></a>  6     class Grouping
       -</span><span class="inferred0"><a name="line7"></a>  7 
       -</span><span class="inferred1"><a name="line8"></a>  8       # ==== Parameters
       -</span><span class="inferred0"><a name="line9"></a>  9       # * &lt;tt&gt;identifier&lt;/tt&gt; - The identifier of the grouping - one of :hour, :day, :week or :month
       -</span><span class="marked1"><a name="line10"></a> 10       def initialize(identifier)
       -</span><span class="marked0"><a name="line11"></a> 11         raise ArgumentError.new(&quot;Invalid grouping #{identifier}&quot;) unless [:hour, :day, :week, :month].include?(identifier)
       -</span><span class="marked1"><a name="line12"></a> 12         @identifier = identifier
       -</span><span class="inferred0"><a name="line13"></a> 13       end
       -</span><span class="inferred1"><a name="line14"></a> 14 
       -</span><span class="inferred0"><a name="line15"></a> 15       # Returns the Grouping's identifier
       -</span><span class="marked1"><a name="line16"></a> 16       def identifier
       -</span><span class="marked0"><a name="line17"></a> 17         @identifier
       -</span><span class="marked1"><a name="line18"></a> 18       end
       -</span><span class="inferred0"><a name="line19"></a> 19 
       -</span><span class="marked1"><a name="line20"></a> 20       def date_parts_from_db_string(db_string) #:nodoc:
       -</span><span class="marked0"><a name="line21"></a> 21         return case ActiveRecord::Base.connection.adapter_name
       -</span><span class="marked1"><a name="line22"></a> 22           when /mysql/i
       -</span><span class="marked0"><a name="line23"></a> 23             from_mysql_db_string(db_string)
       -</span><span class="marked1"><a name="line24"></a> 24           when /sqlite/i
       -</span><span class="marked0"><a name="line25"></a> 25             from_sqlite_db_string(db_string)
       -</span><span class="marked1"><a name="line26"></a> 26           when /postgres/i
       -</span><span class="marked0"><a name="line27"></a> 27             from_postgresql_db_string(db_string)
       -</span><span class="marked1"><a name="line28"></a> 28         end
       -</span><span class="marked0"><a name="line29"></a> 29       end
       -</span><span class="inferred1"><a name="line30"></a> 30 
       -</span><span class="marked0"><a name="line31"></a> 31       def to_sql(date_column) #:nodoc:
       -</span><span class="marked1"><a name="line32"></a> 32         return case ActiveRecord::Base.connection.adapter_name
       -</span><span class="marked0"><a name="line33"></a> 33           when /mysql/i
       -</span><span class="marked1"><a name="line34"></a> 34             mysql_format(date_column)
       -</span><span class="marked0"><a name="line35"></a> 35           when /sqlite/i
       -</span><span class="marked1"><a name="line36"></a> 36             sqlite_format(date_column)
       -</span><span class="marked0"><a name="line37"></a> 37           when /postgres/i
       -</span><span class="marked1"><a name="line38"></a> 38             postgresql_format(date_column)
       -</span><span class="marked0"><a name="line39"></a> 39         end
       -</span><span class="marked1"><a name="line40"></a> 40       end
       -</span><span class="inferred0"><a name="line41"></a> 41 
       -</span><span class="marked1"><a name="line42"></a> 42       private
       -</span><span class="inferred0"><a name="line43"></a> 43 
       -</span><span class="marked1"><a name="line44"></a> 44         def from_mysql_db_string(db_string)
       -</span><span class="marked0"><a name="line45"></a> 45           if @identifier == :week
       -</span><span class="marked1"><a name="line46"></a> 46             parts = [db_string[0..3], db_string[4..5]].map(&amp;:to_i)
       -</span><span class="inferred0"><a name="line47"></a> 47           else
       -</span><span class="marked1"><a name="line48"></a> 48             db_string.split('/').map(&amp;:to_i)
       -</span><span class="inferred0"><a name="line49"></a> 49           end
       -</span><span class="marked1"><a name="line50"></a> 50         end
       -</span><span class="inferred0"><a name="line51"></a> 51 
       -</span><span class="marked1"><a name="line52"></a> 52         def from_sqlite_db_string(db_string)
       -</span><span class="marked0"><a name="line53"></a> 53           if @identifier == :week
       -</span><span class="marked1"><a name="line54"></a> 54             parts = db_string.split('-').map(&amp;:to_i)
       -</span><span class="marked0"><a name="line55"></a> 55             date = Date.new(parts[0], parts[1], parts[2])
       -</span><span class="marked1"><a name="line56"></a> 56             return [date.cwyear, date.cweek]
       -</span><span class="inferred0"><a name="line57"></a> 57           end
       -</span><span class="marked1"><a name="line58"></a> 58           db_string.split('/').map(&amp;:to_i)
       -</span><span class="inferred0"><a name="line59"></a> 59         end
       -</span><span class="inferred1"><a name="line60"></a> 60 
       -</span><span class="marked0"><a name="line61"></a> 61         def from_postgresql_db_string(db_string)
       -</span><span class="marked1"><a name="line62"></a> 62           case @identifier
       -</span><span class="marked0"><a name="line63"></a> 63             when :hour
       -</span><span class="marked1"><a name="line64"></a> 64               return (db_string[0..9].split('-') + [db_string[11..12]]).map(&amp;:to_i)
       -</span><span class="marked0"><a name="line65"></a> 65             when :day
       -</span><span class="marked1"><a name="line66"></a> 66               return db_string[0..9].split('-').map(&amp;:to_i)
       -</span><span class="marked0"><a name="line67"></a> 67             when :week
       -</span><span class="marked1"><a name="line68"></a> 68               parts = db_string[0..9].split('-').map(&amp;:to_i)
       -</span><span class="marked0"><a name="line69"></a> 69               date = Date.new(parts[0], parts[1], parts[2])
       -</span><span class="marked1"><a name="line70"></a> 70               return [date.cwyear, date.cweek]
       -</span><span class="marked0"><a name="line71"></a> 71             when :month
       -</span><span class="marked1"><a name="line72"></a> 72               return db_string[0..6].split('-')[0..1].map(&amp;:to_i)
       -</span><span class="inferred0"><a name="line73"></a> 73           end
       -</span><span class="marked1"><a name="line74"></a> 74         end
       -</span><span class="inferred0"><a name="line75"></a> 75 
       -</span><span class="marked1"><a name="line76"></a> 76         def mysql_format(date_column)
       -</span><span class="uncovered0"><a name="line77"></a> 77           return case @identifier
       -</span><span class="marked1"><a name="line78"></a> 78             when :hour
       -</span><span class="marked0"><a name="line79"></a> 79               &quot;DATE_FORMAT(#{date_column}, '%Y/%m/%d/%H')&quot;
       -</span><span class="marked1"><a name="line80"></a> 80             when :day
       -</span><span class="marked0"><a name="line81"></a> 81               &quot;DATE_FORMAT(#{date_column}, '%Y/%m/%d')&quot;
       -</span><span class="marked1"><a name="line82"></a> 82             when :week
       -</span><span class="marked0"><a name="line83"></a> 83               &quot;YEARWEEK(#{date_column}, 3)&quot;
       -</span><span class="marked1"><a name="line84"></a> 84             when :month
       -</span><span class="marked0"><a name="line85"></a> 85               &quot;DATE_FORMAT(#{date_column}, '%Y/%m')&quot;
       -</span><span class="marked1"><a name="line86"></a> 86           end
       -</span><span class="marked0"><a name="line87"></a> 87         end
       -</span><span class="inferred1"><a name="line88"></a> 88 
       -</span><span class="marked0"><a name="line89"></a> 89         def sqlite_format(date_column)
       -</span><span class="uncovered1"><a name="line90"></a> 90           return case @identifier
       -</span><span class="marked0"><a name="line91"></a> 91             when :hour
       -</span><span class="marked1"><a name="line92"></a> 92               &quot;strftime('%Y/%m/%d/%H', #{date_column})&quot;
       -</span><span class="marked0"><a name="line93"></a> 93             when :day
       -</span><span class="marked1"><a name="line94"></a> 94               &quot;strftime('%Y/%m/%d', #{date_column})&quot;
       -</span><span class="marked0"><a name="line95"></a> 95             when :week
       -</span><span class="marked1"><a name="line96"></a> 96               &quot;date(#{date_column}, 'weekday 0')&quot;
       -</span><span class="marked0"><a name="line97"></a> 97             when :month
       -</span><span class="marked1"><a name="line98"></a> 98               &quot;strftime('%Y/%m', #{date_column})&quot;
       -</span><span class="marked0"><a name="line99"></a> 99           end
       -</span><span class="marked1"><a name="line100"></a>100         end
       -</span><span class="inferred0"><a name="line101"></a>101 
       -</span><span class="marked1"><a name="line102"></a>102         def postgresql_format(date_column)
       -</span><span class="inferred0"><a name="line103"></a>103           return case @identifier
       -</span><span class="marked1"><a name="line104"></a>104             when :hour
       -</span><span class="inferred0"><a name="line105"></a>105               &quot;date_trunc('hour', #{date_column})&quot;
       -</span><span class="marked1"><a name="line106"></a>106             when :day
       -</span><span class="inferred0"><a name="line107"></a>107               &quot;date_trunc('day', #{date_column})&quot;
       -</span><span class="marked1"><a name="line108"></a>108             when :week
       -</span><span class="inferred0"><a name="line109"></a>109               &quot;date_trunc('week', #{date_column})&quot;
       -</span><span class="marked1"><a name="line110"></a>110             when :month
       -</span><span class="marked0"><a name="line111"></a>111               &quot;date_trunc('month', #{date_column})&quot;
       -</span><span class="marked1"><a name="line112"></a>112           end
       -</span><span class="marked0"><a name="line113"></a>113         end
       -</span><span class="inferred1"><a name="line114"></a>114 
       -</span><span class="inferred0"><a name="line115"></a>115     end
       -</span><span class="inferred1"><a name="line116"></a>116 
       -</span><span class="inferred0"><a name="line117"></a>117   end
       -</span><span class="inferred1"><a name="line118"></a>118 
       -</span><span class="inferred0"><a name="line119"></a>119 end
       +<pre><span class="marked1"><a name="line1"></a>  1 module Simplabs #:nodoc:
       +</span><span class="inferred0"><a name="line2"></a>  2 
       +</span><span class="marked1"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       +</span><span class="inferred0"><a name="line4"></a>  4 
       +</span><span class="marked1"><a name="line5"></a>  5     class Grouping #:nodoc:
       +</span><span class="inferred0"><a name="line6"></a>  6 
       +</span><span class="marked1"><a name="line7"></a>  7       def initialize(identifier)
       +</span><span class="marked0"><a name="line8"></a>  8         raise ArgumentError.new(&quot;Invalid grouping #{identifier}&quot;) unless [:hour, :day, :week, :month].include?(identifier)
       +</span><span class="marked1"><a name="line9"></a>  9         @identifier = identifier
       +</span><span class="inferred0"><a name="line10"></a> 10       end
       +</span><span class="inferred1"><a name="line11"></a> 11 
       +</span><span class="marked0"><a name="line12"></a> 12       def identifier
       +</span><span class="marked1"><a name="line13"></a> 13         @identifier
       +</span><span class="marked0"><a name="line14"></a> 14       end
       +</span><span class="inferred1"><a name="line15"></a> 15 
       +</span><span class="marked0"><a name="line16"></a> 16       def date_parts_from_db_string(db_string)
       +</span><span class="marked1"><a name="line17"></a> 17         return case ActiveRecord::Base.connection.adapter_name
       +</span><span class="marked0"><a name="line18"></a> 18           when /mysql/i
       +</span><span class="marked1"><a name="line19"></a> 19             from_mysql_db_string(db_string)
       +</span><span class="marked0"><a name="line20"></a> 20           when /sqlite/i
       +</span><span class="marked1"><a name="line21"></a> 21             from_sqlite_db_string(db_string)
       +</span><span class="marked0"><a name="line22"></a> 22           when /postgres/i
       +</span><span class="marked1"><a name="line23"></a> 23             from_postgresql_db_string(db_string)
       +</span><span class="marked0"><a name="line24"></a> 24         end
       +</span><span class="marked1"><a name="line25"></a> 25       end
       +</span><span class="inferred0"><a name="line26"></a> 26 
       +</span><span class="marked1"><a name="line27"></a> 27       def to_sql(date_column) #:nodoc:
       +</span><span class="marked0"><a name="line28"></a> 28         return case ActiveRecord::Base.connection.adapter_name
       +</span><span class="marked1"><a name="line29"></a> 29           when /mysql/i
       +</span><span class="marked0"><a name="line30"></a> 30             mysql_format(date_column)
       +</span><span class="marked1"><a name="line31"></a> 31           when /sqlite/i
       +</span><span class="marked0"><a name="line32"></a> 32             sqlite_format(date_column)
       +</span><span class="marked1"><a name="line33"></a> 33           when /postgres/i
       +</span><span class="marked0"><a name="line34"></a> 34             postgresql_format(date_column)
       +</span><span class="marked1"><a name="line35"></a> 35         end
       +</span><span class="marked0"><a name="line36"></a> 36       end
       +</span><span class="inferred1"><a name="line37"></a> 37 
       +</span><span class="marked0"><a name="line38"></a> 38       private
       +</span><span class="inferred1"><a name="line39"></a> 39 
       +</span><span class="marked0"><a name="line40"></a> 40         def from_mysql_db_string(db_string)
       +</span><span class="marked1"><a name="line41"></a> 41           if @identifier == :week
       +</span><span class="marked0"><a name="line42"></a> 42             parts = [db_string[0..3], db_string[4..5]].map(&amp;:to_i)
       +</span><span class="inferred1"><a name="line43"></a> 43           else
       +</span><span class="marked0"><a name="line44"></a> 44             db_string.split('/').map(&amp;:to_i)
       +</span><span class="inferred1"><a name="line45"></a> 45           end
       +</span><span class="marked0"><a name="line46"></a> 46         end
       +</span><span class="inferred1"><a name="line47"></a> 47 
       +</span><span class="marked0"><a name="line48"></a> 48         def from_sqlite_db_string(db_string)
       +</span><span class="marked1"><a name="line49"></a> 49           if @identifier == :week
       +</span><span class="marked0"><a name="line50"></a> 50             parts = db_string.split('-').map(&amp;:to_i)
       +</span><span class="marked1"><a name="line51"></a> 51             date = Date.new(parts[0], parts[1], parts[2])
       +</span><span class="marked0"><a name="line52"></a> 52             return [date.cwyear, date.cweek]
       +</span><span class="inferred1"><a name="line53"></a> 53           end
       +</span><span class="marked0"><a name="line54"></a> 54           db_string.split('/').map(&amp;:to_i)
       +</span><span class="inferred1"><a name="line55"></a> 55         end
       +</span><span class="inferred0"><a name="line56"></a> 56 
       +</span><span class="marked1"><a name="line57"></a> 57         def from_postgresql_db_string(db_string)
       +</span><span class="marked0"><a name="line58"></a> 58           case @identifier
       +</span><span class="marked1"><a name="line59"></a> 59             when :hour
       +</span><span class="marked0"><a name="line60"></a> 60               return (db_string[0..9].split('-') + [db_string[11..12]]).map(&amp;:to_i)
       +</span><span class="marked1"><a name="line61"></a> 61             when :day
       +</span><span class="marked0"><a name="line62"></a> 62               return db_string[0..9].split('-').map(&amp;:to_i)
       +</span><span class="marked1"><a name="line63"></a> 63             when :week
       +</span><span class="marked0"><a name="line64"></a> 64               parts = db_string[0..9].split('-').map(&amp;:to_i)
       +</span><span class="marked1"><a name="line65"></a> 65               date = Date.new(parts[0], parts[1], parts[2])
       +</span><span class="marked0"><a name="line66"></a> 66               return [date.cwyear, date.cweek]
       +</span><span class="marked1"><a name="line67"></a> 67             when :month
       +</span><span class="marked0"><a name="line68"></a> 68               return db_string[0..6].split('-')[0..1].map(&amp;:to_i)
       +</span><span class="inferred1"><a name="line69"></a> 69           end
       +</span><span class="marked0"><a name="line70"></a> 70         end
       +</span><span class="inferred1"><a name="line71"></a> 71 
       +</span><span class="marked0"><a name="line72"></a> 72         def mysql_format(date_column)
       +</span><span class="uncovered1"><a name="line73"></a> 73           return case @identifier
       +</span><span class="marked0"><a name="line74"></a> 74             when :hour
       +</span><span class="marked1"><a name="line75"></a> 75               &quot;DATE_FORMAT(#{date_column}, '%Y/%m/%d/%H')&quot;
       +</span><span class="marked0"><a name="line76"></a> 76             when :day
       +</span><span class="marked1"><a name="line77"></a> 77               &quot;DATE_FORMAT(#{date_column}, '%Y/%m/%d')&quot;
       +</span><span class="marked0"><a name="line78"></a> 78             when :week
       +</span><span class="marked1"><a name="line79"></a> 79               &quot;YEARWEEK(#{date_column}, 3)&quot;
       +</span><span class="marked0"><a name="line80"></a> 80             when :month
       +</span><span class="marked1"><a name="line81"></a> 81               &quot;DATE_FORMAT(#{date_column}, '%Y/%m')&quot;
       +</span><span class="marked0"><a name="line82"></a> 82           end
       +</span><span class="marked1"><a name="line83"></a> 83         end
       +</span><span class="inferred0"><a name="line84"></a> 84 
       +</span><span class="marked1"><a name="line85"></a> 85         def sqlite_format(date_column)
       +</span><span class="uncovered0"><a name="line86"></a> 86           return case @identifier
       +</span><span class="marked1"><a name="line87"></a> 87             when :hour
       +</span><span class="marked0"><a name="line88"></a> 88               &quot;strftime('%Y/%m/%d/%H', #{date_column})&quot;
       +</span><span class="marked1"><a name="line89"></a> 89             when :day
       +</span><span class="marked0"><a name="line90"></a> 90               &quot;strftime('%Y/%m/%d', #{date_column})&quot;
       +</span><span class="marked1"><a name="line91"></a> 91             when :week
       +</span><span class="marked0"><a name="line92"></a> 92               &quot;date(#{date_column}, 'weekday 0')&quot;
       +</span><span class="marked1"><a name="line93"></a> 93             when :month
       +</span><span class="marked0"><a name="line94"></a> 94               &quot;strftime('%Y/%m', #{date_column})&quot;
       +</span><span class="marked1"><a name="line95"></a> 95           end
       +</span><span class="marked0"><a name="line96"></a> 96         end
       +</span><span class="inferred1"><a name="line97"></a> 97 
       +</span><span class="marked0"><a name="line98"></a> 98         def postgresql_format(date_column)
       +</span><span class="inferred1"><a name="line99"></a> 99           return case @identifier
       +</span><span class="marked0"><a name="line100"></a>100             when :hour
       +</span><span class="inferred1"><a name="line101"></a>101               &quot;date_trunc('hour', #{date_column})&quot;
       +</span><span class="marked0"><a name="line102"></a>102             when :day
       +</span><span class="inferred1"><a name="line103"></a>103               &quot;date_trunc('day', #{date_column})&quot;
       +</span><span class="marked0"><a name="line104"></a>104             when :week
       +</span><span class="inferred1"><a name="line105"></a>105               &quot;date_trunc('week', #{date_column})&quot;
       +</span><span class="marked0"><a name="line106"></a>106             when :month
       +</span><span class="marked1"><a name="line107"></a>107               &quot;date_trunc('month', #{date_column})&quot;
       +</span><span class="marked0"><a name="line108"></a>108           end
       +</span><span class="marked1"><a name="line109"></a>109         end
       +</span><span class="inferred0"><a name="line110"></a>110 
       +</span><span class="inferred1"><a name="line111"></a>111     end
       +</span><span class="inferred0"><a name="line112"></a>112 
       +</span><span class="inferred1"><a name="line113"></a>113   end
       +</span><span class="inferred0"><a name="line114"></a>114 
       +</span><span class="inferred1"><a name="line115"></a>115 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-report_cache_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-report_cache_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:08 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -571,7 +571,7 @@ span.run100 {
            </thead>
          <tbody><tr class='light'><td><a href='lib-simplabs-reports_as_sparkline-report_cache_rb.html'>lib/simplabs/reports_as_sparkline/report_cache.rb</a>
                </td>
       -      <td class='lines_total'><tt>98</tt>
       +      <td class='lines_total'><tt>100</tt>
                </td>
              <td class='lines_code'><tt>83</tt>
                </td>
       @@ -598,104 +598,106 @@ span.run100 {
              </tr>
            </tbody>
          </table>
       -<pre><span class="marked0"><a name="line1"></a> 1 module Simplabs #:nodoc:
       -</span><span class="inferred1"><a name="line2"></a> 2 
       -</span><span class="marked0"><a name="line3"></a> 3   module ReportsAsSparkline #:nodoc:
       -</span><span class="inferred1"><a name="line4"></a> 4 
       -</span><span class="marked0"><a name="line5"></a> 5     class ReportCache &lt; ActiveRecord::Base #:nodoc:
       -</span><span class="inferred1"><a name="line6"></a> 6 
       -</span><span class="marked0"><a name="line7"></a> 7       set_table_name :reports_as_sparkline_cache
       -</span><span class="inferred1"><a name="line8"></a> 8 
       -</span><span class="marked0"><a name="line9"></a> 9       def self.process(report, options, cache = true, &amp;block)
       -</span><span class="marked1"><a name="line10"></a>10         raise ArgumentError.new('A block must be given') unless block_given?
       -</span><span class="marked0"><a name="line11"></a>11         self.transaction do
       -</span><span class="marked1"><a name="line12"></a>12           cached_data = []
       -</span><span class="marked0"><a name="line13"></a>13           first_reporting_period = ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date])
       -</span><span class="marked1"><a name="line14"></a>14           last_reporting_period = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]) : nil
       -</span><span class="inferred0"><a name="line15"></a>15 
       -</span><span class="marked1"><a name="line16"></a>16           if cache
       -</span><span class="marked0"><a name="line17"></a>17             cached_data = find_cached_data(report, options, first_reporting_period, last_reporting_period)
       -</span><span class="marked1"><a name="line18"></a>18             first_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.first.reporting_period)
       -</span><span class="marked0"><a name="line19"></a>19             last_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period)
       -</span><span class="inferred1"><a name="line20"></a>20           end
       -</span><span class="inferred0"><a name="line21"></a>21 
       -</span><span class="marked1"><a name="line22"></a>22           new_data = if !options[:live_data] &amp;&amp; last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
       -</span><span class="uncovered0"><a name="line23"></a>23             []
       -</span><span class="inferred1"><a name="line24"></a>24           else
       -</span><span class="marked0"><a name="line25"></a>25             end_date = options[:live_data] ? nil : (options[:end_date] ? last_reporting_period.last_date_time : nil)
       -</span><span class="marked1"><a name="line26"></a>26             yield((last_cached_reporting_period.next rescue first_reporting_period).date_time, end_date)
       -</span><span class="inferred0"><a name="line27"></a>27           end
       -</span><span class="inferred1"><a name="line28"></a>28 
       -</span><span class="marked0"><a name="line29"></a>29           prepare_result(new_data, cached_data, report, options, cache)
       -</span><span class="inferred1"><a name="line30"></a>30         end
       -</span><span class="inferred0"><a name="line31"></a>31       end
       -</span><span class="inferred1"><a name="line32"></a>32 
       -</span><span class="marked0"><a name="line33"></a>33       private
       -</span><span class="inferred1"><a name="line34"></a>34 
       -</span><span class="marked0"><a name="line35"></a>35         def self.prepare_result(new_data, cached_data, report, options, cache = true)
       -</span><span class="marked1"><a name="line36"></a>36           new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
       -</span><span class="marked0"><a name="line37"></a>37           result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
       -</span><span class="marked1"><a name="line38"></a>38           last_reporting_period = ReportingPeriod.new(options[:grouping])
       -</span><span class="marked0"><a name="line39"></a>39           reporting_period = cached_data.empty? ? ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date]) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
       -</span><span class="marked1"><a name="line40"></a>40           while reporting_period &lt; (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : last_reporting_period)
       -</span><span class="marked0"><a name="line41"></a>41             cached = build_cached_data(report, options[:grouping], options[:limit], reporting_period, find_value(new_data, reporting_period))
       -</span><span class="marked1"><a name="line42"></a>42             cached.save! if cache
       -</span><span class="marked0"><a name="line43"></a>43             result &lt;&lt; [reporting_period.date_time, cached.value]
       -</span><span class="marked1"><a name="line44"></a>44             reporting_period = reporting_period.next
       -</span><span class="inferred0"><a name="line45"></a>45           end
       -</span><span class="marked1"><a name="line46"></a>46           if options[:live_data]
       -</span><span class="marked0"><a name="line47"></a>47             result &lt;&lt; [last_reporting_period.date_time, find_value(new_data, last_reporting_period)]
       -</span><span class="inferred1"><a name="line48"></a>48           end
       -</span><span class="marked0"><a name="line49"></a>49           result
       -</span><span class="inferred1"><a name="line50"></a>50         end
       -</span><span class="inferred0"><a name="line51"></a>51 
       -</span><span class="marked1"><a name="line52"></a>52         def self.find_value(data, reporting_period)
       -</span><span class="marked0"><a name="line53"></a>53           data = data.detect { |d| d[0] == reporting_period }
       -</span><span class="marked1"><a name="line54"></a>54           data ? data[1] : 0.0
       -</span><span class="inferred0"><a name="line55"></a>55         end
       -</span><span class="inferred1"><a name="line56"></a>56 
       -</span><span class="marked0"><a name="line57"></a>57         def self.build_cached_data(report, grouping, limit, reporting_period, value)
       -</span><span class="marked1"><a name="line58"></a>58           self.new(
       -</span><span class="inferred0"><a name="line59"></a>59             :model_name       =&gt; report.klass.to_s,
       -</span><span class="inferred1"><a name="line60"></a>60             :report_name      =&gt; report.name.to_s,
       -</span><span class="marked0"><a name="line61"></a>61             :grouping         =&gt; grouping.identifier.to_s,
       -</span><span class="inferred1"><a name="line62"></a>62             :aggregation      =&gt; report.aggregation.to_s,
       -</span><span class="inferred0"><a name="line63"></a>63             :reporting_period =&gt; reporting_period.date_time,
       -</span><span class="inferred1"><a name="line64"></a>64             :value            =&gt; value,
       -</span><span class="inferred0"><a name="line65"></a>65             :run_limit        =&gt; limit
       -</span><span class="inferred1"><a name="line66"></a>66           )
       -</span><span class="marked0"><a name="line67"></a>67         end
       -</span><span class="inferred1"><a name="line68"></a>68 
       -</span><span class="marked0"><a name="line69"></a>69         def self.find_cached_data(report, options, first_reporting_period, last_reporting_period)
       -</span><span class="marked1"><a name="line70"></a>70           conditions = [
       -</span><span class="inferred0"><a name="line71"></a>71             'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ?',
       -</span><span class="inferred1"><a name="line72"></a>72             report.klass.to_s,
       -</span><span class="inferred0"><a name="line73"></a>73             report.name.to_s,
       -</span><span class="marked1"><a name="line74"></a>74             options[:grouping].identifier.to_s,
       -</span><span class="inferred0"><a name="line75"></a>75             report.aggregation.to_s,
       -</span><span class="inferred1"><a name="line76"></a>76             options[:limit]
       -</span><span class="inferred0"><a name="line77"></a>77           ]
       -</span><span class="marked1"><a name="line78"></a>78           if last_reporting_period
       -</span><span class="marked0"><a name="line79"></a>79             conditions.first &lt;&lt; ' AND reporting_period BETWEEN ? AND ?'
       -</span><span class="marked1"><a name="line80"></a>80             conditions &lt;&lt; first_reporting_period.date_time
       -</span><span class="marked0"><a name="line81"></a>81             conditions &lt;&lt; last_reporting_period.date_time
       -</span><span class="inferred1"><a name="line82"></a>82           else
       -</span><span class="marked0"><a name="line83"></a>83             conditions.first &lt;&lt; ' AND reporting_period &gt;= ?'
       -</span><span class="marked1"><a name="line84"></a>84             conditions &lt;&lt; first_reporting_period.date_time
       -</span><span class="inferred0"><a name="line85"></a>85           end
       -</span><span class="marked1"><a name="line86"></a>86           self.find(
       -</span><span class="inferred0"><a name="line87"></a>87             :all,
       -</span><span class="inferred1"><a name="line88"></a>88             :conditions =&gt; conditions,
       -</span><span class="inferred0"><a name="line89"></a>89             :limit =&gt; options[:limit],
       -</span><span class="inferred1"><a name="line90"></a>90             :order =&gt; 'reporting_period ASC'
       -</span><span class="inferred0"><a name="line91"></a>91           )
       -</span><span class="inferred1"><a name="line92"></a>92         end
       -</span><span class="inferred0"><a name="line93"></a>93 
       -</span><span class="inferred1"><a name="line94"></a>94     end
       -</span><span class="inferred0"><a name="line95"></a>95 
       -</span><span class="inferred1"><a name="line96"></a>96   end
       -</span><span class="inferred0"><a name="line97"></a>97 
       -</span><span class="inferred1"><a name="line98"></a>98 end
       +<pre><span class="marked1"><a name="line1"></a>  1 module Simplabs #:nodoc:
       +</span><span class="inferred0"><a name="line2"></a>  2 
       +</span><span class="marked1"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       +</span><span class="inferred0"><a name="line4"></a>  4 
       +</span><span class="inferred1"><a name="line5"></a>  5     # The ReportCache class is a regular +ActiveRecord+ model and represents cached results for single reporting periods (table name is +reports_as_sparkline_cache+)
       +</span><span class="inferred0"><a name="line6"></a>  6     # ReportCache instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+, +reporting_period+, +run_limit+
       +</span><span class="marked1"><a name="line7"></a>  7     class ReportCache &lt; ActiveRecord::Base
       +</span><span class="inferred0"><a name="line8"></a>  8 
       +</span><span class="marked1"><a name="line9"></a>  9       set_table_name :reports_as_sparkline_cache
       +</span><span class="inferred0"><a name="line10"></a> 10 
       +</span><span class="marked1"><a name="line11"></a> 11       def self.process(report, options, cache = true, &amp;block) #:nodoc:
       +</span><span class="marked0"><a name="line12"></a> 12         raise ArgumentError.new('A block must be given') unless block_given?
       +</span><span class="marked1"><a name="line13"></a> 13         self.transaction do
       +</span><span class="marked0"><a name="line14"></a> 14           cached_data = []
       +</span><span class="marked1"><a name="line15"></a> 15           first_reporting_period = ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date])
       +</span><span class="marked0"><a name="line16"></a> 16           last_reporting_period = options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]) : nil
       +</span><span class="inferred1"><a name="line17"></a> 17 
       +</span><span class="marked0"><a name="line18"></a> 18           if cache
       +</span><span class="marked1"><a name="line19"></a> 19             cached_data = find_cached_data(report, options, first_reporting_period, last_reporting_period)
       +</span><span class="marked0"><a name="line20"></a> 20             first_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.first.reporting_period)
       +</span><span class="marked1"><a name="line21"></a> 21             last_cached_reporting_period = cached_data.empty? ? nil : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period)
       +</span><span class="inferred0"><a name="line22"></a> 22           end
       +</span><span class="inferred1"><a name="line23"></a> 23 
       +</span><span class="marked0"><a name="line24"></a> 24           new_data = if !options[:live_data] &amp;&amp; last_cached_reporting_period == ReportingPeriod.new(options[:grouping]).previous
       +</span><span class="uncovered1"><a name="line25"></a> 25             []
       +</span><span class="inferred0"><a name="line26"></a> 26           else
       +</span><span class="marked1"><a name="line27"></a> 27             end_date = options[:live_data] ? nil : (options[:end_date] ? last_reporting_period.last_date_time : nil)
       +</span><span class="marked0"><a name="line28"></a> 28             yield((last_cached_reporting_period.next rescue first_reporting_period).date_time, end_date)
       +</span><span class="inferred1"><a name="line29"></a> 29           end
       +</span><span class="inferred0"><a name="line30"></a> 30 
       +</span><span class="marked1"><a name="line31"></a> 31           prepare_result(new_data, cached_data, report, options, cache)
       +</span><span class="inferred0"><a name="line32"></a> 32         end
       +</span><span class="inferred1"><a name="line33"></a> 33       end
       +</span><span class="inferred0"><a name="line34"></a> 34 
       +</span><span class="marked1"><a name="line35"></a> 35       private
       +</span><span class="inferred0"><a name="line36"></a> 36 
       +</span><span class="marked1"><a name="line37"></a> 37         def self.prepare_result(new_data, cached_data, report, options, cache = true)
       +</span><span class="marked0"><a name="line38"></a> 38           new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] }
       +</span><span class="marked1"><a name="line39"></a> 39           result = cached_data.map { |cached| [cached.reporting_period, cached.value] }
       +</span><span class="marked0"><a name="line40"></a> 40           last_reporting_period = ReportingPeriod.new(options[:grouping])
       +</span><span class="marked1"><a name="line41"></a> 41           reporting_period = cached_data.empty? ? ReportingPeriod.first(options[:grouping], (options[:end_date] ? options[:limit] - 1 : options[:limit]), options[:end_date]) : ReportingPeriod.new(options[:grouping], cached_data.last.reporting_period).next
       +</span><span class="marked0"><a name="line42"></a> 42           while reporting_period &lt; (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : last_reporting_period)
       +</span><span class="marked1"><a name="line43"></a> 43             cached = build_cached_data(report, options[:grouping], options[:limit], reporting_period, find_value(new_data, reporting_period))
       +</span><span class="marked0"><a name="line44"></a> 44             cached.save! if cache
       +</span><span class="marked1"><a name="line45"></a> 45             result &lt;&lt; [reporting_period.date_time, cached.value]
       +</span><span class="marked0"><a name="line46"></a> 46             reporting_period = reporting_period.next
       +</span><span class="inferred1"><a name="line47"></a> 47           end
       +</span><span class="marked0"><a name="line48"></a> 48           if options[:live_data]
       +</span><span class="marked1"><a name="line49"></a> 49             result &lt;&lt; [last_reporting_period.date_time, find_value(new_data, last_reporting_period)]
       +</span><span class="inferred0"><a name="line50"></a> 50           end
       +</span><span class="marked1"><a name="line51"></a> 51           result
       +</span><span class="inferred0"><a name="line52"></a> 52         end
       +</span><span class="inferred1"><a name="line53"></a> 53 
       +</span><span class="marked0"><a name="line54"></a> 54         def self.find_value(data, reporting_period)
       +</span><span class="marked1"><a name="line55"></a> 55           data = data.detect { |d| d[0] == reporting_period }
       +</span><span class="marked0"><a name="line56"></a> 56           data ? data[1] : 0.0
       +</span><span class="inferred1"><a name="line57"></a> 57         end
       +</span><span class="inferred0"><a name="line58"></a> 58 
       +</span><span class="marked1"><a name="line59"></a> 59         def self.build_cached_data(report, grouping, limit, reporting_period, value)
       +</span><span class="marked0"><a name="line60"></a> 60           self.new(
       +</span><span class="inferred1"><a name="line61"></a> 61             :model_name       =&gt; report.klass.to_s,
       +</span><span class="inferred0"><a name="line62"></a> 62             :report_name      =&gt; report.name.to_s,
       +</span><span class="marked1"><a name="line63"></a> 63             :grouping         =&gt; grouping.identifier.to_s,
       +</span><span class="inferred0"><a name="line64"></a> 64             :aggregation      =&gt; report.aggregation.to_s,
       +</span><span class="inferred1"><a name="line65"></a> 65             :reporting_period =&gt; reporting_period.date_time,
       +</span><span class="inferred0"><a name="line66"></a> 66             :value            =&gt; value,
       +</span><span class="inferred1"><a name="line67"></a> 67             :run_limit        =&gt; limit
       +</span><span class="inferred0"><a name="line68"></a> 68           )
       +</span><span class="marked1"><a name="line69"></a> 69         end
       +</span><span class="inferred0"><a name="line70"></a> 70 
       +</span><span class="marked1"><a name="line71"></a> 71         def self.find_cached_data(report, options, first_reporting_period, last_reporting_period)
       +</span><span class="marked0"><a name="line72"></a> 72           conditions = [
       +</span><span class="inferred1"><a name="line73"></a> 73             'model_name = ? AND report_name = ? AND grouping = ? AND aggregation = ? AND run_limit = ?',
       +</span><span class="inferred0"><a name="line74"></a> 74             report.klass.to_s,
       +</span><span class="inferred1"><a name="line75"></a> 75             report.name.to_s,
       +</span><span class="marked0"><a name="line76"></a> 76             options[:grouping].identifier.to_s,
       +</span><span class="inferred1"><a name="line77"></a> 77             report.aggregation.to_s,
       +</span><span class="inferred0"><a name="line78"></a> 78             options[:limit]
       +</span><span class="inferred1"><a name="line79"></a> 79           ]
       +</span><span class="marked0"><a name="line80"></a> 80           if last_reporting_period
       +</span><span class="marked1"><a name="line81"></a> 81             conditions.first &lt;&lt; ' AND reporting_period BETWEEN ? AND ?'
       +</span><span class="marked0"><a name="line82"></a> 82             conditions &lt;&lt; first_reporting_period.date_time
       +</span><span class="marked1"><a name="line83"></a> 83             conditions &lt;&lt; last_reporting_period.date_time
       +</span><span class="inferred0"><a name="line84"></a> 84           else
       +</span><span class="marked1"><a name="line85"></a> 85             conditions.first &lt;&lt; ' AND reporting_period &gt;= ?'
       +</span><span class="marked0"><a name="line86"></a> 86             conditions &lt;&lt; first_reporting_period.date_time
       +</span><span class="inferred1"><a name="line87"></a> 87           end
       +</span><span class="marked0"><a name="line88"></a> 88           self.find(
       +</span><span class="inferred1"><a name="line89"></a> 89             :all,
       +</span><span class="inferred0"><a name="line90"></a> 90             :conditions =&gt; conditions,
       +</span><span class="inferred1"><a name="line91"></a> 91             :limit =&gt; options[:limit],
       +</span><span class="inferred0"><a name="line92"></a> 92             :order =&gt; 'reporting_period ASC'
       +</span><span class="inferred1"><a name="line93"></a> 93           )
       +</span><span class="inferred0"><a name="line94"></a> 94         end
       +</span><span class="inferred1"><a name="line95"></a> 95 
       +</span><span class="inferred0"><a name="line96"></a> 96     end
       +</span><span class="inferred1"><a name="line97"></a> 97 
       +</span><span class="inferred0"><a name="line98"></a> 98   end
       +</span><span class="inferred1"><a name="line99"></a> 99 
       +</span><span class="inferred0"><a name="line100"></a>100 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-report_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-report_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:07 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -598,125 +598,125 @@ span.run100 {
              </tr>
            </tbody>
          </table>
       -<pre><span class="marked1"><a name="line1"></a>  1 module Simplabs #:nodoc:
       -</span><span class="inferred0"><a name="line2"></a>  2 
       -</span><span class="marked1"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       -</span><span class="inferred0"><a name="line4"></a>  4 
       -</span><span class="inferred1"><a name="line5"></a>  5     # The Report class that does all the data retrieval and calculations
       -</span><span class="marked0"><a name="line6"></a>  6     class Report
       -</span><span class="inferred1"><a name="line7"></a>  7 
       -</span><span class="marked0"><a name="line8"></a>  8       attr_reader :klass, :name, :date_column, :value_column, :aggregation, :options
       -</span><span class="inferred1"><a name="line9"></a>  9 
       -</span><span class="inferred0"><a name="line10"></a> 10       # ==== Parameters
       -</span><span class="inferred1"><a name="line11"></a> 11       # * &lt;tt&gt;klass&lt;/tt&gt; - The model the report works on (This is the class you invoke Simplabs::ReportsAsSparkline::ClassMethods#reports_as_sparkline on)
       -</span><span class="inferred0"><a name="line12"></a> 12       # * &lt;tt&gt;name&lt;/tt&gt; - The name of the report (as in Simplabs::ReportsAsSparkline::ClassMethods#reports_as_sparkline)
       -</span><span class="inferred1"><a name="line13"></a> 13       #
       -</span><span class="inferred0"><a name="line14"></a> 14       # ==== Options
       -</span><span class="inferred1"><a name="line15"></a> 15       #
       -</span><span class="inferred0"><a name="line16"></a> 16       # * &lt;tt&gt;:date_column&lt;/tt&gt; - The name of the date column on that the records are aggregated
       -</span><span class="inferred1"><a name="line17"></a> 17       # * &lt;tt&gt;:value_column&lt;/tt&gt; - The name of the column that holds the value to sum for aggregation :sum
       -</span><span class="inferred0"><a name="line18"></a> 18       # * &lt;tt&gt;:aggregation&lt;/tt&gt; - The aggregation to use (one of :count, :sum, :minimum, :maximum or :average); when using anything other than :count, :value_column must also be specified (&lt;b&gt;If you really want to e.g. sumon the 'id' column, you have to explicitely say so.&lt;/b&gt;)
       -</span><span class="inferred1"><a name="line19"></a> 19       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (:hour, :day, :week, :month); &lt;b&gt;Beware that reports_as_sparkline treats weeks as starting on monday!&lt;/b&gt;
       -</span><span class="inferred0"><a name="line20"></a> 20       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of periods to get (see :grouping)
       -</span><span class="inferred1"><a name="line21"></a> 21       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -</span><span class="inferred0"><a name="line22"></a> 22       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -</span><span class="inferred1"><a name="line23"></a> 23       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the periods before this date.
       -</span><span class="marked0"><a name="line24"></a> 24       def initialize(klass, name, options = {})
       -</span><span class="marked1"><a name="line25"></a> 25         ensure_valid_options(options)
       -</span><span class="marked0"><a name="line26"></a> 26         @klass        = klass
       -</span><span class="marked1"><a name="line27"></a> 27         @name         = name
       -</span><span class="marked0"><a name="line28"></a> 28         @date_column  = (options[:date_column] || 'created_at').to_s
       -</span><span class="marked1"><a name="line29"></a> 29         @aggregation  = options[:aggregation] || :count
       -</span><span class="marked0"><a name="line30"></a> 30         @value_column = (options[:value_column] || (@aggregation == :count ? 'id' : name)).to_s
       -</span><span class="marked1"><a name="line31"></a> 31         @options = {
       -</span><span class="inferred0"><a name="line32"></a> 32           :limit      =&gt; options[:limit] || 100,
       -</span><span class="inferred1"><a name="line33"></a> 33           :conditions =&gt; options[:conditions] || [],
       -</span><span class="marked0"><a name="line34"></a> 34           :grouping   =&gt; Grouping.new(options[:grouping] || :day),
       -</span><span class="inferred1"><a name="line35"></a> 35           :live_data  =&gt; options[:live_data] || false,
       -</span><span class="inferred0"><a name="line36"></a> 36           :end_date   =&gt; options[:end_date] || false
       -</span><span class="inferred1"><a name="line37"></a> 37         }
       -</span><span class="marked0"><a name="line38"></a> 38         @options.merge!(options)
       -</span><span class="marked1"><a name="line39"></a> 39         @options.freeze
       -</span><span class="inferred0"><a name="line40"></a> 40       end
       -</span><span class="inferred1"><a name="line41"></a> 41 
       -</span><span class="inferred0"><a name="line42"></a> 42       # Runs the report and returns an array of array of DateTimes and Floats
       -</span><span class="inferred1"><a name="line43"></a> 43       #
       -</span><span class="inferred0"><a name="line44"></a> 44       # ==== Options
       -</span><span class="inferred1"><a name="line45"></a> 45       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of periods to get
       -</span><span class="inferred0"><a name="line46"></a> 46       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on (&lt;b&gt;Beware that when you specify conditions here, caching will be disabled&lt;/b&gt;)
       -</span><span class="inferred1"><a name="line47"></a> 47       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (:hour, :day, :week, :month); &lt;b&gt;Beware that reports_as_sparkline treats weeks as starting on monday!&lt;/b&gt;
       -</span><span class="inferred0"><a name="line48"></a> 48       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -</span><span class="inferred1"><a name="line49"></a> 49       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the periods before this date.
       -</span><span class="marked0"><a name="line50"></a> 50       def run(options = {})
       -</span><span class="marked1"><a name="line51"></a> 51         custom_conditions = options.key?(:conditions)
       -</span><span class="marked0"><a name="line52"></a> 52         options = options_for_run(options)
       -</span><span class="marked1"><a name="line53"></a> 53         ReportCache.process(self, options, !custom_conditions) do |begin_at, end_at|
       -</span><span class="marked0"><a name="line54"></a> 54           read_data(begin_at, end_at, options)
       -</span><span class="inferred1"><a name="line55"></a> 55         end
       -</span><span class="inferred0"><a name="line56"></a> 56       end
       -</span><span class="inferred1"><a name="line57"></a> 57 
       -</span><span class="marked0"><a name="line58"></a> 58       private
       -</span><span class="inferred1"><a name="line59"></a> 59 
       -</span><span class="marked0"><a name="line60"></a> 60         def options_for_run(options = {})
       -</span><span class="marked1"><a name="line61"></a> 61           options = options.dup
       -</span><span class="marked0"><a name="line62"></a> 62           ensure_valid_options(options, :run)
       -</span><span class="marked1"><a name="line63"></a> 63           options.reverse_merge!(@options)
       -</span><span class="marked0"><a name="line64"></a> 64           options[:grouping] = Grouping.new(options[:grouping]) unless options[:grouping].is_a?(Grouping)
       -</span><span class="marked1"><a name="line65"></a> 65           return options
       -</span><span class="inferred0"><a name="line66"></a> 66         end
       -</span><span class="inferred1"><a name="line67"></a> 67 
       -</span><span class="marked0"><a name="line68"></a> 68         def read_data(begin_at, end_at, options)
       -</span><span class="marked1"><a name="line69"></a> 69           conditions = setup_conditions(begin_at, end_at, options[:conditions])
       -</span><span class="marked0"><a name="line70"></a> 70           @klass.send(@aggregation,
       -</span><span class="inferred1"><a name="line71"></a> 71             @value_column,
       -</span><span class="inferred0"><a name="line72"></a> 72             :conditions =&gt; conditions,
       -</span><span class="marked1"><a name="line73"></a> 73             :group =&gt; options[:grouping].to_sql(@date_column),
       -</span><span class="marked0"><a name="line74"></a> 74             :order =&gt; &quot;#{options[:grouping].to_sql(@date_column)} ASC&quot;
       -</span><span class="inferred1"><a name="line75"></a> 75           )
       -</span><span class="inferred0"><a name="line76"></a> 76         end
       -</span><span class="inferred1"><a name="line77"></a> 77 
       -</span><span class="marked0"><a name="line78"></a> 78         def setup_conditions(begin_at, end_at, custom_conditions = [])
       -</span><span class="marked1"><a name="line79"></a> 79           conditions = [@klass.send(:sanitize_sql_for_conditions, custom_conditions) || '']
       -</span><span class="marked0"><a name="line80"></a> 80           conditions[0] += &quot;#{(conditions[0].blank? ? '' : ' AND ')}#{ActiveRecord::Base.connection.quote_table_name(@klass.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(@date_column.to_s)} &quot;
       -</span><span class="marked1"><a name="line81"></a> 81           conditions[0] += if begin_at &amp;&amp; end_at
       -</span><span class="marked0"><a name="line82"></a> 82             'BETWEEN ? AND ?'
       -</span><span class="marked1"><a name="line83"></a> 83           elsif begin_at
       -</span><span class="marked0"><a name="line84"></a> 84             '&gt;= ?'
       -</span><span class="marked1"><a name="line85"></a> 85           elsif end_at
       -</span><span class="marked0"><a name="line86"></a> 86             '&lt;= ?'
       -</span><span class="inferred1"><a name="line87"></a> 87           else
       -</span><span class="marked0"><a name="line88"></a> 88             raise ArgumentError.new('You must pass either begin_at, end_at or both to setup_conditions.')
       -</span><span class="inferred1"><a name="line89"></a> 89           end
       -</span><span class="marked0"><a name="line90"></a> 90           conditions &lt;&lt; begin_at if begin_at
       -</span><span class="marked1"><a name="line91"></a> 91           conditions &lt;&lt; end_at if end_at
       -</span><span class="marked0"><a name="line92"></a> 92           conditions
       -</span><span class="inferred1"><a name="line93"></a> 93         end
       -</span><span class="inferred0"><a name="line94"></a> 94 
       -</span><span class="marked1"><a name="line95"></a> 95         def ensure_valid_options(options, context = :initialize)
       -</span><span class="marked0"><a name="line96"></a> 96           case context
       -</span><span class="marked1"><a name="line97"></a> 97             when :initialize
       -</span><span class="marked0"><a name="line98"></a> 98               options.each_key do |k|
       -</span><span class="marked1"><a name="line99"></a> 99                 raise ArgumentError.new(&quot;Invalid option #{k}!&quot;) unless [:limit, :aggregation, :grouping, :date_column, :value_column, :conditions, :live_data, :end_date].include?(k)
       -</span><span class="inferred0"><a name="line100"></a>100               end
       -</span><span class="marked1"><a name="line101"></a>101               raise ArgumentError.new(&quot;Invalid aggregation #{options[:aggregation]}!&quot;) if options[:aggregation] &amp;&amp; ![:count, :sum, :maximum, :minimum, :average].include?(options[:aggregation])
       -</span><span class="marked0"><a name="line102"></a>102               raise ArgumentError.new('The name of the column holding the value to sum has to be specified for aggregation :sum!') if [:sum, :maximum, :minimum, :average].include?(options[:aggregation]) &amp;&amp; !options.key?(:value_column)
       -</span><span class="marked1"><a name="line103"></a>103             when :run
       -</span><span class="marked0"><a name="line104"></a>104               options.each_key do |k|
       -</span><span class="marked1"><a name="line105"></a>105                 raise ArgumentError.new(&quot;Invalid option #{k}!&quot;) unless [:limit, :conditions, :grouping, :live_data, :end_date].include?(k)
       -</span><span class="inferred0"><a name="line106"></a>106               end
       -</span><span class="inferred1"><a name="line107"></a>107           end
       -</span><span class="marked0"><a name="line108"></a>108           raise ArgumentError.new('Options :live_data and :end_date may not both be specified!') if options[:live_data] &amp;&amp; options[:end_date]
       -</span><span class="marked1"><a name="line109"></a>109           raise ArgumentError.new(&quot;Invalid grouping #{options[:grouping]}!&quot;) if options[:grouping] &amp;&amp; ![:hour, :day, :week, :month].include?(options[:grouping])
       -</span><span class="marked0"><a name="line110"></a>110           raise ArgumentError.new(&quot;Invalid conditions: #{options[:conditions].inspect}!&quot;) if options[:conditions] &amp;&amp; !options[:conditions].is_a?(Array) &amp;&amp; !options[:conditions].is_a?(Hash)
       -</span><span class="marked1"><a name="line111"></a>111           raise ArgumentError.new(&quot;Invalid end date: #{options[:end_date].inspect}; must be a DateTime!&quot;) if options[:end_date] &amp;&amp; !options[:end_date].is_a?(DateTime) &amp;&amp; !options[:end_date].is_a?(Time)
       -</span><span class="marked0"><a name="line112"></a>112           raise ArgumentError.new('End date may not be in the future!') if options[:end_date] &amp;&amp; options[:end_date] &gt; DateTime.now
       -</span><span class="inferred1"><a name="line113"></a>113         end
       -</span><span class="inferred0"><a name="line114"></a>114 
       -</span><span class="inferred1"><a name="line115"></a>115     end
       -</span><span class="inferred0"><a name="line116"></a>116 
       -</span><span class="inferred1"><a name="line117"></a>117   end
       -</span><span class="inferred0"><a name="line118"></a>118 
       -</span><span class="inferred1"><a name="line119"></a>119 end
       +<pre><span class="marked0"><a name="line1"></a>  1 module Simplabs #:nodoc:
       +</span><span class="inferred1"><a name="line2"></a>  2 
       +</span><span class="marked0"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       +</span><span class="inferred1"><a name="line4"></a>  4 
       +</span><span class="inferred0"><a name="line5"></a>  5     # The Report class that does all the data retrieval and calculations
       +</span><span class="marked1"><a name="line6"></a>  6     class Report
       +</span><span class="inferred0"><a name="line7"></a>  7 
       +</span><span class="marked1"><a name="line8"></a>  8       attr_reader :klass, :name, :date_column, :value_column, :aggregation, :options
       +</span><span class="inferred0"><a name="line9"></a>  9 
       +</span><span class="inferred1"><a name="line10"></a> 10       # ==== Parameters
       +</span><span class="inferred0"><a name="line11"></a> 11       # * &lt;tt&gt;klass&lt;/tt&gt; - The model the report works on (This is the class you invoke Simplabs::ReportsAsSparkline::ClassMethods#reports_as_sparkline on)
       +</span><span class="inferred1"><a name="line12"></a> 12       # * &lt;tt&gt;name&lt;/tt&gt; - The name of the report (as in Simplabs::ReportsAsSparkline::ClassMethods#reports_as_sparkline)
       +</span><span class="inferred0"><a name="line13"></a> 13       #
       +</span><span class="inferred1"><a name="line14"></a> 14       # ==== Options
       +</span><span class="inferred0"><a name="line15"></a> 15       #
       +</span><span class="inferred1"><a name="line16"></a> 16       # * &lt;tt&gt;:date_column&lt;/tt&gt; - The name of the date column over that the records are aggregated (defaults to &lt;tt&gt;created_at&lt;/tt&gt;)
       +</span><span class="inferred0"><a name="line17"></a> 17       # * &lt;tt&gt;:value_column&lt;/tt&gt; - The name of the column that holds the values to sum up when using aggregation &lt;tt&gt;:sum&lt;/tt&gt;
       +</span><span class="inferred1"><a name="line18"></a> 18       # * &lt;tt&gt;:aggregation&lt;/tt&gt; - The aggregation to use (one of &lt;tt&gt;:count&lt;/tt&gt;, &lt;tt&gt;:sum&lt;/tt&gt;, &lt;tt&gt;:minimum&lt;/tt&gt;, &lt;tt&gt;:maximum&lt;/tt&gt; or &lt;tt&gt;:average&lt;/tt&gt;); when using anything other than &lt;tt&gt;:count&lt;/tt&gt;, &lt;tt&gt;:value_column&lt;/tt&gt; must also be specified (&lt;b&gt;If you really want to e.g. sum up the values in the &lt;tt&gt;id&lt;/tt&gt; column, you have to explicitely say so.&lt;/b&gt;); (defaults to &lt;tt&gt;:count&lt;/tt&gt;)
       +</span><span class="inferred0"><a name="line19"></a> 19       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (&lt;tt&gt;:hour&lt;/tt&gt;, &lt;tt&gt;:day&lt;/tt&gt;, &lt;tt&gt;:week&lt;/tt&gt;, &lt;tt&gt;:month&lt;/tt&gt;); &lt;b&gt;Beware that &lt;tt&gt;reports_as_sparkline&lt;/tt&gt; treats weeks as starting on monday!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line20"></a> 20       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of reporting periods to get (see &lt;tt&gt;:grouping&lt;/tt&gt;), (defaults to 100)
       +</span><span class="inferred0"><a name="line21"></a> 21       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in &lt;tt&gt;ActiveRecord::Base#find&lt;/tt&gt;; only records that match the conditions are reported; &lt;b&gt;Beware that when conditions are specified, caching is disabled!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line22"></a> 22       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specifies whether data for the current reporting period is to be read; &lt;b&gt;if &lt;tt&gt;:live_data&lt;/tt&gt; is &lt;tt&gt;true&lt;/tt&gt;, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to &lt;tt&gt;false&lt;/tt&gt;)&lt;/b&gt;
       +</span><span class="inferred0"><a name="line23"></a> 23       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the &lt;tt&gt;:limit&lt;/tt&gt; reporting periods until this date.
       +</span><span class="marked1"><a name="line24"></a> 24       def initialize(klass, name, options = {})
       +</span><span class="marked0"><a name="line25"></a> 25         ensure_valid_options(options)
       +</span><span class="marked1"><a name="line26"></a> 26         @klass        = klass
       +</span><span class="marked0"><a name="line27"></a> 27         @name         = name
       +</span><span class="marked1"><a name="line28"></a> 28         @date_column  = (options[:date_column] || 'created_at').to_s
       +</span><span class="marked0"><a name="line29"></a> 29         @aggregation  = options[:aggregation] || :count
       +</span><span class="marked1"><a name="line30"></a> 30         @value_column = (options[:value_column] || (@aggregation == :count ? 'id' : name)).to_s
       +</span><span class="marked0"><a name="line31"></a> 31         @options = {
       +</span><span class="inferred1"><a name="line32"></a> 32           :limit      =&gt; options[:limit] || 100,
       +</span><span class="inferred0"><a name="line33"></a> 33           :conditions =&gt; options[:conditions] || [],
       +</span><span class="marked1"><a name="line34"></a> 34           :grouping   =&gt; Grouping.new(options[:grouping] || :day),
       +</span><span class="inferred0"><a name="line35"></a> 35           :live_data  =&gt; options[:live_data] || false,
       +</span><span class="inferred1"><a name="line36"></a> 36           :end_date   =&gt; options[:end_date] || false
       +</span><span class="inferred0"><a name="line37"></a> 37         }
       +</span><span class="marked1"><a name="line38"></a> 38         @options.merge!(options)
       +</span><span class="marked0"><a name="line39"></a> 39         @options.freeze
       +</span><span class="inferred1"><a name="line40"></a> 40       end
       +</span><span class="inferred0"><a name="line41"></a> 41 
       +</span><span class="inferred1"><a name="line42"></a> 42       # Runs the report and returns an array of array of DateTimes and Floats
       +</span><span class="inferred0"><a name="line43"></a> 43       #
       +</span><span class="inferred1"><a name="line44"></a> 44       # ==== Options
       +</span><span class="inferred0"><a name="line45"></a> 45       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (&lt;tt&gt;:hour&lt;/tt&gt;, &lt;tt&gt;:day&lt;/tt&gt;, &lt;tt&gt;:week&lt;/tt&gt;, &lt;tt&gt;:month&lt;/tt&gt;); &lt;b&gt;Beware that &lt;tt&gt;reports_as_sparkline&lt;/tt&gt; treats weeks as starting on monday!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line46"></a> 46       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of reporting periods to get (see &lt;tt&gt;:grouping&lt;/tt&gt;), (defaults to 100)
       +</span><span class="inferred0"><a name="line47"></a> 47       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in &lt;tt&gt;ActiveRecord::Base#find&lt;/tt&gt;; only records that match the conditions are reported; &lt;b&gt;Beware that when conditions are specified, caching is disabled!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line48"></a> 48       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specifies whether data for the current reporting period is to be read; &lt;b&gt;if &lt;tt&gt;:live_data&lt;/tt&gt; is &lt;tt&gt;true&lt;/tt&gt;, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to &lt;tt&gt;false&lt;/tt&gt;)&lt;/b&gt;
       +</span><span class="inferred0"><a name="line49"></a> 49       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the &lt;tt&gt;:limit&lt;/tt&gt; reporting periods until this date.
       +</span><span class="marked1"><a name="line50"></a> 50       def run(options = {})
       +</span><span class="marked0"><a name="line51"></a> 51         custom_conditions = options.key?(:conditions)
       +</span><span class="marked1"><a name="line52"></a> 52         options = options_for_run(options)
       +</span><span class="marked0"><a name="line53"></a> 53         ReportCache.process(self, options, !custom_conditions) do |begin_at, end_at|
       +</span><span class="marked1"><a name="line54"></a> 54           read_data(begin_at, end_at, options)
       +</span><span class="inferred0"><a name="line55"></a> 55         end
       +</span><span class="inferred1"><a name="line56"></a> 56       end
       +</span><span class="inferred0"><a name="line57"></a> 57 
       +</span><span class="marked1"><a name="line58"></a> 58       private
       +</span><span class="inferred0"><a name="line59"></a> 59 
       +</span><span class="marked1"><a name="line60"></a> 60         def options_for_run(options = {})
       +</span><span class="marked0"><a name="line61"></a> 61           options = options.dup
       +</span><span class="marked1"><a name="line62"></a> 62           ensure_valid_options(options, :run)
       +</span><span class="marked0"><a name="line63"></a> 63           options.reverse_merge!(@options)
       +</span><span class="marked1"><a name="line64"></a> 64           options[:grouping] = Grouping.new(options[:grouping]) unless options[:grouping].is_a?(Grouping)
       +</span><span class="marked0"><a name="line65"></a> 65           return options
       +</span><span class="inferred1"><a name="line66"></a> 66         end
       +</span><span class="inferred0"><a name="line67"></a> 67 
       +</span><span class="marked1"><a name="line68"></a> 68         def read_data(begin_at, end_at, options)
       +</span><span class="marked0"><a name="line69"></a> 69           conditions = setup_conditions(begin_at, end_at, options[:conditions])
       +</span><span class="marked1"><a name="line70"></a> 70           @klass.send(@aggregation,
       +</span><span class="inferred0"><a name="line71"></a> 71             @value_column,
       +</span><span class="inferred1"><a name="line72"></a> 72             :conditions =&gt; conditions,
       +</span><span class="marked0"><a name="line73"></a> 73             :group =&gt; options[:grouping].to_sql(@date_column),
       +</span><span class="marked1"><a name="line74"></a> 74             :order =&gt; &quot;#{options[:grouping].to_sql(@date_column)} ASC&quot;
       +</span><span class="inferred0"><a name="line75"></a> 75           )
       +</span><span class="inferred1"><a name="line76"></a> 76         end
       +</span><span class="inferred0"><a name="line77"></a> 77 
       +</span><span class="marked1"><a name="line78"></a> 78         def setup_conditions(begin_at, end_at, custom_conditions = [])
       +</span><span class="marked0"><a name="line79"></a> 79           conditions = [@klass.send(:sanitize_sql_for_conditions, custom_conditions) || '']
       +</span><span class="marked1"><a name="line80"></a> 80           conditions[0] += &quot;#{(conditions[0].blank? ? '' : ' AND ')}#{ActiveRecord::Base.connection.quote_table_name(@klass.table_name)}.#{ActiveRecord::Base.connection.quote_column_name(@date_column.to_s)} &quot;
       +</span><span class="marked0"><a name="line81"></a> 81           conditions[0] += if begin_at &amp;&amp; end_at
       +</span><span class="marked1"><a name="line82"></a> 82             'BETWEEN ? AND ?'
       +</span><span class="marked0"><a name="line83"></a> 83           elsif begin_at
       +</span><span class="marked1"><a name="line84"></a> 84             '&gt;= ?'
       +</span><span class="marked0"><a name="line85"></a> 85           elsif end_at
       +</span><span class="marked1"><a name="line86"></a> 86             '&lt;= ?'
       +</span><span class="inferred0"><a name="line87"></a> 87           else
       +</span><span class="marked1"><a name="line88"></a> 88             raise ArgumentError.new('You must pass either begin_at, end_at or both to setup_conditions.')
       +</span><span class="inferred0"><a name="line89"></a> 89           end
       +</span><span class="marked1"><a name="line90"></a> 90           conditions &lt;&lt; begin_at if begin_at
       +</span><span class="marked0"><a name="line91"></a> 91           conditions &lt;&lt; end_at if end_at
       +</span><span class="marked1"><a name="line92"></a> 92           conditions
       +</span><span class="inferred0"><a name="line93"></a> 93         end
       +</span><span class="inferred1"><a name="line94"></a> 94 
       +</span><span class="marked0"><a name="line95"></a> 95         def ensure_valid_options(options, context = :initialize)
       +</span><span class="marked1"><a name="line96"></a> 96           case context
       +</span><span class="marked0"><a name="line97"></a> 97             when :initialize
       +</span><span class="marked1"><a name="line98"></a> 98               options.each_key do |k|
       +</span><span class="marked0"><a name="line99"></a> 99                 raise ArgumentError.new(&quot;Invalid option #{k}!&quot;) unless [:limit, :aggregation, :grouping, :date_column, :value_column, :conditions, :live_data, :end_date].include?(k)
       +</span><span class="inferred1"><a name="line100"></a>100               end
       +</span><span class="marked0"><a name="line101"></a>101               raise ArgumentError.new(&quot;Invalid aggregation #{options[:aggregation]}!&quot;) if options[:aggregation] &amp;&amp; ![:count, :sum, :maximum, :minimum, :average].include?(options[:aggregation])
       +</span><span class="marked1"><a name="line102"></a>102               raise ArgumentError.new('The name of the column holding the value to sum has to be specified for aggregation :sum!') if [:sum, :maximum, :minimum, :average].include?(options[:aggregation]) &amp;&amp; !options.key?(:value_column)
       +</span><span class="marked0"><a name="line103"></a>103             when :run
       +</span><span class="marked1"><a name="line104"></a>104               options.each_key do |k|
       +</span><span class="marked0"><a name="line105"></a>105                 raise ArgumentError.new(&quot;Invalid option #{k}!&quot;) unless [:limit, :conditions, :grouping, :live_data, :end_date].include?(k)
       +</span><span class="inferred1"><a name="line106"></a>106               end
       +</span><span class="inferred0"><a name="line107"></a>107           end
       +</span><span class="marked1"><a name="line108"></a>108           raise ArgumentError.new('Options :live_data and :end_date may not both be specified!') if options[:live_data] &amp;&amp; options[:end_date]
       +</span><span class="marked0"><a name="line109"></a>109           raise ArgumentError.new(&quot;Invalid grouping #{options[:grouping]}!&quot;) if options[:grouping] &amp;&amp; ![:hour, :day, :week, :month].include?(options[:grouping])
       +</span><span class="marked1"><a name="line110"></a>110           raise ArgumentError.new(&quot;Invalid conditions: #{options[:conditions].inspect}!&quot;) if options[:conditions] &amp;&amp; !options[:conditions].is_a?(Array) &amp;&amp; !options[:conditions].is_a?(Hash)
       +</span><span class="marked0"><a name="line111"></a>111           raise ArgumentError.new(&quot;Invalid end date: #{options[:end_date].inspect}; must be a DateTime!&quot;) if options[:end_date] &amp;&amp; !options[:end_date].is_a?(DateTime) &amp;&amp; !options[:end_date].is_a?(Time)
       +</span><span class="marked1"><a name="line112"></a>112           raise ArgumentError.new('End date may not be in the future!') if options[:end_date] &amp;&amp; options[:end_date] &gt; DateTime.now
       +</span><span class="inferred0"><a name="line113"></a>113         end
       +</span><span class="inferred1"><a name="line114"></a>114 
       +</span><span class="inferred0"><a name="line115"></a>115     end
       +</span><span class="inferred1"><a name="line116"></a>116 
       +</span><span class="inferred0"><a name="line117"></a>117   end
       +</span><span class="inferred1"><a name="line118"></a>118 
       +</span><span class="inferred0"><a name="line119"></a>119 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-reporting_period_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-reporting_period_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:08 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -571,11 +571,11 @@ span.run100 {
            </thead>
          <tbody><tr class='light'><td><a href='lib-simplabs-reports_as_sparkline-reporting_period_rb.html'>lib/simplabs/reports_as_sparkline/reporting_period.rb</a>
                </td>
       -      <td class='lines_total'><tt>108</tt>
       +      <td class='lines_total'><tt>93</tt>
                </td>
              <td class='lines_code'><tt>76</tt>
                </td>
       -      <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>96.3%</tt>
       +      <td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>95.7%</tt>
                      &nbsp;</td>
                    <td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='96'/>
                          <td class='uncovered' width='4'/>
       @@ -598,114 +598,99 @@ span.run100 {
              </tr>
            </tbody>
          </table>
       -<pre><span class="marked0"><a name="line1"></a>  1 module Simplabs #:nodoc:
       -</span><span class="inferred1"><a name="line2"></a>  2 
       -</span><span class="marked0"><a name="line3"></a>  3   module ReportsAsSparkline #:nodoc:
       -</span><span class="inferred1"><a name="line4"></a>  4 
       -</span><span class="inferred0"><a name="line5"></a>  5     # A ReportingPeriod is  - depending on the Grouping - either a specific hour, a day, a month or a year. All records falling into this period will be grouped together.
       -</span><span class="marked1"><a name="line6"></a>  6     class ReportingPeriod
       -</span><span class="inferred0"><a name="line7"></a>  7 
       -</span><span class="marked1"><a name="line8"></a>  8       attr_reader :date_time, :grouping
       -</span><span class="inferred0"><a name="line9"></a>  9 
       -</span><span class="inferred1"><a name="line10"></a> 10       # ==== Parameters
       -</span><span class="inferred0"><a name="line11"></a> 11       # * &lt;tt&gt;grouping&lt;/tt&gt; - The Simplabs::ReportsAsSparkline::Grouping of the reporting period
       -</span><span class="inferred1"><a name="line12"></a> 12       # * &lt;tt&gt;date_time&lt;/tt&gt; - The DateTime that reporting period is created for
       -</span><span class="marked0"><a name="line13"></a> 13       def initialize(grouping, date_time = nil)
       -</span><span class="marked1"><a name="line14"></a> 14         @grouping  = grouping
       -</span><span class="marked0"><a name="line15"></a> 15         @date_time = parse_date_time(date_time || DateTime.now)
       -</span><span class="inferred1"><a name="line16"></a> 16       end
       -</span><span class="inferred0"><a name="line17"></a> 17 
       -</span><span class="inferred1"><a name="line18"></a> 18       # Returns the first reporting period for a grouping and a limit; e.g. the first reporting period for Grouping :day and limit 2 would be Time.now - 2.days
       -</span><span class="inferred0"><a name="line19"></a> 19       #
       -</span><span class="inferred1"><a name="line20"></a> 20       # ==== Parameters
       -</span><span class="inferred0"><a name="line21"></a> 21       # * &lt;tt&gt;grouping&lt;/tt&gt; - The Simplabs::ReportsAsSparkline::Grouping of the reporting period
       -</span><span class="inferred1"><a name="line22"></a> 22       # * &lt;tt&gt;limit&lt;/tt&gt; - The number of reporting periods until the first one
       -</span><span class="marked0"><a name="line23"></a> 23       def self.first(grouping, limit, end_date = nil)
       -</span><span class="marked1"><a name="line24"></a> 24         self.new(grouping, end_date).offset(-limit)
       -</span><span class="marked0"><a name="line25"></a> 25       end
       -</span><span class="inferred1"><a name="line26"></a> 26 
       -</span><span class="marked0"><a name="line27"></a> 27       def self.from_db_string(grouping, db_string) #:nodoc:
       -</span><span class="marked1"><a name="line28"></a> 28         parts = grouping.date_parts_from_db_string(db_string)
       -</span><span class="marked0"><a name="line29"></a> 29         result = case grouping.identifier
       -</span><span class="marked1"><a name="line30"></a> 30           when :hour
       -</span><span class="marked0"><a name="line31"></a> 31             self.new(grouping, DateTime.new(parts[0], parts[1], parts[2], parts[3], 0, 0))
       -</span><span class="marked1"><a name="line32"></a> 32           when :day
       -</span><span class="marked0"><a name="line33"></a> 33             self.new(grouping, Date.new(parts[0], parts[1], parts[2]))
       -</span><span class="marked1"><a name="line34"></a> 34           when :week
       -</span><span class="marked0"><a name="line35"></a> 35             self.new(grouping, Date.commercial(parts[0], parts[1], 1))
       -</span><span class="marked1"><a name="line36"></a> 36           when :month
       -</span><span class="marked0"><a name="line37"></a> 37             self.new(grouping, Date.new(parts[0], parts[1], 1))
       -</span><span class="inferred1"><a name="line38"></a> 38         end
       -</span><span class="marked0"><a name="line39"></a> 39         result
       -</span><span class="inferred1"><a name="line40"></a> 40       end
       -</span><span class="inferred0"><a name="line41"></a> 41 
       -</span><span class="inferred1"><a name="line42"></a> 42       # Returns the next reporting period (that is next hour/day/month/year)
       -</span><span class="marked0"><a name="line43"></a> 43       def next
       -</span><span class="marked1"><a name="line44"></a> 44         self.offset(1)
       -</span><span class="marked0"><a name="line45"></a> 45       end
       -</span><span class="inferred1"><a name="line46"></a> 46 
       -</span><span class="inferred0"><a name="line47"></a> 47       # Returns the previous reporting period (that is next hour/day/month/year)
       -</span><span class="marked1"><a name="line48"></a> 48       def previous
       -</span><span class="marked0"><a name="line49"></a> 49         self.offset(-1)
       -</span><span class="marked1"><a name="line50"></a> 50       end
       -</span><span class="inferred0"><a name="line51"></a> 51 
       -</span><span class="inferred1"><a name="line52"></a> 52       # Returns the reporting period with the specified offset from the current
       -</span><span class="inferred0"><a name="line53"></a> 53       #
       -</span><span class="inferred1"><a name="line54"></a> 54       # ==== Parameters
       -</span><span class="inferred0"><a name="line55"></a> 55       # * &lt;tt&gt;offset&lt;/tt&gt; - The offset to return the reporting period for (specifies the offset in hours/days/months/years), depending on the reporting period's grouping
       -</span><span class="marked1"><a name="line56"></a> 56       def offset(offset)
       -</span><span class="marked0"><a name="line57"></a> 57         self.class.new(@grouping, @date_time + offset.send(@grouping.identifier))
       -</span><span class="marked1"><a name="line58"></a> 58       end
       -</span><span class="inferred0"><a name="line59"></a> 59 
       -</span><span class="marked1"><a name="line60"></a> 60       def ==(other) #:nodoc:
       -</span><span class="marked0"><a name="line61"></a> 61         if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
       -</span><span class="marked1"><a name="line62"></a> 62           return @date_time.to_s == other.date_time.to_s &amp;&amp; @grouping.identifier.to_s == other.grouping.identifier.to_s
       -</span><span class="inferred0"><a name="line63"></a> 63         end
       -</span><span class="uncovered1"><a name="line64"></a> 64         false
       -</span><span class="uncovered0"><a name="line65"></a> 65       end
       -</span><span class="inferred1"><a name="line66"></a> 66 
       -</span><span class="marked0"><a name="line67"></a> 67       def &lt;(other) #:nodoc:
       -</span><span class="marked1"><a name="line68"></a> 68         if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
       -</span><span class="marked0"><a name="line69"></a> 69           return @date_time &lt; other.date_time
       -</span><span class="inferred1"><a name="line70"></a> 70         end
       -</span><span class="uncovered0"><a name="line71"></a> 71         raise ArgumentError.new(&quot;Can only compare instances of #{Simplabs::ReportsAsSparkline::ReportingPeriod.klass}&quot;)
       -</span><span class="uncovered1"><a name="line72"></a> 72       end
       -</span><span class="inferred0"><a name="line73"></a> 73 
       -</span><span class="marked1"><a name="line74"></a> 74       def last_date_time #:nodoc:
       -</span><span class="marked0"><a name="line75"></a> 75         case @grouping.identifier
       -</span><span class="marked1"><a name="line76"></a> 76           when :hour
       -</span><span class="marked0"><a name="line77"></a> 77             DateTime.new(@date_time.year, @date_time.month, @date_time.day, @date_time.hour, 59, 59)
       -</span><span class="marked1"><a name="line78"></a> 78           when :day
       -</span><span class="marked0"><a name="line79"></a> 79             DateTime.new(@date_time.year, @date_time.month, @date_time.day, 23, 59, 59)
       -</span><span class="marked1"><a name="line80"></a> 80           when :week
       -</span><span class="marked0"><a name="line81"></a> 81             date_time = (@date_time - @date_time.wday.days) + 7.days
       -</span><span class="marked1"><a name="line82"></a> 82             Date.new(date_time.year, date_time.month, date_time.day)
       -</span><span class="marked0"><a name="line83"></a> 83           when :month
       -</span><span class="marked1"><a name="line84"></a> 84             Date.new(@date_time.year, @date_time.month, (Date.new(@date_time.year, 12, 31) &lt;&lt; (12 - @date_time.month)).day)
       -</span><span class="inferred0"><a name="line85"></a> 85         end
       -</span><span class="marked1"><a name="line86"></a> 86       end
       -</span><span class="inferred0"><a name="line87"></a> 87 
       -</span><span class="marked1"><a name="line88"></a> 88       private
       -</span><span class="inferred0"><a name="line89"></a> 89 
       -</span><span class="marked1"><a name="line90"></a> 90         def parse_date_time(date_time)
       -</span><span class="marked0"><a name="line91"></a> 91           case @grouping.identifier
       -</span><span class="marked1"><a name="line92"></a> 92             when :hour
       -</span><span class="marked0"><a name="line93"></a> 93               DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour)
       -</span><span class="marked1"><a name="line94"></a> 94             when :day
       -</span><span class="marked0"><a name="line95"></a> 95               date_time.to_date
       -</span><span class="marked1"><a name="line96"></a> 96             when :week
       -</span><span class="marked0"><a name="line97"></a> 97               date_time = (date_time - date_time.wday.days) + 1.day
       -</span><span class="marked1"><a name="line98"></a> 98               Date.new(date_time.year, date_time.month, date_time.day)
       -</span><span class="marked0"><a name="line99"></a> 99             when :month
       -</span><span class="marked1"><a name="line100"></a>100               Date.new(date_time.year, date_time.month, 1)
       -</span><span class="inferred0"><a name="line101"></a>101           end
       -</span><span class="marked1"><a name="line102"></a>102         end
       -</span><span class="inferred0"><a name="line103"></a>103 
       -</span><span class="inferred1"><a name="line104"></a>104     end
       -</span><span class="inferred0"><a name="line105"></a>105 
       -</span><span class="inferred1"><a name="line106"></a>106   end
       -</span><span class="inferred0"><a name="line107"></a>107 
       -</span><span class="inferred1"><a name="line108"></a>108 end
       +<pre><span class="marked1"><a name="line1"></a> 1 module Simplabs #:nodoc:
       +</span><span class="inferred0"><a name="line2"></a> 2 
       +</span><span class="marked1"><a name="line3"></a> 3   module ReportsAsSparkline #:nodoc:
       +</span><span class="inferred0"><a name="line4"></a> 4 
       +</span><span class="marked1"><a name="line5"></a> 5     class ReportingPeriod #:nodoc:
       +</span><span class="inferred0"><a name="line6"></a> 6 
       +</span><span class="marked1"><a name="line7"></a> 7       attr_reader :date_time, :grouping
       +</span><span class="inferred0"><a name="line8"></a> 8 
       +</span><span class="marked1"><a name="line9"></a> 9       def initialize(grouping, date_time = nil)
       +</span><span class="marked0"><a name="line10"></a>10         @grouping  = grouping
       +</span><span class="marked1"><a name="line11"></a>11         @date_time = parse_date_time(date_time || DateTime.now)
       +</span><span class="inferred0"><a name="line12"></a>12       end
       +</span><span class="inferred1"><a name="line13"></a>13 
       +</span><span class="marked0"><a name="line14"></a>14       def self.first(grouping, limit, end_date = nil)
       +</span><span class="marked1"><a name="line15"></a>15         self.new(grouping, end_date).offset(-limit)
       +</span><span class="marked0"><a name="line16"></a>16       end
       +</span><span class="inferred1"><a name="line17"></a>17 
       +</span><span class="marked0"><a name="line18"></a>18       def self.from_db_string(grouping, db_string)
       +</span><span class="marked1"><a name="line19"></a>19         parts = grouping.date_parts_from_db_string(db_string)
       +</span><span class="marked0"><a name="line20"></a>20         result = case grouping.identifier
       +</span><span class="marked1"><a name="line21"></a>21           when :hour
       +</span><span class="marked0"><a name="line22"></a>22             self.new(grouping, DateTime.new(parts[0], parts[1], parts[2], parts[3], 0, 0))
       +</span><span class="marked1"><a name="line23"></a>23           when :day
       +</span><span class="marked0"><a name="line24"></a>24             self.new(grouping, Date.new(parts[0], parts[1], parts[2]))
       +</span><span class="marked1"><a name="line25"></a>25           when :week
       +</span><span class="marked0"><a name="line26"></a>26             self.new(grouping, Date.commercial(parts[0], parts[1], 1))
       +</span><span class="marked1"><a name="line27"></a>27           when :month
       +</span><span class="marked0"><a name="line28"></a>28             self.new(grouping, Date.new(parts[0], parts[1], 1))
       +</span><span class="inferred1"><a name="line29"></a>29         end
       +</span><span class="marked0"><a name="line30"></a>30         result
       +</span><span class="inferred1"><a name="line31"></a>31       end
       +</span><span class="inferred0"><a name="line32"></a>32 
       +</span><span class="marked1"><a name="line33"></a>33       def next
       +</span><span class="marked0"><a name="line34"></a>34         self.offset(1)
       +</span><span class="marked1"><a name="line35"></a>35       end
       +</span><span class="inferred0"><a name="line36"></a>36 
       +</span><span class="marked1"><a name="line37"></a>37       def previous
       +</span><span class="marked0"><a name="line38"></a>38         self.offset(-1)
       +</span><span class="marked1"><a name="line39"></a>39       end
       +</span><span class="inferred0"><a name="line40"></a>40 
       +</span><span class="marked1"><a name="line41"></a>41       def offset(offset)
       +</span><span class="marked0"><a name="line42"></a>42         self.class.new(@grouping, @date_time + offset.send(@grouping.identifier))
       +</span><span class="marked1"><a name="line43"></a>43       end
       +</span><span class="inferred0"><a name="line44"></a>44 
       +</span><span class="marked1"><a name="line45"></a>45       def ==(other)
       +</span><span class="marked0"><a name="line46"></a>46         if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
       +</span><span class="marked1"><a name="line47"></a>47           return @date_time.to_s == other.date_time.to_s &amp;&amp; @grouping.identifier.to_s == other.grouping.identifier.to_s
       +</span><span class="inferred0"><a name="line48"></a>48         end
       +</span><span class="uncovered1"><a name="line49"></a>49         false
       +</span><span class="uncovered0"><a name="line50"></a>50       end
       +</span><span class="inferred1"><a name="line51"></a>51 
       +</span><span class="marked0"><a name="line52"></a>52       def &lt;(other)
       +</span><span class="marked1"><a name="line53"></a>53         if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
       +</span><span class="marked0"><a name="line54"></a>54           return @date_time &lt; other.date_time
       +</span><span class="inferred1"><a name="line55"></a>55         end
       +</span><span class="uncovered0"><a name="line56"></a>56         raise ArgumentError.new(&quot;Can only compare instances of #{Simplabs::ReportsAsSparkline::ReportingPeriod.klass}&quot;)
       +</span><span class="uncovered1"><a name="line57"></a>57       end
       +</span><span class="inferred0"><a name="line58"></a>58 
       +</span><span class="marked1"><a name="line59"></a>59       def last_date_time
       +</span><span class="marked0"><a name="line60"></a>60         case @grouping.identifier
       +</span><span class="marked1"><a name="line61"></a>61           when :hour
       +</span><span class="marked0"><a name="line62"></a>62             DateTime.new(@date_time.year, @date_time.month, @date_time.day, @date_time.hour, 59, 59)
       +</span><span class="marked1"><a name="line63"></a>63           when :day
       +</span><span class="marked0"><a name="line64"></a>64             DateTime.new(@date_time.year, @date_time.month, @date_time.day, 23, 59, 59)
       +</span><span class="marked1"><a name="line65"></a>65           when :week
       +</span><span class="marked0"><a name="line66"></a>66             date_time = (@date_time - @date_time.wday.days) + 7.days
       +</span><span class="marked1"><a name="line67"></a>67             Date.new(date_time.year, date_time.month, date_time.day)
       +</span><span class="marked0"><a name="line68"></a>68           when :month
       +</span><span class="marked1"><a name="line69"></a>69             Date.new(@date_time.year, @date_time.month, (Date.new(@date_time.year, 12, 31) &lt;&lt; (12 - @date_time.month)).day)
       +</span><span class="inferred0"><a name="line70"></a>70         end
       +</span><span class="marked1"><a name="line71"></a>71       end
       +</span><span class="inferred0"><a name="line72"></a>72 
       +</span><span class="marked1"><a name="line73"></a>73       private
       +</span><span class="inferred0"><a name="line74"></a>74 
       +</span><span class="marked1"><a name="line75"></a>75         def parse_date_time(date_time)
       +</span><span class="marked0"><a name="line76"></a>76           case @grouping.identifier
       +</span><span class="marked1"><a name="line77"></a>77             when :hour
       +</span><span class="marked0"><a name="line78"></a>78               DateTime.new(date_time.year, date_time.month, date_time.day, date_time.hour)
       +</span><span class="marked1"><a name="line79"></a>79             when :day
       +</span><span class="marked0"><a name="line80"></a>80               date_time.to_date
       +</span><span class="marked1"><a name="line81"></a>81             when :week
       +</span><span class="marked0"><a name="line82"></a>82               date_time = (date_time - date_time.wday.days) + 1.day
       +</span><span class="marked1"><a name="line83"></a>83               Date.new(date_time.year, date_time.month, date_time.day)
       +</span><span class="marked0"><a name="line84"></a>84             when :month
       +</span><span class="marked1"><a name="line85"></a>85               Date.new(date_time.year, date_time.month, 1)
       +</span><span class="inferred0"><a name="line86"></a>86           end
       +</span><span class="marked1"><a name="line87"></a>87         end
       +</span><span class="inferred0"><a name="line88"></a>88 
       +</span><span class="inferred1"><a name="line89"></a>89     end
       +</span><span class="inferred0"><a name="line90"></a>90 
       +</span><span class="inferred1"><a name="line91"></a>91   end
       +</span><span class="inferred0"><a name="line92"></a>92 
       +</span><span class="inferred1"><a name="line93"></a>93 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline-sparkline_tag_helper_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline-sparkline_tag_helper_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:08 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -608,7 +608,7 @@ span.run100 {
        </span><span class="inferred1"><a name="line8"></a> 8       #
        </span><span class="inferred0"><a name="line9"></a> 9       # ==== Parameters
        </span><span class="inferred1"><a name="line10"></a>10       #
       -</span><span class="inferred0"><a name="line11"></a>11       # * &lt;tt&gt;data&lt;/tt&gt; - The data to render the sparkline for
       +</span><span class="inferred0"><a name="line11"></a>11       # * &lt;tt&gt;data&lt;/tt&gt; - The data to render the sparkline for, is retrieved from a report like &lt;tt&gt;User.registration_report&lt;/tt&gt;
        </span><span class="inferred1"><a name="line12"></a>12       #
        </span><span class="inferred0"><a name="line13"></a>13       # ==== Options
        </span><span class="inferred1"><a name="line14"></a>14       #
       @@ -616,10 +616,10 @@ span.run100 {
        </span><span class="inferred1"><a name="line16"></a>16       # * &lt;tt&gt;height&lt;/tt&gt; - The height of the generated image
        </span><span class="inferred0"><a name="line17"></a>17       # * &lt;tt&gt;line_color&lt;/tt&gt; - The line color of the sparkline (hex code)
        </span><span class="inferred1"><a name="line18"></a>18       # * &lt;tt&gt;fill_color&lt;/tt&gt; - The color to fill the area below the sparkline with (hex code)
       -</span><span class="inferred0"><a name="line19"></a>19       # * &lt;tt&gt;labels&lt;/tt&gt; - The axes to render lables for (Array of :x, :y, :r, :t; this is x axis, y axis, right, top)
       +</span><span class="inferred0"><a name="line19"></a>19       # * &lt;tt&gt;labels&lt;/tt&gt; - The axes to render lables for (Array of &lt;tt&gt;:x&lt;/tt&gt;, &lt;tt&gt;:y+&lt;/tt&gt;, &lt;tt&gt;:r&lt;/tt&gt;, &lt;tt&gt;:t&lt;/tt&gt;; this is x axis, y axis, right, top)
        </span><span class="inferred1"><a name="line20"></a>20       #
        </span><span class="inferred0"><a name="line21"></a>21       # ==== Example
       -</span><span class="inferred1"><a name="line22"></a>22       # &lt;%= sparkline_tag(User.registrations_report, :width =&gt; 200, :height =&gt; 100, :color =&gt; '000') %&gt;
       +</span><span class="inferred1"><a name="line22"></a>22       # &lt;tt&gt;&lt;%= sparkline_tag(User.registrations_report, :width =&gt; 200, :height =&gt; 100, :color =&gt; '000') %&gt;&lt;/tt&gt;
        </span><span class="marked0"><a name="line23"></a>23       def sparkline_tag(data, options = {})
        </span><span class="marked1"><a name="line24"></a>24         options.reverse_merge!({ :width =&gt; 300, :height =&gt; 34, :line_color =&gt; '0077cc', :fill_color =&gt; 'e6f2fa', :labels =&gt; [] })
        </span><span class="marked0"><a name="line25"></a>25         data = data.collect { |d| d[1] }
 (DIR) diff --git a/doc/coverage/lib-simplabs-reports_as_sparkline_rb.html b/doc/coverage/lib-simplabs-reports_as_sparkline_rb.html
       @@ -553,7 +553,7 @@ span.run100 {
        </style>
            </head>
          <body><h3>C0 code coverage information</h3>
       -    <p>Generated on Wed Apr 29 18:53:07 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
       +    <p>Generated on Wed Apr 29 19:33:53 +0200 2009 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
              </p>
            <hr/>
            <pre><span class='marked0'>Code reported as executed by Ruby looks like this...
       @@ -571,7 +571,7 @@ span.run100 {
            </thead>
          <tbody><tr class='light'><td><a href='lib-simplabs-reports_as_sparkline_rb.html'>lib/simplabs/reports_as_sparkline.rb</a>
                </td>
       -      <td class='lines_total'><tt>58</tt>
       +      <td class='lines_total'><tt>59</tt>
                </td>
              <td class='lines_code'><tt>22</tt>
                </td>
       @@ -608,22 +608,22 @@ span.run100 {
        </span><span class="inferred0"><a name="line8"></a> 8 
        </span><span class="marked1"><a name="line9"></a> 9     module ClassMethods
        </span><span class="inferred0"><a name="line10"></a>10 
       -</span><span class="inferred1"><a name="line11"></a>11       # Generates a report on a model. That report can then be executed via the new method &lt;name&gt;_report (see documentation of Simplabs::ReportsAsSparkline::Report#run).
       +</span><span class="inferred1"><a name="line11"></a>11       # Generates a report on a model. That report can then be executed via the new method &lt;tt&gt;&lt;name&gt;_report&lt;/tt&gt; (see documentation of Simplabs::ReportsAsSparkline::Report#run).
        </span><span class="inferred0"><a name="line12"></a>12       # 
        </span><span class="inferred1"><a name="line13"></a>13       # ==== Parameters
        </span><span class="inferred0"><a name="line14"></a>14       #
       -</span><span class="inferred1"><a name="line15"></a>15       # * &lt;tt&gt;name&lt;/tt&gt; - The name of the report, defines the name of the generated report method (&lt;name&gt;_report)
       +</span><span class="inferred1"><a name="line15"></a>15       # * &lt;tt&gt;name&lt;/tt&gt; - The name of the report, defines the name of the generated report method (&lt;tt&gt;&lt;name&gt;_report&lt;/tt&gt;)
        </span><span class="inferred0"><a name="line16"></a>16       #
        </span><span class="inferred1"><a name="line17"></a>17       # ==== Options
        </span><span class="inferred0"><a name="line18"></a>18       #
       -</span><span class="inferred1"><a name="line19"></a>19       # * &lt;tt&gt;:date_column&lt;/tt&gt; - The name of the date column on that the records are aggregated
       -</span><span class="inferred0"><a name="line20"></a>20       # * &lt;tt&gt;:value_column&lt;/tt&gt; - The name of the column that holds the value to sum for aggregation :sum
       -</span><span class="inferred1"><a name="line21"></a>21       # * &lt;tt&gt;:aggregation&lt;/tt&gt; - The aggregation to use (one of :count, :sum, :minimum, :maximum or :average); when using anything other than :count, :value_column must also be specified (&lt;b&gt;If you really want to e.g. sumon the 'id' column, you have to explicitely say so.&lt;/b&gt;)
       -</span><span class="inferred0"><a name="line22"></a>22       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (:hour, :day, :week, :month); &lt;b&gt;Beware that reports_as_sparkline treats weeks as starting on monday!&lt;/b&gt;
       -</span><span class="inferred1"><a name="line23"></a>23       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of periods to get (see :grouping)
       -</span><span class="inferred0"><a name="line24"></a>24       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -</span><span class="inferred1"><a name="line25"></a>25       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -</span><span class="inferred0"><a name="line26"></a>26       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the periods before this date.
       +</span><span class="inferred1"><a name="line19"></a>19       # * &lt;tt&gt;:date_column&lt;/tt&gt; - The name of the date column over that the records are aggregated (defaults to &lt;tt&gt;created_at&lt;/tt&gt;)
       +</span><span class="inferred0"><a name="line20"></a>20       # * &lt;tt&gt;:value_column&lt;/tt&gt; - The name of the column that holds the values to sum up when using aggregation &lt;tt&gt;:sum&lt;/tt&gt;
       +</span><span class="inferred1"><a name="line21"></a>21       # * &lt;tt&gt;:aggregation&lt;/tt&gt; - The aggregation to use (one of &lt;tt&gt;:count&lt;/tt&gt;, &lt;tt&gt;:sum&lt;/tt&gt;, &lt;tt&gt;:minimum&lt;/tt&gt;, &lt;tt&gt;:maximum&lt;/tt&gt; or &lt;tt&gt;:average&lt;/tt&gt;); when using anything other than &lt;tt&gt;:count&lt;/tt&gt;, &lt;tt&gt;:value_column&lt;/tt&gt; must also be specified (&lt;b&gt;If you really want to e.g. sum up the values in the &lt;tt&gt;id&lt;/tt&gt; column, you have to explicitely say so.&lt;/b&gt;); (defaults to &lt;tt&gt;:count&lt;/tt&gt;)
       +</span><span class="inferred0"><a name="line22"></a>22       # * &lt;tt&gt;:grouping&lt;/tt&gt; - The period records are grouped on (&lt;tt&gt;:hour&lt;/tt&gt;, &lt;tt&gt;:day&lt;/tt&gt;, &lt;tt&gt;:week&lt;/tt&gt;, &lt;tt&gt;:month&lt;/tt&gt;); &lt;b&gt;Beware that &lt;tt&gt;reports_as_sparkline&lt;/tt&gt; treats weeks as starting on monday!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line23"></a>23       # * &lt;tt&gt;:limit&lt;/tt&gt; - The number of reporting periods to get (see &lt;tt&gt;:grouping&lt;/tt&gt;), (defaults to 100)
       +</span><span class="inferred0"><a name="line24"></a>24       # * &lt;tt&gt;:conditions&lt;/tt&gt; - Conditions like in &lt;tt&gt;ActiveRecord::Base#find&lt;/tt&gt;; only records that match the conditions are reported; &lt;b&gt;Beware that when conditions are specified, caching is disabled!&lt;/b&gt;
       +</span><span class="inferred1"><a name="line25"></a>25       # * &lt;tt&gt;:live_data&lt;/tt&gt; - Specifies whether data for the current reporting period is to be read; &lt;b&gt;if &lt;tt&gt;:live_data&lt;/tt&gt; is &lt;tt&gt;true&lt;/tt&gt;, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to &lt;tt&gt;false&lt;/tt&gt;)&lt;/b&gt;
       +</span><span class="inferred0"><a name="line26"></a>26       # * &lt;tt&gt;:end_date&lt;/tt&gt; - When specified, the report will only include data for the &lt;tt&gt;:limit&lt;/tt&gt; reporting periods until this date.
        </span><span class="inferred1"><a name="line27"></a>27       #
        </span><span class="inferred0"><a name="line28"></a>28       # ==== Examples
        </span><span class="inferred1"><a name="line29"></a>29       #
       @@ -631,31 +631,32 @@ span.run100 {
        </span><span class="inferred1"><a name="line31"></a>31       #    reports_as_sparkline :games_per_day
        </span><span class="inferred0"><a name="line32"></a>32       #    reports_as_sparkline :games_played_total, :cumulate =&gt; true
        </span><span class="inferred1"><a name="line33"></a>33       #  end
       -</span><span class="inferred0"><a name="line34"></a>34       #  class User &lt; ActiveRecord::Base
       -</span><span class="inferred1"><a name="line35"></a>35       #    reports_as_sparkline :registrations, :aggregation =&gt; :count
       -</span><span class="inferred0"><a name="line36"></a>36       #    reports_as_sparkline :activations,   :aggregation =&gt; :count, :date_column =&gt; :activated_at
       -</span><span class="inferred1"><a name="line37"></a>37       #    reports_as_sparkline :total_users,   :cumulate =&gt; true
       -</span><span class="inferred0"><a name="line38"></a>38       #    reports_as_sparkline :rake,          :aggregation =&gt; :sum,   :value_column =&gt; :profile_visits
       -</span><span class="inferred1"><a name="line39"></a>39       #  end
       -</span><span class="marked0"><a name="line40"></a>40       def reports_as_sparkline(name, options = {})
       -</span><span class="marked1"><a name="line41"></a>41         (class &lt;&lt; self; self; end).instance_eval do
       -</span><span class="marked0"><a name="line42"></a>42           define_method &quot;#{name.to_s}_report&quot;.to_sym do |*args|
       -</span><span class="marked1"><a name="line43"></a>43             if options.delete(:cumulate)
       -</span><span class="uncovered0"><a name="line44"></a>44               report = Simplabs::ReportsAsSparkline::CumulatedReport.new(self, name, options)
       -</span><span class="inferred1"><a name="line45"></a>45             else
       -</span><span class="marked0"><a name="line46"></a>46               report = Simplabs::ReportsAsSparkline::Report.new(self, name, options)
       -</span><span class="inferred1"><a name="line47"></a>47             end
       -</span><span class="marked0"><a name="line48"></a>48             raise ArgumentError.new unless args.length == 0 || (args.length == 1 &amp;&amp; args[0].is_a?(Hash))
       -</span><span class="marked1"><a name="line49"></a>49             report.run(args.length == 0 ? {} : args[0])
       -</span><span class="inferred0"><a name="line50"></a>50           end
       -</span><span class="inferred1"><a name="line51"></a>51         end
       -</span><span class="marked0"><a name="line52"></a>52       end
       -</span><span class="inferred1"><a name="line53"></a>53 
       -</span><span class="inferred0"><a name="line54"></a>54     end
       -</span><span class="inferred1"><a name="line55"></a>55 
       -</span><span class="inferred0"><a name="line56"></a>56   end
       -</span><span class="inferred1"><a name="line57"></a>57 
       -</span><span class="inferred0"><a name="line58"></a>58 end
       +</span><span class="inferred0"><a name="line34"></a>34       #
       +</span><span class="inferred1"><a name="line35"></a>35       #  class User &lt; ActiveRecord::Base
       +</span><span class="inferred0"><a name="line36"></a>36       #    reports_as_sparkline :registrations, :aggregation =&gt; :count
       +</span><span class="inferred1"><a name="line37"></a>37       #    reports_as_sparkline :activations,   :aggregation =&gt; :count, :date_column =&gt; :activated_at
       +</span><span class="inferred0"><a name="line38"></a>38       #    reports_as_sparkline :total_users,   :cumulate =&gt; true
       +</span><span class="inferred1"><a name="line39"></a>39       #    reports_as_sparkline :rake,          :aggregation =&gt; :sum,   :value_column =&gt; :profile_visits
       +</span><span class="inferred0"><a name="line40"></a>40       #  end
       +</span><span class="marked1"><a name="line41"></a>41       def reports_as_sparkline(name, options = {})
       +</span><span class="marked0"><a name="line42"></a>42         (class &lt;&lt; self; self; end).instance_eval do
       +</span><span class="marked1"><a name="line43"></a>43           define_method &quot;#{name.to_s}_report&quot;.to_sym do |*args|
       +</span><span class="marked0"><a name="line44"></a>44             if options.delete(:cumulate)
       +</span><span class="uncovered1"><a name="line45"></a>45               report = Simplabs::ReportsAsSparkline::CumulatedReport.new(self, name, options)
       +</span><span class="inferred0"><a name="line46"></a>46             else
       +</span><span class="marked1"><a name="line47"></a>47               report = Simplabs::ReportsAsSparkline::Report.new(self, name, options)
       +</span><span class="inferred0"><a name="line48"></a>48             end
       +</span><span class="marked1"><a name="line49"></a>49             raise ArgumentError.new unless args.length == 0 || (args.length == 1 &amp;&amp; args[0].is_a?(Hash))
       +</span><span class="marked0"><a name="line50"></a>50             report.run(args.length == 0 ? {} : args[0])
       +</span><span class="inferred1"><a name="line51"></a>51           end
       +</span><span class="inferred0"><a name="line52"></a>52         end
       +</span><span class="marked1"><a name="line53"></a>53       end
       +</span><span class="inferred0"><a name="line54"></a>54 
       +</span><span class="inferred1"><a name="line55"></a>55     end
       +</span><span class="inferred0"><a name="line56"></a>56 
       +</span><span class="inferred1"><a name="line57"></a>57   end
       +</span><span class="inferred0"><a name="line58"></a>58 
       +</span><span class="inferred1"><a name="line59"></a>59 end
        </span></pre><hr/>
            <p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
           version 0.8.1.2.</p>
 (DIR) diff --git a/doc/created.rid b/doc/created.rid
       @@ -1 +1 @@
       -Wed, 29 Apr 2009 18:52:13 +0200
       +Wed, 29 Apr 2009 19:32:38 +0200
 (DIR) diff --git a/doc/files/README_rdoc.html b/doc/files/README_rdoc.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Wed Apr 29 16:35:10 +0200 2009</td>
       +      <td>Wed Apr 29 19:32:28 +0200 2009</td>
            </tr>
            </table>
          </div>
       @@ -71,7 +71,7 @@
            <div id="description">
              <h1>ReportsAsSparkline</h1>
        <p>
       -ReportsAsSparkline enables you to generate reports and sparklines from your
       +ReportsAsSparkline enables you to generate sparkline reports from your
        model&#8216;s data with very little effort.
        </p>
        <h2>Usage</h2>
       @@ -81,42 +81,44 @@ If you hace a <tt>User</tt> model with <tt>created_at</tt> and
        <tt>reports_as_sparkline</tt> to it with the following options:
        </p>
        <ul>
       -<li>:date_column - The name of the date column on that the records are
       -aggregated
       +<li><tt>:date_column</tt> - The name of the date column over that the records
       +are aggregated (defaults to <tt>created_at</tt>)
        
        </li>
       -<li>:value_column - The name of the column that holds the value to sum for
       -aggregation :sum
       +<li><tt>:value_column</tt> - The name of the column that holds the values to
       +sum up when using aggregation <tt>:sum</tt>
        
        </li>
       -<li>:aggregation - The aggregation to use (one of :count, :sum, :minimum,
       -:maximum or :average); when using anything other than :count, :value_column
       -must also be specified (<b>If you really want to e.g. sumon the
       -&#8216;id&#8217; column, you have to explicitely say so.</b>)
       +<li><tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>,
       +<tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>);
       +when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must
       +also be specified (<b>If you really want to e.g. sum up the values in the
       +<tt>id</tt> column, you have to explicitely say so.</b>); (defaults to
       +<tt>:count</tt>)
        
        </li>
       -<li>:grouping - The period records are grouped on (:hour, :day, :week, :month);
       -<b>Beware that reports_as_sparkline treats weeks as starting on monday!</b>
       +<li><tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>,
       +<tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that
       +<tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
        
        </li>
       -<li>:limit - The number of periods to get (see :grouping)
       +<li><tt>:limit</tt> - The number of reporting periods to get (see
       +<tt>:grouping</tt>), (defaults to 100)
        
        </li>
       -<li>:conditions - Conditions like in ActiveRecord::Base#find; only records that
       -match there conditions are reported on
       +<li><tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>;
       +only records that match the conditions are reported; <b>Beware that when
       +conditions are specified, caching is disabled!</b>
        
        </li>
       -<li>:cumulate - Sets whether to cumulate the numbers (instead of [1, 2, 3]
       -returns [1, 3, 6])
       +<li><tt>:live_data</tt> - Specifies whether data for the current reporting
       +period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will
       +experience a performance hit since the request cannot be satisfied from the
       +cache only (defaults to <tt>false</tt>)</b>
        
        </li>
       -<li>:live_data - Specified whether data for the current reporting period is
       -read; if :live_data is true, you will experience a performance hit since
       -the request cannot be satisfied from the cache only (defaults to false)
       -
       -</li>
       -<li>:end_date - When specified, the report will only include data for the
       -periods before this date.
       +<li><tt>:end_date</tt> - When specified, the report will only include data for
       +the <tt>:limit</tt> reporting periods until this date.
        
        </li>
        </ul>
       @@ -143,23 +145,28 @@ When invoking the report, you can override some of the options you
        specified for <tt>reports_as_sparkline</tt>:
        </p>
        <ul>
       -<li>:grouping - The period records are grouped on (:hour, :day, :week, :month)
       +<li><tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>,
       +<tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that
       +<tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
        
        </li>
       -<li>:limit - The number of periods to get (see :grouping)
       +<li><tt>:limit</tt> - The number of reporting periods to get (see
       +<tt>:grouping</tt>), (defaults to 100)
        
        </li>
       -<li>:conditions - Conditions like in ActiveRecord::Base#find; only records that
       -match there conditions are reported on
       +<li><tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>;
       +only records that match the conditions are reported; <b>Beware that when
       +conditions are specified, caching is disabled!</b>
        
        </li>
       -<li>:live_data - Specified whether data for the current reporting period is
       -read; if :live_data is true, you will experience a performance hit since
       -the request cannot be satisfied from the cache only (defaults to false)
       +<li><tt>:live_data</tt> - Specifies whether data for the current reporting
       +period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will
       +experience a performance hit since the request cannot be satisfied from the
       +cache only (defaults to <tt>false</tt>)</b>
        
        </li>
       -<li>:end_date - When specified, the report will be for the periods before this
       -date.
       +<li><tt>:end_date</tt> - When specified, the report will only include data for
       +the <tt>:limit</tt> reporting periods until this date.
        
        </li>
        </ul>
       @@ -171,10 +178,6 @@ date.
          User.activations_report(:grouping =&gt; :week, :limit =&gt; 5)
        </pre>
        <p>
       -<b>Beware that when specifying conditions on invocation of the report, the
       -cache will not be used!</b>
       -</p>
       -<p>
        You can than render sparklines for these reports with sparkline_tag in your
        view:
        </p>
       @@ -185,20 +188,21 @@ view:
        The <tt>sparkline_tag</tt> helper takes the following parameters:
        </p>
        <ul>
       -<li>width - The width of the generated image
       +<li><tt>width</tt> - The width of the generated image
        
        </li>
       -<li>height - The height of the generated image
       +<li><tt>height</tt> - The height of the generated image
        
        </li>
       -<li>line_color - The line color of the sparkline (hex code)
       +<li><tt>line_color</tt> - The line color of the sparkline (hex code)
        
        </li>
       -<li>fill_color - The color to fill the area below the sparkline with (hex code)
       +<li><tt>fill_color</tt> - The color to fill the area below the sparkline with
       +(hex code)
        
        </li>
       -<li>labes - The axes to render lables for (Array of :x, :y, :r, :t; this is x
       -axis, y axis, right, top)
       +<li><tt>labels</tt> - The axes to render lables for (Array of <tt>:x</tt>,
       +<tt>:y+</tt>, <tt>:r</tt>, <tt>:t</tt>; this is x axis, y axis, right, top)
        
        </li>
        </ul>
       @@ -210,13 +214,13 @@ Installation requires 3 simple steps:
        <b>get the plugin</b>
        </p>
        <p>
       -From your RAILS_ROOT in Rails &amp;gt;= 2.1, do
       +From your RAILS_ROOT in Rails &gt;= 2.1, do
        </p>
        <pre>
          ./script/plugin install git://github.com/marcoow/reports_as_sparkline.git
        </pre>
        <p>
       -If you are on Rails &amp;lt; 2.1, do this from your RAILS_ROOT
       +If you are on Rails &lt; 2.1, do this from your RAILS_ROOT
        </p>
        <pre>
          git clone git://github.com/marcoow/reports_as_sparkline.git vendor/plugins/reports_as_sparkline
       @@ -256,9 +260,6 @@ If you are on PostgreSQL, you should add functional indices:
        <li>support for Oracle and DB2 (and others?) missing
        
        </li>
       -<li>Implement data ranges in arguments
       -
       -</li>
        <li>Limit number of data points to maximum that the google chart api allows
        
        </li>
       @@ -280,8 +281,8 @@ href="http://github.com/myronmarston">github.com/myronmarston</a>)
        <h2>Author</h2>
        <p>
        © 2008-2009 Marco Otte-Witte (<a
       -href="http://simplabs.com/#projects">simplabs.com/#projects</a>), Martin
       -Kavalar, released under the MIT license
       +href="http://simplabs.com">simplabs.com</a>), Martin Kavalar, released
       +under the MIT license
        </p>
        
            </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/cumulated_report_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/cumulated_report_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Wed Apr 29 10:44:16 +0200 2009</td>
       +      <td>Wed Apr 29 19:28:16 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/grouping_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/grouping_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Mon Apr 06 10:35:50 +0200 2009</td>
       +      <td>Wed Apr 29 19:18:36 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/report_cache_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/report_cache_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Wed Apr 29 18:14:28 +0200 2009</td>
       +      <td>Wed Apr 29 19:20:49 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/report_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/report_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Wed Apr 29 18:16:51 +0200 2009</td>
       +      <td>Wed Apr 29 19:26:39 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/reporting_period_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/reporting_period_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Wed Apr 29 18:18:14 +0200 2009</td>
       +      <td>Wed Apr 29 19:18:27 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline/sparkline_tag_helper_rb.html b/doc/files/lib/simplabs/reports_as_sparkline/sparkline_tag_helper_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Mon Apr 06 10:35:50 +0200 2009</td>
       +      <td>Wed Apr 29 19:28:41 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/files/lib/simplabs/reports_as_sparkline_rb.html b/doc/files/lib/simplabs/reports_as_sparkline_rb.html
       @@ -56,7 +56,7 @@
            </tr>
            <tr class="top-aligned-row">
              <td><strong>Last Update:</strong></td>
       -      <td>Mon Apr 06 10:35:22 +0200 2009</td>
       +      <td>Wed Apr 29 19:29:22 +0200 2009</td>
            </tr>
            </table>
          </div>
 (DIR) diff --git a/doc/fr_class_index.html b/doc/fr_class_index.html
       @@ -22,9 +22,8 @@
          <div id="index-entries">
            <a href="classes/Simplabs/ReportsAsSparkline/ClassMethods.html">Simplabs::ReportsAsSparkline::ClassMethods</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html">Simplabs::ReportsAsSparkline::CumulatedReport</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/Grouping.html">Simplabs::ReportsAsSparkline::Grouping</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/Report.html">Simplabs::ReportsAsSparkline::Report</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html">Simplabs::ReportsAsSparkline::ReportingPeriod</a><br />
       +    <a href="classes/Simplabs/ReportsAsSparkline/ReportCache.html">Simplabs::ReportsAsSparkline::ReportCache</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/SparklineTagHelper.html">Simplabs::ReportsAsSparkline::SparklineTagHelper</a><br />
          </div>
        </div>
 (DIR) diff --git a/doc/fr_method_index.html b/doc/fr_method_index.html
       @@ -21,18 +21,11 @@
          <h1 class="section-bar">Methods</h1>
          <div id="index-entries">
            <a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000004">cumulate (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html#M000009">first (Simplabs::ReportsAsSparkline::ReportingPeriod)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/Grouping.html#M000007">identifier (Simplabs::ReportsAsSparkline::Grouping)</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000005">initial_cumulative_value (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html#M000008">new (Simplabs::ReportsAsSparkline::ReportingPeriod)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/Grouping.html#M000006">new (Simplabs::ReportsAsSparkline::Grouping)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000013">new (Simplabs::ReportsAsSparkline::Report)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html#M000010">next (Simplabs::ReportsAsSparkline::ReportingPeriod)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html#M000012">offset (Simplabs::ReportsAsSparkline::ReportingPeriod)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/ReportingPeriod.html#M000011">previous (Simplabs::ReportsAsSparkline::ReportingPeriod)</a><br />
       +    <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000006">new (Simplabs::ReportsAsSparkline::Report)</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/ClassMethods.html#M000002">reports_as_sparkline (Simplabs::ReportsAsSparkline::ClassMethods)</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/CumulatedReport.html#M000003">run (Simplabs::ReportsAsSparkline::CumulatedReport)</a><br />
       -    <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000014">run (Simplabs::ReportsAsSparkline::Report)</a><br />
       +    <a href="classes/Simplabs/ReportsAsSparkline/Report.html#M000007">run (Simplabs::ReportsAsSparkline::Report)</a><br />
            <a href="classes/Simplabs/ReportsAsSparkline/SparklineTagHelper.html#M000001">sparkline_tag (Simplabs::ReportsAsSparkline::SparklineTagHelper)</a><br />
          </div>
        </div>
 (DIR) diff --git a/doc/spec.html b/doc/spec.html
       @@ -1085,7 +1085,7 @@ a {
            <dd class="spec passed"><span class="passed_spec_name">should set the parameters for custom colors if custom colors are specified</span></dd>
          </dl>
        </div>
       -<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>41.896488 seconds</strong>";</script>
       +<script type="text/javascript">document.getElementById('duration').innerHTML = "Finished in <strong>38.701549 seconds</strong>";</script>
        <script type="text/javascript">document.getElementById('totals').innerHTML = "268 examples, 0 failures";</script>
        </div>
        </div>
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline.rb b/lib/simplabs/reports_as_sparkline.rb
       @@ -8,22 +8,22 @@ module Simplabs #:nodoc:
        
            module ClassMethods
        
       -      # Generates a report on a model. That report can then be executed via the new method <name>_report (see documentation of Simplabs::ReportsAsSparkline::Report#run).
       +      # Generates a report on a model. That report can then be executed via the new method <tt><name>_report</tt> (see documentation of Simplabs::ReportsAsSparkline::Report#run).
              # 
              # ==== Parameters
              #
       -      # * <tt>name</tt> - The name of the report, defines the name of the generated report method (<name>_report)
       +      # * <tt>name</tt> - The name of the report, defines the name of the generated report method (<tt><name>_report</tt>)
              #
              # ==== Options
              #
       -      # * <tt>:date_column</tt> - The name of the date column on that the records are aggregated
       -      # * <tt>:value_column</tt> - The name of the column that holds the value to sum for aggregation :sum
       -      # * <tt>:aggregation</tt> - The aggregation to use (one of :count, :sum, :minimum, :maximum or :average); when using anything other than :count, :value_column must also be specified (<b>If you really want to e.g. sumon the 'id' column, you have to explicitely say so.</b>)
       -      # * <tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week, :month); <b>Beware that reports_as_sparkline treats weeks as starting on monday!</b>
       -      # * <tt>:limit</tt> - The number of periods to get (see :grouping)
       -      # * <tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -      # * <tt>:live_data</tt> - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -      # * <tt>:end_date</tt> - When specified, the report will only include data for the periods before this date.
       +      # * <tt>:date_column</tt> - The name of the date column over that the records are aggregated (defaults to <tt>created_at</tt>)
       +      # * <tt>:value_column</tt> - The name of the column that holds the values to sum up when using aggregation <tt>:sum</tt>
       +      # * <tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>, <tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>); when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must also be specified (<b>If you really want to e.g. sum up the values in the <tt>id</tt> column, you have to explicitely say so.</b>); (defaults to <tt>:count</tt>)
       +      # * <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
       +      # * <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       +      # * <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +      # * <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
       +      # * <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
              #
              # ==== Examples
              #
       @@ -31,6 +31,7 @@ module Simplabs #:nodoc:
              #    reports_as_sparkline :games_per_day
              #    reports_as_sparkline :games_played_total, :cumulate => true
              #  end
       +      #
              #  class User < ActiveRecord::Base
              #    reports_as_sparkline :registrations, :aggregation => :count
              #    reports_as_sparkline :activations,   :aggregation => :count, :date_column => :activated_at
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/cumulated_report.rb b/lib/simplabs/reports_as_sparkline/cumulated_report.rb
       @@ -6,13 +6,13 @@ module Simplabs #:nodoc:
            #
            # ==== Examples
            #
       -    #  When Simplabs::ReportsAsSparkline::Report returns
       +    # When Simplabs::ReportsAsSparkline::Report returns
            #
       -    #    [[<DateTime today>, 1], [<DateTime yesterday>, 2], etc.]
       +    #  [[<DateTime today>, 1], [<DateTime yesterday>, 2], etc.]
            #
       -    #  Simplabs::ReportsAsSparkline::CumulatedReport returns
       +    # Simplabs::ReportsAsSparkline::CumulatedReport returns
            #
       -    #    [[<DateTime today>, 3], [<DateTime yesterday>, 2], etc.]
       +    #  [[<DateTime today>, 3], [<DateTime yesterday>, 2], etc.]
            class CumulatedReport < Report
        
              # Runs the report (see Simplabs::ReportsAsSparkline::Report#run)
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/grouping.rb b/lib/simplabs/reports_as_sparkline/grouping.rb
       @@ -2,22 +2,18 @@ module Simplabs #:nodoc:
        
          module ReportsAsSparkline #:nodoc:
        
       -    # This is the grouping a report uses to group records in the database
       -    class Grouping
       +    class Grouping #:nodoc:
        
       -      # ==== Parameters
       -      # * <tt>identifier</tt> - The identifier of the grouping - one of :hour, :day, :week or :month
              def initialize(identifier)
                raise ArgumentError.new("Invalid grouping #{identifier}") unless [:hour, :day, :week, :month].include?(identifier)
                @identifier = identifier
              end
        
       -      # Returns the Grouping's identifier
              def identifier
                @identifier
              end
        
       -      def date_parts_from_db_string(db_string) #:nodoc:
       +      def date_parts_from_db_string(db_string)
                return case ActiveRecord::Base.connection.adapter_name
                  when /mysql/i
                    from_mysql_db_string(db_string)
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/report.rb b/lib/simplabs/reports_as_sparkline/report.rb
       @@ -13,14 +13,14 @@ module Simplabs #:nodoc:
              #
              # ==== Options
              #
       -      # * <tt>:date_column</tt> - The name of the date column on that the records are aggregated
       -      # * <tt>:value_column</tt> - The name of the column that holds the value to sum for aggregation :sum
       -      # * <tt>:aggregation</tt> - The aggregation to use (one of :count, :sum, :minimum, :maximum or :average); when using anything other than :count, :value_column must also be specified (<b>If you really want to e.g. sumon the 'id' column, you have to explicitely say so.</b>)
       -      # * <tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week, :month); <b>Beware that reports_as_sparkline treats weeks as starting on monday!</b>
       -      # * <tt>:limit</tt> - The number of periods to get (see :grouping)
       -      # * <tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on
       -      # * <tt>:live_data</tt> - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -      # * <tt>:end_date</tt> - When specified, the report will only include data for the periods before this date.
       +      # * <tt>:date_column</tt> - The name of the date column over that the records are aggregated (defaults to <tt>created_at</tt>)
       +      # * <tt>:value_column</tt> - The name of the column that holds the values to sum up when using aggregation <tt>:sum</tt>
       +      # * <tt>:aggregation</tt> - The aggregation to use (one of <tt>:count</tt>, <tt>:sum</tt>, <tt>:minimum</tt>, <tt>:maximum</tt> or <tt>:average</tt>); when using anything other than <tt>:count</tt>, <tt>:value_column</tt> must also be specified (<b>If you really want to e.g. sum up the values in the <tt>id</tt> column, you have to explicitely say so.</b>); (defaults to <tt>:count</tt>)
       +      # * <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
       +      # * <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       +      # * <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +      # * <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
       +      # * <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
              def initialize(klass, name, options = {})
                ensure_valid_options(options)
                @klass        = klass
       @@ -42,11 +42,11 @@ module Simplabs #:nodoc:
              # Runs the report and returns an array of array of DateTimes and Floats
              #
              # ==== Options
       -      # * <tt>:limit</tt> - The number of periods to get
       -      # * <tt>:conditions</tt> - Conditions like in ActiveRecord::Base#find; only records that match there conditions are reported on (<b>Beware that when you specify conditions here, caching will be disabled</b>)
       -      # * <tt>:grouping</tt> - The period records are grouped on (:hour, :day, :week, :month); <b>Beware that reports_as_sparkline treats weeks as starting on monday!</b>
       -      # * <tt>:live_data</tt> - Specified whether data for the current reporting period is read; if :live_data is true, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to false)
       -      # * <tt>:end_date</tt> - When specified, the report will only include data for the periods before this date.
       +      # * <tt>:grouping</tt> - The period records are grouped on (<tt>:hour</tt>, <tt>:day</tt>, <tt>:week</tt>, <tt>:month</tt>); <b>Beware that <tt>reports_as_sparkline</tt> treats weeks as starting on monday!</b>
       +      # * <tt>:limit</tt> - The number of reporting periods to get (see <tt>:grouping</tt>), (defaults to 100)
       +      # * <tt>:conditions</tt> - Conditions like in <tt>ActiveRecord::Base#find</tt>; only records that match the conditions are reported; <b>Beware that when conditions are specified, caching is disabled!</b>
       +      # * <tt>:live_data</tt> - Specifies whether data for the current reporting period is to be read; <b>if <tt>:live_data</tt> is <tt>true</tt>, you will experience a performance hit since the request cannot be satisfied from the cache only (defaults to <tt>false</tt>)</b>
       +      # * <tt>:end_date</tt> - When specified, the report will only include data for the <tt>:limit</tt> reporting periods until this date.
              def run(options = {})
                custom_conditions = options.key?(:conditions)
                options = options_for_run(options)
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/report_cache.rb b/lib/simplabs/reports_as_sparkline/report_cache.rb
       @@ -2,11 +2,13 @@ module Simplabs #:nodoc:
        
          module ReportsAsSparkline #:nodoc:
        
       -    class ReportCache < ActiveRecord::Base #:nodoc:
       +    # The ReportCache class is a regular +ActiveRecord+ model and represents cached results for single reporting periods (table name is +reports_as_sparkline_cache+)
       +    # ReportCache instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+, +reporting_period+, +run_limit+
       +    class ReportCache < ActiveRecord::Base
        
              set_table_name :reports_as_sparkline_cache
        
       -      def self.process(report, options, cache = true, &block)
       +      def self.process(report, options, cache = true, &block) #:nodoc:
                raise ArgumentError.new('A block must be given') unless block_given?
                self.transaction do
                  cached_data = []
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/reporting_period.rb b/lib/simplabs/reports_as_sparkline/reporting_period.rb
       @@ -2,29 +2,20 @@ module Simplabs #:nodoc:
        
          module ReportsAsSparkline #:nodoc:
        
       -    # A ReportingPeriod is  - depending on the Grouping - either a specific hour, a day, a month or a year. All records falling into this period will be grouped together.
       -    class ReportingPeriod
       +    class ReportingPeriod #:nodoc:
        
              attr_reader :date_time, :grouping
        
       -      # ==== Parameters
       -      # * <tt>grouping</tt> - The Simplabs::ReportsAsSparkline::Grouping of the reporting period
       -      # * <tt>date_time</tt> - The DateTime that reporting period is created for
              def initialize(grouping, date_time = nil)
                @grouping  = grouping
                @date_time = parse_date_time(date_time || DateTime.now)
              end
        
       -      # Returns the first reporting period for a grouping and a limit; e.g. the first reporting period for Grouping :day and limit 2 would be Time.now - 2.days
       -      #
       -      # ==== Parameters
       -      # * <tt>grouping</tt> - The Simplabs::ReportsAsSparkline::Grouping of the reporting period
       -      # * <tt>limit</tt> - The number of reporting periods until the first one
              def self.first(grouping, limit, end_date = nil)
                self.new(grouping, end_date).offset(-limit)
              end
        
       -      def self.from_db_string(grouping, db_string) #:nodoc:
       +      def self.from_db_string(grouping, db_string)
                parts = grouping.date_parts_from_db_string(db_string)
                result = case grouping.identifier
                  when :hour
       @@ -39,39 +30,33 @@ module Simplabs #:nodoc:
                result
              end
        
       -      # Returns the next reporting period (that is next hour/day/month/year)
              def next
                self.offset(1)
              end
        
       -      # Returns the previous reporting period (that is next hour/day/month/year)
              def previous
                self.offset(-1)
              end
        
       -      # Returns the reporting period with the specified offset from the current
       -      #
       -      # ==== Parameters
       -      # * <tt>offset</tt> - The offset to return the reporting period for (specifies the offset in hours/days/months/years), depending on the reporting period's grouping
              def offset(offset)
                self.class.new(@grouping, @date_time + offset.send(@grouping.identifier))
              end
        
       -      def ==(other) #:nodoc:
       +      def ==(other)
                if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
                  return @date_time.to_s == other.date_time.to_s && @grouping.identifier.to_s == other.grouping.identifier.to_s
                end
                false
              end
        
       -      def <(other) #:nodoc:
       +      def <(other)
                if other.class == Simplabs::ReportsAsSparkline::ReportingPeriod
                  return @date_time < other.date_time
                end
                raise ArgumentError.new("Can only compare instances of #{Simplabs::ReportsAsSparkline::ReportingPeriod.klass}")
              end
        
       -      def last_date_time #:nodoc:
       +      def last_date_time
                case @grouping.identifier
                  when :hour
                    DateTime.new(@date_time.year, @date_time.month, @date_time.day, @date_time.hour, 59, 59)
 (DIR) diff --git a/lib/simplabs/reports_as_sparkline/sparkline_tag_helper.rb b/lib/simplabs/reports_as_sparkline/sparkline_tag_helper.rb
       @@ -8,7 +8,7 @@ module Simplabs #:nodoc:
              #
              # ==== Parameters
              #
       -      # * <tt>data</tt> - The data to render the sparkline for
       +      # * <tt>data</tt> - The data to render the sparkline for, is retrieved from a report like <tt>User.registration_report</tt>
              #
              # ==== Options
              #
       @@ -16,10 +16,10 @@ module Simplabs #:nodoc:
              # * <tt>height</tt> - The height of the generated image
              # * <tt>line_color</tt> - The line color of the sparkline (hex code)
              # * <tt>fill_color</tt> - The color to fill the area below the sparkline with (hex code)
       -      # * <tt>labels</tt> - The axes to render lables for (Array of :x, :y, :r, :t; this is x axis, y axis, right, top)
       +      # * <tt>labels</tt> - The axes to render lables for (Array of <tt>:x</tt>, <tt>:y+</tt>, <tt>:r</tt>, <tt>:t</tt>; this is x axis, y axis, right, top)
              #
              # ==== Example
       -      # <%= sparkline_tag(User.registrations_report, :width => 200, :height => 100, :color => '000') %>
       +      # <tt><%= sparkline_tag(User.registrations_report, :width => 200, :height => 100, :color => '000') %></tt>
              def sparkline_tag(data, options = {})
                options.reverse_merge!({ :width => 300, :height => 34, :line_color => '0077cc', :fill_color => 'e6f2fa', :labels => [] })
                data = data.collect { |d| d[1] }