rorschart 0.8.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rorschart/google_chart_mapper.rb +45 -0
- data/lib/rorschart/google_chart_options.rb +81 -0
- data/lib/rorschart/helper.rb +43 -232
- data/lib/rorschart/multiple_series.rb +71 -0
- data/lib/rorschart/pivot_data.rb +88 -0
- data/lib/rorschart/version.rb +1 -1
- data/lib/rorschart.rb +1 -0
- data/test/{rorschart_test.rb → google_chart_mapper_test.rb} +107 -33
- data/test/pivot_data_test.rb +33 -0
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a74ccb096f456a6ede1d3842a61e149d6245b46
|
4
|
+
data.tar.gz: ac5be7dcb098e4501fe559d7866833e9a35ff92e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0a54a4e71280208bb2485d6f3da251e34c3bd22c1719d9672a41b9c74aa5a5f35cbd5c426f2d4cfaa02c1fada2dcf422c10e34f32eefce0cc12e0f5cb96cdfeb
|
7
|
+
data.tar.gz: 2168376181ca0e094c06d49ef0055db98747efa87419bf48d0a3b4d5a5506a29f59f9568b57d493b69823f46b40346637a43178ebe7f18b89dd3f5f8d5142bf9
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
module Rorschart
|
2
|
+
module GoogleChart
|
3
|
+
module Mapper
|
4
|
+
|
5
|
+
require 'rorschart/pivot_data'
|
6
|
+
|
7
|
+
def format_if_needed(data_source)
|
8
|
+
data_source.is_a?(String) ? data_source : to_datatable_format(data_source)
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_datatable_format(data)
|
12
|
+
|
13
|
+
return data if is_already_converted? data
|
14
|
+
|
15
|
+
if (data.is_a? Rorschart::MultipleSeries)
|
16
|
+
pivot = data
|
17
|
+
else
|
18
|
+
pivot = PivotData.new(data)
|
19
|
+
pivot.sort_by_date!
|
20
|
+
end
|
21
|
+
|
22
|
+
return {cols: pivot.cols, rows: add_rows(pivot.rows) }
|
23
|
+
end
|
24
|
+
|
25
|
+
def is_already_converted?(data)
|
26
|
+
(data.class == Hash) and (data.keys == ["cols", "rows"])
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_rows(rows)
|
30
|
+
rows.map{|row|
|
31
|
+
{"c" =>
|
32
|
+
row.map{|col|
|
33
|
+
{"v" => col}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def chart_class_from_string(klass_symbol)
|
40
|
+
"google.visualization." + klass_symbol.to_s
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Rorschart
|
2
|
+
module GoogleChart
|
3
|
+
module Options
|
4
|
+
|
5
|
+
def default_options
|
6
|
+
{
|
7
|
+
fontName: "'Helvetica Neue', Helvetica, Arial, sans-serif",
|
8
|
+
pointSize: 8,
|
9
|
+
lineWidth: 3,
|
10
|
+
chartArea: {
|
11
|
+
width: '100%',
|
12
|
+
height: '70%'
|
13
|
+
},
|
14
|
+
titlePosition: 'out',
|
15
|
+
axisTitlesPosition: 'in',
|
16
|
+
legend: {
|
17
|
+
textStyle: {
|
18
|
+
fontSize: 12,
|
19
|
+
color: "#444"
|
20
|
+
},
|
21
|
+
alignment: "end",
|
22
|
+
position: "top"
|
23
|
+
},
|
24
|
+
curveType: "function",
|
25
|
+
hAxis: {
|
26
|
+
textStyle: {
|
27
|
+
color: "#666",
|
28
|
+
fontSize: 12
|
29
|
+
},
|
30
|
+
gridlines: {
|
31
|
+
color: "transparent"
|
32
|
+
},
|
33
|
+
baselineColor: "#ccc",
|
34
|
+
viewWindow: {}
|
35
|
+
},
|
36
|
+
vAxis: {
|
37
|
+
textStyle: {
|
38
|
+
color: "#666",
|
39
|
+
fontSize: 12
|
40
|
+
},
|
41
|
+
textPosition: 'in',
|
42
|
+
baselineColor: "#ccc",
|
43
|
+
viewWindow: {}
|
44
|
+
},
|
45
|
+
tooltip: {
|
46
|
+
textStyle: {
|
47
|
+
color: "#666",
|
48
|
+
fontSize: 12
|
49
|
+
}
|
50
|
+
},
|
51
|
+
#A nice Color Scheme from http://www.colourlovers.com/palettes/top
|
52
|
+
colors: ['#00A0B0', '#6A4A3C', '#CC333F', '#EB6841', '#EDC951'],
|
53
|
+
# colors: ['#F8FCC1', '#CC0C39', '#E6781E', '#C8CF02', '#1693A7'],
|
54
|
+
allowHtml: true
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def chart_options(klass_symbol)
|
59
|
+
{
|
60
|
+
"Table" => {
|
61
|
+
cssClassNames: {
|
62
|
+
tableRow: 'table_row',
|
63
|
+
headerRow: 'header_row',
|
64
|
+
headerCell: 'header_cel'
|
65
|
+
},
|
66
|
+
height: "100%"
|
67
|
+
},
|
68
|
+
"AreaChart" => {
|
69
|
+
isStacked: true,
|
70
|
+
},
|
71
|
+
"PieChart" => {
|
72
|
+
legend: {
|
73
|
+
alignment: "start",
|
74
|
+
position: "right"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}[klass_symbol] || {}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/rorschart/helper.rb
CHANGED
@@ -1,125 +1,53 @@
|
|
1
1
|
require "json"
|
2
2
|
require "erb"
|
3
|
+
require "rorschart/google_chart_mapper"
|
4
|
+
require "rorschart/google_chart_options"
|
3
5
|
|
4
6
|
module Rorschart
|
5
|
-
module Helper
|
6
|
-
|
7
|
-
def default_options
|
8
|
-
{
|
9
|
-
fontName: "'Helvetica Neue', Helvetica, Arial, sans-serif",
|
10
|
-
pointSize: 8,
|
11
|
-
lineWidth: 3,
|
12
|
-
chartArea: {
|
13
|
-
width: '100%',
|
14
|
-
height: '70%'
|
15
|
-
},
|
16
|
-
titlePosition: 'out',
|
17
|
-
axisTitlesPosition: 'in',
|
18
|
-
legend: {
|
19
|
-
textStyle: {
|
20
|
-
fontSize: 12,
|
21
|
-
color: "#444"
|
22
|
-
},
|
23
|
-
alignment: "end",
|
24
|
-
position: "top"
|
25
|
-
},
|
26
|
-
curveType: "function",
|
27
|
-
hAxis: {
|
28
|
-
textStyle: {
|
29
|
-
color: "#666",
|
30
|
-
fontSize: 12
|
31
|
-
},
|
32
|
-
gridlines: {
|
33
|
-
color: "transparent"
|
34
|
-
},
|
35
|
-
baselineColor: "#ccc",
|
36
|
-
viewWindow: {}
|
37
|
-
},
|
38
|
-
vAxis: {
|
39
|
-
textStyle: {
|
40
|
-
color: "#666",
|
41
|
-
fontSize: 12
|
42
|
-
},
|
43
|
-
textPosition: 'in',
|
44
|
-
baselineColor: "#ccc",
|
45
|
-
viewWindow: {}
|
46
|
-
},
|
47
|
-
tooltip: {
|
48
|
-
textStyle: {
|
49
|
-
color: "#666",
|
50
|
-
fontSize: 12
|
51
|
-
}
|
52
|
-
},
|
53
|
-
#A nice Color Scheme from http://www.colourlovers.com/palettes/top
|
54
|
-
colors: ['#00A0B0', '#6A4A3C', '#CC333F', '#EB6841', '#EDC951'],
|
55
|
-
# colors: ['#F8FCC1', '#CC0C39', '#E6781E', '#C8CF02', '#1693A7'],
|
56
|
-
allowHtml: true
|
57
|
-
}
|
58
|
-
end
|
59
|
-
|
60
|
-
def chart_options(klass_symbol)
|
61
|
-
{
|
62
|
-
"Table" => {
|
63
|
-
cssClassNames: {
|
64
|
-
tableRow: 'table_row',
|
65
|
-
headerRow: 'header_row',
|
66
|
-
headerCell: 'header_cel'
|
67
|
-
},
|
68
|
-
height: "100%"
|
69
|
-
},
|
70
|
-
"AreaChart" => {
|
71
|
-
isStacked: true,
|
72
|
-
},
|
73
|
-
"PieChart" => {
|
74
|
-
legend: {
|
75
|
-
alignment: "start",
|
76
|
-
position: "right"
|
77
|
-
}
|
78
|
-
}
|
79
|
-
}[klass_symbol] || {}
|
80
|
-
end
|
81
7
|
|
82
|
-
|
83
|
-
|
84
|
-
|
8
|
+
module Helper
|
9
|
+
|
10
|
+
def line_chart(data_source, options = {})
|
11
|
+
rorschart_chart "LineChart", data_source, options
|
12
|
+
end
|
85
13
|
|
86
|
-
|
87
|
-
|
88
|
-
|
14
|
+
def pie_chart(data_source, options = {})
|
15
|
+
rorschart_chart "PieChart", data_source, options
|
16
|
+
end
|
89
17
|
|
90
|
-
|
91
|
-
|
92
|
-
|
18
|
+
def column_chart(data_source, options = {})
|
19
|
+
rorschart_chart "ColumnChart", data_source, options
|
20
|
+
end
|
93
21
|
|
94
|
-
|
95
|
-
|
96
|
-
|
22
|
+
def bar_chart(data_source, options = {})
|
23
|
+
rorschart_chart "BarChart", data_source, options
|
24
|
+
end
|
97
25
|
|
98
|
-
|
99
|
-
|
100
|
-
|
26
|
+
def area_chart(data_source, options = {})
|
27
|
+
rorschart_chart "AreaChart", data_source, options
|
28
|
+
end
|
101
29
|
|
102
|
-
|
103
|
-
|
104
|
-
|
30
|
+
def table_chart(data_source, options = {})
|
31
|
+
rorschart_chart "Table", data_source, options
|
32
|
+
end
|
105
33
|
|
106
|
-
|
107
|
-
|
108
|
-
|
34
|
+
def geo_chart(data_source, options = {})
|
35
|
+
rorschart_chart "GeoChart", data_source, options
|
36
|
+
end
|
109
37
|
|
110
|
-
|
111
|
-
|
112
|
-
|
38
|
+
def to_chart(data_source)
|
39
|
+
to_datatable_format(data_source).to_json
|
40
|
+
end
|
113
41
|
|
114
|
-
|
42
|
+
def rorschart_chart(klass_name, dataSource, options = {})
|
115
43
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
44
|
+
dataSource = format_if_needed(dataSource)
|
45
|
+
element_id = options.delete(:id) || generateChartId
|
46
|
+
options = default_options.merge(chart_options(klass_name)).deep_merge(options);
|
47
|
+
height = options.delete(:height) || "300px"
|
120
48
|
|
121
|
-
|
122
|
-
|
49
|
+
html = <<HTML
|
50
|
+
<div id="#{ERB::Util.html_escape(element_id)}" style="height: #{ERB::Util.html_escape(height)}; width:100%;">
|
123
51
|
Rorchart is not initialized.
|
124
52
|
</div>
|
125
53
|
HTML
|
@@ -130,135 +58,18 @@ HTML
|
|
130
58
|
</script>
|
131
59
|
JS
|
132
60
|
|
133
|
-
|
134
|
-
end
|
135
|
-
|
136
|
-
private
|
137
|
-
|
138
|
-
|
139
|
-
def format_if_needed(data_source)
|
140
|
-
data_source.is_a?(String) ? data_source : to_datatable_format(data_source)
|
141
|
-
end
|
142
|
-
|
143
|
-
def to_datatable_format(data)
|
144
|
-
|
145
|
-
data = convert_objects_to_array_of_hash(data)
|
146
|
-
data = merge_series(data)
|
147
|
-
|
148
|
-
case data
|
149
|
-
when Array
|
150
|
-
|
151
|
-
case data.first
|
152
|
-
when Array
|
153
|
-
cols = columns_from_array_row(data.first)
|
154
|
-
rows = add_rows data
|
155
|
-
|
156
|
-
when Hash
|
157
|
-
cols = columns_from_hash_row(data)
|
158
|
-
rows = add_rows data.map{|row| row.values}
|
159
|
-
end
|
160
|
-
|
161
|
-
when Hash
|
162
|
-
cols = columns_from_array_row(data.first)
|
163
|
-
rows = add_rows data
|
164
|
-
end
|
165
|
-
|
166
|
-
return {cols: cols, rows: rows}
|
167
|
-
end
|
168
|
-
|
169
|
-
def merge_series(data)
|
170
|
-
|
171
|
-
return data if data.first.nil? || data.first.is_a?(Array)
|
172
|
-
prototype = flatten_array_hash(data).inject({}) { |h, (k, v)| h[k] = nil; h }
|
173
|
-
return data if prototype.values.size > 3
|
174
|
-
|
175
|
-
series = {}
|
176
|
-
data.each { |e|
|
177
|
-
key = e.values.first
|
178
|
-
series[key] = series[key] ? convert_grouped_values_into_series(series[key], e) : prototype.merge(e)
|
179
|
-
}
|
180
|
-
|
181
|
-
if series.keys[0].is_a? Date
|
182
|
-
series.sort.collect{|e| e[1]}
|
183
|
-
else
|
184
|
-
series.values
|
61
|
+
(html + js).html_safe
|
185
62
|
end
|
186
|
-
end
|
187
|
-
|
188
|
-
def convert_grouped_values_into_series(serieA, serieB)
|
189
|
-
# if (serieB.values.size == 3)
|
190
|
-
# serieA.merge({serieB.values[1] => serieB.values[2]})
|
191
|
-
# else
|
192
|
-
# serieA.merge(serieB)
|
193
|
-
# end
|
194
|
-
serieA.merge(serieB)
|
195
|
-
end
|
196
|
-
|
197
|
-
def flatten_array_hash(data)
|
198
|
-
data.inject({}){|row, hash| row.merge(hash)}
|
199
|
-
end
|
200
|
-
|
201
|
-
def add_rows(rows)
|
202
|
-
rows.map{|row|
|
203
|
-
{"c" =>
|
204
|
-
row.map{|col|
|
205
|
-
{"v" => col}
|
206
|
-
}
|
207
|
-
}
|
208
|
-
}
|
209
|
-
end
|
210
|
-
|
211
|
-
def generateChartId
|
212
|
-
@current_chart_id ||= 0
|
213
|
-
"chart#{@current_chart_id += 1}"
|
214
|
-
end
|
215
|
-
|
216
|
-
def convert_objects_to_array_of_hash(data)
|
217
|
-
|
218
|
-
data = data.to_a if data.is_a? ActiveRecord::Relation
|
219
|
-
data = [] << data if data.is_a? ActiveRecord::Base
|
220
|
-
|
221
|
-
if data.is_a? Array and data.first.is_a? ActiveRecord::Base
|
222
|
-
data = data.map{|m| model_to_hash_without_empty_primary_key(m)}
|
223
|
-
end
|
224
|
-
|
225
|
-
return data
|
226
|
-
end
|
227
|
-
|
228
|
-
def model_to_hash_without_empty_primary_key(object)
|
229
|
-
primary_keys = object.class.columns.map{|c| c.name if c.primary}.compact
|
230
|
-
object.attributes.except(primary_keys.first)
|
231
|
-
end
|
232
|
-
|
233
|
-
def chart_class_from_string(klass_symbol)
|
234
|
-
"google.visualization." + klass_symbol.to_s
|
235
|
-
end
|
236
|
-
|
237
|
-
def columns_from_hash_row(data)
|
238
|
-
hash_row = flatten_array_hash(data)
|
239
|
-
hash_row.map { |c|
|
240
|
-
{:type => type_to_string(c[1]), :label => c[0]}
|
241
|
-
}
|
242
|
-
end
|
243
63
|
|
244
|
-
|
245
|
-
array_row.map { |c|
|
246
|
-
{:type => type_to_string(c), :label => default_label_for_type(c)}
|
247
|
-
}
|
248
|
-
end
|
64
|
+
private
|
249
65
|
|
250
|
-
|
251
|
-
|
252
|
-
return 'datetime' if (cel.is_a? DateTime) or (cel.is_a? Time)
|
253
|
-
return 'date' if cel.is_a? Date
|
254
|
-
return 'boolean' if (!!cel == cel)
|
255
|
-
return 'string'
|
256
|
-
end
|
66
|
+
include Rorschart::GoogleChart::Mapper
|
67
|
+
include Rorschart::GoogleChart::Options
|
257
68
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
69
|
+
def generateChartId
|
70
|
+
@current_chart_id ||= 0
|
71
|
+
"chart#{@current_chart_id += 1}"
|
72
|
+
end
|
262
73
|
|
263
74
|
end
|
264
75
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Rorschart
|
2
|
+
class MultipleSeries
|
3
|
+
|
4
|
+
attr_accessor :raw_series, :pivot_series
|
5
|
+
|
6
|
+
def initialize(raw_series)
|
7
|
+
@raw_series = raw_series
|
8
|
+
@pivot_series = raw_series.collect { |serie|
|
9
|
+
PivotData.new(serie)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def cols
|
14
|
+
cols_with_dup = @pivot_series.inject([]) { |cols, series|
|
15
|
+
cols + series.cols
|
16
|
+
}
|
17
|
+
|
18
|
+
cols_with_dup.uniq
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
def rows
|
23
|
+
# create union of all series first columns, to represent all abscisse values available
|
24
|
+
union_x = union_of_first_columns()
|
25
|
+
|
26
|
+
# Preparation: store all series rows in a hash indexed by first column
|
27
|
+
series_indexed = []
|
28
|
+
@pivot_series.each { |serie|
|
29
|
+
series_indexed << index_series_by_first_col(serie)
|
30
|
+
}
|
31
|
+
|
32
|
+
# The Merge:
|
33
|
+
# For abscisse value, grab for each serie the corresponding row - or nil
|
34
|
+
union_series = []
|
35
|
+
union_x.each { |x|
|
36
|
+
row = [x]
|
37
|
+
series_indexed.each { |serie_hash|
|
38
|
+
row << serie_hash[x]
|
39
|
+
}
|
40
|
+
union_series << row.flatten
|
41
|
+
}
|
42
|
+
|
43
|
+
# Return union of all series
|
44
|
+
union_series
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def uniq_label(label)
|
50
|
+
end
|
51
|
+
|
52
|
+
def union_of_first_columns
|
53
|
+
(
|
54
|
+
@pivot_series.inject([]) { |union, serie|
|
55
|
+
union + serie.rows
|
56
|
+
}
|
57
|
+
).collect{|r| r[0]}.uniq.sort
|
58
|
+
end
|
59
|
+
|
60
|
+
def index_series_by_first_col(serie)
|
61
|
+
|
62
|
+
serie_hash = {}
|
63
|
+
serie.rows.each { |row|
|
64
|
+
serie_hash[row[0]] = row.drop(1)
|
65
|
+
}
|
66
|
+
|
67
|
+
serie_hash
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Rorschart
|
2
|
+
|
3
|
+
class PivotData
|
4
|
+
|
5
|
+
attr_accessor :cols, :rows
|
6
|
+
|
7
|
+
def initialize(raw_data)
|
8
|
+
|
9
|
+
data = convert_objects_to_array_of_hash(raw_data)
|
10
|
+
data = data.to_pivot if data.is_a? Rorschart::MultipleSeries
|
11
|
+
|
12
|
+
case data
|
13
|
+
when Array
|
14
|
+
case data.first
|
15
|
+
when Array
|
16
|
+
cols = columns_from_array_row(data.first)
|
17
|
+
when Hash
|
18
|
+
cols = columns_from_hash_row(data)
|
19
|
+
data = data.map{|row| row.values}
|
20
|
+
end
|
21
|
+
when Hash
|
22
|
+
cols = columns_from_array_row(data.first)
|
23
|
+
end
|
24
|
+
|
25
|
+
@rows = data.to_a
|
26
|
+
@cols = cols
|
27
|
+
end
|
28
|
+
|
29
|
+
def sort_by_date!
|
30
|
+
|
31
|
+
if ['datetime', 'date'].include? @cols.first[:type]
|
32
|
+
@rows.sort!
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def convert_objects_to_array_of_hash(data)
|
40
|
+
|
41
|
+
data = data.to_a if data.is_a? ActiveRecord::Relation
|
42
|
+
data = [] << data if data.is_a? ActiveRecord::Base
|
43
|
+
|
44
|
+
if data.is_a? Array and data.first.is_a? ActiveRecord::Base
|
45
|
+
data = data.map{|m| model_to_hash_without_empty_primary_key(m)}
|
46
|
+
end
|
47
|
+
|
48
|
+
return data
|
49
|
+
end
|
50
|
+
|
51
|
+
def model_to_hash_without_empty_primary_key(object)
|
52
|
+
primary_keys = object.class.columns.map{|c| c.name if c.primary}.compact
|
53
|
+
object.attributes.except(primary_keys.first)
|
54
|
+
end
|
55
|
+
|
56
|
+
def columns_from_hash_row(data)
|
57
|
+
hash_row = flatten_array_hash(data)
|
58
|
+
hash_row.map { |c|
|
59
|
+
{:type => type_to_string(c[1]), :label => c[0]}
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def columns_from_array_row(array_row)
|
64
|
+
array_row.map { |c|
|
65
|
+
{:type => type_to_string(c), :label => default_label_for_type(c)}
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def type_to_string(cel)
|
70
|
+
return 'number' if (cel.is_a? Integer) or (cel.is_a? Float) or cel.nil?
|
71
|
+
return 'datetime' if (cel.is_a? DateTime) or (cel.is_a? Time)
|
72
|
+
return 'date' if cel.is_a? Date
|
73
|
+
return 'boolean' if (!!cel == cel)
|
74
|
+
return 'string'
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_label_for_type(cel)
|
78
|
+
return 'Date' if (cel.is_a? DateTime) or (cel.is_a? Date)
|
79
|
+
return 'Value'
|
80
|
+
end
|
81
|
+
|
82
|
+
def flatten_array_hash(data)
|
83
|
+
data.inject({}){|row, hash| row.merge(hash)}
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
data/lib/rorschart/version.rb
CHANGED
data/lib/rorschart.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
require "test_helper"
|
2
|
+
require "rorschart/google_chart_mapper"
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
include Rorschart::
|
4
|
+
class TestGoogleChartMapper < Minitest::Unit::TestCase
|
5
|
+
|
6
|
+
include Rorschart::GoogleChart::Mapper
|
6
7
|
|
7
8
|
def compare_dataTable(right, left)
|
8
9
|
assert_equal right[:cols], left[:cols]
|
@@ -14,8 +15,8 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
14
15
|
|
15
16
|
# Given
|
16
17
|
data = {
|
17
|
-
DateTime.now =>
|
18
|
-
DateTime.now
|
18
|
+
DateTime.now - 1 => 18,
|
19
|
+
DateTime.now => 17
|
19
20
|
}
|
20
21
|
|
21
22
|
# When
|
@@ -28,8 +29,8 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
28
29
|
{type: 'number', label: 'Value'}
|
29
30
|
],
|
30
31
|
rows: [
|
31
|
-
{c:[{v: DateTime.now}, {v:
|
32
|
-
{c:[{v: DateTime.now
|
32
|
+
{c:[{v: DateTime.now - 1}, {v: 18}]},
|
33
|
+
{c:[{v: DateTime.now}, {v: 17}]}
|
33
34
|
]
|
34
35
|
}
|
35
36
|
|
@@ -62,6 +63,32 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
62
63
|
|
63
64
|
def test_from_an_array_of_hash_and_detect_type_and_reuse_column_name
|
64
65
|
|
66
|
+
# Given
|
67
|
+
data = [
|
68
|
+
{"collector_tstamp"=> Date.parse("2013-11-28"), "count"=> 49},
|
69
|
+
{"collector_tstamp"=> Date.parse("2013-12-02"), "count"=> 44}
|
70
|
+
]
|
71
|
+
|
72
|
+
# When
|
73
|
+
dataTable = to_datatable_format(data)
|
74
|
+
|
75
|
+
# Then
|
76
|
+
excepted = {
|
77
|
+
cols: [
|
78
|
+
{type: 'date', label: 'collector_tstamp'},
|
79
|
+
{type: 'number', label: 'count'}
|
80
|
+
],
|
81
|
+
rows: [
|
82
|
+
{c:[{v: Date.parse("2013-11-28")}, {v: 49}]},
|
83
|
+
{c:[{v: Date.parse("2013-12-02")}, {v: 44}]}
|
84
|
+
]
|
85
|
+
}
|
86
|
+
|
87
|
+
compare_dataTable excepted, dataTable
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_order_date_series
|
91
|
+
|
65
92
|
# Given
|
66
93
|
data = [
|
67
94
|
{"collector_tstamp"=> Date.parse("2013-12-02"), "count"=> 44},
|
@@ -79,7 +106,7 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
79
106
|
],
|
80
107
|
rows: [
|
81
108
|
{c:[{v: Date.parse("2013-11-28")}, {v: 49}]},
|
82
|
-
{c:[{v: Date.parse("2013-12-02")}, {v: 44}]}
|
109
|
+
{c:[{v: Date.parse("2013-12-02")}, {v: 44}]}
|
83
110
|
]
|
84
111
|
}
|
85
112
|
|
@@ -90,8 +117,8 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
90
117
|
|
91
118
|
# Given
|
92
119
|
data = [
|
93
|
-
[Date.parse("2013-
|
94
|
-
[Date.parse("2013-
|
120
|
+
[Date.parse("2013-11-28"), 49],
|
121
|
+
[Date.parse("2013-12-02"), 44]
|
95
122
|
]
|
96
123
|
|
97
124
|
# When
|
@@ -104,8 +131,8 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
104
131
|
{type: 'number', label: 'Value'}
|
105
132
|
],
|
106
133
|
rows: [
|
107
|
-
{c:[{v: Date.parse("2013-
|
108
|
-
{c:[{v: Date.parse("2013-
|
134
|
+
{c:[{v: Date.parse("2013-11-28")}, {v: 49}]},
|
135
|
+
{c:[{v: Date.parse("2013-12-02")}, {v: 44}]}
|
109
136
|
]
|
110
137
|
}
|
111
138
|
|
@@ -162,14 +189,20 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
162
189
|
end
|
163
190
|
|
164
191
|
def test_merge_two_series
|
192
|
+
|
165
193
|
# Given
|
166
|
-
|
194
|
+
serie1 = [
|
167
195
|
{"collector_tstamp"=> Date.parse("2013-12-01"), "count"=> 1},
|
168
|
-
{"collector_tstamp"=> Date.parse("2013-12-02"), "count"=> 2}
|
196
|
+
{"collector_tstamp"=> Date.parse("2013-12-02"), "count"=> 2}
|
197
|
+
]
|
198
|
+
|
199
|
+
serie2 = [
|
169
200
|
{"collector_tstamp"=> Date.parse("2013-12-02"), "visit"=> 11},
|
170
|
-
{"collector_tstamp"=> Date.parse("2013-12-03"), "visit"=> 3}
|
201
|
+
{"collector_tstamp"=> Date.parse("2013-12-03"), "visit"=> 3}
|
171
202
|
]
|
172
203
|
|
204
|
+
data = Rorschart::MultipleSeries.new [serie1, serie2]
|
205
|
+
|
173
206
|
# When
|
174
207
|
series = to_datatable_format(data)
|
175
208
|
|
@@ -191,19 +224,68 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
191
224
|
|
192
225
|
end
|
193
226
|
|
227
|
+
def test_merge_multiple_series
|
228
|
+
|
229
|
+
# Given
|
230
|
+
serie1 = [
|
231
|
+
{"collector_tstamp"=> Date.parse("2013-12-01"), "count"=> 1},
|
232
|
+
{"collector_tstamp"=> Date.parse("2013-12-02"), "count"=> 2}
|
233
|
+
]
|
234
|
+
|
235
|
+
serie2 = [
|
236
|
+
{"collector_tstamp"=> Date.parse("2013-12-02"), "visit"=> 11},
|
237
|
+
{"collector_tstamp"=> Date.parse("2013-12-03"), "visit"=> 3}
|
238
|
+
]
|
239
|
+
|
240
|
+
serie3 = [
|
241
|
+
{"collector_tstamp"=> Date.parse("2013-12-02"), "visit"=> 6},
|
242
|
+
{"collector_tstamp"=> Date.parse("2013-12-03"), "visit"=> 8},
|
243
|
+
{"collector_tstamp"=> Date.parse("2013-12-04"), "visit"=> 9}
|
244
|
+
]
|
245
|
+
|
246
|
+
|
247
|
+
data = Rorschart::MultipleSeries.new [serie1, serie2, serie3]
|
248
|
+
|
249
|
+
# When
|
250
|
+
series = to_datatable_format(data)
|
251
|
+
|
252
|
+
# Then
|
253
|
+
excepted = {
|
254
|
+
cols: [
|
255
|
+
{type: 'date', label: 'collector_tstamp'},
|
256
|
+
{type: 'number', label: 'count'},
|
257
|
+
{type: 'number', label: 'visit'}
|
258
|
+
],
|
259
|
+
rows: [
|
260
|
+
{c:[{v: Date.parse("2013-12-01")}, {v: 1}, {v: nil}, {v: nil}]},
|
261
|
+
{c:[{v: Date.parse("2013-12-02")}, {v: 2}, {v: 11}, {v: 6}]},
|
262
|
+
{c:[{v: Date.parse("2013-12-03")}, {v: nil}, {v: 3}, {v: 8}]},
|
263
|
+
{c:[{v: Date.parse("2013-12-04")}, {v: nil}, {v: nil}, {v: 9}]},
|
264
|
+
]
|
265
|
+
}
|
266
|
+
|
267
|
+
compare_dataTable excepted, series
|
268
|
+
|
269
|
+
end
|
270
|
+
|
194
271
|
def test_merge_two_series_with_first_serie_start_later
|
272
|
+
|
195
273
|
# Given
|
196
|
-
|
274
|
+
serie1 = [
|
197
275
|
{"collector_tstamp"=> Date.parse("2013-12-03"), "count"=> 1},
|
198
276
|
{"collector_tstamp"=> Date.parse("2013-12-04"), "count"=> 2},
|
199
|
-
{"collector_tstamp"=> Date.parse("2013-12-05"), "count"=> 3}
|
277
|
+
{"collector_tstamp"=> Date.parse("2013-12-05"), "count"=> 3}
|
278
|
+
]
|
200
279
|
|
280
|
+
serie2 = [
|
201
281
|
{"collector_tstamp"=> Date.parse("2013-12-01"), "visit"=> 5},
|
202
282
|
{"collector_tstamp"=> Date.parse("2013-12-02"), "visit"=> 6},
|
203
283
|
{"collector_tstamp"=> Date.parse("2013-12-03"), "visit"=> 7},
|
204
|
-
{"collector_tstamp"=> Date.parse("2013-12-04"), "visit"=> 8}
|
284
|
+
{"collector_tstamp"=> Date.parse("2013-12-04"), "visit"=> 8}
|
205
285
|
]
|
206
286
|
|
287
|
+
data = Rorschart::MultipleSeries.new [serie1, serie2]
|
288
|
+
|
207
289
|
# When
|
208
290
|
series = to_datatable_format(data)
|
209
291
|
|
@@ -226,7 +308,7 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
226
308
|
compare_dataTable excepted, series
|
227
309
|
|
228
310
|
end
|
229
|
-
|
311
|
+
|
230
312
|
# def test_convert_numeric_grouped_dy_date_and_another_field_into_multiseries
|
231
313
|
|
232
314
|
# # Given
|
@@ -287,22 +369,14 @@ class TestRorschart < Minitest::Unit::TestCase
|
|
287
369
|
# compare_dataTable excepted, dataTable
|
288
370
|
# end
|
289
371
|
|
290
|
-
def
|
291
|
-
|
372
|
+
def test_is_already_converted?
|
292
373
|
# Given
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
]
|
298
|
-
|
299
|
-
# When
|
300
|
-
flat = flatten_array_hash(data)
|
301
|
-
|
302
|
-
# Then
|
303
|
-
excepted = {:a => 2, :b => 2, :c => 4}
|
374
|
+
data_converted = {
|
375
|
+
"cols" => [{type: 'number', label: 'count'}],
|
376
|
+
"rows" => []
|
377
|
+
}
|
304
378
|
|
305
|
-
assert_equal
|
379
|
+
assert_equal true, is_already_converted?(data_converted)
|
306
380
|
end
|
307
381
|
|
308
382
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "rorschart/pivot_data"
|
3
|
+
|
4
|
+
module Rorschart
|
5
|
+
|
6
|
+
class TestPivotData < Minitest::Unit::TestCase
|
7
|
+
|
8
|
+
def test_flatten_data
|
9
|
+
|
10
|
+
# Given
|
11
|
+
data = [
|
12
|
+
{:a => 1, :b => 2},
|
13
|
+
{:a => 2, :b => 3},
|
14
|
+
{:b => 2, :c => 4}
|
15
|
+
]
|
16
|
+
|
17
|
+
# When
|
18
|
+
|
19
|
+
pivot_data = PivotData.new(nil)
|
20
|
+
flat = pivot_data.send(:flatten_array_hash, data)
|
21
|
+
|
22
|
+
# flat = flatten_array_hash(data)
|
23
|
+
|
24
|
+
# Then
|
25
|
+
excepted = {:a => 2, :b => 2, :c => 4}
|
26
|
+
|
27
|
+
assert_equal excepted, flat
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rorschart
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Pantera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,11 +98,16 @@ files:
|
|
98
98
|
- app/assets/stylesheets/rorschart.css
|
99
99
|
- lib/rorschart.rb
|
100
100
|
- lib/rorschart/engine.rb
|
101
|
+
- lib/rorschart/google_chart_mapper.rb
|
102
|
+
- lib/rorschart/google_chart_options.rb
|
101
103
|
- lib/rorschart/helper.rb
|
104
|
+
- lib/rorschart/multiple_series.rb
|
105
|
+
- lib/rorschart/pivot_data.rb
|
102
106
|
- lib/rorschart/rails.rb
|
103
107
|
- lib/rorschart/version.rb
|
104
108
|
- rorschart.gemspec
|
105
|
-
- test/
|
109
|
+
- test/google_chart_mapper_test.rb
|
110
|
+
- test/pivot_data_test.rb
|
106
111
|
- test/test_helper.rb
|
107
112
|
homepage: https://github.com/epantera/rorschart
|
108
113
|
licenses:
|
@@ -129,5 +134,6 @@ signing_key:
|
|
129
134
|
specification_version: 4
|
130
135
|
summary: Beautiful Google Charts from Rails data structures
|
131
136
|
test_files:
|
132
|
-
- test/
|
137
|
+
- test/google_chart_mapper_test.rb
|
138
|
+
- test/pivot_data_test.rb
|
133
139
|
- test/test_helper.rb
|