gvis 2.0.4 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  *.gem
2
2
  .bundle
3
3
  Gemfile.lock
4
+ gemfiles/*.lock
4
5
  pkg/*
5
6
  .yardoc/*
6
7
  doc/*
@@ -1,13 +1,20 @@
1
1
  language: ruby
2
+ script: "bundle exec rake test_with_coveralls"
2
3
  rvm:
3
- - 1.8.7
4
4
  - 1.9.2
5
5
  - 1.9.3
6
- - jruby-18mode # JRuby in 1.8 mode
7
- - jruby-19mode # JRuby in 1.9 mode
8
- - rbx-18mode
6
+ - 2.0.0
7
+ - jruby-19mode
9
8
  - rbx-19mode
10
- - ruby-head
9
+ gemfile:
10
+ - gemfiles/3.0.gemfile
11
+ - gemfiles/3.1.gemfile
12
+ - gemfiles/3.2.gemfile
13
+ # - gemfiles/4.0.gemfile
14
+ branches:
15
+ only:
16
+ - master
17
+ - develop
11
18
  notifications:
12
19
  recipients:
13
20
  - jeremy.olliver@gmail.com
@@ -0,0 +1,19 @@
1
+ appraise "rails3.0" do
2
+ gem 'activesupport', '~> 3.0'
3
+ gem 'actionpack', '~> 3.0'
4
+ end
5
+
6
+ appraise "rails3.1" do
7
+ gem 'activesupport', '~> 3.1'
8
+ gem 'actionpack', '~> 3.1'
9
+ end
10
+
11
+ appraise "rails3.2" do
12
+ gem 'activesupport', '~> 3.2'
13
+ gem 'actionpack', '~> 3.2'
14
+ end
15
+
16
+ appraise "rails4.0" do
17
+ gem 'activesupport', '~> 4.0'
18
+ gem 'actionpack', '~> 4.0'
19
+ end
@@ -1,6 +1,13 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 2.1.0
5
+ -----
6
+
7
+ * Support loading javascript via https (if the page is https)
8
+ * escapes single quotes within values/id's
9
+ * Official Support for 1.8.7 dropped (may, or may not work)
10
+
4
11
  2.0.4
5
12
  -----
6
13
 
@@ -41,4 +48,4 @@ Changelog
41
48
  1.0.0
42
49
  -----
43
50
 
44
- * Initial release (As rails plugin)
51
+ * Initial release (As rails plugin)
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
- Gvis [![Build Status](https://secure.travis-ci.org/jeremyolliver/gvis.png)](http://travis-ci.org/jeremyolliver/gvis)
1
+ Gvis
2
2
  ====
3
3
 
4
+ [![Gem Version](https://badge.fury.io/rb/gvis.png)](http://badge.fury.io/rb/gvis) : Latest published version on [rubygems.org](https://rubygems.org/gems/gvis/)
5
+
6
+ [![Build Status](https://secure.travis-ci.org/jeremyolliver/gvis.png)](http://travis-ci.org/jeremyolliver/gvis) [![Coverage Status](https://coveralls.io/repos/jeremyolliver/gvis/badge.png?branch=master)](https://coveralls.io/r/jeremyolliver/gvis) [![Code Climate](https://codeclimate.com/github/jeremyolliver/gvis.png)](https://codeclimate.com/github/jeremyolliver/gvis) Current master branch status
7
+
4
8
  Rails plugin that provides a Ruby wrapper for easily loading the Google Visualization API, and simple generation of the javascript required to plot the graphs
5
9
  For a full list of the graphs provided by google's visualization api see the [gallery](http://code.google.com/apis/visualization/documentation/gallery.html)
6
10
  For documentation on how to use each graph type see google's [API documentation](http://code.google.com/apis/visualization/documentation/)
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
3
 
4
+ require 'appraisal'
5
+
4
6
  require 'rake/testtask'
5
7
  Rake::TestTask.new(:test) do |test|
6
8
  test.libs << 'lib' << 'test'
@@ -9,3 +11,8 @@ Rake::TestTask.new(:test) do |test|
9
11
  end
10
12
 
11
13
  task :default => :test
14
+
15
+ # Pushes test coverage results to coveralls.io, we will only do this during CI builds
16
+ require 'coveralls/rake/task'
17
+ Coveralls::RakeTask.new
18
+ task :test_with_coveralls => [:test, 'coveralls:push']
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.0"
6
+ gem "actionpack", "~> 3.0"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.1"
6
+ gem "actionpack", "~> 3.1"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 3.2"
6
+ gem "actionpack", "~> 3.2"
7
+
8
+ gemspec :path=>"../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "http://rubygems.org"
4
+
5
+ gem "activesupport", "~> 4.0"
6
+ gem "actionpack", "~> 4.0"
7
+
8
+ gemspec :path=>"../"
@@ -16,13 +16,14 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.require_paths = ["lib"]
18
18
 
19
- s.add_dependency 'json'
19
+ # Gem dependencies
20
+ s.add_runtime_dependency 'json'
20
21
 
22
+ # Gem development/test dependencies
21
23
  s.add_development_dependency 'rake'
22
24
  s.add_development_dependency 'bundler'
23
25
  s.add_development_dependency 'minitest'
24
- s.add_development_dependency 'simplecov'
25
- # Although this runs on rails 3, I'm only specifying this as development dependency for now,
26
- # (instead of runtime dependency) since rails can be vendored and need not be installed/required as gems
27
- s.add_development_dependency 'actionpack', '> 3.0.0'
26
+ s.add_development_dependency 'coveralls'
27
+ s.add_development_dependency 'appraisal'
28
+ s.add_development_dependency 'actionpack', '> 3.0.0' # For rendering test views
28
29
  end
@@ -14,7 +14,8 @@ module GoogleVisualization
14
14
  # Include the Visualization API code from google.
15
15
  # (Omit this call if you prefer to include the API in your own js package)
16
16
  def include_visualization_api
17
- javascript_include_tag("http://www.google.com/jsapi")
17
+ # Ensure we use https when the page is loaded on https so we don't make the page look insecure
18
+ javascript_include_tag("//www.google.com/jsapi")
18
19
  end
19
20
 
20
21
  # Call this method from the within the head tag (or alternately just before the closing body tag)
@@ -70,7 +71,7 @@ module GoogleVisualization
70
71
 
71
72
  # Output a div with given id on the page right now, that our graph will be embedded into
72
73
  html = html_options.collect {|key,value| "#{key}=\"#{value}\"" }.join(" ")
73
- concat raw(%Q(<div id="#{id}" #{html}><!-- /--></div>))
74
+ concat raw(%Q(<div id="#{escape_id(id)}" #{html}><!-- /--></div>))
74
75
  nil # Return nil just incase this is called with an output erb tag, as we don't to output the html twice
75
76
  end
76
77
 
@@ -90,16 +91,16 @@ module GoogleVisualization
90
91
  # @return [String] javascript that creates the chart, and adds it to the window variable
91
92
  def generate_visualization(id, chart_type, table, options={})
92
93
  # Generate the js chart data
93
- output = "chartData['#{id}'] = new google.visualization.DataTable();"
94
+ output = "chartData['#{escape_id(id)}'] = new google.visualization.DataTable();"
94
95
  table.columns.each do |col|
95
- output += "chartData['#{id}'].addColumn('#{table.column_types[col]}', '#{col}');"
96
+ output += "chartData['#{escape_id(id)}'].addColumn('#{escape(table.column_types[col])}', '#{escape(col)}');"
96
97
  end
97
98
  option_str = parse_options(options)
98
99
 
99
100
  output += %Q(
100
- chartData['#{id}'].addRows(#{table.format_data});
101
- visualizationCharts['#{id}'] = new google.visualization.#{chart_type.to_s.camelize}(document.getElementById('#{id}'));
102
- visualizationCharts['#{id}'].draw(chartData['#{id}'], {#{option_str}});
101
+ chartData['#{escape_id(id)}'].addRows(#{table.format_data});
102
+ visualizationCharts['#{escape_id(id)}'] = new google.visualization.#{chart_type.to_s.camelize}(document.getElementById('#{escape_id(id)}'));
103
+ visualizationCharts['#{escape_id(id)}'].draw(chartData['#{escape_id(id)}'], {#{option_str}});
103
104
  )
104
105
  end
105
106
 
@@ -112,9 +113,9 @@ module GoogleVisualization
112
113
  if val.kind_of? Hash
113
114
  str += "{" + parse_options(val) + "}"
114
115
  elsif val.kind_of? Array
115
- str += "[ " + val.collect { |v| "'#{v}'" }.join(", ") + " ]"
116
+ str += "[ " + val.collect { |v| "'#{escape(v)}'" }.join(", ") + " ]"
116
117
  else
117
- str += (val.kind_of?(String) ? "'#{val}'" : val.to_s)
118
+ str += Gvis::DataCell.new(val).to_js
118
119
  end
119
120
  str
120
121
  end.join(',')
@@ -136,4 +137,18 @@ module GoogleVisualization
136
137
  debugging
137
138
  end
138
139
 
139
- end
140
+ def escape(s)
141
+ if s
142
+ ERB::Util.json_escape(s)
143
+ end
144
+ end
145
+
146
+ def escape_id(id)
147
+ if id
148
+ # Let's be extra strict and validate for characters allowed in HTML id attribute.
149
+ # Allow word characters (letters and underscores), digits, dashes, colons and periods.
150
+ id.gsub(/[^\w\d\-\:\.]/, "_")
151
+ end
152
+ end
153
+
154
+ end
@@ -1,2 +1,3 @@
1
1
  require 'gvis/data_table'
2
+ require 'gvis/data_cell'
2
3
  require 'google_visualization'
@@ -0,0 +1,38 @@
1
+ # This is an internal class intended for use by the helper methods present in the {GoogleVisualization} class.
2
+ #
3
+ # Converts a Ruby object into a string containing valid javascript for 'string' 'number' 'boolean' 'date' 'datetime' 'timeofday' types
4
+ # http://code.google.com/apis/chart/interactive/docs/reference.html#DataTable_getValue
5
+ #
6
+ # @author Jeremy Olliver
7
+ module Gvis
8
+ class DataCell
9
+ attr_accessor :value
10
+ attr_accessor :type
11
+
12
+ def initialize(value, type = '')
13
+ @value = value
14
+ @type = type
15
+ end
16
+
17
+ def to_js
18
+ # Format/escape individual values for javascript, checking column types, and the ruby value as a failsafe
19
+ if @type == "datetime" || @value.is_a?(DateTime)
20
+ # Format a DateTime as a javascript date object down to seconds
21
+ @value.is_a?(DateTime) ? "new Date (#{@value.year},#{@value.month - 1},#{@value.day},#{@value.hour},#{@value.min},#{@value.sec})" : @value.to_json
22
+ elsif @type == "date" || @value.is_a?(Date)
23
+ # Format a Date object as a javascript date
24
+ @value.is_a?(Date) ? "new Date (#{@value.year},#{@value.month - 1},#{@value.day})" : @value.to_json
25
+ elsif @type == "timeofday" || @value.is_a?(Time)
26
+ # Format a Time as a javascript date object down to milliseconds
27
+ @value.is_a?(Time) ? "[#{@value.hour},#{@value.min},#{@value.sec},#{@value.usec}]" : @value.to_json
28
+ else
29
+ # Non date/time values can be JS escaped/formatted safely with # to_json
30
+ @value.to_json
31
+ end
32
+ end
33
+
34
+ def to_s
35
+ @value.to_s
36
+ end
37
+ end
38
+ end
@@ -8,7 +8,7 @@ module Gvis
8
8
 
9
9
  require 'json'
10
10
 
11
- COLUMN_TYPES = ["string", "number", "date", "datetime"]
11
+ COLUMN_TYPES = ["string", "number", "date", "datetime", "timeofday"]
12
12
 
13
13
  attr_accessor :data, :table_columns, :column_types
14
14
 
@@ -74,18 +74,7 @@ module Gvis
74
74
  @data.each do |row|
75
75
  values = []
76
76
  row.each_with_index do |entry,index|
77
- # Format/escape individual values for javascript, checking column types, and the ruby value as a failsafe
78
- safe_val = if @column_types[index] == "date" || entry.is_a?(Date)
79
- # Format a date object as a javascript date
80
- entry.is_a?(String) ? entry : "new Date (#{entry.year},#{entry.month - 1},#{entry.day})"
81
- elsif @column_types[index] == "datetime" || entry.is_a?(Time)
82
- # Format a Time (datetime) as a javascript date object down to seconds
83
- entry.is_a?(String) ? entry : "new Date (#{entry.year},#{entry.month - 1},#{entry.day},#{entry.hour},#{entry.min},#{entry.sec})"
84
- else
85
- # Non date/time values can be JS escaped/formatted safely with # to_json
86
- entry.to_json
87
- end
88
- values << safe_val
77
+ values << Gvis::DataCell.new(entry, @column_types.to_a[index][1]).to_js
89
78
  end
90
79
  rowstring = "[#{values.join(", ")}]"
91
80
  formatted_rows << rowstring
@@ -1,3 +1,3 @@
1
1
  module Gvis
2
- VERSION = "2.0.4"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,5 +1,5 @@
1
- require 'simplecov'
2
- SimpleCov.start
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
3
 
4
4
  require 'minitest/unit'
5
5
 
@@ -8,7 +8,7 @@ class TestDataTable < MiniTest::Unit::TestCase
8
8
 
9
9
  def test_attributes_methods_and_constants
10
10
  assert defined?(Gvis::DataTable::COLUMN_TYPES)
11
- assert_equal ["string", "number", "date", "datetime"], Gvis::DataTable::COLUMN_TYPES
11
+ assert_equal ["string", "number", "date", "datetime", "timeofday"], Gvis::DataTable::COLUMN_TYPES
12
12
  defined_attributes = [:data, :table_columns, :column_types]
13
13
  defined_attributes.each do |a|
14
14
  assert @table.respond_to?(a), "DataTable should have attribute #{a} defined"
@@ -52,11 +52,12 @@ class TestDataTable < MiniTest::Unit::TestCase
52
52
  end
53
53
 
54
54
  def test_formatting_data
55
- @table.columns = [["Name", "String"], ["age", "number"], ["dob", "date"], ["now", "datetime"]]
56
- now = Time.utc(2011,1,23,11,30,4)
57
- @table.add_rows([["Jeremy Olliver", 23, Date.new(2011,1,1), now], ["Optimus Prime", 1000, Date.new(1980,2,23), now], ["'The MegaTron'", 999, Date.new(1981,1,1), now]])
55
+ @table.columns = [["Name", "String"], ["age", "number"], ["dob", "date"], ["now", "datetime"], ["time", "timeofday"]]
56
+ now_datetime = DateTime.new(2011,1,23,11,30,4)
57
+ now_time = Time.utc(2011,01,23,02,45,43,21)
58
+ @table.add_rows([["Jeremy Olliver", 23, Date.new(2011,1,1), now_datetime, now_time], ["Optimus Prime", 1000, Date.new(1980,2,23), now_datetime, now_time], ["'The MegaTron'", 999, Date.new(1981,1,1), now_datetime, now_time]])
58
59
 
59
- assert_equal %q([["Jeremy Olliver", 23, new Date (2011,0,1), new Date (2011,0,23,11,30,4)], ["Optimus Prime", 1000, new Date (1980,1,23), new Date (2011,0,23,11,30,4)], ["'The MegaTron'", 999, new Date (1981,0,1), new Date (2011,0,23,11,30,4)]]), @table.format_data
60
+ assert_equal %q([["Jeremy Olliver", 23, new Date (2011,0,1), new Date (2011,0,23,11,30,4), [2,45,43,21]], ["Optimus Prime", 1000, new Date (1980,1,23), new Date (2011,0,23,11,30,4), [2,45,43,21]], ["'The MegaTron'", 999, new Date (1981,0,1), new Date (2011,0,23,11,30,4), [2,45,43,21]]]), @table.format_data
60
61
  end
61
62
 
62
63
  end
@@ -58,4 +58,15 @@ class TestGoogleVisualization < MiniTest::Unit::TestCase
58
58
  assert_match("<div id=\"my_chart\"", output, "The graph div should exist on the page")
59
59
  end
60
60
 
61
+ def test_annotated_timeline
62
+ output = @view.render("test/views/_annotatedtimeline.html.erb")
63
+ assert_match("'packages':['annotatedtimeline']", output, "the annotated timeline package should have been loaded")
64
+ assert_match("<div id=\"my_chart\"", output, "The graph div should exist on the page")
65
+ assert_match("zoomStartTime: new Date (2011,0,1)", output, "The a zoomStartTime date option should exist on the page")
66
+ assert_match("thickness: 11", output, "The a thickness number option should exist on the page")
67
+ assert_match("displayZoomButtons: true", output, "The a displayZoomButtons boolean option should exist on the page")
68
+ assert_match("timeofdayTest: [1,2,3,4]", output, "The a timeofDayTest timeofday option should exist on the page")
69
+ assert_match("nullTest: null", output, "The a nullTest null option should exist on the page")
70
+ end
71
+
61
72
  end
@@ -0,0 +1,15 @@
1
+ <% visualization "my_chart", "AnnotatedTimeline", :width => 600, :height => 400, :thickness => 11, :displayZoomButtons => true, :timeofdayTest => Time.utc(2000,"jan",1,1,2,3,4), :nullTest => nil, :zoomStartTime => Date.new(2011,01,01), :html => {:style => 'width:600px; height:300px', :class => "graph_chart"} do |chart| %>
2
+ <%# Add the columns that the graph will have %>
3
+ <% chart.date "Date" %>
4
+ <% chart.number "Sales" %>
5
+
6
+ <%# Add the data %>
7
+ <% chart.add_rows([
8
+ [Date.new(1998,1,1), 1000],
9
+ [Date.new(1998,1,1), 950],
10
+ [Date.new(1998,1,1), 300],
11
+ [Date.new(1998,2,1), 1200],
12
+ [Date.new(1998,2,1), 950],
13
+ [Date.new(1998,2,1), 788]
14
+ ]) %>
15
+ <% end %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gvis
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-11 00:00:00.000000000 Z
12
+ date: 2013-09-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -76,7 +76,23 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: simplecov
79
+ name: coveralls
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: appraisal
80
96
  requirement: !ruby/object:Gem::Requirement
81
97
  none: false
82
98
  requirements:
@@ -114,21 +130,29 @@ executables: []
114
130
  extensions: []
115
131
  extra_rdoc_files: []
116
132
  files:
133
+ - .coveralls.yml
117
134
  - .gitignore
118
135
  - .travis.yml
136
+ - Appraisals
119
137
  - CHANGELOG.md
120
138
  - Gemfile
121
139
  - MIT-LICENSE
122
140
  - README.md
123
141
  - Rakefile
142
+ - gemfiles/rails3.0.gemfile
143
+ - gemfiles/rails3.1.gemfile
144
+ - gemfiles/rails3.2.gemfile
145
+ - gemfiles/rails4.0.gemfile
124
146
  - gvis.gemspec
125
147
  - lib/google_visualization.rb
126
148
  - lib/gvis.rb
149
+ - lib/gvis/data_cell.rb
127
150
  - lib/gvis/data_table.rb
128
151
  - lib/gvis/version.rb
129
152
  - test/helper.rb
130
153
  - test/test_data_table.rb
131
154
  - test/test_google_visualization.rb
155
+ - test/views/_annotatedtimeline.html.erb
132
156
  - test/views/_corechart.html.erb
133
157
  - test/views/_motionchart.html.erb
134
158
  - test/views/layout.html.erb
@@ -160,6 +184,8 @@ test_files:
160
184
  - test/helper.rb
161
185
  - test/test_data_table.rb
162
186
  - test/test_google_visualization.rb
187
+ - test/views/_annotatedtimeline.html.erb
163
188
  - test/views/_corechart.html.erb
164
189
  - test/views/_motionchart.html.erb
165
190
  - test/views/layout.html.erb
191
+ has_rdoc: