analytics_charts 1.3.5 → 1.4.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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 560cfd775caca338fcc64c9c31ca41fa3ae2f579
|
4
|
+
data.tar.gz: 7cdc37b4d833273ee9cc78140fdaec0804a8d752
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b9cb90391084cc7aeec0070665991a7817e99fa9195cfe14e03727b89037ac6709db349f809fca8d48926f79a3fc29a365317724d374fdea3cf57406a05b9ea
|
7
|
+
data.tar.gz: 099a6abce765a6eb45f7df431c190644970e15d6a3b56878c24a76ae240ac4b67351f7734db0a3c4431dff53206608a91ae46669207a7bf1a80368d254c43cbf
|
@@ -6,7 +6,8 @@ class AnalyticsCharts::CustomModule
|
|
6
6
|
@d = Draw.new
|
7
7
|
@d.fill = 'white'
|
8
8
|
@d.font = 'Helvetica'
|
9
|
-
@
|
9
|
+
@pointsize = 18
|
10
|
+
@d.pointsize = @pointsize
|
10
11
|
@d.font_weight = 500
|
11
12
|
@composite_image = Image.read(image_path)[0]
|
12
13
|
@dummy_image = Image.new(1,1)
|
@@ -18,7 +19,7 @@ class AnalyticsCharts::CustomModule
|
|
18
19
|
puts "Had some error in CustomModule, probably a nil calling each"
|
19
20
|
return
|
20
21
|
end
|
21
|
-
@height = @composite_rows + @rows_of_text.size *
|
22
|
+
@height = @composite_rows + @rows_of_text.size * @pointsize
|
22
23
|
@base_image = Image.new(@composite_columns, @height) {
|
23
24
|
self.background_color = "black"
|
24
25
|
}
|
@@ -27,16 +28,16 @@ class AnalyticsCharts::CustomModule
|
|
27
28
|
@d.stroke_width(1)
|
28
29
|
@d = @d.line(0, @composite_rows, @composite_columns, @composite_rows)
|
29
30
|
@d.draw(@base_image)
|
30
|
-
y_offset =
|
31
|
+
y_offset = @pointsize + @composite_rows + @d.get_type_metrics(@dummy_image,"a").height / 2
|
31
32
|
@rows_of_text.each do |text|
|
32
33
|
text = text.gsub(/['%]/, '%' => '%%', "'" => "\'")
|
33
34
|
if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
|
34
35
|
text.sub!("@$$", "")
|
35
|
-
@d.annotate(@base_image, 0 ,0,
|
36
|
+
@d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
|
36
37
|
next
|
37
38
|
else
|
38
|
-
@d.annotate(@base_image, 0 ,0,
|
39
|
-
y_offset +=
|
39
|
+
@d.annotate(@base_image, 0 ,0, @pointsize, y_offset, text)
|
40
|
+
y_offset += @pointsize
|
40
41
|
end
|
41
42
|
end
|
42
43
|
@base_image.write(output_path)
|
@@ -69,7 +70,7 @@ class AnalyticsCharts::CustomModule
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def fits_in_a_line(text)
|
72
|
-
return @d.get_type_metrics(@dummy_image,text).width < @composite_image.columns -
|
73
|
+
return @d.get_type_metrics(@dummy_image,text).width < @composite_image.columns - @pointsize * 2
|
73
74
|
end
|
74
75
|
end
|
75
76
|
#Reference: Draw defaults[ font: "Helvetica", pointsize:12, x/y resolution 72 DPI, font_weight: 400]
|
@@ -57,7 +57,8 @@ class AnalyticsCharts::CustomPie
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
|
+
def insert_text_with_circle(x_offset, y_offset, text, features = {})
|
61
62
|
features.each { |feature, attribute|
|
62
63
|
set_feature(feature, attribute)
|
63
64
|
}
|
@@ -66,13 +67,14 @@ class AnalyticsCharts::CustomPie
|
|
66
67
|
@d.annotate(@base_image, 0 ,0, x_offset, y_offset, text)
|
67
68
|
height = @d.get_type_metrics(@base_image, text).ascent
|
68
69
|
y_offset -= height / 2
|
69
|
-
|
70
|
-
|
71
|
-
@d.
|
72
|
-
@d
|
73
|
-
@d = @d.
|
74
|
-
|
70
|
+
circle_xpos = x_offset - 10
|
71
|
+
radius = 5
|
72
|
+
@d.stroke_width(radius)
|
73
|
+
@d.stroke features["fill"] unless features["fill"].nil?
|
74
|
+
@d = @d.ellipse(circle_xpos, y_offset,
|
75
|
+
radius / 2.0, radius / 2.0, 0, 360 + 1.0) # <= +0.5 'fudge factor' gets rid of the ugly gaps
|
75
76
|
end
|
77
|
+
|
76
78
|
def insert_text(x_offset, y_offset, text, features = {})
|
77
79
|
features.each { |feature, attribute|
|
78
80
|
set_feature(feature, attribute)
|
@@ -88,19 +90,13 @@ class AnalyticsCharts::CustomPie
|
|
88
90
|
@d = @d.stroke "#FFFFFF"
|
89
91
|
@d = @d.ellipse(@pie_center_x, @pie_center_y,
|
90
92
|
@pie_radius / 2.0, @pie_radius / 2.0,
|
91
|
-
|
92
|
-
@d
|
93
|
-
@d.
|
94
|
-
|
95
|
-
@d =
|
96
|
-
|
97
|
-
|
98
|
-
@d.stroke_width(10)
|
99
|
-
@d = @d.ellipse(@pie_center_x, @pie_center_y + 20,
|
100
|
-
5,5,
|
101
|
-
0, 360) # <= +0.5 'fudge factor' gets rid of the ugly gaps
|
102
|
-
draw_pie_label(@pie_center_x,@pie_center_y, 45,
|
103
|
-
@pie_radius, "$0", 4)
|
93
|
+
0, 360 + 0.5) # <= +0.5 'fudge factor' gets rid of the ugly gaps
|
94
|
+
@d.draw(@base_image)
|
95
|
+
# If we don't refresh draw, future "@d.draw(@base_image)" will redraw the circle,
|
96
|
+
# overlapping on the text written below
|
97
|
+
@d = Draw.new
|
98
|
+
insert_text(@pie_center_x - 30, @pie_center_y, "No data....",
|
99
|
+
@label_hash.merge({'fill'=> '#000000', 'font_weight'=> 700 }))
|
104
100
|
return
|
105
101
|
end
|
106
102
|
if @data.size > 0
|
@@ -172,7 +168,7 @@ class AnalyticsCharts::CustomPie
|
|
172
168
|
@aggregate.each_with_index do |data_row, i|
|
173
169
|
next if degrees[i] == 0
|
174
170
|
half_angle = prev_degrees + degrees[i] / 2
|
175
|
-
label_string = '$' + data_row.round(
|
171
|
+
label_string = '$' + data_row.round(0).to_s
|
176
172
|
draw_pie_label(@pie_center_x,@pie_center_y, half_angle + label_offset_degrees[i],
|
177
173
|
@pie_radius, label_string, i)
|
178
174
|
prev_degrees += degrees[i]
|
@@ -189,7 +185,7 @@ class AnalyticsCharts::CustomPie
|
|
189
185
|
def draw_labels
|
190
186
|
@d.align = LeftAlign
|
191
187
|
sorted_data = @data.sort_by{|key,value| -value[1]} # Sort by descending quality
|
192
|
-
x_offset = @label_start_x
|
188
|
+
x_offset = @label_start_x + 15
|
193
189
|
y_offset = @label_start_y
|
194
190
|
for data in sorted_data
|
195
191
|
has_data = false
|
@@ -205,16 +201,16 @@ class AnalyticsCharts::CustomPie
|
|
205
201
|
case data[1][1]
|
206
202
|
when 3
|
207
203
|
# label_hash gets merged and overrided by fill and font_weight.
|
208
|
-
|
204
|
+
insert_text_with_circle(x_offset, y_offset, text,
|
209
205
|
@label_hash.merge({'fill'=> '#1E753B', 'font_weight'=> font_weight }))
|
210
206
|
when 2
|
211
|
-
|
207
|
+
insert_text_with_circle(x_offset, y_offset, text,
|
212
208
|
@label_hash.merge({'fill'=> '#C1B630', 'font_weight'=> font_weight }))
|
213
209
|
when 1
|
214
|
-
|
210
|
+
insert_text_with_circle(x_offset, y_offset, text,
|
215
211
|
@label_hash.merge({'fill'=> '#BE6428', 'font_weight'=> font_weight }))
|
216
212
|
when 0
|
217
|
-
|
213
|
+
insert_text_with_circle(x_offset, y_offset, text,
|
218
214
|
@label_hash.merge({'fill'=> '#AD1F25', 'font_weight'=> font_weight }))
|
219
215
|
end
|
220
216
|
else
|
@@ -236,6 +232,8 @@ class AnalyticsCharts::CustomPie
|
|
236
232
|
end
|
237
233
|
y_offset += @label_offset
|
238
234
|
end
|
235
|
+
insert_text_with_circle(x_offset, y_offset, '= purchased by you',
|
236
|
+
@label_hash.merge({'fill'=> '#FFFFFF', 'font_weight'=> 900 }))
|
239
237
|
end
|
240
238
|
|
241
239
|
def draw_pie_label(center_x, center_y, angle, radius, percent, index)
|
@@ -6,30 +6,47 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
|
|
6
6
|
@organization = organization
|
7
7
|
@legend_data = Array.new(["","","",""])
|
8
8
|
@thresholds = Array(["","","",""]) # Will populate with integer thresholds
|
9
|
-
@columns = 450
|
10
9
|
@composite_image = Image.read(meme)[0]
|
11
|
-
@composite_columns = @composite_image.columns
|
12
|
-
@composite_rows = @composite_image.rows
|
13
|
-
@rows_with_no_disclaimer = [200 + 20, 20 + 16 * num_labels + 20].max + @composite_rows
|
14
|
-
@dummy_image = Image.new(1,1)
|
15
10
|
@d = Draw.new
|
16
11
|
@d.pointsize = 12
|
17
12
|
@d.font_weight = 700
|
18
|
-
@
|
19
|
-
@
|
13
|
+
@dummy_image = Image.new(1,1)
|
14
|
+
@composite_columns = @composite_image.columns
|
15
|
+
@composite_rows = @composite_image.rows
|
16
|
+
@org_texts = tokenize_text_by_lines(organization)
|
17
|
+
@org_text_size = 14
|
18
|
+
@label_size = 16
|
19
|
+
org_text_offset = @org_texts.size * @org_text_size
|
20
|
+
# (num_labels + 1) to account for white key on bottom of labels
|
21
|
+
@height_with_no_disclaimer = [200 + 20, 20 + @label_size * (num_labels + 1) + 20].max + @composite_rows + org_text_offset
|
22
|
+
@disclaimer_texts = tokenize_text_by_lines(disclaimer)
|
23
|
+
@height = @height_with_no_disclaimer + @disclaimer_texts.size * 12 + 5
|
20
24
|
@data = Hash.new # Value is array with two items
|
21
25
|
@aggregate = Array([0,0,0,0]) # Cluster brands into categories
|
22
|
-
@label_hash = {'pointsize'=>
|
26
|
+
@label_hash = {'pointsize'=> @label_size,'font_weight'=> 700 }
|
23
27
|
@pie_label_hash = {'pointsize'=> 14, 'font_weight' => 600 }
|
24
28
|
set_pie_colors(%w(#AD1F25 #BE6428 #C1B630 #1E753B #FFFFFF))
|
25
|
-
@base_image = Image.new(@
|
29
|
+
@base_image = Image.new(@composite_columns, @height) {
|
26
30
|
self.background_color = "black"
|
27
31
|
}
|
28
32
|
@base_image.composite!(@composite_image,0,0,OverCompositeOp)
|
29
33
|
set_pie_geometry(325, 60+ @composite_rows, 50)
|
30
|
-
set_label_values(22, 20+@composite_rows,
|
31
|
-
|
32
|
-
|
34
|
+
set_label_values(22, 20+@composite_rows, @label_size)
|
35
|
+
annotate_organization(org_text_offset)
|
36
|
+
annotate_disclaimer
|
37
|
+
end
|
38
|
+
def annotate_organization(offset)
|
39
|
+
y_offset = @height_with_no_disclaimer - offset
|
40
|
+
@org_texts.each do |text|
|
41
|
+
insert_text(22, y_offset ,text,
|
42
|
+
@label_hash.merge({'fill' => '#FFFFFF', 'pointsize'=> @org_text_size, 'font_weight'=> 500 }))
|
43
|
+
@d.annotate(@base_image, 0 ,0, 22, y_offset, text)
|
44
|
+
y_offset += @org_text_size
|
45
|
+
end
|
46
|
+
end
|
47
|
+
def annotate_disclaimer
|
48
|
+
y_offset = @height_with_no_disclaimer + @d.get_type_metrics(@dummy_image,"a").height + 5
|
49
|
+
@disclaimer_texts.each do |text|
|
33
50
|
if text.include? "@$$" # No paragraph break if we insert this uncommonly used word
|
34
51
|
text.sub!("@$$", "")
|
35
52
|
insert_text(22, y_offset ,text,
|
@@ -47,22 +64,12 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
|
|
47
64
|
def write(filename='graph.png')
|
48
65
|
draw
|
49
66
|
draw_labels
|
50
|
-
draw_organization
|
51
67
|
draw_legend
|
52
68
|
draw_line
|
53
69
|
@d.draw(@base_image)
|
54
70
|
@base_image.write(filename)
|
55
71
|
end
|
56
72
|
|
57
|
-
def draw_organization
|
58
|
-
insert_text(22, @rows_with_no_disclaimer - 20, @organization,
|
59
|
-
@label_hash.merge({'fill' => '#FFFFFF', 'pointsize'=> 10 }))
|
60
|
-
category_disclaimer = "(categories only for demo purposes)"
|
61
|
-
insert_text(22, @rows_with_no_disclaimer - 10, category_disclaimer,
|
62
|
-
@label_hash.merge({'fill' => '#FFFFFF', 'pointsize'=> 10 }))
|
63
|
-
|
64
|
-
end
|
65
|
-
|
66
73
|
def insert_legend(label, quality, color)
|
67
74
|
case color
|
68
75
|
when "green"
|
@@ -115,20 +122,26 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
|
|
115
122
|
end
|
116
123
|
end
|
117
124
|
end
|
125
|
+
|
118
126
|
def draw_line
|
119
127
|
@d.stroke('white')
|
120
128
|
@d.stroke_width(1)
|
121
|
-
@d.line(0,@
|
129
|
+
@d.line(0,@height_with_no_disclaimer,@composite_columns,@height_with_no_disclaimer)
|
122
130
|
end
|
123
131
|
|
124
132
|
def tokenize_text_by_lines(text)
|
125
133
|
# First split the text by the line carriage element
|
126
134
|
carriage_split_lines = text.split("\r\n")
|
135
|
+
puts carriage_split_lines
|
127
136
|
line_tokens = Array.new
|
128
137
|
carriage_split_lines.each do |carriage_split_line|
|
138
|
+
puts carriage_split_line
|
129
139
|
line_wrap_lines = line_wrap(carriage_split_line)
|
130
|
-
|
131
|
-
|
140
|
+
begin
|
141
|
+
line_wrap_lines.each { |line| line_tokens.push(line) }
|
142
|
+
line_tokens.push("\r\n")
|
143
|
+
rescue
|
144
|
+
end
|
132
145
|
end
|
133
146
|
line_tokens
|
134
147
|
end
|
@@ -149,7 +162,7 @@ class AnalyticsCharts::PieAndLabels < AnalyticsCharts::CustomPie
|
|
149
162
|
end
|
150
163
|
|
151
164
|
def fits_in_a_line(text)
|
152
|
-
return @d.get_type_metrics(@dummy_image,text).width < @
|
165
|
+
return @d.get_type_metrics(@dummy_image,text).width < @composite_columns - 44
|
153
166
|
end
|
154
167
|
|
155
168
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: analytics_charts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- STEPHEN YU
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|