use yardoc for documentation - reportable - Unnamed repository; edit this file 'description' to name the repository. (DIR) Log (DIR) Files (DIR) Refs (DIR) README --- (DIR) commit b94d337cd6b1aa0fc6aa285542e7c9f2ad3553e7 (DIR) parent 7a999addb7eef8518d36310c56b4ca80450f3a4d (HTM) Author: Marco Otte-Witte <marco.otte-witte@simplabs.com> Date: Wed, 24 Feb 2010 21:38:14 +0100 use yardoc for documentation Diffstat: M .gitignore | 1 + A README.md | 5 +++++ D README.rdoc | 4 ---- M Rakefile | 14 +++++++------- M generators/reports_as_sparkline_mi… | 2 +- M lib/saulabs/reportable.rb | 43 +++++++++++++++++++------------ M lib/saulabs/reportable/cumulated_r… | 19 ++++++++----------- M lib/saulabs/reportable/grouping.rb | 33 +++++++++++++++++++++++++++---- M lib/saulabs/reportable/report.rb | 90 +++++++++++++++++++++++-------- M lib/saulabs/reportable/report_cach… | 56 ++++++++++++++++++++++--------- M lib/saulabs/reportable/reporting_p… | 94 ++++++++++++++++++++++++++++--- M lib/saulabs/reportable/sparkline_t… | 39 ++++++++++++++++++++----------- 12 files changed, 296 insertions(+), 104 deletions(-) --- (DIR) diff --git a/.gitignore b/.gitignore @@ -2,3 +2,4 @@ spec/log/spec.log spec/db/reportable.sqlite3.db doc +.yardoc (DIR) diff --git a/README.md b/README.md @@ -0,0 +1,4 @@ +Reportable +---------- + +Former ReportsAsSparkline; expect new features, cleaner code etc. in the next weeks +\ No newline at end of file (DIR) diff --git a/README.rdoc b/README.rdoc @@ -1,3 +0,0 @@ -= Reportable - -Former ReportsAsSparkline; expect new features, cleaner code etc. in the next weeks -\ No newline at end of file (DIR) diff --git a/Rakefile b/Rakefile @@ -22,13 +22,13 @@ Spec::Rake::SpecTask.new(:spec) do |t| t.spec_files = FileList['spec/**/*_spec.rb'] end -desc 'Generate documentation for the ReportsAsSparkline plugin.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'doc' - rdoc.title = 'ReportsAsSparkline' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README.rdoc') - rdoc.rdoc_files.include('lib/**/*.rb') +begin + require 'yard' + YARD::Rake::YardocTask.new(:doc) do |t| + t.files = ['lib/**/*.rb', '-', 'README.md'] + t.options = ['--no-private', '--title', 'Reportable Documentation'] + end +rescue LoadError end begin (DIR) diff --git a/generators/reports_as_sparkline_migration/reports_as_sparkline_migration_generator.rb b/generators/reports_as_sparkline_migration/reports_as_sparkline_migration_generator.rb @@ -1,4 +1,4 @@ -class ReportableMigrationGenerator < Rails::Generator::NamedBase #:nodoc: +class ReportableMigrationGenerator < Rails::Generator::NamedBase def manifest record do |m| (DIR) diff --git a/lib/saulabs/reportable.rb b/lib/saulabs/reportable.rb @@ -1,31 +1,40 @@ -module Saulabs #:nodoc: +module Saulabs module Reportable - def self.included(base) #:nodoc: + # Includes the {Saulabs::Reportable.reportable} method into +base+. + # + def self.included(base) base.extend ClassMethods end module ClassMethods - # Generates a report on a model. That report can then be executed via the new method <tt><name>_report</tt> (see documentation of Saulabs::Reportable::Report#run). + # Generates a report on a model. That report can then be executed via the new method +<name>_report+ (see documentation of {Saulabs::Reportable::Report#run}). # - # ==== Parameters + # @param [String] name + # the name of the report, also defines the name of the generated report method (+<name>_report+) + # @param [Hash] options + # the options to generate the reports with # - # * <tt>name</tt> - The name of the report, defines the name of the generated report method (<tt><name>_report</tt>) + # @option options [Symbol] :date_column (created_at) + # the name of the date column over that the records are aggregated + # @option options [String, Symbol] :value_column (:id) + # the name of the column that holds the values to aggregate when using a calculation aggregation like +:sum+ + # @option options [Symbol] :aggregation (:count) + # the aggregation to use (one of +:count+, +:sum+, +:minimum+, +:maximum+ or +:average+); when using anything other than +:count+, +:value_column+ must also be specified + # @option options [Symbol] :grouping (:day) + # the period records are grouped in (+:hour+, +:day+, +:week+, +:month+); <b>Beware that <tt>reportable</tt> treats weeks as starting on monday!</b> + # @option options [Fixnum] :limit (100) + # the number of reporting periods to get (see +:grouping+) + # @option options [Hash] :conditions ({}) + # conditions like in +ActiveRecord::Base#find+; only records that match these conditions are reported; + # @option options [Boolean] :live_data (false) + # specifies whether data for the current reporting period is to be read; <b>if +:live_data+ is +true+, you will experience a performance hit since the request cannot be satisfied from the cache alone</b> + # @option options [DateTime, Boolean] :end_date (false) + # when specified, the report will only include data for the +:limit+ reporting periods until this date. # - # ==== Options - # - # * <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>reportable</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 + # @example Declaring reports on a model # # class User < ActiveRecord::Base # reportable :registrations, :aggregation => :count (DIR) diff --git a/lib/saulabs/reportable/cumulated_report.rb b/lib/saulabs/reportable/cumulated_report.rb @@ -1,26 +1,23 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable - # A special report class that cumulates all data (see Saulabs::Reportable::Report) + # A special report class that cumulates all data (see {Saulabs::Reportable::Report}) # - # ==== Examples - # - # When Saulabs::Reportable::Report returns + # @example Cumulated reports as opposed to regular reports # # [[<DateTime today>, 1], [<DateTime yesterday>, 2], etc.] - # - # Saulabs::Reportable::CumulatedReport returns - # # [[<DateTime today>, 3], [<DateTime yesterday>, 2], etc.] + # class CumulatedReport < Report - # Runs the report (see Saulabs::Reportable::Report#run) + # Runs the report (see {Saulabs::Reportable::Report#run}) + # def run(options = {}) cumulate(super, options_for_run(options)) end - protected + private def cumulate(data, options) first_reporting_period = ReportingPeriod.first(options[:grouping], options[:limit], options[:end_date]) (DIR) diff --git a/lib/saulabs/reportable/grouping.rb b/lib/saulabs/reportable/grouping.rb @@ -1,18 +1,38 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable - class Grouping #:nodoc: + # The grouping specifies which records are grouped into one {Saulabs::Reportable::ReportingPeriod}. + # + class Grouping + # Initializes a new grouping. + # + # @param [Symbol] identifier + # 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 + # Gets the identifier of the grouping. + # + # @returns [Symbol] + # the identifier of the grouping. + # def identifier @identifier end + # Gets an array of date parts from a DB string. + # + # @param [String] db_string + # the DB string to get the date parts from + # + # @returns [Array<Fixnum>] + # array of numbers that represent the values of the date + # def date_parts_from_db_string(db_string) case ActiveRecord::Base.connection.adapter_name when /mysql/i @@ -24,7 +44,12 @@ module Saulabs #:nodoc: end end - def to_sql(date_column) #:nodoc: + # Converts the grouping into a DB specific string that can be used to group records. + # + # @param [String] date_column + # the name of the DB column that holds the date + # + def to_sql(date_column) case ActiveRecord::Base.connection.adapter_name when /mysql/i mysql_format(date_column) (DIR) diff --git a/lib/saulabs/reportable/report.rb b/lib/saulabs/reportable/report.rb @@ -1,26 +1,61 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable - # The Report class that does all the data retrieval and calculations + # The Report class that does all the data retrieval and calculations. + # class Report - attr_reader :klass, :name, :date_column, :value_column, :aggregation, :options + # the model the report works on (This is the class you invoke {Saulabs::Reportable::ClassMethods#reportable} on) + # + attr_reader :klass + + # the name of the report (as in {Saulabs::Reportable::ClassMethods#reportable}) + # + attr_reader :name + + # the name of the date column over that the records are aggregated + # + attr_reader :date_column + + # the name of the column that holds the values to aggregate when using a calculation aggregation like +:sum+ + # + attr_reader :value_column - # ==== Parameters - # * <tt>klass</tt> - The model the report works on (This is the class you invoke Saulabs::Reportable::ClassMethods#reportable on) - # * <tt>name</tt> - The name of the report (as in Saulabs::Reportable::ClassMethods#reportable) + # the aggregation to use (one of +:count+, +:sum+, +:minimum+, +:maximum+ or +:average+); when using anything other than +:count+, +:value_column+ must also be specified # - # ==== Options + attr_reader :aggregation + + # options for the report + # + attr_reader :options + + # Initializes a new {Saulabs::Reportable::Report} + # + # @param [Class] klass + # the model the report works on (This is the class you invoke {Saulabs::Reportable::ClassMethods#reportable} on) + # @param [String] name + # the name of the report (as in {Saulabs::Reportable::ClassMethods#reportable}) + # @param [Hash] options + # options for the report creation + # + # @option options [Symbol] :date_column (created_at) + # the name of the date column over that the records are aggregated + # @option options [String, Symbol] :value_column (:id) + # the name of the column that holds the values to aggregate when using a calculation aggregation like +:sum+ + # @option options [Symbol] :aggregation (:count) + # the aggregation to use (one of +:count+, +:sum+, +:minimum+, +:maximum+ or +:average+); when using anything other than +:count+, +:value_column+ must also be specified + # @option options [Symbol] :grouping (:day) + # the period records are grouped in (+:hour+, +:day+, +:week+, +:month+); <b>Beware that <tt>reportable</tt> treats weeks as starting on monday!</b> + # @option options [Fixnum] :limit (100) + # the number of reporting periods to get (see +:grouping+) + # @option options [Hash] :conditions ({}) + # conditions like in +ActiveRecord::Base#find+; only records that match these conditions are reported; + # @option options [Boolean] :live_data (false) + # specifies whether data for the current reporting period is to be read; <b>if +:live_data+ is +true+, you will experience a performance hit since the request cannot be satisfied from the cache alone</b> + # @option options [DateTime, Boolean] :end_date (false) + # when specified, the report will only include data for the +:limit+ reporting periods until 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>reportable</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 @@ -41,12 +76,23 @@ module Saulabs #:nodoc: # Runs the report and returns an array of array of DateTimes and Floats # - # ==== Options - # * <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>reportable</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 - # * <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. + # @param [Hash] options + # options to run the report with + # + # @option options [Symbol] :grouping (:day) + # the period records are grouped in (+:hour+, +:day+, +:week+, +:month+); <b>Beware that <tt>reportable</tt> treats weeks as starting on monday!</b> + # @option options [Fixnum] :limit (100) + # the number of reporting periods to get (see +:grouping+) + # @option options [Hash] :conditions ({}) + # conditions like in +ActiveRecord::Base#find+; only records that match these conditions are reported; + # @option options [Boolean] :live_data (false) + # specifies whether data for the current reporting period is to be read; <b>if +:live_data+ is +true+, you will experience a performance hit since the request cannot be satisfied from the cache alone</b> + # @option options [DateTime, Boolean] :end_date (false) + # when specified, the report will only include data for the +:limit+ reporting periods until this date. + # + # @returns [Array<Array<DateTime, Float>>] + # the result of the report as pairs of {DateTime}s and {Float}s + # def run(options = {}) options = options_for_run(options) ReportCache.process(self, options) do |begin_at, end_at| (DIR) diff --git a/lib/saulabs/reportable/report_cache.rb b/lib/saulabs/reportable/report_cache.rb @@ -1,9 +1,10 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable - # The ReportCache class is a regular +ActiveRecord+ model and represents cached results for single reporting periods (table name is +reportable_cache+) - # ReportCache instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+ and +reporting_period+ + # The +ReportCache+ class is a regular {ActiveRecord} model and represents cached results for single {Saulabs::Reportable::ReportingPeriod}s. + # +ReportCache+ instances are identified by the combination of +model_name+, +report_name+, +grouping+, +aggregation+ and +reporting_period+. + # class ReportCache < ActiveRecord::Base set_table_name :reportable_cache @@ -12,17 +13,19 @@ module Saulabs #:nodoc: # Clears the cache for the specified +klass+ and +report+ # - # === Parameters - # * <tt>klass</tt> - The model the report to clear the cache for works on - # * <tt>report</tt> - The name of the report to clear the cache for + # @param [Class] klass + # the model the report to clear the cache for works on + # @param [Symbol] report + # the name of the report to clear the cache for + # + # @example Clearing the cache for a report + # + # class User < ActiveRecord::Base + # reportable :registrations + # end + # + # Saulabs::Reportable::ReportCache.clear_for(User, :registrations) # - # === Example - # To clear the cache for a report defined as - # class User < ActiveRecord::Base - # reportable :registrations - # end - # just do - # Saulabs::Reportable::ReportCache.clear_for(User, :registrations) def self.clear_for(klass, report) self.delete_all(:conditions => { :model_name => klass.name, @@ -30,7 +33,28 @@ module Saulabs #:nodoc: }) end - def self.process(report, options, &block) #:nodoc: + # Processes the report using the respective cache. + # + # @param [Saulabe::Reportable::Report] report + # the report to process + # @param [Hash] options + # options for the report + # + # @option options [Symbol] :grouping (:day) + # the period records are grouped in (+:hour+, +:day+, +:week+, +:month+); <b>Beware that <tt>reportable</tt> treats weeks as starting on monday!</b> + # @option options [Fixnum] :limit (100) + # the number of reporting periods to get (see +:grouping+) + # @option options [Hash] :conditions ({}) + # conditions like in +ActiveRecord::Base#find+; only records that match these conditions are reported; + # @option options [Boolean] :live_data (false) + # specifies whether data for the current reporting period is to be read; <b>if +:live_data+ is +true+, you will experience a performance hit since the request cannot be satisfied from the cache alone</b> + # @option options [DateTime, Boolean] :end_date (false) + # when specified, the report will only include data for the +:limit+ reporting periods until this date. + # + # @returns [Array<Array<DateTime, Float>>] + # the result of the report as pairs of {DateTime}s and {Float}s + # + def self.process(report, options, &block) raise ArgumentError.new('A block must be given') unless block_given? self.transaction do cached_data = read_cached_data(report, options) @@ -44,7 +68,7 @@ module Saulabs #:nodoc: def self.prepare_result(new_data, cached_data, report, options) new_data = new_data.map { |data| [ReportingPeriod.from_db_string(options[:grouping], data[0]), data[1]] } cached_data.map! { |cached| [ReportingPeriod.new(options[:grouping], cached.reporting_period), cached.value] } - current_reporting_period = ReportingPeriod.current(options[:grouping]) + current_reporting_period = ReportingPeriod.new(options[:grouping]) reporting_period = get_first_reporting_period(options) result = [] while reporting_period < (options[:end_date] ? ReportingPeriod.new(options[:grouping], options[:end_date]).next : current_reporting_period) (DIR) diff --git a/lib/saulabs/reportable/reporting_period.rb b/lib/saulabs/reportable/reporting_period.rb @@ -1,28 +1,74 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable - class ReportingPeriod #:nodoc: + # A reporting period is a specific hour or a specific day etc. depending on the used {Saulabs::Reportable::Grouping}. + # + class ReportingPeriod - attr_reader :date_time, :grouping + # The actual {DateTime} the reporting period represents + # + attr_reader :date_time + # The {Saulabs::Reportable::Grouping} of the reporting period + # + attr_reader :grouping + + # Initializes a new reporting period. + # + # @param [Saulabs::Reportable::Grouping] grouping + # the grouping the generate the reporting period for + # @param [DateTime] date_time + # the {DateTime} to generate the reporting period for + # def initialize(grouping, date_time = nil) @grouping = grouping @date_time = parse_date_time(date_time || DateTime.now) end + # Gets a reporting period relative to the current one. + # + # @param [Fixnum] offset + # the offset to get the reporting period for + # + # @returns [Saulabs::Reportable::ReportingPeriod] + # the reporting period relative by offset to the current one + # + # @example Getting the reporting period one week later + # + # reporting_period = Saulabs::Reportable::ReportingPeriod.new(:week, DateTime.now) + # next_week = reporting_period.offset(1) + # def offset(offset) self.class.new(@grouping, @date_time + offset.send(@grouping.identifier)) end + # Gets the first reporting period for a grouping and a limit (optionally relative to and end date). + # + # @param [Saulabs::ReportingPeriod::Grouping] grouping + # the grouping to get the first reporting period for + # @param [Fixnum] limit + # the limit to get the first reporting period for + # @param [DateTime] end_date + # the end date to get the first reporting period for (the first reporting period is then +end_date+ - +limit+ * +grouping+) + # + # @returns [Saulabs::Reportable::ReportingPeriod] + # the first reporting period for the grouping, limit and optionally end date + # def self.first(grouping, limit, end_date = nil) self.new(grouping, end_date).offset(-limit) end - def self.current(grouping) - self.new(grouping, Time.now) - end - + # Gets a reporting period from a DB date string. + # + # @param [Saulabs::Reportable::Grouping] grouping + # the grouping to get the reporting period for + # @param [String] db_string + # the DB string to parse and get the reporting period for + # + # @returns [Saulabs::Reportable::ReportingPeriod] + # the reporting period for the {Saulabs::Reportable::Grouping} as parsed from the db string + # def self.from_db_string(grouping, db_string) parts = grouping.date_parts_from_db_string(db_string) result = case grouping.identifier @@ -38,14 +84,32 @@ module Saulabs #:nodoc: result end + # Gets the next reporting period. + # + # @returns [Saulabs::Reportable::ReportingPeriod] + # the reporting period after the current one + # def next self.offset(1) end + # Gets the previous reporting period. + # + # @returns [Saulabs::Reportable::ReportingPeriod] + # the reporting period before the current one + # def previous self.offset(-1) end + # Gets whether the reporting period +other+ is equal to the current one. + # + # @param [Saulabs::Reportable::ReportingPeriod] other + # the reporting period to check for whether it is equal to the current one + # + # @returns [Boolean] + # true if +other+ is equal to the current reporting period, false otherwise + # def ==(other) if other.is_a?(Saulabs::Reportable::ReportingPeriod) @date_time.to_s == other.date_time.to_s && @grouping.identifier.to_s == other.grouping.identifier.to_s @@ -56,6 +120,14 @@ module Saulabs #:nodoc: end end + # Gets whether the reporting period +other+ is smaller to the current one. + # + # @param [Saulabs::Reportable::ReportingPeriod] other + # the reporting period to check for whether it is smaller to the current one + # + # @returns [Boolean] + # true if +other+ is smaller to the current reporting period, false otherwise + # def <(other) if other.is_a?(Saulabs::Reportable::ReportingPeriod) return @date_time < other.date_time @@ -66,6 +138,12 @@ module Saulabs #:nodoc: end end + # Gets the latest point in time that is included the reporting period. The latest point in time included in a reporting period + # for grouping hour would be that hour and 59 minutes and 59 seconds. + # + # @returns [DateTime] + # the latest point in time that is included in the reporting period + # def last_date_time case @grouping.identifier when :hour (DIR) diff --git a/lib/saulabs/reportable/sparkline_tag_helper.rb b/lib/saulabs/reportable/sparkline_tag_helper.rb @@ -1,27 +1,38 @@ -module Saulabs #:nodoc: +module Saulabs - module Reportable #:nodoc: + module Reportable module SparklineTagHelper # Renders a sparkline with the given data. # - # ==== Parameters + # @param [Array<Array<DateTime, Float>>] data + # an array of report data as returned by {Saulabs::Reportable::Report#run} + # @param [Hash] options + # options for the sparkline # - # * <tt>data</tt> - The data to render the sparkline for, is retrieved from a report like <tt>User.registration_report</tt> + # @option options [Fixnum] :width (300) + # the width of the generated image + # @option options [Fixnum] :height (34) + # the height of the generated image + # @option options [String] :line_color ('0077cc') + # the line color of the generated image + # @option options [String] :fill_color ('e6f2fa') + # the fill color of the generated image + # @option options [Array<Symbol>] :labels ([]) + # the axes to render lables for (Array of +:x+, +:y+, +:r+, +:t+; this is x axis, y axis, right, top) + # @option options [String] :alt ('') + # the alt attribute for the generated image + # @option options [String] :title ('') + # the title attribute for the generated image # - # ==== Options + # @returns [String] + # an image tag showing a sparkline for the passed +data+ # - # * <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) - # * <tt>alt</tt> - The HTML img alt tag - # * <tt>title</tt> - The HTML img title tag + # @example Rendering a sparkline tag for report data + # + # <%= sparkline_tag(User.registrations_report, :width => 200, :height => 100, :color => '000') %> # - # ==== Example - # <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 => [], :alt => '', :title => '' }) data = data.collect { |d| d[1] }