googlecharts-1.6.8/ 0000755 0001750 0001750 00000000000 11750001056 013560 5 ustar boutil boutil googlecharts-1.6.8/README.markdown 0000644 0001750 0001750 00000025162 11750001056 016267 0 ustar boutil boutil The goal of this Gem is to make the creation of Google Charts a simple and easy task.
require 'googlecharts'
Gchart.line( :size => '200x300',
:title => "example title",
:bg => 'efefef',
:legend => ['first data set label', 'second data set label'],
:data => [10, 30, 120, 45, 72])
Check out the [full documentation over there](http://googlecharts.rubyforge.org/)
This gem is fully tested using Rspec, check the rspec folder for more examples.
See at the bottom of this file who reported using this gem.
Chart Type
-------------
This gem supports the following types of charts:
* line,
* line_xy
* sparkline
* scatter
* bar
* venn
* pie
* pie_3d
* google meter
Googlecharts also supports graphical themes and you can easily load your own.
To create a chart, simply require Gchart and call any of the existing type:
require 'gchart'
Gchart.pie
Chart Title
-------------
To add a title to a chart pass the title to your chart:
Gchart.line(:title => 'Sexy Charts!')
You can also specify the color and/or size
Gchart.line(:title => 'Sexy Charts!', :title_color => 'FF0000', :title_size => '20')
Colors
-------------
Specify a color with at least a 6-letter string of hexadecimal values in the format RRGGBB. For example:
* FF0000 = red
* 00FF00 = green
* 0000FF = blue
* 000000 = black
* FFFFFF = white
You can optionally specify transparency by appending a value between 00 and FF where 00 is completely transparent and FF completely opaque. For example:
* 0000FFFF = solid blue
* 0000FF00 = transparent blue
If you need to use multiple colors, check the doc. Usually you just need to pass :attribute => 'FF0000,00FF00'
Some charts have more options than other, make sure to refer to the documentation.
Background options:
-------------
If you don't set the background option, your graph will be transparent.
* You have 3 types of background http://code.google.com/apis/chart/#chart_or_background_fill
- solid
- gradient
- stripes
By default, if you set a background color, the fill will be solid:
Gchart.bar(:bg => 'efefef')
However you can specify another fill type such as:
Gchart.line(:bg => {:color => 'efefef', :type => 'gradient'})
In the above code, we decided to have a gradient background, however since we only passed one color, the chart will start by the specified color and transition to white. By the default, the gradient angle is 0. Change it as follows:
Gchart.line(:title =>'bg example', :bg => {:color => 'efefef', :type => 'gradient', :angle => 90})
For a more advance use of colors, refer to http://code.google.com/apis/chart/#linear_gradient
Gchart.line(:bg => {:color => '76A4FB,1,ffffff,0', :type => 'gradient'})
The same way you set the background color, you can also set the graph background:
Gchart.line(:graph_bg => 'cccccc')
or both
Gchart.line(:bg => {:color => '76A4FB,1,ffffff,0', :type => 'gradient'}, :graph_bg => 'cccccc', :title => 'Sexy Chart')
Another type of fill is stripes http://code.google.com/apis/chart/#linear_stripes
Gchart.line(:bg => {:color => 'efefef', :type => 'stripes'})
You can customize the amount of stripes, colors and width by changing the color value.
Themes
--------
Googlecharts comes with 4 themes: keynote, thirty7signals, pastel and greyscale. (ganked from [Gruff](http://github.com/topfunky/gruff/tree/master)
Gchart.line(
:theme => :keynote,
:data => [[0,40,10,70,20],[41,10,80,50,40],[20,60,30,60,80],[5,23,35,10,56],[80,90,5,30,60]],
:title => 'keynote'
)
* keynote

* thirty7signals

* pastel

* greyscale

You can also use your own theme. Create a yml file using the same format as the themes located in lib/themes.yml
Load your theme(s):
Chart::Theme.add_theme_file("#{File.dirname(__FILE__)}/fixtures/another_test_theme.yml")
And use the standard method signature to use your own theme:
Gchart.line(:theme => :custom_theme, :data => [[0, 40, 10, 70, 20],[41, 10, 80, 50]], :title => 'greyscale')
Legend & Labels
-------------
You probably will want to use a legend or labels for your graph.
Gchart.line(:legend => 'legend label')
or
Gchart.line(:legend => ['legend label 1', 'legend label 2'])
Will do the trick. You can also use the labels alias (makes more sense when using the pie charts)
chart = Gchart.pie(:labels => ['label 1', 'label 2'])
Multiple axis labels
-------------
Multiple axis labels are available for line charts, bar charts and scatter plots.
* x = bottom x-axis
* t = top x-axis
* y = left y-axis
* r = right y-axis
Gchart.line(:axis_with_label => 'x,y,r,t')
To add labels on these axis:
Gchart.line(:axis_with_label => 'x,y,r,t',
:axis_labels => ['Jan|July|Jan|July|Jan', '0|100', 'A|B|C', '2005|2006|2007'])
Note that each array entry could also be an array but represent the
labels for the corresponding axis.
A question which comes back often is how do I only display the y axis
label? Solution:
Gchart.line(
:data => [0,20, 40, 60, 140, 230, 60],
:axis_with_labels => 'y')
Custom axis ranges
---------------
If you want to display a custom range for an axis, you need to set the
range as described in the Google charts documentation: min, max, step:
Gchart.line( :data => [17, 17, 11, 8, 2],
:axis_with_labels => ['x', 'y'],
:axis_labels => [['J', 'F', 'M', 'A', 'M']],
:axis_range => [nil, [2,17,5]])
In this case, the custom axis range is only defined for y (second
entry) with a minimum value of 2, max 17 and a step of 5.
This is also valid if you want to set a x axis and automatically define
the y labels.
Data options
-------------
Data are passed using an array or a nested array.
Gchart.bar(:data => [1,2,4,67,100,41,234])
Gchart.bar(:data => [[1,2,4,67,100,41,234],[45,23,67,12,67,300, 250]])
By default, the graph is drawn with your max value representing 100% of the height or width of the graph. You can change that my passing the max value.
Gchart.bar(:data => [1,2,4,67,100,41,234], :max_value => 300)
Gchart.bar(:data => [1,2,4,67,100,41,234], :max_value => 'auto')
or if you want to use the real values from your dataset:
Gchart.bar(:data => [1,2,4,67,100,41,234], :max_value => false)
You can also define a different encoding to add more granularity:
Gchart.bar(:data => [1,2,4,67,100,41,234], :encoding => 'simple')
Gchart.bar(:data => [1,2,4,67,100,41,234], :encoding => 'extended')
Gchart.bar(:data => [1,2,4,67,100,41,234], :encoding => 'text')
Pies:
-------------
you have 2 type of pies:
- Gchart.pie() the standard 2D pie
_ Gchart.pie_3d() the fancy 3D pie
To set labels, you can use one of these two options:
@legend = ['Matt_fu', 'Rob_fu']
Gchart.pie_3d(:title => @title, :labels => @legend, :data => @data, :size => '400x200')
Gchart.pie_3d(:title => @title, :legend => @legend, :data => @data, :size => '400x200')
Bars:
-------------
A bar chart can accept options to set the width of the bars, spacing between bars and spacing between bar groups. To set these, you can either provide a string, array or hash.
The Google API sets these options in the order of width, spacing, and group spacing, with both spacing values being optional. So, if you provide a string or array, provide them in that order:
Gchart.bar(:data => @data, :bar_width_and_spacing => '25,6') # width of 25, spacing of 6
Gchart.bar(:data => @data, :bar_width_and_spacing => '25,6,12') # width of 25, spacing of 6, group spacing of 12
Gchart.bar(:data => @data, :bar_width_and_spacing => [25,6]) # width of 25, spacing of 6
Gchart.bar(:data => @data, :bar_width_and_spacing => 25) # width of 25
The hash lets you set these values directly, with the Google default values set for any options you don't include:
Gchart.bar(:data => @data, :bar_width_and_spacing => {:width => 19})
Gchart.bar(:data => @data, :bar_width_and_spacing => {:spacing => 10, :group_spacing => 12})
Radar:
-------------
In a Radar graph, the x-axis is circular. The points can be connected by straight lines or curved lines.
Gchart.radar(:data => @data, :curved => true)
Sparklines:
-------------
A sparkline chart has exactly the same parameters as a line chart. The only difference is that the axes lines are not drawn for sparklines by default.
Google-o-meter
-------------
A Google-o-meter has a few restrictions. It may only use a solid filled background and it may only have one label.
Record Chart PNG file in filesystem Sample :
--------------------------------------------
Multi Lines Chart Sample :
chart = Gchart.new( :type => 'line',
:title => "example title",
:data => [[17, 17, 11, 8, 2],[10, 20, 15, 5, 7],[2, 3, 7, 9, 12]],
:line_colors => 'e0440e,e62ae5,287eec',
:legend => ['courbe 1','courbe 2','courbe 3'],
:axis_with_labels => ['x', 'y'],
:axis_range => [[0,100,20], [0,20,5]],
:filename => "tmp/chart.png")
# Record file in filesystem
chart.file
try yourself
-------------
Gchart.bar( :data => [[1,2,4,67,100,41,234],[45,23,67,12,67,300, 250]],
:title => 'SD Ruby Fu level',
:legend => ['matt','patrick'],
:bg => {:color => '76A4FB', :type => 'gradient'},
:bar_colors => 'ff0000,00ff00')
"http://chart.apis.google.com/chart?chs=300x200&chdl=matt|patrick&chd=s:AAANUIv,JENCN9y&chtt=SDRuby+Fu+level&chf=bg,lg,0,76A4FB,0,ffffff,1&cht=bvs&chco=ff0000,00ff00"
Gchart.pie(:data => [20,10,15,5,50], :title => 'SDRuby Fu level', :size => '400x200', :labels => ['matt', 'rob', 'patrick', 'ryan', 'jordan'])
http://chart.apis.google.com/chart?cht=p&chs=400x200&chd=s:YMSG9&chtt=SDRuby+Fu+level&chl=matt|rob|patrick|ryan|jordan googlecharts-1.6.8/metadata.yml 0000644 0001750 0001750 00000003242 11750001056 016064 0 ustar boutil boutil --- !ruby/object:Gem::Specification
name: googlecharts
version: !ruby/object:Gem::Version
hash: 31
prerelease:
segments:
- 1
- 6
- 8
version: 1.6.8
platform: ruby
authors:
- Matt Aimonetti
- Andrey Deryabin
autorequire:
bindir: bin
cert_chain: []
date: 2011-05-21 00:00:00 +04:00
default_executable:
dependencies: []
description: Generate charts using Google API & Ruby
email: mattaimonetti@gmail.com deriabin@gmail.com
executables: []
extensions: []
extra_rdoc_files: []
files:
- .gitignore
- History.txt
- License.txt
- README
- README.markdown
- README.txt
- Rakefile
- googlecharts.gemspec
- lib/gchart.rb
- lib/gchart/aliases.rb
- lib/gchart/theme.rb
- lib/gchart/version.rb
- lib/googlecharts.rb
- lib/themes.yml
- spec/fixtures/another_test_theme.yml
- spec/fixtures/test_theme.yml
- spec/gchart_spec.rb
- spec/spec_helper.rb
- spec/theme_spec.rb
has_rdoc: true
homepage: http://googlecharts.rubyforge.org/
licenses: []
post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ">="
- !ruby/object:Gem::Version
hash: 3
segments:
- 0
version: "0"
required_rubygems_version: !ruby/object:Gem::Requirement
none: false
requirements:
- - ">="
- !ruby/object:Gem::Version
hash: 3
segments:
- 0
version: "0"
requirements: []
rubyforge_project:
rubygems_version: 1.5.2
signing_key:
specification_version: 3
summary: Generate charts using Google API & Ruby
test_files:
- spec/fixtures/another_test_theme.yml
- spec/fixtures/test_theme.yml
- spec/gchart_spec.rb
- spec/spec_helper.rb
- spec/theme_spec.rb
googlecharts-1.6.8/README.txt 0000644 0001750 0001750 00000000125 11750001056 015254 0 ustar boutil boutil CHECK README.markdown (open as a text file)
http://github.com/mattetti/googlecharts googlecharts-1.6.8/googlecharts.gemspec 0000644 0001750 0001750 00000001407 11750001056 017610 0 ustar boutil boutil # -*- encoding: utf-8 -*-
$:.push File.expand_path("../lib", __FILE__)
require "gchart/version"
Gem::Specification.new do |s|
s.name = %q{googlecharts}
s.version = GchartInfo::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ["Matt Aimonetti", "Andrey Deryabin"]
s.date = %q{2011-05-21}
s.summary = %q{Generate charts using Google API & Ruby}
s.description = %q{Generate charts using Google API & Ruby}
s.email = %q{mattaimonetti@gmail.com deriabin@gmail.com}
s.homepage = %q{http://googlecharts.rubyforge.org/}
s.files = `git ls-files`.split("\n")
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
end
googlecharts-1.6.8/README 0000644 0001750 0001750 00000000000 11750001056 014426 0 ustar boutil boutil googlecharts-1.6.8/History.txt 0000644 0001750 0001750 00000003402 11750001056 015761 0 ustar boutil boutil == 1.6.8
* added title alignment support
== 1.6.7
* changed url for ssl connection
== 1.6.6
* added ssl support
* refactored code
* аdded ability to set the legend position
* fixed legend position value
* separated labels and legends for pies
== 1.3.6
* support nil values. The Google Charts API specifies that a single underscore (_) can be used to omit a value from a line chart with 'simple' data encoding, and a double underscore (__) can do the same for a chart with 'extended' data encoding. (Matt Moyer)
* allow a label to appear on a google-o-meter via the :legend option. (hallettj)
== 1.3.5
* added code to properly escape image tag URLs (mokolabs)
* added themes support + 4 default themes (keynote, thirty7signals, pastel, greyscale) chart.line(:theme=>:keynote) (jakehow)
== 1.3.4
* updated documentation and cleaned it up (mokolabs)
* added support for custom class, id and alt tags when using the image_tag format (i.e Gchart.line(:data => [0, 26], :format => 'image_tag')) (mokolabs)
== 1.3.2 - 1.3.3
* changes required by github
== 1.3.1
* added width and spacing options
== 1.3.0
* added support for google-o-meter
* fixed a bug when the max value of a data set was 0
== 1.2.0
* added support for sparklines
== 1.1.0
* fixed another bug fix related to the uri escaping required to download the file properly.
== 1.0.0
* fixed the (URI::InvalidURIError) issue
== 0.2.0
* added export options (file and image tag)
* added support for all arguments to be passed as a string or an array
== 0.1.0 2007-12-11
* fixed the axis labels
== 0.0.3 2007-12-11
* added :chart_background alias and fixed a bug related to the background colors.
== 0.0.2 2007-12-11
* added support for more features and aliases
== 0.0.1 2007-12-08
* 1 major enhancement:
* Initial release
googlecharts-1.6.8/Rakefile 0000644 0001750 0001750 00000000024 11750001056 015221 0 ustar boutil boutil require 'rubygems' googlecharts-1.6.8/lib/ 0000755 0001750 0001750 00000000000 11750001056 014326 5 ustar boutil boutil googlecharts-1.6.8/lib/gchart.rb 0000644 0001750 0001750 00000047370 11750001056 016136 0 ustar boutil boutil $:.unshift File.dirname(__FILE__)
require 'gchart/version'
require 'gchart/theme'
require "net/http"
require "net/https"
require "uri"
require "cgi"
require 'enumerator'
class Gchart
include GchartInfo
def self.url(use_ssl = false)
if use_ssl
'https://chart.googleapis.com/chart?'
else
'http://chart.apis.google.com/chart?'
end
end
def self.types
@types ||= ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map', 'radar']
end
def self.simple_chars
@simple_chars ||= ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a
end
def self.chars
@chars ||= simple_chars + ['-', '.']
end
def self.ext_pairs
@ext_pairs ||= chars.map { |char_1| chars.map { |char_2| char_1 + char_2 } }.flatten
end
def self.default_filename
'chart.png'
end
attr_accessor :title, :type, :width, :height, :curved, :horizontal, :grouped, :legend, :legend_position, :labels, :data, :encoding, :bar_colors,
:title_color, :title_size, :title_alignment, :custom, :axis_with_labels, :axis_labels, :bar_width_and_spacing, :id, :alt, :klass,
:range_markers, :geographical_area, :map_colors, :country_codes, :axis_range, :filename, :min, :max, :colors, :usemap
attr_accessor :bg_type, :bg_color, :bg_angle, :chart_type, :chart_color, :chart_angle, :axis_range, :thickness, :new_markers, :grid_lines, :use_ssl
attr_accessor :min_value, :max_value
types.each do |type|
instance_eval <<-DYNCLASSMETH
def #{type}(options = {})
# Start with theme defaults if a theme is set
theme = options[:theme]
options = theme ? Chart::Theme.load(theme).to_options.merge(options) : options
# # Extract the format and optional filename, then clean the hash
format = options[:format] || 'url'
options[:filename] ||= default_filename
options.delete(:format)
#update map_colors to become bar_colors
options.update(:bar_colors => options[:map_colors]) if options.has_key?(:map_colors)
chart = new(options.merge!({:type => "#{type}"}))
chart.send(format)
end
DYNCLASSMETH
end
def self.version
VERSION::STRING
end
def self.method_missing(m, options={})
raise NoMethodError, "#{m} is not a supported chart format. Please use one of the following: #{supported_types}."
end
def initialize(options={})
@type = options[:type] || 'line'
@data = []
@width = 300
@height = 200
@curved = false
@horizontal = false
@grouped = false
@use_ssl = false
@encoding = 'simple'
# @max_value = 'auto'
# @min_value defaults to nil meaning zero
@filename = options[:filename]
# Sets the alt tag when chart is exported as image tag
@alt = 'Google Chart'
# Sets the CSS id selector when chart is exported as image tag
@id = false
# Sets the CSS class selector when chart is exported as image tag
@klass = options[:class] || false
# set the options value if definable
options.each do |attribute, value|
send("#{attribute}=", value) if self.respond_to?("#{attribute}=")
end
end
def self.supported_types
self.types.join(' ')
end
# Defines the Graph size using the following format:
# width X height
def size=(size='300x200')
@width, @height = size.split("x").map { |dimension| dimension.to_i }
end
def size
"#{width}x#{height}"
end
def dimensions
# TODO: maybe others?
[:line_xy, :scatter].include?(type) ? 2 : 1
end
# Sets the orientation of a bar graph
def orientation=(orientation='h')
if orientation == 'h' || orientation == 'horizontal'
self.horizontal = true
elsif orientation == 'v' || orientation == 'vertical'
self.horizontal = false
end
end
# Sets the bar graph presentation (stacked or grouped)
def stacked=(option=true)
@grouped = option ? false : true
end
def bg=(options)
if options.is_a?(String)
@bg_color = options
elsif options.is_a?(Hash)
@bg_color = options[:color]
@bg_type = options[:type]
@bg_angle = options[:angle]
end
end
def graph_bg=(options)
if options.is_a?(String)
@chart_color = options
elsif options.is_a?(Hash)
@chart_color = options[:color]
@chart_type = options[:type]
@chart_angle = options[:angle]
end
end
def max_value=(max_v)
if max_v =~ /false/
@max_value = false
else
@max_value = max_v
end
end
def min_value=(min_v)
if min_v =~ /false/
@min_value = false
else
@min_value = min_v
end
end
# returns the full data range as an array
# it also sets the data range if not defined
def full_data_range(ds)
return if max_value == false
ds.each_with_index do |mds, mds_index|
mds[:min_value] ||= min_value
mds[:max_value] ||= max_value
if mds_index == 0 && type.to_s == 'bar'
# TODO: unless you specify a zero line (using chp or chds),
# the min_value of a bar chart is always 0.
#mds[:min_value] ||= mds[:data].first.to_a.compact.min
mds[:min_value] ||= 0
end
if (mds_index == 0 && type.to_s == 'bar' &&
!grouped && mds[:data].first.is_a?(Array))
totals = []
mds[:data].each do |l|
l.each_with_index do |v, index|
next if v.nil?
totals[index] ||= 0
totals[index] += v
end
end
mds[:max_value] ||= totals.compact.max
else
all = mds[:data].flatten.compact
# default min value should be 0 unless set to auto
if mds[:min_value] == 'auto'
mds[:min_value] = all.min
else
min = all.min
mds[:min_value] ||= (min && min < 0 ? min : 0)
end
mds[:max_value] ||= all.max
end
end
unless axis_range
@calculated_axis_range = true
@axis_range = ds.map{|mds| [mds[:min_value], mds[:max_value]]}
if dimensions == 1 && (type.to_s != 'bar' || horizontal)
tmp = axis_range.fetch(0, [])
@axis_range[0] = axis_range.fetch(1, [])
@axis_range[1] = tmp
end
end
# return [min, max] unless (min.nil? || max.nil?)
# @max = (max_value.nil? || max_value == 'auto') ? ds.compact.map{|mds| mds.compact.max}.max : max_value
#
# if min_value.nil?
# min_ds_value = ds.compact.map{|mds| mds.compact.min}.min || 0
# @min = (min_ds_value < 0) ? min_ds_value : 0
# else
# @min = min_value == 'auto' ? ds.compact.map{|mds| mds.compact.min}.min || 0 : min_value
# end
# @axis_range = [[min,max]]
end
def dataset
if @dataset
@dataset
else
@dataset = convert_dataset(data || [])
full_data_range(@dataset) # unless axis_range
@dataset
end
end
# Sets of data to handle multiple sets
def datasets
datasets = []
dataset.each do |d|
if d[:data].first.is_a?(Array)
datasets += d[:data]
else
datasets << d[:data]
end
end
datasets
end
def self.jstize(string)
# See http://github.com/mattetti/googlecharts/issues#issue/27
#URI.escape( string ).gsub("%7C", "|")
# See discussion: http://github.com/mattetti/googlecharts/commit/9b5cfb93aa51aae06611057668e631cd515ec4f3#comment_51347
string.gsub(' ', '+').gsub(/\[|\{|\}|\\|\^|\[|\]|\`|\]/) {|c| "%#{c[0].to_s.upcase}"}
#string.gsub(' ', '+').gsub(/\[|\{|\}|\||\\|\^|\[|\]|\`|\]/) {|c| "%#{c[0].to_s.upcase}"}
end
# load all the custom aliases
require 'gchart/aliases'
# Returns the chart's generated PNG as a blob. (borrowed from John's gchart.rubyforge.org)
def fetch
url = URI.parse(self.class.url(use_ssl))
req = Net::HTTP::Post.new(url.path)
req.body = query_builder
req.content_type = 'application/x-www-form-urlencoded'
http = Net::HTTP.new(url.host, url.port)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER if use_ssl
http.use_ssl = use_ssl
http.start {|resp| resp.request(req) }.body
end
# Writes the chart's generated PNG to a file. (borrowed from John's gchart.rubyforge.org)
def write
io_or_file = filename || self.class.default_filename
return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
open(io_or_file, "wb+") { |io| io.write(fetch) }
end
# Format
def image_tag
image = "
"
end
alias_method :img_tag, :image_tag
def url
url_builder
end
def file
write
end
#
def jstize(string)
self.class.jstize(string)
end
private
# The title size cannot be set without specifying a color.
# A dark key will be used for the title color if no color is specified
def set_title
title_params = "chtt=#{title}"
unless (title_color.nil? && title_size.nil? && title_alignment.nil?)
title_params << "&chts=" + (color, size, alignment = (title_color || '454545'), title_size, (title_alignment.to_s[0,1] || 'c')).compact.join(',')
end
title_params
end
def set_size
"chs=#{size}"
end
def set_data
data = send("#{@encoding}_encoding")
"chd=#{data}"
end
def set_colors
@bg_type = fill_type(bg_type) || 's' if bg_color
@chart_type = fill_type(chart_type) || 's' if chart_color
"chf=" + {'bg' => fill_for(bg_type, bg_color, bg_angle), 'c' => fill_for(chart_type, chart_color, chart_angle)}.map{|k,v| "#{k},#{v}" unless v.nil?}.compact.join('|')
end
# set bar, line colors
def set_bar_colors
@bar_colors = bar_colors.join(',') if bar_colors.is_a?(Array)
"chco=#{bar_colors}"
end
def set_country_codes
@country_codes = country_codes.join() if country_codes.is_a?(Array)
"chld=#{country_codes}"
end
# set bar spacing
# chbh=
# ,
# ,
#
def set_bar_width_and_spacing
width_and_spacing_values = case bar_width_and_spacing
when String
bar_width_and_spacing
when Array
bar_width_and_spacing.join(',')
when Hash
width = bar_width_and_spacing[:width] || 23
spacing = bar_width_and_spacing[:spacing] || 4
group_spacing = bar_width_and_spacing[:group_spacing] || 8
[width,spacing,group_spacing].join(',')
else
bar_width_and_spacing.to_s
end
"chbh=#{width_and_spacing_values}"
end
def set_range_markers
markers = case range_markers
when Hash
set_range_marker(range_markers)
when Array
range_markers.collect{|marker| set_range_marker(marker)}.join('|')
end
"chm=#{markers}"
end
def set_range_marker(options)
orientation = ['vertical', 'Vertical', 'V', 'v', 'R'].include?(options[:orientation]) ? 'R' : 'r'
"#{orientation},#{options[:color]},0,#{options[:start_position]},#{options[:stop_position]}#{',1' if options[:overlaid?]}"
end
def fill_for(type=nil, color='', angle=nil)
unless type.nil?
case type
when 'lg'
angle ||= 0
color = "#{color},0,ffffff,1" if color.split(',').size == 1
"#{type},#{angle},#{color}"
when 'ls'
angle ||= 90
color = "#{color},0.2,ffffff,0.2" if color.split(',').size == 1
"#{type},#{angle},#{color}"
else
"#{type},#{color}"
end
end
end
# A chart can have one or many legends.
# Gchart.line(:legend => 'label')
# or
# Gchart.line(:legend => ['first label', 'last label'])
def set_legend
if type.to_s =~ /meter/
@labels = legend
return set_labels
end
if legend.is_a?(Array)
"chdl=#{@legend.map{|label| "#{CGI::escape(label.to_s)}"}.join('|')}"
else
"chdl=#{legend}"
end
end
def set_legend_position
case @legend_position.to_s
when /(bottom|b)$/
"chdlp=b"
when /(bottom_vertical|bv)$/
"chdlp=bv"
when /(top|t)$/
"chdlp=t"
when /(top_vertical|tv)$/
"chdlp=tv"
when /(right|r)$/
"chdlp=r"
when /(left|l)$/
"chdlp=l"
end
end
def set_line_thickness
"chls=#{thickness}"
end
def set_line_markers
"chm=#{new_markers}"
end
def set_grid_lines
"chg=#{grid_lines}"
end
def set_labels
if labels.is_a?(Array)
"chl=#{@labels.map{|label| "#{CGI::escape(label.to_s)}"}.join('|')}"
else
"chl=#{@labels}"
end
end
def set_axis_with_labels
@axis_with_labels = axis_with_labels.join(',') if @axis_with_labels.is_a?(Array)
"chxt=#{axis_with_labels}"
end
def set_axis_labels
if axis_labels.is_a?(Array)
if RUBY_VERSION.to_f < 1.9
labels_arr = axis_labels.enum_with_index.map{|labels,index| [index,labels]}
else
labels_arr = axis_labels.map.with_index.map{|labels,index| [index,labels]}
end
elsif axis_labels.is_a?(Hash)
labels_arr = axis_labels.to_a
end
labels_arr.map! do |index,labels|
if labels.is_a?(Array)
"#{index}:|#{labels.map{|label| "#{CGI::escape(label.to_s)}"}.join('|')}"
else
"#{index}:|#{labels}"
end
end
"chxl=#{labels_arr.join('|')}"
end
# http://code.google.com/apis/chart/labels.html#axis_range
# Specify a range for axis labels
def set_axis_range
# a passed axis_range should look like:
# [[10,100]] or [[10,100,4]] or [[10,100], [20,300]]
# in the second example, 4 is the interval
set = @calculated_axis_range ? datasets : axis_range || datasets
return unless set && set.respond_to?(:each) && set.find {|o| o}.respond_to?(:each)
'chxr=' + set.enum_for(:each_with_index).map do |axis_range, index|
next nil if axis_range.nil? # ignore this axis
min, max, step = axis_range
if axis_range.size > 3 || step && max && step > max # this is a full series
max = axis_range.compact.max
step = nil
end
[index, (min_value || min || 0), (max_value || max), step].compact.join(',')
end.compact.join("|")
end
def set_geographical_area
"chtm=#{geographical_area}"
end
def set_type
'cht=' + case type.to_s
when 'line' then "lc"
when 'line_xy' then "lxy"
when 'pie_3d' then "p3"
when 'pie' then "p"
when 'venn' then "v"
when 'scatter' then "s"
when 'sparkline' then "ls"
when 'meter' then "gom"
when 'map' then "t"
when 'radar'
"r" + (curved? ? 's' : '')
when 'bar'
"b" + (horizontal? ? "h" : "v") + (grouped? ? "g" : "s")
end
end
def fill_type(type)
case type
when 'solid' then 's'
when 'gradient' then 'lg'
when 'stripes' then 'ls'
end
end
def number_visible
n = 0
dataset.each do |mds|
return n.to_s if mds[:invisible] == true
if mds[:data].first.is_a?(Array)
n += mds[:data].length
else
n += 1
end
end
""
end
# Turns input into an array of axis hashes, dependent on the chart type
def convert_dataset(ds)
if dimensions == 2
# valid inputs include:
# an array of >=2 arrays, or an array of >=2 hashes
ds = ds.map do |d|
d.is_a?(Hash) ? d : {:data => d}
end
elsif dimensions == 1
# valid inputs include:
# a hash, an array of data, an array of >=1 array, or an array of >=1 hash
if ds.is_a?(Hash)
ds = [ds]
elsif not ds.first.is_a?(Hash)
ds = [{:data => ds}]
end
end
ds
end
# just an alias
def axis_set
dataset
end
def convert_to_simple_value(number)
if number.nil?
"_"
else
value = self.class.simple_chars[number.to_i]
value.nil? ? "_" : value
end
end
def convert_to_extended_value(number)
if number.nil?
'__'
else
value = self.class.ext_pairs[number.to_i]
value.nil? ? "__" : value
end
end
def encode_scaled_dataset(chars, nil_char)
dsets = []
dataset.each do |ds|
if max_value != false
range = ds[:max_value] - ds[:min_value]
range = 1 if range == 0
end
unless ds[:data].first.is_a?(Array)
ldatasets = [ds[:data]]
else
ldatasets = ds[:data]
end
ldatasets.each do |l|
dsets << l.map do |number|
if number.nil?
nil_char
else
unless range.nil? || range.zero?
number = chars.size * (number - ds[:min_value]) / range.to_f
number = [number, chars.size - 1].min
end
chars[number.to_i]
end
end.join
end
end
dsets.join(',')
end
# http://code.google.com/apis/chart/#simple
# Simple encoding has a resolution of 62 different values.
# Allowing five pixels per data point, this is sufficient for line and bar charts up
# to about 300 pixels. Simple encoding is suitable for all other types of chart regardless of size.
def simple_encoding
"s" + number_visible + ":" + encode_scaled_dataset(self.class.simple_chars, '_')
end
# http://code.google.com/apis/chart/#text
# Text encoding with data scaling lets you specify arbitrary positive or
# negative floating point numbers, in combination with a scaling parameter
# that lets you specify a custom range for your chart. This chart is useful
# when you don't want to worry about limiting your data to a specific range,
# or do the calculations to scale your data down or up to fit nicely inside
# a chart.
#
# Valid values range from (+/-)9.999e(+/-)100, and only four non-zero digits are supported (that is, 123400, 1234, 12.34, and 0.1234 are valid, but 12345, 123.45 and 123400.5 are not).
#
# This encoding is not available for maps.
#
def text_encoding
chds = dataset.map{|ds| "#{ds[:min_value]},#{ds[:max_value]}" }.join(",")
"t" + number_visible + ":" + datasets.map{ |ds| ds.map{|e|e||'_'}.join(',') }.join('|') + "&chds=" + chds
end
# http://code.google.com/apis/chart/#extended
# Extended encoding has a resolution of 4,096 different values
# and is best used for large charts where a large data range is required.
def extended_encoding
"e" + number_visible + ":" + encode_scaled_dataset(self.class.ext_pairs, '__')
end
def url_builder(options="")
self.class.url(use_ssl) + query_builder(options)
end
def query_builder(options="")
query_params = instance_variables.sort.map do |var|
case var.to_s
when '@data'
set_data unless data == []
# Set the graph size
when '@width'
set_size unless width.nil? || height.nil?
when '@type'
set_type
when '@title'
set_title unless title.nil?
when '@legend'
set_legend unless legend.nil?
when '@labels'
set_labels unless labels.nil?
when '@legend_position'
set_legend_position unless legend_position.nil?
when '@thickness'
set_line_thickness
when '@new_markers'
set_line_markers
when '@bg_color'
set_colors
when '@chart_color'
set_colors if bg_color.nil?
when '@bar_colors'
set_bar_colors
when '@bar_width_and_spacing'
set_bar_width_and_spacing
when '@axis_with_labels'
set_axis_with_labels
when '@axis_labels'
set_axis_labels
when '@range_markers'
set_range_markers
when '@grid_lines'
set_grid_lines
when '@geographical_area'
set_geographical_area
when '@country_codes'
set_country_codes
when '@custom'
custom
end
end.compact
query_params << set_axis_range
# Use ampersand as default delimiter
unless options == :html
delimiter = '&'
# Escape ampersand for html image tags
else
delimiter = '&'
end
jstize(query_params.join(delimiter))
end
end
googlecharts-1.6.8/lib/googlecharts.rb 0000644 0001750 0001750 00000000121 11750001056 017326 0 ustar boutil boutil require 'gchart'
Googlecharts = Gchart unless Object.const_defined? 'Googlechart' googlecharts-1.6.8/lib/themes.yml 0000644 0001750 0001750 00000002057 11750001056 016342 0 ustar boutil boutil #Default themes ganked from Gruff: http://github.com/topfunky/gruff/tree/master
:keynote:
:colors:
- &blue 6886B4
- &yellow FDD84E
- &green 72AE6E
- &red D1695E
- &purple 8A6EAF
- &orange EFAA43
- &white FFFFFF
- &black !str 000000
:bar_colors: [ *blue, *yellow, *green, *red, *purple, *orange ]
:background: *black
:chart_background: *white
:thirty7signals:
:colors:
- &green 339933
- &purple cc99cc
- &blue 336699
- &yellow FFF804
- &red ff0000
- &orange cf5910
:bar_colors: [ *yellow, *blue, *green, *red, *purple, *orange ]
:background: *white
:pastel:
:colors:
- &blue a9dada
- &green aedaa9
- &peach daaea9
- &yellow dadaa9
- &dk_purple a9a9da
- &purple daaeda
- &grey dadada
:bar_colors: [ *blue, *green, *peach, *yellow, *dk_purple ]
:background_color: *white
:greyscale:
:bar_colors: [
282828,
383838,
686868,
989898,
c8c8c8,
e8e8e8
]
:background_color: *white googlecharts-1.6.8/lib/gchart/ 0000755 0001750 0001750 00000000000 11750001056 015576 5 ustar boutil boutil googlecharts-1.6.8/lib/gchart/theme.rb 0000644 0001750 0001750 00000002237 11750001056 017231 0 ustar boutil boutil require 'yaml'
module Chart
class Theme
class ThemeNotFound < RuntimeError; end
@@theme_files = ["#{File.dirname(__FILE__)}/../themes.yml"]
attr_accessor :colors
attr_accessor :bar_colors
attr_accessor :background
attr_accessor :chart_background
def self.load(theme_name)
theme = new(theme_name)
end
def self.theme_files
@@theme_files
end
# Allows you to specify paths for custom theme files in YAML format
def self.add_theme_file(file)
@@theme_files << file
end
def initialize(theme_name)
themes = {}
@@theme_files.each {|f| themes.update YAML::load(File.open(f))}
theme = themes[theme_name]
if theme
self.colors = theme[:colors]
self.bar_colors = theme[:bar_colors]
self.background = theme[:background]
self.chart_background = theme[:chart_background]
self
else
raise(ThemeNotFound, "Could not locate the #{theme_name} theme ...")
end
end
def to_options
{:background => background, :chart_background => chart_background, :bar_colors => bar_colors.join(',')}
end
end
end googlecharts-1.6.8/lib/gchart/aliases.rb 0000644 0001750 0001750 00000000713 11750001056 017545 0 ustar boutil boutil class Gchart
alias_method :background=, :bg=
alias_method :chart_bg=, :graph_bg=
alias_method :chart_color=, :graph_bg=
alias_method :chart_background=, :graph_bg=
alias_method :bar_color=, :bar_colors=
alias_method :line_colors=, :bar_colors=
alias_method :line_color=, :bar_colors=
alias_method :slice_colors=, :bar_colors=
alias_method :horizontal?, :horizontal
alias_method :grouped?, :grouped
alias_method :curved?, :curved
end
googlecharts-1.6.8/lib/gchart/version.rb 0000644 0001750 0001750 00000000063 11750001056 017607 0 ustar boutil boutil module GchartInfo #:nodoc:
VERSION = "1.6.8"
end
googlecharts-1.6.8/spec/ 0000755 0001750 0001750 00000000000 11750001056 014512 5 ustar boutil boutil googlecharts-1.6.8/spec/gchart_spec.rb 0000644 0001750 0001750 00000072646 11750001056 017340 0 ustar boutil boutil require File.dirname(__FILE__) + '/spec_helper.rb'
require File.dirname(__FILE__) + '/../lib/gchart'
Chart::Theme.add_theme_file("#{File.dirname(__FILE__)}/fixtures/test_theme.yml")
# Time to add your specs!
# http://rspec.rubyforge.org/
describe "The Gchart class" do
it "should show supported_types on error" do
Gchart.supported_types.should match(/line/)
end
it "should return supported types" do
Gchart.types.include?('line').should be_true
end
end
describe "generating a default Gchart" do
before(:each) do
@chart = Gchart.line
end
it "should include the Google URL" do
@chart.include?("http://chart.apis.google.com/chart?").should be_true
end
it "should have a default size" do
@chart.should include('chs=300x200')
end
it "should be able to have a custom size" do
Gchart.line(:size => '400x600').include?('chs=400x600').should be_true
Gchart.line(:width => 400, :height => 600).include?('chs=400x600').should be_true
end
it "should have query parameters in predictable order" do
Gchart.line(:axis_with_labels => 'x,y,r', :size => '400x600').should match(/chxt=.+cht=.+chs=/)
end
it "should have a type" do
@chart.include?('cht=lc').should be_true
end
it 'should use theme defaults if theme is set' do
Gchart.line(:theme=>:test).should include('chco=6886B4,FDD84E')
if RUBY_VERSION.to_f < 1.9
Gchart.line(:theme=>:test).should include(Gchart.jstize('chf=c,s,FFFFFF|bg,s,FFFFFF'))
else
Gchart.line(:theme=>:test).should include(Gchart.jstize('chf=bg,s,FFFFFF|c,s,FFFFFF'))
end
end
it "should use the simple encoding by default with auto max value" do
# 9 is the max value in simple encoding, 26 being our max value the 2nd encoded value should be 9
Gchart.line(:data => [0, 26]).should include('chd=s:A9')
Gchart.line(:data => [0, 26], :max_value => 26, :axis_with_labels => 'y').should include('chxr=0,0,26')
end
it "should support simple encoding with and without max_value" do
Gchart.line(:data => [0, 26], :max_value => 26).should include('chd=s:A9')
Gchart.line(:data => [0, 26], :max_value => false).should include('chd=s:Aa')
end
it "should support the extended encoding and encode properly" do
Gchart.line(:data => [0, 10], :encoding => 'extended', :max_value => false).include?('chd=e:AA').should be_true
Gchart.line(:encoding => 'extended',
:max_value => false,
:data => [[0,25,26,51,52,61,62,63], [64,89,90,115,4084]]
).include?('chd=e:AAAZAaAzA0A9A-A.,BABZBaBz.0').should be_true
end
it "should auto set the max value for extended encoding" do
Gchart.line(:data => [0, 25], :encoding => 'extended', :max_value => false).should include('chd=e:AAAZ')
# Extended encoding max value is '..'
Gchart.line(:data => [0, 25], :encoding => 'extended').include?('chd=e:AA..').should be_true
end
it "should be able to have data with text encoding" do
Gchart.line(:data => [10, 5.2, 4, 45, 78], :encoding => 'text').should include('chd=t:10,5.2,4,45,78')
end
it "should be able to have missing data points with text encoding" do
Gchart.line(:data => [10, 5.2, nil, 45, 78], :encoding => 'text').should include('chd=t:10,5.2,_,45,78')
end
it "should handle max and min values with text encoding" do
Gchart.line(:data => [10, 5.2, 4, 45, 78], :encoding => 'text').should include('chds=0,78')
end
it "should automatically handle negative values with proper max/min limits when using text encoding" do
Gchart.line(:data => [-10, 5.2, 4, 45, 78], :encoding => 'text').should include('chds=-10,78')
end
it "should handle negative values with manual max/min limits when using text encoding" do
Gchart.line(:data => [-10, 5.2, 4, 45, 78], :encoding => 'text', :min_value => -20, :max_value => 100).include?('chds=-20,100').should be_true
end
it "should set the proper axis values when using text encoding and negative values" do
Gchart.bar( :data => [[-10], [100]],
:encoding => 'text',
:horizontal => true,
:min_value => -20,
:max_value => 100,
:axis_with_labels => 'x',
:bar_colors => ['FD9A3B', '4BC7DC']).should include("chxr=0,-20,100")
end
it "should be able to have multiple set of data with text encoding" do
Gchart.line(:data => [[10, 5.2, 4, 45, 78], [20, 40, 70, 15, 99]], :encoding => 'text').include?(Gchart.jstize('chd=t:10,5.2,4,45,78|20,40,70,15,99')).should be_true
end
it "should be able to receive a custom param" do
Gchart.line(:custom => 'ceci_est_une_pipe').include?('ceci_est_une_pipe').should be_true
end
it "should be able to set label axis" do
Gchart.line(:axis_with_labels => 'x,y,r').include?('chxt=x,y,r').should be_true
Gchart.line(:axis_with_labels => ['x','y','r']).include?('chxt=x,y,r').should be_true
end
it "should be able to have axis labels" do
Gchart.line(:axis_labels => ['Jan|July|Jan|July|Jan', '0|100', 'A|B|C', '2005|2006|2007']).include?(Gchart.jstize('chxl=0:|Jan|July|Jan|July|Jan|1:|0|100|2:|A|B|C|3:|2005|2006|2007')).should be_true
Gchart.line(:axis_labels => ['Jan|July|Jan|July|Jan']).include?(Gchart.jstize('chxl=0:|Jan|July|Jan|July|Jan')).should be_true
Gchart.line(:axis_labels => [['Jan','July','Jan','July','Jan']]).include?(Gchart.jstize('chxl=0:|Jan|July|Jan|July|Jan')).should be_true
Gchart.line(:axis_labels => [['Jan','July','Jan','July','Jan'], ['0','100'], ['A','B','C'], ['2005','2006','2007']]).include?(Gchart.jstize('chxl=0:|Jan|July|Jan|July|Jan|1:|0|100|2:|A|B|C|3:|2005|2006|2007')).should be_true
end
def labeled_line(options = {})
Gchart.line({:data => @data, :axis_with_labels => 'x,y'}.merge(options))
end
it "should display ranges properly" do
@data = [85,107,123,131,155,172,173,189,203,222,217,233,250,239,256,267,247,261,275,295,288,305,322,307,325,347,331,346,363,382,343,359,383,352,374,393,358,379,396,416,377,398,419,380,409,426,453,432,452,465,436,460,480,440,457,474,501,457,489,507,347,373,413,402,424,448,475,488,513,475,507,530,440,476,500,518,481,512,531,367,396,423,387,415,446,478,442,469,492,463,489,508,463,491,518,549,503,526,547,493,530,549,493,520,541,564,510,535,564,492,512,537,502,530,548,491,514,538,568,524,548,568,512,533,552,577,520,545,570,516,536,555,514,536,566,521,553,579,604,541,569,595,551,581,602,549,576,606,631,589,615,650,597,624,646,672,605,626,654,584,608,631,574,597,622,559,591,614,644,580,603,629,584,615,631,558,591,618,641,314,356,395,397,429,450,421,454,477,507,458,490,560,593]
labeled_line(:axis_labels => [((1..24).to_a << 1)]).
should include('chxr=0,85,672')
end
def labeled_bar(options = {})
Gchart.bar({:data => @data,
:axis_with_labels => 'x,y',
:axis_labels => [(1..12).to_a],
:encoding => "text"
}.merge(options))
end
it "should force the y range properly" do
@data = [1,1,1,1,1,1,1,1,6,2,1,1]
labeled_bar(
:axis_range => [[0,0],[0,16]]
).should include('chxr=0,0,0|1,0,16')
labeled_bar(
:max_value => 16,
:axis_range => [[0,0],[0,16]]
).should include('chxr=0,0,16|1,0,16')
# nil means ignore axis
labeled_bar(
:axis_range => [nil,[0,16]]
).should include('chxr=1,0,16')
# empty array means take defaults
labeled_bar(
:max_value => 16,
:axis_range => [[],[0,16]]
).should include('chxr=0,0,16|1,0,16')
labeled_bar(
:axis_range => [[],[0,16]]
).should include('chxr=0,0|1,0,16')
Gchart.line(
:data => [0,20, 40, 60, 140, 230, 60],
:axis_with_labels => 'y').should include("chxr=0,0,230")
end
it "should take in consideration the max value when creating a range" do
data = [85,107,123,131,155,172,173,189,203,222,217,233,250,239,256,267,247,261,275,295,288,305,322,307,325,347,331,346,363,382,343,359,383,352,374,393,358,379,396,416,377,398,419,380,409,426,453,432,452,465,436,460,480,440,457,474,501,457,489,507,347,373,413,402,424,448,475,488,513,475,507,530,440,476,500,518,481,512,531,367,396,423,387,415,446,478,442,469,492,463,489,508,463,491,518,549,503,526,547,493,530,549,493,520,541,564,510,535,564,492,512,537,502,530,548,491,514,538,568,524,548,568,512,533,552,577,520,545,570,516,536,555,514,536,566,521,553,579,604,541,569,595,551,581,602,549,576,606,631,589,615,650,597,624,646,672,605,626,654,584,608,631,574,597,622,559,591,614,644,580,603,629,584,615,631,558,591,618,641,314,356,395,397,429,450,421,454,477,507,458,490,560,593]
url = Gchart.line(:data => data, :axis_with_labels => 'x,y', :axis_labels => [((1..24).to_a << 1)], :max_value => 700)
url.should include('chxr=0,85,700')
end
it 'should generate different labels and legend' do
Gchart.pie(:legend => %w(1 2 3), :labels=>%w(one two three)).should(include('chdl=1|2|3') && include('chl=one|two|three'))
end
end
describe "generating different type of charts" do
it "should be able to generate a line chart" do
Gchart.line.should be_an_instance_of(String)
Gchart.line.include?('cht=lc').should be_true
end
it "should be able to generate a sparkline chart" do
Gchart.sparkline.should be_an_instance_of(String)
Gchart.sparkline.include?('cht=ls').should be_true
end
it "should be able to generate a line xy chart" do
Gchart.line_xy.should be_an_instance_of(String)
Gchart.line_xy.include?('cht=lxy').should be_true
end
it "should be able to generate a scatter chart" do
Gchart.scatter.should be_an_instance_of(String)
Gchart.scatter.include?('cht=s').should be_true
end
it "should be able to generate a bar chart" do
Gchart.bar.should be_an_instance_of(String)
Gchart.bar.include?('cht=bvs').should be_true
end
it "should be able to generate a Venn diagram" do
Gchart.venn.should be_an_instance_of(String)
Gchart.venn.include?('cht=v').should be_true
end
it "should be able to generate a Pie Chart" do
Gchart.pie.should be_an_instance_of(String)
Gchart.pie.include?('cht=p').should be_true
end
it "should be able to generate a Google-O-Meter" do
Gchart.meter.should be_an_instance_of(String)
Gchart.meter.include?('cht=gom').should be_true
end
it "should be able to generate a map chart" do
Gchart.map.should be_an_instance_of(String)
Gchart.map.include?('cht=t').should be_true
end
it "should not support other types" do
msg = "sexy is not a supported chart format. Please use one of the following: #{Gchart.supported_types}."
lambda{Gchart.sexy}.should raise_error(NoMethodError)
end
end
describe "range markers" do
it "should be able to generate given a hash of range-marker options" do
Gchart.line(:range_markers => {:start_position => 0.59, :stop_position => 0.61, :color => 'ff0000'}).include?('chm=r,ff0000,0,0.59,0.61').should be_true
end
it "should be able to generate given an array of range-marker hash options" do
Gchart.line(:range_markers => [
{:start_position => 0.59, :stop_position => 0.61, :color => 'ff0000'},
{:start_position => 0, :stop_position => 0.6, :color => '666666'},
{:color => 'cccccc', :start_position => 0.6, :stop_position => 1}
]).include?(Gchart.jstize('r,ff0000,0,0.59,0.61|r,666666,0,0,0.6|r,cccccc,0,0.6,1')).should be_true
end
it "should allow a :overlaid? to be set" do
Gchart.line(:range_markers => {:start_position => 0.59, :stop_position => 0.61, :color => 'ffffff', :overlaid? => true}).include?('chm=r,ffffff,0,0.59,0.61,1').should be_true
Gchart.line(:range_markers => {:start_position => 0.59, :stop_position => 0.61, :color => 'ffffff', :overlaid? => false}).include?('chm=r,ffffff,0,0.59,0.61').should be_true
end
describe "when setting the orientation option" do
before(:each) do
@options = {:start_position => 0.59, :stop_position => 0.61, :color => 'ff0000'}
end
it "to vertical (R) if given a valid option" do
Gchart.line(:range_markers => @options.merge(:orientation => 'v')).include?('chm=R').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'V')).include?('chm=R').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'R')).include?('chm=R').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'vertical')).include?('chm=R').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'Vertical')).include?('chm=R').should be_true
end
it "to horizontal (r) if given a valid option (actually anything other than the vertical options)" do
Gchart.line(:range_markers => @options.merge(:orientation => 'horizontal')).include?('chm=r').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'h')).include?('chm=r').should be_true
Gchart.line(:range_markers => @options.merge(:orientation => 'etc')).include?('chm=r').should be_true
end
it "if left blank defaults to horizontal (r)" do
Gchart.line(:range_markers => @options).include?('chm=r').should be_true
end
end
end
describe "a bar graph" do
it "should have a default vertical orientation" do
Gchart.bar.include?('cht=bvs').should be_true
end
it "should be able to have a different orientation" do
Gchart.bar(:orientation => 'vertical').include?('cht=bvs').should be_true
Gchart.bar(:orientation => 'v').include?('cht=bvs').should be_true
Gchart.bar(:orientation => 'h').include?('cht=bhs').should be_true
Gchart.bar(:orientation => 'horizontal').include?('cht=bhs').should be_true
Gchart.bar(:horizontal => false).include?('cht=bvs').should be_true
end
it "should be set to be stacked by default" do
Gchart.bar.include?('cht=bvs').should be_true
end
it "should be able to stacked or grouped" do
Gchart.bar(:stacked => true).include?('cht=bvs').should be_true
Gchart.bar(:stacked => false).include?('cht=bvg').should be_true
Gchart.bar(:grouped => true).include?('cht=bvg').should be_true
Gchart.bar(:grouped => false).include?('cht=bvs').should be_true
end
it "should be able to have different bar colors" do
Gchart.bar(:bar_colors => 'efefef,00ffff').include?('chco=').should be_true
Gchart.bar(:bar_colors => 'efefef,00ffff').include?('chco=efefef,00ffff').should be_true
# alias
Gchart.bar(:bar_color => 'efefef').include?('chco=efefef').should be_true
end
it "should be able to have different bar colors when using an array of colors" do
Gchart.bar(:bar_colors => ['efefef','00ffff']).include?('chco=efefef,00ffff').should be_true
end
it 'should be able to accept a string of width and spacing options' do
Gchart.bar(:bar_width_and_spacing => '25,6').include?('chbh=25,6').should be_true
end
it 'should be able to accept a single fixnum width and spacing option to set the bar width' do
Gchart.bar(:bar_width_and_spacing => 25).include?('chbh=25').should be_true
end
it 'should be able to accept an array of width and spacing options' do
Gchart.bar(:bar_width_and_spacing => [25,6,12]).include?('chbh=25,6,12').should be_true
Gchart.bar(:bar_width_and_spacing => [25,6]).include?('chbh=25,6').should be_true
Gchart.bar(:bar_width_and_spacing => [25]).include?('chbh=25').should be_true
end
describe "with a hash of width and spacing options" do
before(:each) do
@default_width = 23
@default_spacing = 4
@default_group_spacing = 8
end
it 'should be able to have a custom bar width' do
Gchart.bar(:bar_width_and_spacing => {:width => 19}).include?("chbh=19,#{@default_spacing},#{@default_group_spacing}").should be_true
end
it 'should be able to have custom spacing' do
Gchart.bar(:bar_width_and_spacing => {:spacing => 19}).include?("chbh=#{@default_width},19,#{@default_group_spacing}").should be_true
end
it 'should be able to have custom group spacing' do
Gchart.bar(:bar_width_and_spacing => {:group_spacing => 19}).include?("chbh=#{@default_width},#{@default_spacing},19").should be_true
end
end
end
describe "a line chart" do
before(:each) do
@title = 'Chart Title'
@legend = ['first data set label', 'n data set label']
@chart = Gchart.line(:title => @title, :legend => @legend)
end
it 'should be able have a chart title' do
@chart.include?("chtt=Chart+Title").should be_true
end
it "should be able to a custom color, size and alignment for title" do
Gchart.line(:title => @title, :title_color => 'FF0000').include?('chts=FF0000').should be_true
Gchart.line(:title => @title, :title_size => '20').include?('chts=454545,20').should be_true
Gchart.line(:title => @title, :title_size => '20', :title_alignment => :left).include?('chts=454545,20,l').should be_true
end
it "should be able to have multiple legends" do
@chart.include?(Gchart.jstize("chdl=first+data+set+label|n+data+set+label")).should be_true
end
it "should escape text values in url" do
title = 'Chart & Title'
legend = ['first data & set label', 'n data set label']
chart = Gchart.line(:title => title, :legend => legend)
chart.include?(Gchart.jstize("chdl=first+data+%26+set+label|n+data+set+label")).should be_true
end
it "should be able to have one legend" do
chart = Gchart.line(:legend => 'legend label')
chart.include?("chdl=legend+label").should be_true
end
it "should be able to set the position of the legend" do
title = 'Chart & Title'
legend = ['first data & set label', 'n data set label']
chart = Gchart.line(:title => title, :legend => legend, :legend_position => :bottom_vertical)
chart.include?("chdlp=bv").should be_true
chart = Gchart.line(:title => title, :legend => legend, :legend_position => 'r')
chart.include?("chdlp=r").should be_true
end
it "should be able to set the background fill" do
Gchart.line(:bg => 'efefef').should include("chf=bg,s,efefef")
Gchart.line(:bg => {:color => 'efefef', :type => 'solid'}).should include("chf=bg,s,efefef")
Gchart.line(:bg => {:color => 'efefef', :type => 'gradient'}).should include("chf=bg,lg,0,efefef,0,ffffff,1")
Gchart.line(:bg => {:color => 'efefef,0,ffffff,1', :type => 'gradient'}).should include("chf=bg,lg,0,efefef,0,ffffff,1")
Gchart.line(:bg => {:color => 'efefef', :type => 'gradient', :angle => 90}).should include("chf=bg,lg,90,efefef,0,ffffff,1")
Gchart.line(:bg => {:color => 'efefef', :type => 'stripes'}).should include("chf=bg,ls,90,efefef,0.2,ffffff,0.2")
end
it "should be able to set a graph fill" do
Gchart.line(:graph_bg => 'efefef').should include("chf=c,s,efefef")
Gchart.line(:graph_bg => {:color => 'efefef', :type => 'solid'}).include?("chf=c,s,efefef").should be_true
Gchart.line(:graph_bg => {:color => 'efefef', :type => 'gradient'}).include?("chf=c,lg,0,efefef,0,ffffff,1").should be_true
Gchart.line(:graph_bg => {:color => 'efefef,0,ffffff,1', :type => 'gradient'}).include?("chf=c,lg,0,efefef,0,ffffff,1").should be_true
Gchart.line(:graph_bg => {:color => 'efefef', :type => 'gradient', :angle => 90}).include?("chf=c,lg,90,efefef,0,ffffff,1").should be_true
end
it "should be able to set both a graph and a background fill" do
Gchart.line(:bg => 'efefef', :graph_bg => '76A4FB').include?("bg,s,efefef").should be_true
Gchart.line(:bg => 'efefef', :graph_bg => '76A4FB').include?("c,s,76A4FB").should be_true
if RUBY_VERSION.to_f < 1.9
Gchart.line(:bg => 'efefef', :graph_bg => '76A4FB').include?(Gchart.jstize("chf=c,s,76A4FB|bg,s,efefef")).should be_true
else
Gchart.line(:bg => 'efefef', :graph_bg => '76A4FB').include?(Gchart.jstize("chf=bg,s,efefef|c,s,76A4FB")).should be_true
end
end
it "should be able to have different line colors" do
Gchart.line(:line_colors => 'efefef|00ffff').include?(Gchart.jstize('chco=efefef|00ffff')).should be_true
Gchart.line(:line_color => 'efefef|00ffff').include?(Gchart.jstize('chco=efefef|00ffff')).should be_true
end
it "should be able to render a graph where all the data values are 0" do
Gchart.line(:data => [0, 0, 0]).should include("chd=s:AAA")
end
end
describe "a sparkline chart" do
before(:each) do
@title = 'Chart Title'
@legend = ['first data set label', 'n data set label']
@jstized_legend = Gchart.jstize(@legend.join('|'))
@data = [27,25,25,25,25,27,100,31,25,36,25,25,39,25,31,25,25,25,26,26,25,25,28,25,25,100,28,27,31,25,27,27,29,25,27,26,26,25,26,26,35,33,34,25,26,25,36,25,26,37,33,33,37,37,39,25,25,25,25]
@chart = Gchart.sparkline(:title => @title, :data => @data, :legend => @legend)
end
it "should create a sparkline" do
@chart.include?('cht=ls').should be_true
end
it 'should be able have a chart title' do
@chart.include?("chtt=Chart+Title").should be_true
end
it "should be able to a custom color and size title" do
Gchart.sparkline(:title => @title, :title_color => 'FF0000').include?('chts=FF0000').should be_true
Gchart.sparkline(:title => @title, :title_size => '20').include?('chts=454545,20').should be_true
end
it "should be able to have multiple legends" do
@chart.include?(Gchart.jstize("chdl=first+data+set+label|n+data+set+label")).should be_true
end
it "should be able to have one legend" do
chart = Gchart.sparkline(:legend => 'legend label')
chart.include?("chdl=legend+label").should be_true
end
it "should be able to set the background fill" do
Gchart.sparkline(:bg => 'efefef').include?("chf=bg,s,efefef").should be_true
Gchart.sparkline(:bg => {:color => 'efefef', :type => 'solid'}).include?("chf=bg,s,efefef").should be_true
Gchart.sparkline(:bg => {:color => 'efefef', :type => 'gradient'}).include?("chf=bg,lg,0,efefef,0,ffffff,1").should be_true
Gchart.sparkline(:bg => {:color => 'efefef,0,ffffff,1', :type => 'gradient'}).include?("chf=bg,lg,0,efefef,0,ffffff,1").should be_true
Gchart.sparkline(:bg => {:color => 'efefef', :type => 'gradient', :angle => 90}).include?("chf=bg,lg,90,efefef,0,ffffff,1").should be_true
Gchart.sparkline(:bg => {:color => 'efefef', :type => 'stripes'}).include?("chf=bg,ls,90,efefef,0.2,ffffff,0.2").should be_true
end
it "should be able to set a graph fill" do
Gchart.sparkline(:graph_bg => 'efefef').include?("chf=c,s,efefef").should be_true
Gchart.sparkline(:graph_bg => {:color => 'efefef', :type => 'solid'}).include?("chf=c,s,efefef").should be_true
Gchart.sparkline(:graph_bg => {:color => 'efefef', :type => 'gradient'}).include?("chf=c,lg,0,efefef,0,ffffff,1").should be_true
Gchart.sparkline(:graph_bg => {:color => 'efefef,0,ffffff,1', :type => 'gradient'}).include?("chf=c,lg,0,efefef,0,ffffff,1").should be_true
Gchart.sparkline(:graph_bg => {:color => 'efefef', :type => 'gradient', :angle => 90}).include?("chf=c,lg,90,efefef,0,ffffff,1").should be_true
end
it "should be able to set both a graph and a background fill" do
Gchart.sparkline(:bg => 'efefef', :graph_bg => '76A4FB').include?("bg,s,efefef").should be_true
Gchart.sparkline(:bg => 'efefef', :graph_bg => '76A4FB').include?("c,s,76A4FB").should be_true
if RUBY_VERSION.to_f < 1.9
Gchart.sparkline(:bg => 'efefef', :graph_bg => '76A4FB').include?(Gchart.jstize("chf=c,s,76A4FB|bg,s,efefef")).should be_true
else
Gchart.sparkline(:bg => 'efefef', :graph_bg => '76A4FB').include?(Gchart.jstize("chf=bg,s,efefef|c,s,76A4FB")).should be_true
end
end
it "should be able to have different line colors" do
Gchart.sparkline(:line_colors => 'efefef|00ffff').include?(Gchart.jstize('chco=efefef|00ffff')).should be_true
Gchart.sparkline(:line_color => 'efefef|00ffff').include?(Gchart.jstize('chco=efefef|00ffff')).should be_true
end
end
describe "a 3d pie chart" do
before(:each) do
@title = 'Chart Title'
@legend = ['first data set label', 'n data set label']
@jstized_legend = Gchart.jstize(@legend.join('|'))
@data = [12,8,40,15,5]
@chart = Gchart.pie(:title => @title, :legend => @legend, :data => @data)
end
it "should create a pie" do
@chart.include?('cht=p').should be_true
end
it "should be able to be in 3d" do
Gchart.pie_3d(:title => @title, :legend => @legend, :data => @data).include?('cht=p3').should be_true
end
end
describe "a google-o-meter" do
before(:each) do
@data = [70]
@legend = ['arrow points here']
@jstized_legend = Gchart.jstize(@legend.join('|'))
@chart = Gchart.meter(:data => @data)
end
it "should create a meter" do
@chart.include?('cht=gom').should be_true
end
it "should be able to set a solid background fill" do
Gchart.meter(:bg => 'efefef').include?("chf=bg,s,efefef").should be_true
Gchart.meter(:bg => {:color => 'efefef', :type => 'solid'}).include?("chf=bg,s,efefef").should be_true
end
it "should be able to set labels by using the legend or labesl accessor" do
Gchart.meter(:title => @title, :labels => @legend, :data => @data).should include("chl=#{@jstized_legend}")
Gchart.meter(:title => @title, :labels => @legend, :data => @data).should == Gchart.meter(:title => @title, :legend => @legend, :data => @data)
end
end
describe "a map chart" do
before(:each) do
@data = [0,100,50,32]
@geographical_area = 'usa'
@map_colors = ['FFFFFF', 'FF0000', 'FFFF00', '00FF00']
@country_codes = ['MT', 'WY', "ID", 'SD']
@chart = Gchart.map(:data => @data, :encoding => 'text', :size => '400x300',
:geographical_area => @geographical_area, :map_colors => @map_colors,
:country_codes => @country_codes)
end
it "should create a map" do
@chart.include?('cht=t').should be_true
end
it "should set the geographical area" do
@chart.include?('chtm=usa').should be_true
end
it "should set the map colors" do
@chart.include?('chco=FFFFFF,FF0000,FFFF00,00FF00').should be_true
end
it "should set the country/state codes" do
@chart.include?('chld=MTWYIDSD').should be_true
end
it "should set the chart data" do
@chart.include?('chd=t:0,100,50,32').should be_true
end
end
describe 'exporting a chart' do
it "should be available in the url format by default" do
Gchart.line(:data => [0, 26], :format => 'url').should == Gchart.line(:data => [0, 26])
end
it "should be available as an image tag" do
Gchart.line(:data => [0, 26], :format => 'image_tag').should match(/
/)
end
it "should be available as an image tag using img_tag alias" do
Gchart.line(:data => [0, 26], :format => 'img_tag').should match(/
/)
end
it "should be available as an image tag using custom dimensions" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :size => '400x400').should match(/
/)
end
it "should be available as an image tag using custom alt text" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :alt => 'Sexy chart').should match(/
/)
end
it "should be available as an image tag using custom title text" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :title => 'Sexy chart').should match(/
/)
end
it "should be available as an image tag using custom css id selector" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :id => 'chart').should match(/
/)
end
it "should be available as an image tag using custom css class selector" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :class => 'chart').should match(/
/)
end
it "should use ampersands to separate key/value pairs in URLs by default" do
Gchart.line(:data => [0, 26]).should satisfy {|chart| chart.include? "&" }
Gchart.line(:data => [0, 26]).should_not satisfy {|chart| chart.include? "&" }
end
it "should escape ampersands in URLs when used as an image tag" do
Gchart.line(:data => [0, 26], :format => 'image_tag', :class => 'chart').should satisfy {|chart| chart.include? "&" }
end
it "should be available as a file" do
File.delete('chart.png') if File.exist?('chart.png')
Gchart.line(:data => [0, 26], :format => 'file')
File.exist?('chart.png').should be_true
File.delete('chart.png') if File.exist?('chart.png')
end
it "should be available as a file using a custom file name" do
File.delete('custom_file_name.png') if File.exist?('custom_file_name.png')
Gchart.line(:data => [0, 26], :format => 'file', :filename => 'custom_file_name.png')
File.exist?('custom_file_name.png').should be_true
File.delete('custom_file_name.png') if File.exist?('custom_file_name.png')
end
it "should work even with multiple attrs" do
File.delete('foo.png') if File.exist?('foo.png')
Gchart.line(:size => '400x200',
:data => [1,2,3,4,5],
# :axis_labels => [[1,2,3,4, 5], %w[foo bar]],
:axis_with_labels => 'x,r',
:format => "file",
:filename => "foo.png"
)
File.exist?('foo.png').should be_true
File.delete('foo.png') if File.exist?('foo.png')
end
end
describe 'SSL support' do
it 'should change url if is presented' do
Gchart.line(:use_ssl => true).should include('https://chart.googleapis.com/chart?')
end
it "should be available as a file" do
File.delete('chart.png') if File.exist?('chart.png')
Gchart.line(:data => [0, 26], :format => 'file', :use_ssl => true)
File.exist?('chart.png').should be_true
File.delete('chart.png') if File.exist?('chart.png')
end
end
googlecharts-1.6.8/spec/theme_spec.rb 0000644 0001750 0001750 00000002632 11750001056 017156 0 ustar boutil boutil require File.dirname(__FILE__) + '/spec_helper.rb'
require File.dirname(__FILE__) + '/../lib/gchart'
describe "generating a default Gchart" do
it 'should be able to add additional theme files' do
Chart::Theme.theme_files.should_not include("#{File.dirname(__FILE__)}/fixtures/another_test_theme.yml")
Chart::Theme.add_theme_file("#{File.dirname(__FILE__)}/fixtures/another_test_theme.yml")
Chart::Theme.theme_files.should include("#{File.dirname(__FILE__)}/fixtures/another_test_theme.yml")
end
it 'should be able to load themes from the additional theme files' do
lambda { Chart::Theme.load(:test_two) }.should_not raise_error
end
it 'should raise ThemeNotFound if theme does not exist' do
lambda { Chart::Theme.load(:nonexistent) }.should raise_error(Chart::Theme::ThemeNotFound, "Could not locate the nonexistent theme ...")
end
it 'should set colors array' do
Chart::Theme.load(:keynote).colors.should eql(["6886B4", "FDD84E", "72AE6E", "D1695E", "8A6EAF", "EFAA43", "FFFFFF", "000000"])
end
it 'should set bar colors array' do
Chart::Theme.load(:keynote).bar_colors.should eql(["6886B4", "FDD84E", "72AE6E", "D1695E", "8A6EAF", "EFAA43"])
end
it 'should set background' do
Chart::Theme.load(:keynote).background.should eql("000000")
end
it 'should set chart background' do
Chart::Theme.load(:keynote).chart_background.should eql("FFFFFF")
end
end googlecharts-1.6.8/spec/fixtures/ 0000755 0001750 0001750 00000000000 11750001056 016363 5 ustar boutil boutil googlecharts-1.6.8/spec/fixtures/another_test_theme.yml 0000644 0001750 0001750 00000000243 11750001056 022766 0 ustar boutil boutil :test_two:
:colors:
- &blue 6886B4
- &yellow FDD84E
- &grey 333333
:bar_colors: [ *blue, *yellow ]
:background: *grey
:chart_background: *grey
googlecharts-1.6.8/spec/fixtures/test_theme.yml 0000644 0001750 0001750 00000000241 11750001056 021244 0 ustar boutil boutil :test:
:colors:
- &blue 6886B4
- &yellow FDD84E
- &white FFFFFF
:bar_colors: [ *blue, *yellow ]
:background: *white
:chart_background: *white googlecharts-1.6.8/spec/spec_helper.rb 0000644 0001750 0001750 00000000142 11750001056 017325 0 ustar boutil boutil begin
require 'rspec'
rescue LoadError
require 'rubygems'
gem 'rspec'
require 'rspec'
end
googlecharts-1.6.8/.gitignore 0000644 0001750 0001750 00000000035 11750001056 015546 0 ustar boutil boutil .DS_Store
log/*
.manifest
pkg googlecharts-1.6.8/License.txt 0000644 0001750 0001750 00000002041 11750001056 015700 0 ustar boutil boutil Copyright (c) 2007 Matt Aimonetti
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.