analytics_charts 1.6.3 → 1.7.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 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