treemap21 0.1.0 → 0.3.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/treemap21.rb +196 -83
- metadata +28 -8
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0c0ef895191c2b9096739debe2f5fc0587e0de4cd1e79353d476fa5d8f9511f
|
4
|
+
data.tar.gz: 4275d68e6f555f9b523238e418551fcdf3ac9e9d6e2c481d38b06399cd625c2d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89e4ef858bb13e906b729720e0bea919959b464c8e662b421cad97c9ccdf0d010b1aa31453a8cd1d8e7d91838aa5b85256c8bd19b9364c0dfca29d32d953cbc0
|
7
|
+
data.tar.gz: af28c7e0cae6d56c98b03b3d328a27d0c4c724b739df29dc0a1ce0721849356072731f98efd70ea07c2711ab347f79cf907d567efb11b775ab16e262395f0dc0
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/treemap21.rb
CHANGED
@@ -2,84 +2,115 @@
|
|
2
2
|
|
3
3
|
# file: treemap21.rb
|
4
4
|
|
5
|
-
|
5
|
+
require 'c32'
|
6
6
|
require 'rexle'
|
7
|
+
require 'weblet'
|
8
|
+
require 'polyrex'
|
7
9
|
|
8
10
|
|
9
11
|
class Treemap21
|
12
|
+
using ColouredText
|
13
|
+
|
14
|
+
attr_reader :to_html, :title
|
15
|
+
|
16
|
+
def initialize(obj, orientation: :landscape, title: 'Treemap',
|
17
|
+
weblet_file: nil, debug: false)
|
18
|
+
|
19
|
+
@orientation, @title, @debug = orientation, title, debug
|
20
|
+
|
21
|
+
@a = case obj
|
22
|
+
when Array
|
23
|
+
a
|
24
|
+
when String
|
25
|
+
|
26
|
+
if obj.lstrip =~ /<?polyrex / then
|
27
|
+
|
28
|
+
px = Polyrex.new obj
|
29
|
+
doc = Rexle.new(px.to_tree)
|
30
|
+
scan_xml(doc.root)
|
31
|
+
|
32
|
+
elsif obj.lstrip =~ /</ then
|
33
|
+
|
34
|
+
doc = Rexle.new(obj)
|
35
|
+
scan_xml(doc.root)
|
36
|
+
|
37
|
+
else
|
38
|
+
|
39
|
+
# most likely a raw polyrex document without the processing
|
40
|
+
# instruction or header
|
41
|
+
|
42
|
+
head = "<?polyrex schema='items[title, description]/item[title," +
|
43
|
+
" pct, url]' delimiter=' # '?>\ntitle: Unititled\ndescription: " +
|
44
|
+
"Treemap record data"
|
45
|
+
|
46
|
+
s = head + "\n\n" + obj.lstrip
|
47
|
+
px = Polyrex.new s
|
48
|
+
doc = Rexle.new(px.to_tree)
|
49
|
+
scan_xml(doc.root)
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
10
54
|
|
11
|
-
|
12
|
-
|
13
|
-
@
|
14
|
-
|
55
|
+
weblet_file ||= File.join(File.dirname(__FILE__), '..', 'data',
|
56
|
+
'treemap21.txt')
|
57
|
+
@to_html = build_html(weblet_file)
|
58
|
+
|
15
59
|
end
|
60
|
+
|
61
|
+
private
|
16
62
|
|
17
|
-
def
|
18
|
-
|
19
|
-
|
63
|
+
def build_html(weblet_file)
|
64
|
+
|
65
|
+
# used for the box id
|
66
|
+
@counter, @count = 2, 1
|
67
|
+
|
68
|
+
doc3 = Rexle.new("<div id='box1' class='cbox'/>")
|
20
69
|
doc = mapper(doc3, @a, orientation: @orientation)
|
70
|
+
|
71
|
+
cbox_css = doc.root.xpath('//div[@class="cbox1"]').map do |e|
|
72
|
+
hex = 3.times.map { rand(60..250).to_s(16) }.join
|
73
|
+
"#%s { background-color: #%s}" % [e.attributes[:id], hex]
|
74
|
+
end
|
75
|
+
|
21
76
|
boxes = doc.root.xml pretty: true
|
77
|
+
w = Weblet.new(weblet_file)
|
22
78
|
|
23
|
-
|
24
|
-
|
25
|
-
<head>
|
26
|
-
<style>
|
27
|
-
|
28
|
-
.cbox, .long, .cbox1 {
|
29
|
-
width: 100%;
|
30
|
-
height: 100%;
|
31
|
-
}
|
32
|
-
.cbox1 ~.long, .cbox1 {
|
33
|
-
float: left;
|
34
|
-
}
|
35
|
-
.cbox1 {
|
36
|
-
display: flex;
|
37
|
-
justify-content: center;
|
38
|
-
align-items: center;
|
39
|
-
}
|
40
|
-
|
41
|
-
.cbox1 span { background-color: transparent;}
|
42
|
-
|
43
|
-
.c10 {font-size: 8em}
|
44
|
-
.c9 {font-size: 7.5em}
|
45
|
-
.c8 {font-size: 6em}
|
46
|
-
.c7 {font-size: 5.0em}
|
47
|
-
.c6 {font-size: 4.9em}
|
48
|
-
.c5 {font-size: 4.5em}
|
49
|
-
.c4 {font-size: 3.2em}
|
50
|
-
.c3 {font-size: 2.1em}
|
51
|
-
.c2 {font-size: 1.9em}
|
52
|
-
.c1 {font-size: 1.6em}
|
53
|
-
.c0 {font-size: 1.1em}
|
54
|
-
|
55
|
-
</style>
|
56
|
-
</head>
|
57
|
-
<body>
|
58
|
-
|
59
|
-
|
60
|
-
#{boxes}
|
61
|
-
|
62
|
-
</body>
|
63
|
-
</html>
|
64
|
-
EOF
|
79
|
+
w.render :html, binding
|
80
|
+
|
65
81
|
end
|
66
82
|
|
67
|
-
|
68
|
-
|
69
|
-
def add_box(text, attr={}, cfont)
|
70
|
-
|
71
|
-
a = attr.map {|key, value| "%s: %s" % [key, value]}
|
72
|
-
h = {class: 'cbox1 ' + cfont, style: a.join('; ')}
|
83
|
+
def add_box(text, url=nil, attr={})
|
84
|
+
|
73
85
|
span = Rexle::Element.new('span', value: text)
|
86
|
+
|
87
|
+
#a = attr.map {|key, value| "%s: %s" % [key, value]}
|
88
|
+
|
89
|
+
h = {
|
90
|
+
id: 'cbox' + @count.to_s,
|
91
|
+
class: 'cbox1 '
|
92
|
+
}
|
93
|
+
@count = @count + 1
|
94
|
+
|
74
95
|
doc = Rexle::Element.new('div', attributes: h)
|
75
|
-
|
96
|
+
|
97
|
+
if url then
|
98
|
+
anchor = Rexle::Element.new('a', attributes: {href: url, draggable: 'false'})
|
99
|
+
anchor.root.add span
|
100
|
+
doc.root.add anchor.root
|
101
|
+
else
|
102
|
+
doc.root.add span
|
103
|
+
|
104
|
+
end
|
105
|
+
|
76
106
|
doc.root
|
77
|
-
|
107
|
+
|
78
108
|
end
|
79
109
|
|
80
110
|
def mapper(doc, a, orientation: :landscape, total: 100)
|
81
|
-
|
111
|
+
|
82
112
|
if @debug then
|
113
|
+
puts 'a: ' + a.inspect
|
83
114
|
puts 'orientation: ' + orientation.inspect
|
84
115
|
puts 'total: ' + total.inspect
|
85
116
|
end
|
@@ -91,52 +122,134 @@ EOF
|
|
91
122
|
@canvas_height = 100; @canvas_width = @canvas_height / 2
|
92
123
|
'cbox'
|
93
124
|
end
|
94
|
-
|
95
|
-
|
125
|
+
|
126
|
+
a.map! do |x|
|
127
|
+
x[1] = x[1].nil? ? 1 : x[1].to_f
|
128
|
+
x
|
129
|
+
end
|
96
130
|
|
97
131
|
# find the largest box
|
98
|
-
a2 = a.sort_by
|
99
|
-
|
100
|
-
|
132
|
+
a2 = a.sort_by {|_, val, _| val}
|
133
|
+
|
134
|
+
# get the total value
|
135
|
+
total = a2.sum {|x| x[1]}
|
136
|
+
puts 'total ; ' + total.inspect if @debug
|
137
|
+
|
138
|
+
|
139
|
+
# calculate the percentages
|
140
|
+
a3 = a2.map do |title, val, url, list|
|
141
|
+
apct = 100 / (total / val.to_f)
|
142
|
+
[title, val, url, list, apct]
|
143
|
+
end
|
144
|
+
puts 'a3: ' + a3.inspect if @debug
|
101
145
|
|
146
|
+
puts 'a3.first: ' + a3.first.inspect if @debug
|
147
|
+
item = a3.pop
|
148
|
+
|
149
|
+
percent = item[1]
|
102
150
|
remainder = total - percent
|
103
151
|
# how much space does the largest box take?
|
104
|
-
|
105
|
-
|
152
|
+
rpct = 100 / (total / percent.to_f)
|
153
|
+
rem_pct = 100 - rpct
|
106
154
|
|
107
|
-
new_orientation = if
|
155
|
+
new_orientation = if rpct.round <= 133 and rpct.round >= 9993 then
|
108
156
|
orientation
|
109
157
|
else
|
110
158
|
orientation == :landscape ? :portrait : :landscape
|
111
159
|
end
|
112
160
|
|
113
161
|
puts 'new_orientation: ' + new_orientation.inspect if @debug
|
114
|
-
|
115
|
-
dimension = orientation == :landscape ? :width : :height
|
116
162
|
|
117
|
-
|
118
|
-
|
119
|
-
|
163
|
+
dimension = orientation == :landscape ? :width : :height
|
164
|
+
hstyle = { dimension => rpct.round.to_s + '%' }
|
165
|
+
style = hstyle.map {|key, value| "%s: %s" % [key, value]}.join(';')
|
166
|
+
|
167
|
+
h = {
|
168
|
+
class: klass,
|
169
|
+
style: style
|
120
170
|
}
|
121
171
|
|
122
|
-
|
123
|
-
|
172
|
+
div = Rexle::Element.new('div', attributes: h)
|
173
|
+
|
174
|
+
|
175
|
+
if item[3].is_a? Array then
|
176
|
+
|
177
|
+
# it's a group item
|
178
|
+
group_name, url = item.values_at(0, 2)
|
179
|
+
#<div class='glabel'> <span>Group A</span> </div>
|
180
|
+
group = Rexle::Element.new('div', attributes: {style: style, class: 'glabel'})
|
181
|
+
span = Rexle::Element.new('span', value: group_name)
|
182
|
+
|
183
|
+
if url then
|
184
|
+
|
185
|
+
anchor = Rexle::Element.new('a', attributes: {href: url})
|
186
|
+
anchor.root.add span
|
187
|
+
group.add anchor.root
|
188
|
+
|
189
|
+
else
|
190
|
+
|
191
|
+
group.add span
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
div.add group
|
196
|
+
|
197
|
+
style = "%s: %s%%; font-size: %s%%" % [ dimension, rem_pct.round,
|
198
|
+
rem_pct.round]
|
199
|
+
doc4 = Rexle.new("<div id='box%s' class='%s' style='%s'/>" % \
|
200
|
+
[@counter, klass, style])
|
201
|
+
puts ('rem_pct: ' + rem_pct.inspect).debug if @debug
|
202
|
+
mapper(div, item[3], orientation: orientation)
|
203
|
+
|
204
|
+
#group_foot = Rexle::Element.new('div', attributes: {class: 'gfoot'})
|
205
|
+
#div.add group_foot
|
206
|
+
|
207
|
+
else
|
208
|
+
|
209
|
+
title, value, url, list, percent = item
|
210
|
+
|
211
|
+
|
212
|
+
if @debug then
|
213
|
+
puts 'percent: ' + percent.inspect
|
214
|
+
end
|
215
|
+
|
216
|
+
#e = add_box(title, url, {}, ("c%02d" % factor).to_s[0..-2])
|
217
|
+
e = add_box(title, url, {})
|
218
|
+
puts 'e: ' + e.inspect if @debug
|
219
|
+
|
220
|
+
end
|
221
|
+
|
222
|
+
div.add e
|
223
|
+
doc.root.add div
|
124
224
|
|
125
|
-
|
225
|
+
if a3.any? then
|
126
226
|
|
127
|
-
|
227
|
+
style = "%s: %s%%; font-size: %s%%" % [ dimension, rem_pct.round,
|
228
|
+
rem_pct.round + 15]
|
229
|
+
doc3 = Rexle.new("<div id='box%s' class='%s' style='%s'/>" % \
|
230
|
+
[@counter, klass, style])
|
231
|
+
@counter += 1
|
128
232
|
|
129
|
-
|
130
|
-
|
131
|
-
|
233
|
+
puts ('_rem_pct: ' + rem_pct.inspect).debug if @debug
|
234
|
+
doc2 = mapper(doc3, a3, orientation: new_orientation, total: remainder)
|
235
|
+
doc.root.add doc2.root
|
132
236
|
|
133
|
-
|
237
|
+
end
|
238
|
+
|
239
|
+
return doc
|
134
240
|
|
135
|
-
|
241
|
+
end
|
242
|
+
|
243
|
+
def scan_xml(e)
|
136
244
|
|
137
|
-
|
245
|
+
e.xpath('item').map do |node|
|
138
246
|
|
139
|
-
|
247
|
+
title, pct, url = node.attributes.values
|
248
|
+
|
249
|
+
r = [title, pct, url]
|
250
|
+
r << scan_xml(node) if node.children.any?
|
251
|
+
r
|
252
|
+
end
|
140
253
|
|
141
254
|
end
|
142
255
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: treemap21
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James Robertson
|
@@ -35,28 +35,48 @@ cert_chain:
|
|
35
35
|
12lnvOZUZbofT7ctIMQL18INESoDYcmiH9r34KV6UCK9H/Ifm5CPKEYee8nilRM+
|
36
36
|
yIv4TcA8Psh7eTn7IAvLK4C0
|
37
37
|
-----END CERTIFICATE-----
|
38
|
-
date: 2021-05-
|
38
|
+
date: 2021-05-18 00:00:00.000000000 Z
|
39
39
|
dependencies:
|
40
40
|
- !ruby/object:Gem::Dependency
|
41
|
-
name:
|
41
|
+
name: polyrex
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
43
43
|
requirements:
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '1.
|
46
|
+
version: '1.3'
|
47
47
|
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: 1.
|
49
|
+
version: 1.3.1
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '1.
|
56
|
+
version: '1.3'
|
57
57
|
- - ">="
|
58
58
|
- !ruby/object:Gem::Version
|
59
|
-
version: 1.
|
59
|
+
version: 1.3.1
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: weblet
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - "~>"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0.3'
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.3.5
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.3'
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 0.3.5
|
60
80
|
description:
|
61
81
|
email: digital.robertson@gmail.com
|
62
82
|
executables: []
|
@@ -87,5 +107,5 @@ rubyforge_project:
|
|
87
107
|
rubygems_version: 2.7.10
|
88
108
|
signing_key:
|
89
109
|
specification_version: 4
|
90
|
-
summary:
|
110
|
+
summary: Treemapping gem which generates an HTML document.
|
91
111
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|