<commit_before>$:.unshift File.dirname(__FILE__)
require 'gchart/version'
require 'gchart/theme'
require "open-uri"
require "uri"
require "cgi"
require 'enumerator'

class Gchart
  include GchartInfo
  
  def self.url
    "http://chart.apis.google.com/chart?" 
  end
  
  def self.types
    @types ||= ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map']
  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, :horizontal, :grouped, :legend, :data, :encoding, :min_value, :max_value, :bar_colors,
                :title_color, :title_size, :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
  
  attr_accessor :bg_type, :bg_color, :bg_angle, :chart_type, :chart_color, :chart_angle, :axis_range
  
  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] ||= Gchart.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 version
    Gchart::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
    @horizontal = false
    @grouped = false
    @encoding = 'simple'
    @max_value = 'auto'
    @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.to_s}=", value) if self.respond_to?("#{attribute}=")
    end
  end
  
  def self.supported_types
    Gchart.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
  
  # 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
  
  # returns the full data range as an array
  # it also sets the data range if not defined
  def full_data_range(ds)
    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_value == 'auto') 
      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  
    end 
    @axis_range = [[@min,@max]]
  end
  
  def dataset
    if @dataset
     @dataset 
    else
      @dataset = prepare_dataset(data)
      full_data_range(dataset) unless axis_range
      @dataset
    end
  end
  
  def self.jstize(string)
    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
    open(query_builder) { |io| io.read }
  end

  # Writes the chart's generated PNG to a file. (borrowed from John's gchart.rubyforge.org)
  def write
    io_or_file = filename || Gchart.default_filename
    return io_or_file.write(fetch) if io_or_file.respond_to?(:write)<commit_msg>Don't escape '|' in url<commit_after>$:.unshift File.dirname(__FILE__)
require 'gchart/version'
require 'gchart/theme'
require "open-uri"
require "uri"
require "cgi"
require 'enumerator'

class Gchart
  include GchartInfo
  
  def self.url
    "http://chart.apis.google.com/chart?" 
  end
  
  def self.types
    @types ||= ['line', 'line_xy', 'scatter', 'bar', 'venn', 'pie', 'pie_3d', 'jstize', 'sparkline', 'meter', 'map']
  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, :horizontal, :grouped, :legend, :data, :encoding, :min_value, :max_value, :bar_colors,
                :title_color, :title_size, :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
  
  attr_accessor :bg_type, :bg_color, :bg_angle, :chart_type, :chart_color, :chart_angle, :axis_range
  
  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] ||= Gchart.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 version
    Gchart::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
    @horizontal = false
    @grouped = false
    @encoding = 'simple'
    @max_value = 'auto'
    @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.to_s}=", value) if self.respond_to?("#{attribute}=")
    end
  end
  
  def self.supported_types
    Gchart.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
  
  # 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
  
  # returns the full data range as an array
  # it also sets the data range if not defined
  def full_data_range(ds)
    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_value == 'auto') 
      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  
    end 
    @axis_range = [[@min,@max]]
  end
  
  def dataset
    if @dataset
     @dataset 
    else
      @dataset = prepare_dataset(data)
      full_data_range(dataset) unless axis_range
      @dataset
    end
  end
  
  def self.jstize(string)
    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
    open(query_builder) { |io| io.read }
  end

  # Writes the chart's generated PNG to a file. (borrowed from John's gchart.rubyforge.org)
  def write
    io_or_file = filename || Gchart.default_filename
    return io_or_file.write(fetch) if io_or_file.respond_to?(:write)
{'fraction_non_alphanumeric': 0.13744700894959963, 'fraction_numerical': 0.004333490343853038, 'mean_word_length': 3.0612088752869164, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2585928', 'n_tokens_mistral': 3715, 'n_tokens_neox': 3627, 'n_words': 958}