swagchart 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -5
- data/lib/swagchart/helper.rb +29 -37
- data/lib/swagchart/version.rb +1 -1
- data/swagchart.gemspec +11 -11
- data/test/swagchart_test.rb +43 -17
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0b90ec9a585d353f053ee64cf5c3e7cfa4f11fa
|
4
|
+
data.tar.gz: 9d6698e336db48e4f0bdd24664331c203b8f7b94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4f9bf2efd57e5d1b14249918b8580982f23754890f07aaec7b958b82720bad7e31f1777ca73ba2e9df1197da870740e0244d2af9e84dd6756b518fb729950d5
|
7
|
+
data.tar.gz: b6517a1a50e024544766edb7af8b893f53555dc2bcc00c133bae3e244da98496c3e6f8c46dd7ba77c4b0baba960cc4842a6428af72c85ddd5daf30375d7c9b3f
|
data/Gemfile.lock
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
swagchart (1.
|
4
|
+
swagchart (1.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
-
minitest (5.
|
10
|
-
rake (
|
9
|
+
minitest (5.9.0)
|
10
|
+
rake (11.1.2)
|
11
11
|
|
12
12
|
PLATFORMS
|
13
13
|
ruby
|
14
14
|
|
15
15
|
DEPENDENCIES
|
16
16
|
bundler (~> 1.3)
|
17
|
-
minitest
|
18
|
-
rake
|
17
|
+
minitest (~> 5.9.0)
|
18
|
+
rake (~> 11.1.2)
|
19
19
|
swagchart!
|
20
|
+
|
21
|
+
BUNDLED WITH
|
22
|
+
1.11.2
|
data/lib/swagchart/helper.rb
CHANGED
@@ -5,84 +5,77 @@ require 'securerandom'
|
|
5
5
|
|
6
6
|
module Swagchart
|
7
7
|
module Helper
|
8
|
-
|
9
|
-
|
8
|
+
def default_chart_options(opts = nil)
|
9
|
+
@default_chart_options ||= {}
|
10
|
+
return @default_chart_options unless opts
|
10
11
|
@default_chart_options = opts
|
11
12
|
end
|
12
13
|
|
13
|
-
def chart(type, data, opts={}, &block)
|
14
|
+
def chart(type, data, opts = {}, &block)
|
14
15
|
opts[:options] ||= {}
|
15
|
-
opts[:options] =
|
16
|
+
opts[:options] = default_chart_options.merge(opts[:options])
|
16
17
|
@google_visualization_included ||= false
|
17
18
|
type = camelize(type.to_s)
|
18
|
-
opts[:columns] = opts[:columns].split(',').map(&:strip) if opts[:columns].is_a?(String)
|
19
19
|
data = data.to_a if data.is_a?(Hash)
|
20
|
-
if
|
21
|
-
|
22
|
-
opts
|
23
|
-
elsif data.respond_to?(:unshift) && data.respond_to?(:first) && opts[:columns]
|
24
|
-
data.unshift opts.delete(:columns)
|
20
|
+
if opts[:columns]
|
21
|
+
opts[:columns] = opts[:columns].split(',').map(&:strip) if opts[:columns].is_a?(String)
|
22
|
+
data.unshift opts[:columns]
|
25
23
|
end
|
26
24
|
chart_id = ERB::Util.html_escape(opts.delete(:chart_id) || "chart_#{SecureRandom.uuid}")
|
27
|
-
style = 'height:320px;' #dirty hack right here .. you can override that with your style though
|
25
|
+
style = 'height:320px;' # dirty hack right here .. you can override that with your style though
|
28
26
|
style << ERB::Util.html_escape(opts.delete(:style)) if opts[:style]
|
29
27
|
html = ''
|
30
|
-
unless @google_visualization_included #we only need to include this once
|
28
|
+
unless @google_visualization_included # we only need to include this once
|
31
29
|
html << jsapi_includes_template
|
32
30
|
@google_visualization_included = true
|
33
31
|
end
|
34
32
|
options = opts.delete(:options) || {}
|
35
|
-
html << chart_template(id: chart_id, type: type, style: style, options: options, data: data)
|
33
|
+
html << chart_template(id: chart_id, type: type, style: style, options: options, data: data, columns: opts[:columns])
|
36
34
|
html.respond_to?(:html_safe) ? html.html_safe : html
|
37
35
|
end
|
38
36
|
|
39
37
|
private
|
40
38
|
|
41
|
-
def hash_array_to_data_table(ha)
|
42
|
-
cols = ha.first.keys
|
43
|
-
rows = ha.map{|r| cols.reduce([]){|s,e| s<<r[e]} }
|
44
|
-
[cols, *rows]
|
45
|
-
end
|
46
|
-
|
47
39
|
def camelize(str)
|
48
40
|
str.split('_').each(&:capitalize!).join('')
|
49
41
|
end
|
50
42
|
|
51
|
-
def autocast_data_template
|
43
|
+
def autocast_data_template(opts = {})
|
52
44
|
js = ''
|
53
45
|
js << 'if(Array.isArray(data) && !Array.isArray(data[0])){'
|
54
46
|
js << 'var keys=[], vals=[], row=[]; for(var k in data[0]){keys.push(k)}; for(var d in data){row=[]; for(var k in keys){row.push(data[d][keys[k]])}; vals.push(row)}; vals.unshift(keys); data = vals;'
|
55
|
-
js << '}
|
47
|
+
js << '}'
|
48
|
+
js << 'else{data.unshift(Array(data[0].length).join(".").split("."));}' unless opts[:columns]
|
56
49
|
js << "for(var i=0;i<data.length;i++){for(var j=0;j<data[i].length;j++){if(typeof data[i][j] === 'string'){"
|
57
50
|
js << 'var pd = Date.parse(data[i][j]); if(!isNaN(pd)){data[i][j] = new Date(pd)};'
|
58
|
-
js <<
|
51
|
+
js << '}}};console.log(data);'
|
59
52
|
js
|
60
53
|
end
|
61
54
|
|
62
|
-
def chart_template(opts={})
|
55
|
+
def chart_template(opts = {})
|
63
56
|
html = "<div id='#{opts[:id]}' style='#{opts[:style]}'>Loading...</div>"
|
64
|
-
html <<
|
65
|
-
html <<
|
57
|
+
html << '<script type="text/javascript">'
|
58
|
+
html << 'google.setOnLoadCallback(function(){'
|
66
59
|
chart_js = chart_js_template(opts)
|
67
60
|
html << (opts[:data].is_a?(String) ? async_ajax_load_wrapper(opts[:data], chart_js) : chart_js)
|
68
|
-
html <<
|
61
|
+
html << '});</script>'
|
69
62
|
html
|
70
63
|
end
|
71
64
|
|
72
|
-
def chart_js_template(opts={})
|
65
|
+
def chart_js_template(opts = {})
|
73
66
|
js = ''
|
74
|
-
js << "var data = #{opts[:data]};" unless opts[:data].is_a?(String)
|
75
|
-
js << autocast_data_template
|
76
|
-
js <<
|
67
|
+
js << "var data = #{opts[:data].to_json};" unless opts[:data].is_a?(String)
|
68
|
+
js << autocast_data_template(opts)
|
69
|
+
js << 'var dt = google.visualization.arrayToDataTable(data);'
|
77
70
|
js << "new google.visualization.#{opts[:type]}(document.getElementById('#{opts[:id]}')).draw(dt, #{opts[:options].to_json});"
|
78
71
|
js
|
79
72
|
end
|
80
73
|
|
81
74
|
def async_ajax_load_wrapper(url, js_code)
|
82
|
-
js =
|
83
|
-
js <<
|
84
|
-
js <<
|
85
|
-
js <<
|
75
|
+
js = 'var xhr = new XMLHttpRequest();'
|
76
|
+
js << 'xhr.onreadystatechange = function(){'
|
77
|
+
js << 'if(xhr.readyState === 4) { if(xhr.status>=200 && xhr.status<400){'
|
78
|
+
js << 'var data = JSON.parse(xhr.responseText);'
|
86
79
|
js << js_code
|
87
80
|
js << "}else{ console.log('Could not load data from #{url}. Status ' + xhr.status); }}};"
|
88
81
|
js << "xhr.open('GET', '#{url}'); xhr.send(null);"
|
@@ -94,10 +87,9 @@ module Swagchart
|
|
94
87
|
html << "google.load('visualization', '1');"
|
95
88
|
html << "google.load('visualization', '1', {packages: ["
|
96
89
|
html << "'corechart', 'geochart', 'map', 'treemap', 'annotatedtimeline','sankey', 'orgchart', 'calendar', 'gauge', 'timeline'"
|
97
|
-
html <<
|
98
|
-
html <<
|
90
|
+
html << ']});'
|
91
|
+
html << '</script>'
|
99
92
|
html
|
100
93
|
end
|
101
|
-
|
102
94
|
end
|
103
95
|
end
|
data/lib/swagchart/version.rb
CHANGED
data/swagchart.gemspec
CHANGED
@@ -4,21 +4,21 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'swagchart/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'swagchart'
|
8
8
|
spec.version = Swagchart::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = []
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['pachacamac']
|
10
|
+
spec.email = ['pachacamac@inboxalias.com']
|
11
|
+
spec.description = 'Use Google Charts easily within your Rails or Sinatra project or anywhere really'
|
12
|
+
spec.summary = 'Small Wrapper Around Google CHARTS'
|
13
|
+
spec.homepage = 'https://github.com/pachacamac/swagchart'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
|
+
spec.add_development_dependency 'minitest', '~> 5.9'
|
23
|
+
spec.add_development_dependency 'rake', '~> 11.1'
|
24
24
|
end
|
data/test/swagchart_test.rb
CHANGED
@@ -5,31 +5,57 @@ class TestSwagchart < Minitest::Test
|
|
5
5
|
include Swagchart::Helper
|
6
6
|
|
7
7
|
def test_no_random_exceptions
|
8
|
+
assert chart(:line_chart, [{y: 23, x: 42}, {y: 666, x: 999}])
|
8
9
|
assert chart(:line_chart, [[23, 42], [666, 999]], columns: ['x', 'y'])
|
9
10
|
assert chart(:line_chart, [[23, 42], [666, 999]], columns: ['x', 'y'], style: 'width:100%;')
|
10
11
|
assert chart(:bar_chart, [['x', 'y'],[23, 42], [666, 999]])
|
11
12
|
assert chart('GeoMap', [{'Country'=>'Germany', 'Population'=>8600000}, {'Country'=>'France', 'Population'=>6500000}])
|
12
13
|
end
|
13
14
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
# def test_annotations
|
16
|
+
# c = chart(
|
17
|
+
# :line_chart,
|
18
|
+
# [[0, nil, nil, 5], [1, 'foo', 'Foobar', 2], [2, nil, nil, 6], [3, 'bar', 'Barfoo', 3], [4, nil, nil, 8]],
|
19
|
+
# #[{y: 0, x: 5}, {y: 1, x: 2}, {y: 2, x: 6}, {y: 3, x: 3}, {y: 4, x: 8}],
|
20
|
+
# columns: ['y', {type: 'string', role: 'annotation'}, {type: 'string', role: 'annotationText'}, 'foo'],
|
21
|
+
# options: {annotations: {style: 'line'}}
|
22
|
+
# )
|
23
|
+
# c = "<script type='text/javascript' src='http://www.google.com/jsapi'></script>\n#{c}"
|
24
|
+
# File.write('/tmp/chart.html', c)
|
25
|
+
# `see /tmp/chart.html`
|
26
|
+
# end
|
20
27
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
28
|
+
# def test_normal_chart
|
29
|
+
# c = chart(
|
30
|
+
# :line_chart,
|
31
|
+
# [{y: 1, x: 2},{y: 2, x: 7},{y: 3, x: 4}],
|
32
|
+
# )
|
33
|
+
# c = "<script type='text/javascript' src='http://www.google.com/jsapi'></script>\n#{c}"
|
34
|
+
# File.write('/tmp/chart.html', c)
|
35
|
+
# `see /tmp/chart.html`
|
36
|
+
# end
|
27
37
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
38
|
+
# not relevant anymore since it's parsed in JS
|
39
|
+
|
40
|
+
# def test_time_object_literals
|
41
|
+
# t = Time.parse('2014-12-24 13:37:04')
|
42
|
+
# raw_chart = chart(:line_chart, [[t, 42], [t+3600, 999]], columns: ['x', 'y'])
|
43
|
+
# assert raw_chart.include?('new Date(2014,11,24,13,37,4)') #month starts at 0 in js
|
44
|
+
# assert raw_chart.include?('new Date(2014,11,24,14,37,4)')
|
45
|
+
# end
|
46
|
+
|
47
|
+
# def test_date_object_literals
|
48
|
+
# d1, d2 = Date.new(2014, 12, 24), Date.new(2014, 12, 31)
|
49
|
+
# raw_chart = chart(:line_chart, [[d1, 42], [d2, 999]], columns: ['x', 'y'])
|
50
|
+
# assert raw_chart.include?('new Date(2014,11,24)')
|
51
|
+
# assert raw_chart.include?('new Date(2014,11,31)')
|
52
|
+
# end
|
53
|
+
|
54
|
+
# def test_datetime_object_literals
|
55
|
+
# dt = Time.parse('2014-12-24 13:37:04').to_datetime
|
56
|
+
# raw_chart = chart(:line_chart, [[dt, 42]], columns: ['x', 'y'])
|
57
|
+
# assert raw_chart.include?('new Date(2014,11,24,13,37,4)')
|
58
|
+
# end
|
33
59
|
|
34
60
|
# def test_chart_output
|
35
61
|
# puts chart('GeoMap', [{'Country'=>'Germany', 'Population'=>8600000}, {'Country'=>'France', 'Population'=>6500000}], columns: ['x', 'y'], :hAxis => {title: 'Year'}, style:'width:100%;')
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swagchart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pachacamac
|
8
|
-
- naema
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2016-
|
11
|
+
date: 2016-05-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
@@ -26,36 +25,37 @@ dependencies:
|
|
26
25
|
- !ruby/object:Gem::Version
|
27
26
|
version: '1.3'
|
28
27
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
28
|
+
name: minitest
|
30
29
|
requirement: !ruby/object:Gem::Requirement
|
31
30
|
requirements:
|
32
|
-
- - "
|
31
|
+
- - "~>"
|
33
32
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
33
|
+
version: '5.9'
|
35
34
|
type: :development
|
36
35
|
prerelease: false
|
37
36
|
version_requirements: !ruby/object:Gem::Requirement
|
38
37
|
requirements:
|
39
|
-
- - "
|
38
|
+
- - "~>"
|
40
39
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
40
|
+
version: '5.9'
|
42
41
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
42
|
+
name: rake
|
44
43
|
requirement: !ruby/object:Gem::Requirement
|
45
44
|
requirements:
|
46
|
-
- - "
|
45
|
+
- - "~>"
|
47
46
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
47
|
+
version: '11.1'
|
49
48
|
type: :development
|
50
49
|
prerelease: false
|
51
50
|
version_requirements: !ruby/object:Gem::Requirement
|
52
51
|
requirements:
|
53
|
-
- - "
|
52
|
+
- - "~>"
|
54
53
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
54
|
+
version: '11.1'
|
56
55
|
description: Use Google Charts easily within your Rails or Sinatra project or anywhere
|
57
56
|
really
|
58
|
-
email:
|
57
|
+
email:
|
58
|
+
- pachacamac@inboxalias.com
|
59
59
|
executables: []
|
60
60
|
extensions: []
|
61
61
|
extra_rdoc_files: []
|
@@ -75,7 +75,7 @@ files:
|
|
75
75
|
- swagchart.gemspec
|
76
76
|
- test/swagchart_test.rb
|
77
77
|
- test/test_helper.rb
|
78
|
-
homepage:
|
78
|
+
homepage: https://github.com/pachacamac/swagchart
|
79
79
|
licenses:
|
80
80
|
- MIT
|
81
81
|
metadata: {}
|
@@ -95,7 +95,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
95
|
version: '0'
|
96
96
|
requirements: []
|
97
97
|
rubyforge_project:
|
98
|
-
rubygems_version: 2.
|
98
|
+
rubygems_version: 2.5.1
|
99
99
|
signing_key:
|
100
100
|
specification_version: 4
|
101
101
|
summary: Small Wrapper Around Google CHARTS
|