require "dates2svg/version"
class Dates2SVG
BOX_SIZE = 15
BORDER = 1
BOX_WITH_BORDER = (BOX_SIZE + BORDER)
def initialize(dates, options={})
@dates = dates
@options = options
parse_dates
end
def parse_dates
@dates.map do |date|
date_from_facet_value(date)
end.sort do |a, b|
a.year.to_i <=> b.year.to_i
end.group_by(&:year).each do |year, dates|
years << Dates2SVG::Year.new(year, dates)
end
end
def date_from_facet_value(facet)
facet.value[/^(\d{4})-(\d{2})-(\d{2})/]
Dates2SVG::DateWithValue.new(:year => $1, :month => $2, :day => $3, :hits => facet.hits)
end
def years
@years ||= []
end
def max
@max ||= years.map{|year| year.months.map{|month| month.hits} }.flatten.max
end
def color_range
self.class.color_range(@options.merge(:max => @max))
end
def color_options
@options[:color_options] || self.class.color_options
end
def to_svg
svg = ""
# + 35 and +50 gives us the space for the year month text
svg << ""
end
def self.color_range(options={})
max_hits = options[:max] || 3000
section = (max_hits) / 5
colors = {}
color_options = options[:color_options] || self.color_options
ranges = [[0], (1..(section * 1)),
(((section * 1) + 1)..(section * 2)),
(((section * 2) + 1)..(section * 3)),
(((section * 3) + 1)..(section * 4)),
(((section * 4) + 1)..max_hits)]
color_options.each_with_index do |color, index|
unless ranges[index].is_a?(Range) and [ranges[index].first, ranges[index].last].include?(0)
colors[ranges[index]] = color
end
end
colors
end
def self.color_options(options={})
options[:color_options] || ["#EEEEEE", "#330000", "#660000", "#990000", "#CC0000", "#FF0000"]
end
private
def all_years
@options[:year_range] || years.map{|y| y.year }
end
def calendar_year_listing
svg = ""
all_years.each_with_index do |year, index|
svg << "#{year}"
end
svg
end
def calendar_month_listing
svg = ""
["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", " Oct", "Nov", "Dec"].each_with_index do |month, index|
svg << "#{month}"
end
svg
end
class DateWithValue
attr_reader :year, :month, :day, :hits
def initialize(ops={})
@year = ops[:year]
@month = ops[:month]
@day = ops[:day]
@hits = ops[:hits]
end
end
class Year
attr_reader :year
def initialize(year, dates)
@year = year
@dates = dates
parse_dates
end
def parse_dates
@dates.sort do |a, b|
a.month.to_i <=> b.month.to_i
end.group_by(&:month).map do |month, dates|
months << Dates2SVG::Month.new(@year, month, dates)
end
end
def months
@months ||= []
end
def to_svg(options={})
svg = ""
svg << ""
all_months.each_with_index do |month, index|
unless months.select{|m| m.month == month}.length == 0
svg << months.select{|m| m.month == month}.first.to_svg(options.merge(:index => index))
else
svg << Dates2SVG::Month.new(@year, month, []).to_svg(options.merge(:index => index))
end
end
svg << ""
end
private
def all_months
["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"]
end
end
class Month
attr_reader :year, :month
def initialize(year, month, dates)
@year = year
@month = month
@dates = dates
end
def hits
@hits ||= (@dates.map{|d| d.hits.to_i }.inject(:+) || 0)
end
def to_svg(options={})
svg = ""
svg << ""
svg << "#{hits} hits on #{@year}-#{@month}"
svg << ""
end
private
def color(options={})
max_hits = options[:max] || 3000
section = (max_hits / 5)
max = section * 5
return Dates2SVG.color_options(options).last if hits > max
colors = Dates2SVG.color_range(options)
begin
# .first turns the hash into an array and .last gets the value
colors.select{|k,v| k.include?(hits) }.first.last
rescue
Dates2SVG.color_options(options).first
end
end
end
end