analytics_charts 1.6.3 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1d9067379ba9f035efe9d800b9eaae2f2e34d5b7
4
- data.tar.gz: 34f7044fceb4dec013c51c447f269341cf77b3f0
3
+ metadata.gz: 3591ea166bdaed5eb90ee72f9881c17f8b94f86c
4
+ data.tar.gz: 387073f74b7a5f8816ffbfa5f38c2cbc1491f5dc
5
5
  SHA512:
6
- metadata.gz: 7692c627604cb402b15d1ef8d439114162ec79f5df83da543991e61594d440c9091381327d48b3fb38b0fd0053304a5298ae614a8a7281416dc784bdc15eb4cd
7
- data.tar.gz: dd9a5594a70712e534d139ad887ef89f3c32f35dfe50d64b86552b8add62494c91ad4c2ec3c808cbe730fae28a8a73bc6bfa99a93d79ad7d0619ce0d76846c61
6
+ metadata.gz: 828091a522244d336487604fe644b8a429d65d9d16c3060ed962bc2f349ef00a6e41e992c8f8a7fecfbb0efebe65107f73f73150a0967c56f2110c118bfb0123
7
+ data.tar.gz: 8c59f8315e3ce67d40a2b0dcc15a22080efa8a60176d03de04fb06765fcfe89ac9d457b19c28cc2641b587d5303551125b68c1676540de2bb81a666980fc6458
@@ -14,7 +14,6 @@ class AnalyticsCharts::CustomModule
14
14
  @dummy_image = Image.new(1,1)
15
15
  @composite_columns = @composite_image.columns
16
16
  @composite_rows = @composite_image.rows
17
- puts "@composite_columns: " + @composite_columns.to_s
18
17
  text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
19
18
  begin
20
19
  @rows_of_text = tokenize_text_by_lines(text)
@@ -24,9 +23,14 @@ class AnalyticsCharts::CustomModule
24
23
  end
25
24
 
26
25
  num_separators = @rows_of_text.count {|row| row.empty? }
27
- @sep_offset = 7
28
- starting_offset = @pointsize
29
- @height = @composite_rows + (@rows_of_text.size - num_separators) * @pointsize + num_separators * @sep_offset + starting_offset
26
+ num_special_sep = @rows_of_text.count {|row| row.include? "@$$" }
27
+ @line_height = @pointsize + 2
28
+ @sep_offset = @line_height / 2
29
+ starting_offset = @line_height / 2
30
+ ending_offset = @line_height / 2
31
+ @height = @composite_rows + (@rows_of_text.size - num_separators) *
32
+ @line_height + (num_separators-num_special_sep) * @sep_offset +
33
+ starting_offset + ending_offset
30
34
  @base_image = Image.new(@composite_columns, @height) {
31
35
  self.background_color = "black"
32
36
  }
@@ -35,19 +39,19 @@ class AnalyticsCharts::CustomModule
35
39
  @d.stroke_width(1)
36
40
  @d = @d.line(0, @composite_rows, @composite_columns, @composite_rows)
37
41
  @d.draw(@base_image)
38
- y_offset = starting_offset + @composite_rows
42
+ y_offset = @composite_rows + starting_offset
39
43
  @rows_of_text.each do |text|
40
44
  if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
41
45
  text.sub!("@$$", "")
42
46
  y_offset -= @sep_offset
47
+ y_offset += @line_height
43
48
  @d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
44
- y_offset += @pointsize
45
49
  next
46
50
  else
47
51
  if text.empty?
48
52
  y_offset += @sep_offset
49
53
  else
50
- y_offset += @pointsize
54
+ y_offset += @line_height
51
55
  @d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
52
56
  end
53
57
  end
@@ -68,12 +72,12 @@ class AnalyticsCharts::CustomModule
68
72
  def line_wrap(text)
69
73
  tokens = text.split.reverse # Pop stuff off
70
74
  # Safety check, do not allow super long words.
71
- tokens.each {|token| return "" if not fits_in_a_line(token) }
75
+ tokens.each {|token| return "" if not fits_in_a_line?(token) }
72
76
  line_wrap_tokens = Array.new
73
77
  line_builder = ""
74
78
  while tokens.size != 0
75
79
  line_builder = tokens.pop # Pop the first word in a line
76
- while tokens.size != 0 and fits_in_a_line(line_builder + " " + tokens.last)
80
+ while tokens.size != 0 and fits_in_a_line?(line_builder + " " + tokens.last)
77
81
  line_builder += " " + tokens.pop
78
82
  end
79
83
  line_wrap_tokens.push(line_builder) # Add to list of lines
@@ -81,8 +85,7 @@ class AnalyticsCharts::CustomModule
81
85
  line_wrap_tokens
82
86
  end
83
87
 
84
- def fits_in_a_line(text)
85
- puts text + " SIZE: " + @d.get_type_metrics(@dummy_image,text).width.to_s + " COLUMNS: " + (@composite_image.columns - 36).to_s
88
+ def fits_in_a_line?(text)
86
89
  return @d.get_type_metrics(@dummy_image,text).width < @composite_image.columns - 36
87
90
  end
88
91
  end
@@ -10,6 +10,7 @@ class AnalyticsCharts::CustomPie
10
10
  attr_accessor :label_start_x
11
11
  attr_accessor :label_start_y
12
12
  attr_accessor :label_offset
13
+
13
14
  def initialize(image_path, label_hash, pie_label_hash)
14
15
  @base_image = Image.read(image_path)[0]
15
16
  @columns = @base_image.columns
@@ -44,6 +45,7 @@ class AnalyticsCharts::CustomPie
44
45
  def highest_score(index, score)
45
46
  @thresholds[index] = score
46
47
  end
48
+
47
49
  def insert_pie_data(name, amount, quality)
48
50
  #convert all '&#39; instances to an apostrophe
49
51
  name = name.gsub(/&#39;/, "\'")
@@ -58,13 +60,24 @@ class AnalyticsCharts::CustomPie
58
60
  end
59
61
  end
60
62
 
63
+ def label_attributes=(label = {})
64
+ @label_attributes = label
65
+ end
66
+
67
+ def label_attributes
68
+ @label_attributes ||= {}
69
+ end
70
+
71
+ def label_height=(height)
72
+ @label_height = height
73
+ end
74
+
75
+ def label_height
76
+ @label_height ||= 12
77
+ end
78
+
61
79
  def insert_text_with_circle(x_offset, y_offset, text, features = {})
62
- features.each { |feature, attribute|
63
- set_feature(feature, attribute)
64
- }
65
- # Double quotes automatically escaped in rails db. Refer to Rmagick doc for escaping stuff
66
- text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
67
- @d.annotate(@base_image, 0 ,0, x_offset, y_offset, text)
80
+ insert_text(x_offset, y_offset, text, features)
68
81
  height = @d.get_type_metrics(@base_image, text).ascent
69
82
  y_offset -= height / 2
70
83
  circle_xpos = x_offset - 10
@@ -79,6 +92,7 @@ class AnalyticsCharts::CustomPie
79
92
  features.each { |feature, attribute|
80
93
  set_feature(feature, attribute)
81
94
  }
95
+ # Double quotes automatically escaped in rails db. Refer to Rmagick doc for escaping stuff
82
96
  text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
83
97
  @d.annotate(@base_image, 0 ,0, x_offset, y_offset, text)
84
98
  end
@@ -95,7 +109,7 @@ class AnalyticsCharts::CustomPie
95
109
  # If we don't refresh draw, future "@d.draw(@base_image)" will redraw the circle,
96
110
  # overlapping on the text written below
97
111
  @d = Draw.new
98
- insert_text(@pie_center_x - 30, @pie_center_y, "No Data",
112
+ insert_text(@pie_center_x - 30, @pie_center_y, "(No Data)",
99
113
  @label_hash.merge({'fill'=> '#000000', 'font_weight'=> 700 }))
100
114
  return
101
115
  end
@@ -165,10 +179,10 @@ class AnalyticsCharts::CustomPie
165
179
  end
166
180
  end
167
181
  prev_degrees = 60.0 # Now focus on labels
168
- @aggregate.each_with_index do |data_row, i|
182
+ @aggregate.each_with_index do |cluster_data_value, i|
169
183
  next if degrees[i] == 0
170
184
  half_angle = prev_degrees + degrees[i] / 2
171
- label_string = '$' + data_row.round(0).to_s
185
+ label_string = process_pie_label_data(cluster_data_value)
172
186
  draw_pie_label(@pie_center_x,@pie_center_y, half_angle + label_offset_degrees[i],
173
187
  @pie_radius, label_string, i)
174
188
  prev_degrees += degrees[i]
@@ -176,6 +190,26 @@ class AnalyticsCharts::CustomPie
176
190
  end
177
191
  end
178
192
 
193
+ def process_pie_label_data(cluster_data_value)
194
+ if cluster_data_value < 10**3
195
+ return '$' + cluster_data_value.round(0).to_s
196
+ elsif cluster_data_value < 10**6
197
+ cluster_data_value /= 10**3 # Truncates decimals
198
+ return '$' + cluster_data_value.round(0).to_s + 'K'# Round is unnecessary, but add anyways
199
+ elsif cluster_data_value < 10**9
200
+ cluster_data_value /= 10**6
201
+ return '$' + cluster_data_value.round(0).to_s + 'M'
202
+ elsif cluster_data_value < 10**12
203
+ cluster_data_value /= 10**9
204
+ return '$' + cluster_data_value.round(0).to_s + 'B'
205
+ elsif cluster_data_value < 10**15
206
+ cluster_data_value /= 10**12
207
+ return '$' + cluster_data_value.round(0).to_s + 'T'
208
+ else
209
+ return '>1T'
210
+ end
211
+ end
212
+
179
213
  def write(filename='graph.png')
180
214
  draw
181
215
  draw_labels
@@ -187,50 +221,49 @@ class AnalyticsCharts::CustomPie
187
221
  sorted_data = @data.sort_by{|key,value| -value[1]} # Sort by descending quality
188
222
  x_offset = @label_start_x + 15
189
223
  y_offset = @label_start_y
224
+ @label_hash = @label_hash.merge(label_attributes)
190
225
  for data in sorted_data
191
226
  has_data = false
192
227
  if data[1][0] > 0 # Amount > 0
193
- font_weight = 900 # Very Bold
194
228
  text = data[0]
195
229
  has_data = true
196
230
  else
197
231
  text = data[0]
198
- font_weight = 900 # Very Bold
199
232
  end
200
233
  if has_data
201
234
  case data[1][1]
202
235
  when 3
203
236
  # label_hash gets merged and overrided by fill and font_weight.
204
237
  insert_text_with_circle(x_offset, y_offset, text,
205
- @label_hash.merge({'fill'=> '#1E753B', 'font_weight'=> font_weight }))
238
+ @label_hash.merge({'fill'=> '#1E753B'}))
206
239
  when 2
207
240
  insert_text_with_circle(x_offset, y_offset, text,
208
- @label_hash.merge({'fill'=> '#C1B630', 'font_weight'=> font_weight }))
241
+ @label_hash.merge({'fill'=> '#C1B630'}))
209
242
  when 1
210
243
  insert_text_with_circle(x_offset, y_offset, text,
211
- @label_hash.merge({'fill'=> '#BE6428', 'font_weight'=> font_weight }))
244
+ @label_hash.merge({'fill'=> '#BE6428'}))
212
245
  when 0
213
246
  insert_text_with_circle(x_offset, y_offset, text,
214
- @label_hash.merge({'fill'=> '#AD1F25', 'font_weight'=> font_weight }))
247
+ @label_hash.merge({'fill'=> '#AD1F25'}))
215
248
  end
216
249
  else
217
250
  case data[1][1]
218
251
  when 3
219
252
  # label_hash gets merged and overrided by fill and font_weight.
220
253
  insert_text(x_offset, y_offset, text,
221
- @label_hash.merge({'fill'=> '#1E753B', 'font_weight'=> font_weight }))
254
+ @label_hash.merge({'fill'=> '#1E753B'}))
222
255
  when 2
223
256
  insert_text(x_offset, y_offset, text,
224
- @label_hash.merge({'fill'=> '#C1B630', 'font_weight'=> font_weight }))
257
+ @label_hash.merge({'fill'=> '#C1B630'}))
225
258
  when 1
226
259
  insert_text(x_offset, y_offset, text,
227
- @label_hash.merge({'fill'=> '#BE6428', 'font_weight'=> font_weight }))
260
+ @label_hash.merge({'fill'=> '#BE6428'}))
228
261
  when 0
229
262
  insert_text(x_offset, y_offset, text,
230
- @label_hash.merge({'fill'=> '#AD1F25', 'font_weight'=> font_weight }))
263
+ @label_hash.merge({'fill'=> '#AD1F25'}))
231
264
  end
232
265
  end
233
- y_offset += @label_offset
266
+ y_offset += self.label_height
234
267
  end
235
268
  insert_text_with_circle(x_offset, y_offset, '= purchased by you',
236
269
  @label_hash.merge({'fill'=> '#252525', 'font_weight'=> 900 }))
@@ -269,6 +302,11 @@ class AnalyticsCharts::CustomPie
269
302
  insert_text(x, y, percent, {'fill'=> @colors[index]}.merge(@pie_label_hash))# {'fill'=> 'black', 'font_weight'=> 700, 'pointsize'=>48})
270
303
  end
271
304
 
305
+ def recalibrate_metrics_for_labels
306
+ label_attributes.each { |feature, attribute|
307
+ set_feature(feature, attribute)
308
+ }
309
+ end
272
310
  def set_feature(feature, attribute)
273
311
  begin
274
312
  case feature
@@ -12,19 +12,24 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
12
12
  @d.font_weight = 700
13
13
  @dummy_image = Image.new(1,1)
14
14
  @composite_columns = @composite_image.columns
15
- puts @composite_columns
16
15
  @composite_rows = @composite_image.rows
17
- @org_text_size = 14
18
16
  organization = organization.gsub(/['%]/, '%' => '%%', "'" => "\'")
17
+ @org_text_size = 14
18
+ @org_height = @org_text_size + 1
19
19
  @org_texts = tokenize_text_by_lines(organization,
20
20
  {'fill' => '#FFFFFF', 'pointsize'=> @org_text_size, 'font_weight'=> 500 })
21
+ org_text_offset = @org_texts.size * @org_height
22
+
21
23
  @label_size = 16
22
- org_text_offset = @org_texts.size * @org_text_size
24
+ self.label_attributes = {'pointsize' => @label_size, 'font_weight' => 900}
25
+ recalibrate_metrics_for_labels
26
+ self.label_height = @label_size + 1
27
+
23
28
  # (num_labels + 1) to account for white key on bottom of labels
24
- @height_with_no_disclaimer = [200 + 20, 20 + @label_size * (num_labels + 1) + 20].max + @composite_rows + org_text_offset
29
+ @height_with_no_disclaimer = [200 + 20, 20 + self.label_height * (num_labels + 1) + 20].max + @composite_rows + org_text_offset
25
30
  disclaimer = disclaimer.gsub(/['%]/, '%' => '%%', "'" => "\'")
26
31
  @disclaimer_texts = tokenize_text_by_lines(disclaimer)
27
- @height = @height_with_no_disclaimer + @disclaimer_texts.size * 12 + 5
32
+ @height = @height_with_no_disclaimer + @disclaimer_texts.size * 12
28
33
  @data = Hash.new # Value is array with two items
29
34
  @aggregate = Array([0,0,0,0]) # Cluster brands into categories
30
35
  @label_hash = {'pointsize'=> @label_size,'font_weight'=> 700 }
@@ -45,11 +50,11 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
45
50
  insert_text(22, y_offset ,text,
46
51
  @label_hash.merge({'fill' => '#FFFFFF', 'pointsize'=> @org_text_size, 'font_weight'=> 500 }))
47
52
  @d.annotate(@base_image, 0 ,0, 22, y_offset, text)
48
- y_offset += @org_text_size
53
+ y_offset += @org_height
49
54
  end
50
55
  end
51
56
  def annotate_disclaimer
52
- y_offset = @height_with_no_disclaimer + @d.get_type_metrics(@dummy_image,"a").height + 5
57
+ y_offset = @height_with_no_disclaimer + @d.get_type_metrics(@dummy_image,"a").height
53
58
  @disclaimer_texts.each do |text|
54
59
  if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
55
60
  text.sub!("@$$", "")
@@ -153,12 +158,12 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
153
158
  def line_wrap(text)
154
159
  tokens = text.split.reverse # Pop stuff off
155
160
  # Safety check, do not allow super long words.
156
- tokens.each {|token| return "" if not fits_in_a_line(token) }
161
+ tokens.each {|token| return "" if not fits_in_a_line?(token) }
157
162
  line_wrap_tokens = Array.new
158
163
  line_builder = ""
159
164
  while tokens.size != 0
160
165
  line_builder = tokens.pop # Pop the first word in a line
161
- while tokens.size != 0 and fits_in_a_line(line_builder + " " + tokens.last)
166
+ while tokens.size != 0 and fits_in_a_line?(line_builder + " " + tokens.last)
162
167
  line_builder += " " + tokens.pop
163
168
  end
164
169
  line_wrap_tokens.push(line_builder) # Add to list of lines
@@ -166,7 +171,7 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
166
171
  line_wrap_tokens
167
172
  end
168
173
 
169
- def fits_in_a_line(text)
174
+ def fits_in_a_line?(text)
170
175
  return @d.get_type_metrics(@dummy_image,text).width < @composite_columns - 44
171
176
  end
172
177
 
@@ -1,3 +1,3 @@
1
1
  module AnalyticsCharts
2
- VERSION = "1.6.3"
2
+ VERSION = "1.7.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: analytics_charts
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.3
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - STEPHEN YU