googlecharts-1.6.8/0000755000175000017500000000000011750001056013560 5ustar boutilboutilgooglecharts-1.6.8/README.markdown0000644000175000017500000002516211750001056016267 0ustar boutilboutilThe 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 ![keynote](http://chart.apis.google.com/chart?chtt=keynote&chco=6886B4,FDD84E,72AE6E,D1695E,8A6EAF,EFAA43&chs=300x200&cht=lc&chd=s:AbGvN,bG2hb,NoUo2,DPXGl,29DUo&chf=c,s,FFFFFF|bg,s,000000) * thirty7signals ![37signals](http://chart.apis.google.com/chart?chtt=thirty7signals&chco=FFF804,336699,339933,ff0000,cc99cc,cf5910&chs=300x200&cht=lc&chd=s:AbGvN,bG2hb,NoUo2,DPXGl,29DUo&chf=bg,s,FFFFFF) * pastel ![pastel](http://chart.apis.google.com/chart?chtt=pastel&chco=a9dada,aedaa9,daaea9,dadaa9,a9a9da&chs=300x200&cht=lc&chd=s:AbGvN,bG2hb,NoUo2,DPXGl,29DUo) * greyscale ![greyscale](http://chart.apis.google.com/chart?chtt=greyscale&chco=282828,383838,686868,989898,c8c8c8,e8e8e8&chs=300x200&cht=lc&chd=s:AbGvN,bG2hb,NoUo2,DPXGl,29DUo) 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|jordangooglecharts-1.6.8/metadata.yml0000644000175000017500000000324211750001056016064 0ustar boutilboutil--- !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.txt0000644000175000017500000000012511750001056015254 0ustar boutilboutilCHECK README.markdown (open as a text file) http://github.com/mattetti/googlechartsgooglecharts-1.6.8/googlecharts.gemspec0000644000175000017500000000140711750001056017610 0ustar boutilboutil# -*- 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/README0000644000175000017500000000000011750001056014426 0ustar boutilboutilgooglecharts-1.6.8/History.txt0000644000175000017500000000340211750001056015761 0ustar boutilboutil== 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/Rakefile0000644000175000017500000000002411750001056015221 0ustar boutilboutilrequire 'rubygems' googlecharts-1.6.8/lib/0000755000175000017500000000000011750001056014326 5ustar boutilboutilgooglecharts-1.6.8/lib/gchart.rb0000644000175000017500000004737011750001056016136 0ustar boutilboutil$:.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 = ", # , # 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.rb0000644000175000017500000000012111750001056017326 0ustar boutilboutilrequire 'gchart' Googlecharts = Gchart unless Object.const_defined? 'Googlechart'googlecharts-1.6.8/lib/themes.yml0000644000175000017500000000205711750001056016342 0ustar boutilboutil#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: *whitegooglecharts-1.6.8/lib/gchart/0000755000175000017500000000000011750001056015576 5ustar boutilboutilgooglecharts-1.6.8/lib/gchart/theme.rb0000644000175000017500000000223711750001056017231 0ustar boutilboutilrequire '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 endgooglecharts-1.6.8/lib/gchart/aliases.rb0000644000175000017500000000071311750001056017545 0ustar boutilboutilclass 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.rb0000644000175000017500000000006311750001056017607 0ustar boutilboutilmodule GchartInfo #:nodoc: VERSION = "1.6.8" end googlecharts-1.6.8/spec/0000755000175000017500000000000011750001056014512 5ustar boutilboutilgooglecharts-1.6.8/spec/gchart_spec.rb0000644000175000017500000007264611750001056017340 0ustar boutilboutilrequire 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(/Google Chart/) end it "should be available as an image tag using img_tag alias" do Gchart.line(:data => [0, 26], :format => 'img_tag').should match(/Google Chart/) 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(/Google Chart/) 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(/Sexy chart/) 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(/Google Chart/) 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(/Google Chart/) 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(/Google Chart/) 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.rb0000644000175000017500000000263211750001056017156 0ustar boutilboutilrequire 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 endgooglecharts-1.6.8/spec/fixtures/0000755000175000017500000000000011750001056016363 5ustar boutilboutilgooglecharts-1.6.8/spec/fixtures/another_test_theme.yml0000644000175000017500000000024311750001056022766 0ustar boutilboutil: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.yml0000644000175000017500000000024111750001056021244 0ustar boutilboutil:test: :colors: - &blue 6886B4 - &yellow FDD84E - &white FFFFFF :bar_colors: [ *blue, *yellow ] :background: *white :chart_background: *whitegooglecharts-1.6.8/spec/spec_helper.rb0000644000175000017500000000014211750001056017325 0ustar boutilboutilbegin require 'rspec' rescue LoadError require 'rubygems' gem 'rspec' require 'rspec' end googlecharts-1.6.8/.gitignore0000644000175000017500000000003511750001056015546 0ustar boutilboutil.DS_Store log/* .manifest pkggooglecharts-1.6.8/License.txt0000644000175000017500000000204111750001056015700 0ustar boutilboutilCopyright (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.