rubyvis 0.6.0 → 0.6.1
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 +7 -0
- data/.gitignore +16 -0
- data/.travis.yml +13 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +37 -0
- data/History.txt +6 -0
- data/LICENSE.txt +23 -0
- data/{README.txt → README.md} +15 -12
- data/Rakefile +4 -11
- data/lib/rubyvis.rb +1 -1
- data/lib/rubyvis/scale/quantitative.rb +14 -18
- data/lib/rubyvis/scene/svg_label.rb +1 -1
- data/rubyvis.gemspec +21 -0
- data/spec/anchor_spec.rb +2 -1
- data/spec/line_spec.rb +2 -2
- data/spec/scale_linear_datetime_spec.rb +23 -8
- data/spec/spec_helper.rb +2 -1
- metadata +31 -214
- data/.gemtest +0 -0
- data/vendor/protovis/protovis-r3.3.js +0 -287
- data/vendor/protovis/src/behavior/Behavior.js +0 -32
- data/vendor/protovis/src/behavior/Drag.js +0 -112
- data/vendor/protovis/src/behavior/Pan.js +0 -110
- data/vendor/protovis/src/behavior/Point.js +0 -157
- data/vendor/protovis/src/behavior/Resize.js +0 -104
- data/vendor/protovis/src/behavior/Select.js +0 -100
- data/vendor/protovis/src/behavior/Zoom.js +0 -85
- data/vendor/protovis/src/color/Color.js +0 -598
- data/vendor/protovis/src/color/Colors.js +0 -135
- data/vendor/protovis/src/color/Ramp.js +0 -17
- data/vendor/protovis/src/data/Arrays.js +0 -277
- data/vendor/protovis/src/data/Dom.js +0 -380
- data/vendor/protovis/src/data/Flatten.js +0 -146
- data/vendor/protovis/src/data/Histogram.js +0 -120
- data/vendor/protovis/src/data/LinearScale.js +0 -54
- data/vendor/protovis/src/data/LogScale.js +0 -142
- data/vendor/protovis/src/data/Nest.js +0 -257
- data/vendor/protovis/src/data/Numbers.js +0 -313
- data/vendor/protovis/src/data/Objects.js +0 -78
- data/vendor/protovis/src/data/OrdinalScale.js +0 -267
- data/vendor/protovis/src/data/QuantileScale.js +0 -180
- data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
- data/vendor/protovis/src/data/RootScale.js +0 -55
- data/vendor/protovis/src/data/Scale.js +0 -86
- data/vendor/protovis/src/data/Transform.js +0 -109
- data/vendor/protovis/src/data/Tree.js +0 -124
- data/vendor/protovis/src/data/Vector.js +0 -118
- data/vendor/protovis/src/geo/Geo.js +0 -5
- data/vendor/protovis/src/geo/GeoScale.js +0 -307
- data/vendor/protovis/src/geo/LatLng.js +0 -23
- data/vendor/protovis/src/geo/Projection.js +0 -43
- data/vendor/protovis/src/geo/Projections.js +0 -117
- data/vendor/protovis/src/lang/Array.js +0 -112
- data/vendor/protovis/src/lang/init.js +0 -26
- data/vendor/protovis/src/layout/Arc.js +0 -178
- data/vendor/protovis/src/layout/Bullet.js +0 -164
- data/vendor/protovis/src/layout/Cluster.js +0 -205
- data/vendor/protovis/src/layout/Force.js +0 -309
- data/vendor/protovis/src/layout/Grid.js +0 -119
- data/vendor/protovis/src/layout/Hierarchy.js +0 -249
- data/vendor/protovis/src/layout/Horizon.js +0 -159
- data/vendor/protovis/src/layout/Indent.js +0 -83
- data/vendor/protovis/src/layout/Layout.js +0 -56
- data/vendor/protovis/src/layout/Matrix.js +0 -177
- data/vendor/protovis/src/layout/Network.js +0 -302
- data/vendor/protovis/src/layout/Pack.js +0 -323
- data/vendor/protovis/src/layout/Partition.js +0 -203
- data/vendor/protovis/src/layout/Rollup.js +0 -203
- data/vendor/protovis/src/layout/Stack.js +0 -391
- data/vendor/protovis/src/layout/Tree.js +0 -282
- data/vendor/protovis/src/layout/Treemap.js +0 -347
- data/vendor/protovis/src/mark/Anchor.js +0 -81
- data/vendor/protovis/src/mark/Area.js +0 -268
- data/vendor/protovis/src/mark/Bar.js +0 -93
- data/vendor/protovis/src/mark/Dot.js +0 -212
- data/vendor/protovis/src/mark/Ease.js +0 -150
- data/vendor/protovis/src/mark/Image.js +0 -154
- data/vendor/protovis/src/mark/Label.js +0 -155
- data/vendor/protovis/src/mark/Line.js +0 -195
- data/vendor/protovis/src/mark/Mark.js +0 -1237
- data/vendor/protovis/src/mark/Panel.js +0 -273
- data/vendor/protovis/src/mark/Rule.js +0 -143
- data/vendor/protovis/src/mark/Transient.js +0 -7
- data/vendor/protovis/src/mark/Transition.js +0 -195
- data/vendor/protovis/src/mark/Wedge.js +0 -244
- data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
- data/vendor/protovis/src/physics/ChargeForce.js +0 -184
- data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
- data/vendor/protovis/src/physics/Constraint.js +0 -26
- data/vendor/protovis/src/physics/DragForce.js +0 -49
- data/vendor/protovis/src/physics/Force.js +0 -25
- data/vendor/protovis/src/physics/Particle.js +0 -81
- data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
- data/vendor/protovis/src/physics/Quadtree.js +0 -195
- data/vendor/protovis/src/physics/Simulation.js +0 -159
- data/vendor/protovis/src/physics/SpringForce.js +0 -141
- data/vendor/protovis/src/pv-internals.js +0 -154
- data/vendor/protovis/src/pv.js +0 -95
- data/vendor/protovis/src/scene/SvgArea.js +0 -172
- data/vendor/protovis/src/scene/SvgBar.js +0 -28
- data/vendor/protovis/src/scene/SvgCurve.js +0 -354
- data/vendor/protovis/src/scene/SvgDot.js +0 -81
- data/vendor/protovis/src/scene/SvgImage.js +0 -45
- data/vendor/protovis/src/scene/SvgLabel.js +0 -46
- data/vendor/protovis/src/scene/SvgLine.js +0 -159
- data/vendor/protovis/src/scene/SvgPanel.js +0 -126
- data/vendor/protovis/src/scene/SvgRule.js +0 -26
- data/vendor/protovis/src/scene/SvgScene.js +0 -185
- data/vendor/protovis/src/scene/SvgWedge.js +0 -66
- data/vendor/protovis/src/text/DateFormat.js +0 -262
- data/vendor/protovis/src/text/Format.js +0 -78
- data/vendor/protovis/src/text/NumberFormat.js +0 -227
- data/vendor/protovis/src/text/TimeFormat.js +0 -115
|
@@ -1,323 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new, empty circle-packing layout. Layouts are not typically
|
|
3
|
-
* constructed directly; instead, they are added to an existing panel via
|
|
4
|
-
* {@link pv.Mark#add}.
|
|
5
|
-
*
|
|
6
|
-
* @class Implements a hierarchical layout using circle-packing. The meaning of
|
|
7
|
-
* the exported mark prototypes changes slightly in the space-filling
|
|
8
|
-
* implementation:<ul>
|
|
9
|
-
*
|
|
10
|
-
* <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Dot}.
|
|
11
|
-
*
|
|
12
|
-
* <p><li><tt>link</tt> - unsupported; undefined. Links are encoded implicitly
|
|
13
|
-
* in the arrangement of the space-filling nodes.
|
|
14
|
-
*
|
|
15
|
-
* <p><li><tt>label</tt> - for rendering node labels; typically a
|
|
16
|
-
* {@link pv.Label}.
|
|
17
|
-
*
|
|
18
|
-
* </ul>The pack layout support dynamic sizing for leaf nodes, if a
|
|
19
|
-
* {@link #size} psuedo-property is specified. The default size function returns
|
|
20
|
-
* 1, causing all leaf nodes to be sized equally, and all internal nodes to be
|
|
21
|
-
* sized by the number of leaf nodes they have as descendants.
|
|
22
|
-
*
|
|
23
|
-
* <p>The size function can be used in conjunction with the order property,
|
|
24
|
-
* which allows the nodes to the sorted by the computed size. Note: for sorting
|
|
25
|
-
* based on other data attributes, simply use the default <tt>null</tt> for the
|
|
26
|
-
* order property, and sort the nodes beforehand using the {@link pv.Dom}
|
|
27
|
-
* operator.
|
|
28
|
-
*
|
|
29
|
-
* <p>For more details on how to use this layout, see
|
|
30
|
-
* {@link pv.Layout.Hierarchy}.
|
|
31
|
-
*
|
|
32
|
-
* @extends pv.Layout.Hierarchy
|
|
33
|
-
* @see <a href="http://portal.acm.org/citation.cfm?id=1124772.1124851"
|
|
34
|
-
* >"Visualization of large hierarchical data by circle packing"</a> by W. Wang,
|
|
35
|
-
* H. Wang, G. Dai, and H. Wang, ACM CHI 2006.
|
|
36
|
-
*/
|
|
37
|
-
pv.Layout.Pack = function() {
|
|
38
|
-
pv.Layout.Hierarchy.call(this);
|
|
39
|
-
|
|
40
|
-
this.node
|
|
41
|
-
.shapeRadius(function(n) { return n.radius; })
|
|
42
|
-
.strokeStyle("rgb(31, 119, 180)")
|
|
43
|
-
.fillStyle("rgba(31, 119, 180, .25)");
|
|
44
|
-
|
|
45
|
-
this.label
|
|
46
|
-
.textAlign("center");
|
|
47
|
-
|
|
48
|
-
/* Hide unsupported link. */
|
|
49
|
-
delete this.link;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
pv.Layout.Pack.prototype = pv.extend(pv.Layout.Hierarchy)
|
|
53
|
-
.property("spacing", Number)
|
|
54
|
-
.property("order", String); // ascending, descending, reverse, null
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Default properties for circle-packing layouts. The default spacing parameter
|
|
58
|
-
* is 1 and the default order is "ascending".
|
|
59
|
-
*
|
|
60
|
-
* @type pv.Layout.Pack
|
|
61
|
-
*/
|
|
62
|
-
pv.Layout.Pack.prototype.defaults = new pv.Layout.Pack()
|
|
63
|
-
.extend(pv.Layout.Hierarchy.prototype.defaults)
|
|
64
|
-
.spacing(1)
|
|
65
|
-
.order("ascending");
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The spacing parameter; defaults to 1, which provides a little bit of padding
|
|
69
|
-
* between sibling nodes and the enclosing circle. Larger values increase the
|
|
70
|
-
* spacing, by making the sibling nodes smaller; a value of zero makes the leaf
|
|
71
|
-
* nodes as large as possible, with no padding on enclosing circles.
|
|
72
|
-
*
|
|
73
|
-
* @type number
|
|
74
|
-
* @name pv.Layout.Pack.prototype.spacing
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* The sibling node order. The default order is <tt>null</tt>, which means to
|
|
79
|
-
* use the sibling order specified by the nodes property as-is. A value of
|
|
80
|
-
* "ascending" will sort siblings in ascending order of size, while "descending"
|
|
81
|
-
* will do the reverse. For sorting based on data attributes other than size,
|
|
82
|
-
* use the default <tt>null</tt> for the order property, and sort the nodes
|
|
83
|
-
* beforehand using the {@link pv.Dom} operator.
|
|
84
|
-
*
|
|
85
|
-
* @see pv.Dom.Node#sort
|
|
86
|
-
* @type string
|
|
87
|
-
* @name pv.Layout.Pack.prototype.order
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
/** @private The default size function. */
|
|
91
|
-
pv.Layout.Pack.prototype.$radius = function() { return 1; };
|
|
92
|
-
|
|
93
|
-
// TODO is it possible for spacing to operate in pixel space?
|
|
94
|
-
// Right now it appears to be multiples of the smallest radius.
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Specifies the sizing function. By default, a sizing function is disabled and
|
|
98
|
-
* all nodes are given constant size. The sizing function is invoked for each
|
|
99
|
-
* leaf node in the tree (passed to the constructor).
|
|
100
|
-
*
|
|
101
|
-
* <p>For example, if the tree data structure represents a file system, with
|
|
102
|
-
* files as leaf nodes, and each file has a <tt>bytes</tt> attribute, you can
|
|
103
|
-
* specify a size function as:
|
|
104
|
-
*
|
|
105
|
-
* <pre> .size(function(d) d.bytes)</pre>
|
|
106
|
-
*
|
|
107
|
-
* As with other properties, a size function may specify additional arguments to
|
|
108
|
-
* access the data associated with the layout and any enclosing panels.
|
|
109
|
-
*
|
|
110
|
-
* @param {function} f the new sizing function.
|
|
111
|
-
* @returns {pv.Layout.Pack} this.
|
|
112
|
-
*/
|
|
113
|
-
pv.Layout.Pack.prototype.size = function(f) {
|
|
114
|
-
this.$radius = typeof f == "function"
|
|
115
|
-
? function() { return Math.sqrt(f.apply(this, arguments)); }
|
|
116
|
-
: (f = Math.sqrt(f), function() { return f; });
|
|
117
|
-
return this;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/** @private */
|
|
121
|
-
pv.Layout.Pack.prototype.buildImplied = function(s) {
|
|
122
|
-
if (pv.Layout.Hierarchy.prototype.buildImplied.call(this, s)) return;
|
|
123
|
-
|
|
124
|
-
var that = this,
|
|
125
|
-
nodes = s.nodes,
|
|
126
|
-
root = nodes[0];
|
|
127
|
-
|
|
128
|
-
/** @private Compute the radii of the leaf nodes. */
|
|
129
|
-
function radii(nodes) {
|
|
130
|
-
var stack = pv.Mark.stack;
|
|
131
|
-
stack.unshift(null);
|
|
132
|
-
for (var i = 0, n = nodes.length; i < n; i++) {
|
|
133
|
-
var c = nodes[i];
|
|
134
|
-
if (!c.firstChild) {
|
|
135
|
-
c.radius = that.$radius.apply(that, (stack[0] = c, stack));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
stack.shift();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/** @private */
|
|
142
|
-
function packTree(n) {
|
|
143
|
-
var nodes = [];
|
|
144
|
-
for (var c = n.firstChild; c; c = c.nextSibling) {
|
|
145
|
-
if (c.firstChild) c.radius = packTree(c);
|
|
146
|
-
c.n = c.p = c;
|
|
147
|
-
nodes.push(c);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/* Sort. */
|
|
151
|
-
switch (s.order) {
|
|
152
|
-
case "ascending": {
|
|
153
|
-
nodes.sort(function(a, b) { return a.radius - b.radius; });
|
|
154
|
-
break;
|
|
155
|
-
}
|
|
156
|
-
case "descending": {
|
|
157
|
-
nodes.sort(function(a, b) { return b.radius - a.radius; });
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
case "reverse": nodes.reverse(); break;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
return packCircle(nodes);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/** @private */
|
|
167
|
-
function packCircle(nodes) {
|
|
168
|
-
var xMin = Infinity,
|
|
169
|
-
xMax = -Infinity,
|
|
170
|
-
yMin = Infinity,
|
|
171
|
-
yMax = -Infinity,
|
|
172
|
-
a, b, c, j, k;
|
|
173
|
-
|
|
174
|
-
/** @private */
|
|
175
|
-
function bound(n) {
|
|
176
|
-
xMin = Math.min(n.x - n.radius, xMin);
|
|
177
|
-
xMax = Math.max(n.x + n.radius, xMax);
|
|
178
|
-
yMin = Math.min(n.y - n.radius, yMin);
|
|
179
|
-
yMax = Math.max(n.y + n.radius, yMax);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/** @private */
|
|
183
|
-
function insert(a, b) {
|
|
184
|
-
var c = a.n;
|
|
185
|
-
a.n = b;
|
|
186
|
-
b.p = a;
|
|
187
|
-
b.n = c;
|
|
188
|
-
c.p = b;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/** @private */
|
|
192
|
-
function splice(a, b) {
|
|
193
|
-
a.n = b;
|
|
194
|
-
b.p = a;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** @private */
|
|
198
|
-
function intersects(a, b) {
|
|
199
|
-
var dx = b.x - a.x,
|
|
200
|
-
dy = b.y - a.y,
|
|
201
|
-
dr = a.radius + b.radius;
|
|
202
|
-
return (dr * dr - dx * dx - dy * dy) > .001; // within epsilon
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/* Create first node. */
|
|
206
|
-
a = nodes[0];
|
|
207
|
-
a.x = -a.radius;
|
|
208
|
-
a.y = 0;
|
|
209
|
-
bound(a);
|
|
210
|
-
|
|
211
|
-
/* Create second node. */
|
|
212
|
-
if (nodes.length > 1) {
|
|
213
|
-
b = nodes[1];
|
|
214
|
-
b.x = b.radius;
|
|
215
|
-
b.y = 0;
|
|
216
|
-
bound(b);
|
|
217
|
-
|
|
218
|
-
/* Create third node and build chain. */
|
|
219
|
-
if (nodes.length > 2) {
|
|
220
|
-
c = nodes[2];
|
|
221
|
-
place(a, b, c);
|
|
222
|
-
bound(c);
|
|
223
|
-
insert(a, c);
|
|
224
|
-
a.p = c;
|
|
225
|
-
insert(c, b);
|
|
226
|
-
b = a.n;
|
|
227
|
-
|
|
228
|
-
/* Now iterate through the rest. */
|
|
229
|
-
for (var i = 3; i < nodes.length; i++) {
|
|
230
|
-
place(a, b, c = nodes[i]);
|
|
231
|
-
|
|
232
|
-
/* Search for the closest intersection. */
|
|
233
|
-
var isect = 0, s1 = 1, s2 = 1;
|
|
234
|
-
for (j = b.n; j != b; j = j.n, s1++) {
|
|
235
|
-
if (intersects(j, c)) {
|
|
236
|
-
isect = 1;
|
|
237
|
-
break;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
if (isect == 1) {
|
|
241
|
-
for (k = a.p; k != j.p; k = k.p, s2++) {
|
|
242
|
-
if (intersects(k, c)) {
|
|
243
|
-
if (s2 < s1) {
|
|
244
|
-
isect = -1;
|
|
245
|
-
j = k;
|
|
246
|
-
}
|
|
247
|
-
break;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/* Update node chain. */
|
|
253
|
-
if (isect == 0) {
|
|
254
|
-
insert(a, c);
|
|
255
|
-
b = c;
|
|
256
|
-
bound(c);
|
|
257
|
-
} else if (isect > 0) {
|
|
258
|
-
splice(a, j);
|
|
259
|
-
b = j;
|
|
260
|
-
i--;
|
|
261
|
-
} else if (isect < 0) {
|
|
262
|
-
splice(j, b);
|
|
263
|
-
a = j;
|
|
264
|
-
i--;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/* Re-center the circles and return the encompassing radius. */
|
|
271
|
-
var cx = (xMin + xMax) / 2,
|
|
272
|
-
cy = (yMin + yMax) / 2,
|
|
273
|
-
cr = 0;
|
|
274
|
-
for (var i = 0; i < nodes.length; i++) {
|
|
275
|
-
var n = nodes[i];
|
|
276
|
-
n.x -= cx;
|
|
277
|
-
n.y -= cy;
|
|
278
|
-
cr = Math.max(cr, n.radius + Math.sqrt(n.x * n.x + n.y * n.y));
|
|
279
|
-
}
|
|
280
|
-
return cr + s.spacing;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/** @private */
|
|
284
|
-
function place(a, b, c) {
|
|
285
|
-
var da = b.radius + c.radius,
|
|
286
|
-
db = a.radius + c.radius,
|
|
287
|
-
dx = b.x - a.x,
|
|
288
|
-
dy = b.y - a.y,
|
|
289
|
-
dc = Math.sqrt(dx * dx + dy * dy),
|
|
290
|
-
cos = (db * db + dc * dc - da * da) / (2 * db * dc),
|
|
291
|
-
theta = Math.acos(cos),
|
|
292
|
-
x = cos * db,
|
|
293
|
-
h = Math.sin(theta) * db;
|
|
294
|
-
dx /= dc;
|
|
295
|
-
dy /= dc;
|
|
296
|
-
c.x = a.x + x * dx + h * dy;
|
|
297
|
-
c.y = a.y + x * dy - h * dx;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/** @private */
|
|
301
|
-
function transform(n, x, y, k) {
|
|
302
|
-
for (var c = n.firstChild; c; c = c.nextSibling) {
|
|
303
|
-
c.x += n.x;
|
|
304
|
-
c.y += n.y;
|
|
305
|
-
transform(c, x, y, k);
|
|
306
|
-
}
|
|
307
|
-
n.x = x + k * n.x;
|
|
308
|
-
n.y = y + k * n.y;
|
|
309
|
-
n.radius *= k;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
radii(nodes);
|
|
313
|
-
|
|
314
|
-
/* Recursively compute the layout. */
|
|
315
|
-
root.x = 0;
|
|
316
|
-
root.y = 0;
|
|
317
|
-
root.radius = packTree(root);
|
|
318
|
-
|
|
319
|
-
var w = this.width(),
|
|
320
|
-
h = this.height(),
|
|
321
|
-
k = 1 / Math.max(2 * root.radius / w, 2 * root.radius / h);
|
|
322
|
-
transform(root, w / 2, h / 2, k);
|
|
323
|
-
};
|
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new, empty partition layout. Layouts are not typically
|
|
3
|
-
* constructed directly; instead, they are added to an existing panel via
|
|
4
|
-
* {@link pv.Mark#add}.
|
|
5
|
-
*
|
|
6
|
-
* @class Implemeents a hierarchical layout using the partition (or sunburst,
|
|
7
|
-
* icicle) algorithm. This layout provides both node-link and space-filling
|
|
8
|
-
* implementations of partition diagrams. In many ways it is similar to
|
|
9
|
-
* {@link pv.Layout.Cluster}, except that leaf nodes are positioned based on
|
|
10
|
-
* their distance from the root.
|
|
11
|
-
*
|
|
12
|
-
* <p>The partition layout support dynamic sizing for leaf nodes, if a
|
|
13
|
-
* {@link #size} psuedo-property is specified. The default size function returns
|
|
14
|
-
* 1, causing all leaf nodes to be sized equally, and all internal nodes to be
|
|
15
|
-
* sized by the number of leaf nodes they have as descendants.
|
|
16
|
-
*
|
|
17
|
-
* <p>The size function can be used in conjunction with the order property,
|
|
18
|
-
* which allows the nodes to the sorted by the computed size. Note: for sorting
|
|
19
|
-
* based on other data attributes, simply use the default <tt>null</tt> for the
|
|
20
|
-
* order property, and sort the nodes beforehand using the {@link pv.Dom}
|
|
21
|
-
* operator.
|
|
22
|
-
*
|
|
23
|
-
* <p>For more details on how to use this layout, see
|
|
24
|
-
* {@link pv.Layout.Hierarchy}.
|
|
25
|
-
*
|
|
26
|
-
* @see pv.Layout.Partition.Fill
|
|
27
|
-
* @extends pv.Layout.Hierarchy
|
|
28
|
-
*/
|
|
29
|
-
pv.Layout.Partition = function() {
|
|
30
|
-
pv.Layout.Hierarchy.call(this);
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
pv.Layout.Partition.prototype = pv.extend(pv.Layout.Hierarchy)
|
|
34
|
-
.property("order", String) // null, ascending, descending?
|
|
35
|
-
.property("orient", String) // top, left, right, bottom, radial
|
|
36
|
-
.property("innerRadius", Number)
|
|
37
|
-
.property("outerRadius", Number);
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* The sibling node order. The default order is <tt>null</tt>, which means to
|
|
41
|
-
* use the sibling order specified by the nodes property as-is. A value of
|
|
42
|
-
* "ascending" will sort siblings in ascending order of size, while "descending"
|
|
43
|
-
* will do the reverse. For sorting based on data attributes other than size,
|
|
44
|
-
* use the default <tt>null</tt> for the order property, and sort the nodes
|
|
45
|
-
* beforehand using the {@link pv.Dom} operator.
|
|
46
|
-
*
|
|
47
|
-
* @see pv.Dom.Node#sort
|
|
48
|
-
* @type string
|
|
49
|
-
* @name pv.Layout.Partition.prototype.order
|
|
50
|
-
*/
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* The orientation. The default orientation is "top", which means that the root
|
|
54
|
-
* node is placed on the top edge, leaf nodes appear at the bottom, and internal
|
|
55
|
-
* nodes are in-between. The following orientations are supported:<ul>
|
|
56
|
-
*
|
|
57
|
-
* <li>left - left-to-right.
|
|
58
|
-
* <li>right - right-to-left.
|
|
59
|
-
* <li>top - top-to-bottom.
|
|
60
|
-
* <li>bottom - bottom-to-top.
|
|
61
|
-
* <li>radial - radially, with the root at the center.</ul>
|
|
62
|
-
*
|
|
63
|
-
* @type string
|
|
64
|
-
* @name pv.Layout.Partition.prototype.orient
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* The inner radius; defaults to 0. This property applies only to radial
|
|
69
|
-
* orientations, and can be used to compress the layout radially. Note that for
|
|
70
|
-
* the node-link implementation, the root node is always at the center,
|
|
71
|
-
* regardless of the value of this property; this property only affects internal
|
|
72
|
-
* and leaf nodes. For the space-filling implementation, a non-zero value of
|
|
73
|
-
* this property will result in the root node represented as a ring rather than
|
|
74
|
-
* a circle.
|
|
75
|
-
*
|
|
76
|
-
* @type number
|
|
77
|
-
* @name pv.Layout.Partition.prototype.innerRadius
|
|
78
|
-
*/
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* The outer radius; defaults to fill the containing panel, based on the height
|
|
82
|
-
* and width of the layout. If the layout has no height and width specified, it
|
|
83
|
-
* will extend to fill the enclosing panel.
|
|
84
|
-
*
|
|
85
|
-
* @type number
|
|
86
|
-
* @name pv.Layout.Partition.prototype.outerRadius
|
|
87
|
-
*/
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Default properties for partition layouts. The default orientation is "top".
|
|
91
|
-
*
|
|
92
|
-
* @type pv.Layout.Partition
|
|
93
|
-
*/
|
|
94
|
-
pv.Layout.Partition.prototype.defaults = new pv.Layout.Partition()
|
|
95
|
-
.extend(pv.Layout.Hierarchy.prototype.defaults)
|
|
96
|
-
.orient("top");
|
|
97
|
-
|
|
98
|
-
/** @private */
|
|
99
|
-
pv.Layout.Partition.prototype.$size = function() { return 1; };
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Specifies the sizing function. By default, a sizing function is disabled and
|
|
103
|
-
* all nodes are given constant size. The sizing function is invoked for each
|
|
104
|
-
* leaf node in the tree (passed to the constructor).
|
|
105
|
-
*
|
|
106
|
-
* <p>For example, if the tree data structure represents a file system, with
|
|
107
|
-
* files as leaf nodes, and each file has a <tt>bytes</tt> attribute, you can
|
|
108
|
-
* specify a size function as:
|
|
109
|
-
*
|
|
110
|
-
* <pre> .size(function(d) d.bytes)</pre>
|
|
111
|
-
*
|
|
112
|
-
* As with other properties, a size function may specify additional arguments to
|
|
113
|
-
* access the data associated with the layout and any enclosing panels.
|
|
114
|
-
*
|
|
115
|
-
* @param {function} f the new sizing function.
|
|
116
|
-
* @returns {pv.Layout.Partition} this.
|
|
117
|
-
*/
|
|
118
|
-
pv.Layout.Partition.prototype.size = function(f) {
|
|
119
|
-
this.$size = f;
|
|
120
|
-
return this;
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
/** @private */
|
|
124
|
-
pv.Layout.Partition.prototype.buildImplied = function(s) {
|
|
125
|
-
if (pv.Layout.Hierarchy.prototype.buildImplied.call(this, s)) return;
|
|
126
|
-
|
|
127
|
-
var that = this,
|
|
128
|
-
root = s.nodes[0],
|
|
129
|
-
stack = pv.Mark.stack,
|
|
130
|
-
maxDepth = 0;
|
|
131
|
-
|
|
132
|
-
/* Recursively compute the tree depth and node size. */
|
|
133
|
-
stack.unshift(null);
|
|
134
|
-
root.visitAfter(function(n, i) {
|
|
135
|
-
if (i > maxDepth) maxDepth = i;
|
|
136
|
-
n.size = n.firstChild
|
|
137
|
-
? pv.sum(n.childNodes, function(n) { return n.size; })
|
|
138
|
-
: that.$size.apply(that, (stack[0] = n, stack));
|
|
139
|
-
});
|
|
140
|
-
stack.shift();
|
|
141
|
-
|
|
142
|
-
/* Order */
|
|
143
|
-
switch (s.order) {
|
|
144
|
-
case "ascending": root.sort(function(a, b) { return a.size - b.size; }); break;
|
|
145
|
-
case "descending": root.sort(function(b, a) { return a.size - b.size; }); break;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/* Compute the unit breadth and depth of each node. */
|
|
149
|
-
var ds = 1 / maxDepth;
|
|
150
|
-
root.minBreadth = 0;
|
|
151
|
-
root.breadth = .5;
|
|
152
|
-
root.maxBreadth = 1;
|
|
153
|
-
root.visitBefore(function(n) {
|
|
154
|
-
var b = n.minBreadth, s = n.maxBreadth - b;
|
|
155
|
-
for (var c = n.firstChild; c; c = c.nextSibling) {
|
|
156
|
-
c.minBreadth = b;
|
|
157
|
-
c.maxBreadth = b += (c.size / n.size) * s;
|
|
158
|
-
c.breadth = (b + c.minBreadth) / 2;
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
root.visitAfter(function(n, i) {
|
|
162
|
-
n.minDepth = (i - 1) * ds;
|
|
163
|
-
n.maxDepth = n.depth = i * ds;
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
pv.Layout.Hierarchy.NodeLink.buildImplied.call(this, s);
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Constructs a new, empty space-filling partition layout. Layouts are not
|
|
171
|
-
* typically constructed directly; instead, they are added to an existing panel
|
|
172
|
-
* via {@link pv.Mark#add}.
|
|
173
|
-
*
|
|
174
|
-
* @class A variant of partition layout that is space-filling. The meaning of
|
|
175
|
-
* the exported mark prototypes changes slightly in the space-filling
|
|
176
|
-
* implementation:<ul>
|
|
177
|
-
*
|
|
178
|
-
* <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Bar} for
|
|
179
|
-
* non-radial orientations, and a {@link pv.Wedge} for radial orientations.
|
|
180
|
-
*
|
|
181
|
-
* <p><li><tt>link</tt> - unsupported; undefined. Links are encoded implicitly
|
|
182
|
-
* in the arrangement of the space-filling nodes.
|
|
183
|
-
*
|
|
184
|
-
* <p><li><tt>label</tt> - for rendering node labels; typically a
|
|
185
|
-
* {@link pv.Label}.
|
|
186
|
-
*
|
|
187
|
-
* </ul>For more details on how to use this layout, see
|
|
188
|
-
* {@link pv.Layout.Partition}.
|
|
189
|
-
*
|
|
190
|
-
* @extends pv.Layout.Partition
|
|
191
|
-
*/
|
|
192
|
-
pv.Layout.Partition.Fill = function() {
|
|
193
|
-
pv.Layout.Partition.call(this);
|
|
194
|
-
pv.Layout.Hierarchy.Fill.constructor.call(this);
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
pv.Layout.Partition.Fill.prototype = pv.extend(pv.Layout.Partition);
|
|
198
|
-
|
|
199
|
-
/** @private */
|
|
200
|
-
pv.Layout.Partition.Fill.prototype.buildImplied = function(s) {
|
|
201
|
-
if (pv.Layout.Partition.prototype.buildImplied.call(this, s)) return;
|
|
202
|
-
pv.Layout.Hierarchy.Fill.buildImplied.call(this, s);
|
|
203
|
-
};
|