rubyvis 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +37 -0
  6. data/History.txt +6 -0
  7. data/LICENSE.txt +23 -0
  8. data/{README.txt → README.md} +15 -12
  9. data/Rakefile +4 -11
  10. data/lib/rubyvis.rb +1 -1
  11. data/lib/rubyvis/scale/quantitative.rb +14 -18
  12. data/lib/rubyvis/scene/svg_label.rb +1 -1
  13. data/rubyvis.gemspec +21 -0
  14. data/spec/anchor_spec.rb +2 -1
  15. data/spec/line_spec.rb +2 -2
  16. data/spec/scale_linear_datetime_spec.rb +23 -8
  17. data/spec/spec_helper.rb +2 -1
  18. metadata +31 -214
  19. data/.gemtest +0 -0
  20. data/vendor/protovis/protovis-r3.3.js +0 -287
  21. data/vendor/protovis/src/behavior/Behavior.js +0 -32
  22. data/vendor/protovis/src/behavior/Drag.js +0 -112
  23. data/vendor/protovis/src/behavior/Pan.js +0 -110
  24. data/vendor/protovis/src/behavior/Point.js +0 -157
  25. data/vendor/protovis/src/behavior/Resize.js +0 -104
  26. data/vendor/protovis/src/behavior/Select.js +0 -100
  27. data/vendor/protovis/src/behavior/Zoom.js +0 -85
  28. data/vendor/protovis/src/color/Color.js +0 -598
  29. data/vendor/protovis/src/color/Colors.js +0 -135
  30. data/vendor/protovis/src/color/Ramp.js +0 -17
  31. data/vendor/protovis/src/data/Arrays.js +0 -277
  32. data/vendor/protovis/src/data/Dom.js +0 -380
  33. data/vendor/protovis/src/data/Flatten.js +0 -146
  34. data/vendor/protovis/src/data/Histogram.js +0 -120
  35. data/vendor/protovis/src/data/LinearScale.js +0 -54
  36. data/vendor/protovis/src/data/LogScale.js +0 -142
  37. data/vendor/protovis/src/data/Nest.js +0 -257
  38. data/vendor/protovis/src/data/Numbers.js +0 -313
  39. data/vendor/protovis/src/data/Objects.js +0 -78
  40. data/vendor/protovis/src/data/OrdinalScale.js +0 -267
  41. data/vendor/protovis/src/data/QuantileScale.js +0 -180
  42. data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
  43. data/vendor/protovis/src/data/RootScale.js +0 -55
  44. data/vendor/protovis/src/data/Scale.js +0 -86
  45. data/vendor/protovis/src/data/Transform.js +0 -109
  46. data/vendor/protovis/src/data/Tree.js +0 -124
  47. data/vendor/protovis/src/data/Vector.js +0 -118
  48. data/vendor/protovis/src/geo/Geo.js +0 -5
  49. data/vendor/protovis/src/geo/GeoScale.js +0 -307
  50. data/vendor/protovis/src/geo/LatLng.js +0 -23
  51. data/vendor/protovis/src/geo/Projection.js +0 -43
  52. data/vendor/protovis/src/geo/Projections.js +0 -117
  53. data/vendor/protovis/src/lang/Array.js +0 -112
  54. data/vendor/protovis/src/lang/init.js +0 -26
  55. data/vendor/protovis/src/layout/Arc.js +0 -178
  56. data/vendor/protovis/src/layout/Bullet.js +0 -164
  57. data/vendor/protovis/src/layout/Cluster.js +0 -205
  58. data/vendor/protovis/src/layout/Force.js +0 -309
  59. data/vendor/protovis/src/layout/Grid.js +0 -119
  60. data/vendor/protovis/src/layout/Hierarchy.js +0 -249
  61. data/vendor/protovis/src/layout/Horizon.js +0 -159
  62. data/vendor/protovis/src/layout/Indent.js +0 -83
  63. data/vendor/protovis/src/layout/Layout.js +0 -56
  64. data/vendor/protovis/src/layout/Matrix.js +0 -177
  65. data/vendor/protovis/src/layout/Network.js +0 -302
  66. data/vendor/protovis/src/layout/Pack.js +0 -323
  67. data/vendor/protovis/src/layout/Partition.js +0 -203
  68. data/vendor/protovis/src/layout/Rollup.js +0 -203
  69. data/vendor/protovis/src/layout/Stack.js +0 -391
  70. data/vendor/protovis/src/layout/Tree.js +0 -282
  71. data/vendor/protovis/src/layout/Treemap.js +0 -347
  72. data/vendor/protovis/src/mark/Anchor.js +0 -81
  73. data/vendor/protovis/src/mark/Area.js +0 -268
  74. data/vendor/protovis/src/mark/Bar.js +0 -93
  75. data/vendor/protovis/src/mark/Dot.js +0 -212
  76. data/vendor/protovis/src/mark/Ease.js +0 -150
  77. data/vendor/protovis/src/mark/Image.js +0 -154
  78. data/vendor/protovis/src/mark/Label.js +0 -155
  79. data/vendor/protovis/src/mark/Line.js +0 -195
  80. data/vendor/protovis/src/mark/Mark.js +0 -1237
  81. data/vendor/protovis/src/mark/Panel.js +0 -273
  82. data/vendor/protovis/src/mark/Rule.js +0 -143
  83. data/vendor/protovis/src/mark/Transient.js +0 -7
  84. data/vendor/protovis/src/mark/Transition.js +0 -195
  85. data/vendor/protovis/src/mark/Wedge.js +0 -244
  86. data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
  87. data/vendor/protovis/src/physics/ChargeForce.js +0 -184
  88. data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
  89. data/vendor/protovis/src/physics/Constraint.js +0 -26
  90. data/vendor/protovis/src/physics/DragForce.js +0 -49
  91. data/vendor/protovis/src/physics/Force.js +0 -25
  92. data/vendor/protovis/src/physics/Particle.js +0 -81
  93. data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
  94. data/vendor/protovis/src/physics/Quadtree.js +0 -195
  95. data/vendor/protovis/src/physics/Simulation.js +0 -159
  96. data/vendor/protovis/src/physics/SpringForce.js +0 -141
  97. data/vendor/protovis/src/pv-internals.js +0 -154
  98. data/vendor/protovis/src/pv.js +0 -95
  99. data/vendor/protovis/src/scene/SvgArea.js +0 -172
  100. data/vendor/protovis/src/scene/SvgBar.js +0 -28
  101. data/vendor/protovis/src/scene/SvgCurve.js +0 -354
  102. data/vendor/protovis/src/scene/SvgDot.js +0 -81
  103. data/vendor/protovis/src/scene/SvgImage.js +0 -45
  104. data/vendor/protovis/src/scene/SvgLabel.js +0 -46
  105. data/vendor/protovis/src/scene/SvgLine.js +0 -159
  106. data/vendor/protovis/src/scene/SvgPanel.js +0 -126
  107. data/vendor/protovis/src/scene/SvgRule.js +0 -26
  108. data/vendor/protovis/src/scene/SvgScene.js +0 -185
  109. data/vendor/protovis/src/scene/SvgWedge.js +0 -66
  110. data/vendor/protovis/src/text/DateFormat.js +0 -262
  111. data/vendor/protovis/src/text/Format.js +0 -78
  112. data/vendor/protovis/src/text/NumberFormat.js +0 -227
  113. data/vendor/protovis/src/text/TimeFormat.js +0 -115
@@ -1,83 +0,0 @@
1
- /**
2
- * Constructs a new, empty indent layout. Layouts are not typically constructed
3
- * directly; instead, they are added to an existing panel via
4
- * {@link pv.Mark#add}.
5
- *
6
- * @class Implements a hierarchical layout using the indent algorithm. This
7
- * layout implements a node-link diagram where the nodes are presented in
8
- * preorder traversal, and nodes are indented based on their depth from the
9
- * root. This technique is used ubiquitously by operating systems to represent
10
- * file directories; although it requires much vertical space, indented trees
11
- * allow efficient <i>interactive</i> exploration of trees to find a specific
12
- * node. In addition they allow rapid scanning of node labels, and multivariate
13
- * data such as file sizes can be displayed adjacent to the hierarchy.
14
- *
15
- * <p>The indent layout can be configured using the <tt>depth</tt> and
16
- * <tt>breadth</tt> properties, which control the increments in pixel space for
17
- * each indent and row in the layout. This layout does not support multiple
18
- * orientations; the root node is rendered in the top-left, while
19
- * <tt>breadth</tt> is a vertical offset from the top, and <tt>depth</tt> is a
20
- * horizontal offset from the left.
21
- *
22
- * <p>For more details on how to use this layout, see
23
- * {@link pv.Layout.Hierarchy}.
24
- *
25
- * @extends pv.Layout.Hierarchy
26
- */
27
- pv.Layout.Indent = function() {
28
- pv.Layout.Hierarchy.call(this);
29
- this.link.interpolate("step-after");
30
- };
31
-
32
- pv.Layout.Indent.prototype = pv.extend(pv.Layout.Hierarchy)
33
- .property("depth", Number)
34
- .property("breadth", Number);
35
-
36
- /**
37
- * The horizontal offset between different levels of the tree; defaults to 15.
38
- *
39
- * @type number
40
- * @name pv.Layout.Indent.prototype.depth
41
- */
42
-
43
- /**
44
- * The vertical offset between nodes; defaults to 15.
45
- *
46
- * @type number
47
- * @name pv.Layout.Indent.prototype.breadth
48
- */
49
-
50
- /**
51
- * Default properties for indent layouts. By default the depth and breadth
52
- * offsets are 15 pixels.
53
- *
54
- * @type pv.Layout.Indent
55
- */
56
- pv.Layout.Indent.prototype.defaults = new pv.Layout.Indent()
57
- .extend(pv.Layout.Hierarchy.prototype.defaults)
58
- .depth(15)
59
- .breadth(15);
60
-
61
- /** @private */
62
- pv.Layout.Indent.prototype.buildImplied = function(s) {
63
- if (pv.Layout.Hierarchy.prototype.buildImplied.call(this, s)) return;
64
-
65
- var nodes = s.nodes,
66
- bspace = s.breadth,
67
- dspace = s.depth,
68
- ax = 0,
69
- ay = 0;
70
-
71
- /** @private */
72
- function position(n, breadth, depth) {
73
- n.x = ax + depth++ * dspace;
74
- n.y = ay + breadth++ * bspace;
75
- n.midAngle = 0;
76
- for (var c = n.firstChild; c; c = c.nextSibling) {
77
- breadth = position(c, breadth, depth);
78
- }
79
- return breadth;
80
- }
81
-
82
- position(nodes[0], 1, 1);
83
- };
@@ -1,56 +0,0 @@
1
- /**
2
- * Constructs a new, empty layout with default properties. Layouts are not
3
- * typically constructed directly; instead, a concrete subclass is added to an
4
- * existing panel via {@link pv.Mark#add}.
5
- *
6
- * @class Represents an abstract layout, encapsulating a visualization technique
7
- * such as a streamgraph or treemap. Layouts are themselves containers,
8
- * extending from {@link pv.Panel}, and defining a set of mark prototypes as
9
- * children. These mark prototypes provide default properties that together
10
- * implement the given visualization technique.
11
- *
12
- * <p>Layouts do not initially contain any marks; any exported marks (such as a
13
- * network layout's <tt>link</tt> and <tt>node</tt>) are intended to be used as
14
- * prototypes. By adding a concrete mark, such as a {@link pv.Bar}, to the
15
- * appropriate mark prototype, the mark is added to the layout and inherits the
16
- * given properties. This approach allows further customization of the layout,
17
- * either by choosing a different mark type to add, or more simply by overriding
18
- * some of the layout's defined properties.
19
- *
20
- * <p>Each concrete layout, such as treemap or circle-packing, has different
21
- * behavior and may export different mark prototypes, depending on what marks
22
- * are typically needed to render the desired visualization. Therefore it is
23
- * important to understand how each layout is structured, such that the provided
24
- * mark prototypes are used appropriately.
25
- *
26
- * <p>In addition to the mark prototypes, layouts may define custom properties
27
- * that affect the overall behavior of the layout. For example, a treemap layout
28
- * might use a property to specify which layout algorithm to use. These
29
- * properties are just like other mark properties, and can be defined as
30
- * constants or as functions. As with panels, the data property can be used to
31
- * replicate layouts, and properties can be defined to in terms of layout data.
32
- *
33
- * @extends pv.Panel
34
- */
35
- pv.Layout = function() {
36
- pv.Panel.call(this);
37
- };
38
-
39
- pv.Layout.prototype = pv.extend(pv.Panel);
40
-
41
- /**
42
- * @private Defines a local property with the specified name and cast. Note that
43
- * although the property method is only defined locally, the cast function is
44
- * global, which is necessary since properties are inherited!
45
- *
46
- * @param {string} name the property name.
47
- * @param {function} [cast] the cast function for this property.
48
- */
49
- pv.Layout.prototype.property = function(name, cast) {
50
- if (!this.hasOwnProperty("properties")) {
51
- this.properties = pv.extend(this.properties);
52
- }
53
- this.properties[name] = true;
54
- this.propertyMethod(name, false, pv.Mark.cast[name] = cast);
55
- return this;
56
- };
@@ -1,177 +0,0 @@
1
- /**
2
- * Constructs a new, empty matrix network 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 network visualization using a matrix view. This is, in
7
- * effect, a visualization of the graph's <i>adjacency matrix</i>: the cell at
8
- * row <i>i</i>, column <i>j</i>, corresponds to the link from node <i>i</i> to
9
- * node <i>j</i>. The fill color of each cell is binary by default, and
10
- * corresponds to whether a link exists between the two nodes. If the underlying
11
- * graph has links with variable values, the <tt>fillStyle</tt> property can be
12
- * substited to use an appropriate color function, such as {@link pv.ramp}.
13
- *
14
- * <p>For undirected networks, the matrix is symmetric around the diagonal. For
15
- * directed networks, links in opposite directions can be rendered on opposite
16
- * sides of the diagonal using <tt>directed(true)</tt>. The graph is assumed to
17
- * be undirected by default.
18
- *
19
- * <p>The mark prototypes for this network layout are slightly different than
20
- * other implementations:<ul>
21
- *
22
- * <li><tt>node</tt> - unsupported; undefined. No mark is needed to visualize
23
- * nodes directly, as the nodes are implicit in the location (rows and columns)
24
- * of the links.
25
- *
26
- * <p><li><tt>link</tt> - for rendering links; typically a {@link pv.Bar}. The
27
- * link mark is added directly to the layout, with the data property defined as
28
- * all possible pairs of nodes. Each pair is represented as a
29
- * {@link pv.Network.Layout.Link}, though the <tt>linkValue</tt> attribute may
30
- * be 0 if no link exists in the graph.
31
- *
32
- * <p><li><tt>label</tt> - for rendering node labels; typically a
33
- * {@link pv.Label}. The label mark is added directly to the layout, with the
34
- * data property defined via the layout's <tt>nodes</tt> property; note,
35
- * however, that the nodes are duplicated so as to provide a label across the
36
- * top and down the side. Properties such as <tt>strokeStyle</tt> and
37
- * <tt>fillStyle</tt> can be overridden to compute properties from node data
38
- * dynamically.
39
- *
40
- * </ul>For more details on how to use this layout, see
41
- * {@link pv.Layout.Network}.
42
- *
43
- * @extends pv.Layout.Network
44
- */
45
- pv.Layout.Matrix = function() {
46
- pv.Layout.Network.call(this);
47
- var that = this,
48
- n, // cached matrix size
49
- dx, // cached cell width
50
- dy, // cached cell height
51
- labels, // cached labels (array of strings)
52
- pairs, // cached pairs (array of links)
53
- buildImplied = that.buildImplied;
54
-
55
- /** @private Cache layout state to optimize properties. */
56
- this.buildImplied = function(s) {
57
- buildImplied.call(this, s);
58
- n = s.nodes.length;
59
- dx = s.width / n;
60
- dy = s.height / n;
61
- labels = s.$matrix.labels;
62
- pairs = s.$matrix.pairs;
63
- };
64
-
65
- /* Links are all pairs of nodes. */
66
- this.link
67
- .data(function() { return pairs; })
68
- .left(function() { return dx * (this.index % n); })
69
- .top(function() { return dy * Math.floor(this.index / n); })
70
- .width(function() { return dx; })
71
- .height(function() { return dy; })
72
- .lineWidth(1.5)
73
- .strokeStyle("#fff")
74
- .fillStyle(function(l) { return l.linkValue ? "#555" : "#eee"; })
75
- .parent = this;
76
-
77
- /* No special add for links! */
78
- delete this.link.add;
79
-
80
- /* Labels are duplicated for top & left. */
81
- this.label
82
- .data(function() { return labels; })
83
- .left(function() { return this.index & 1 ? dx * ((this.index >> 1) + .5) : 0; })
84
- .top(function() { return this.index & 1 ? 0 : dy * ((this.index >> 1) + .5); })
85
- .textMargin(4)
86
- .textAlign(function() { return this.index & 1 ? "left" : "right"; })
87
- .textAngle(function() { return this.index & 1 ? -Math.PI / 2 : 0; });
88
-
89
- /* The node mark is unused. */
90
- delete this.node;
91
- };
92
-
93
- pv.Layout.Matrix.prototype = pv.extend(pv.Layout.Network)
94
- .property("directed", Boolean);
95
-
96
- /**
97
- * Whether this matrix visualization is directed (bidirectional). By default,
98
- * the graph is assumed to be undirected, such that the visualization is
99
- * symmetric across the matrix diagonal. If the network is directed, then
100
- * forward links are drawn above the diagonal, while reverse links are drawn
101
- * below.
102
- *
103
- * @type boolean
104
- * @name pv.Layout.Matrix.prototype.directed
105
- */
106
-
107
- /**
108
- * Specifies an optional sort function. The sort function follows the same
109
- * comparator contract required by {@link pv.Dom.Node#sort}. Specifying a sort
110
- * function provides an alternative to sort the nodes as they are specified by
111
- * the <tt>nodes</tt> property; the main advantage of doing this is that the
112
- * comparator function can access implicit fields populated by the network
113
- * layout, such as the <tt>linkDegree</tt>.
114
- *
115
- * <p>Note that matrix visualizations are particularly sensitive to order. This
116
- * is referred to as the seriation problem, and many different techniques exist
117
- * to find good node orders that emphasize clusters, such as spectral layout and
118
- * simulated annealing.
119
- *
120
- * @param {function} f comparator function for nodes.
121
- * @returns {pv.Layout.Matrix} this.
122
- */
123
- pv.Layout.Matrix.prototype.sort = function(f) {
124
- this.$sort = f;
125
- return this;
126
- };
127
-
128
- /** @private */
129
- pv.Layout.Matrix.prototype.buildImplied = function(s) {
130
- if (pv.Layout.Network.prototype.buildImplied.call(this, s)) return;
131
-
132
- var nodes = s.nodes,
133
- links = s.links,
134
- sort = this.$sort,
135
- n = nodes.length,
136
- index = pv.range(n),
137
- labels = [],
138
- pairs = [],
139
- map = {};
140
-
141
- s.$matrix = {labels: labels, pairs: pairs};
142
-
143
- /* Sort the nodes. */
144
- if (sort) index.sort(function(a, b) { return sort(nodes[a], nodes[b]); });
145
-
146
- /* Create pairs. */
147
- for (var i = 0; i < n; i++) {
148
- for (var j = 0; j < n; j++) {
149
- var a = index[i],
150
- b = index[j],
151
- p = {
152
- row: i,
153
- col: j,
154
- sourceNode: nodes[a],
155
- targetNode: nodes[b],
156
- linkValue: 0
157
- };
158
- pairs.push(map[a + "." + b] = p);
159
- }
160
- }
161
-
162
- /* Create labels. */
163
- for (var i = 0; i < n; i++) {
164
- var a = index[i];
165
- labels.push(nodes[a], nodes[a]);
166
- }
167
-
168
- /* Accumulate link values. */
169
- for (var i = 0; i < links.length; i++) {
170
- var l = links[i],
171
- source = l.sourceNode.index,
172
- target = l.targetNode.index,
173
- value = l.linkValue;
174
- map[source + "." + target].linkValue += value;
175
- if (!s.directed) map[target + "." + source].linkValue += value;
176
- }
177
- };
@@ -1,302 +0,0 @@
1
- /**
2
- * Constructs a new, empty network layout. Layouts are not typically constructed
3
- * directly; instead, they are added to an existing panel via
4
- * {@link pv.Mark#add}.
5
- *
6
- * @class Represents an abstract layout for network diagrams. This class
7
- * provides the basic structure for both node-link diagrams (such as
8
- * force-directed graph layout) and space-filling network diagrams (such as
9
- * sunbursts and treemaps). Note that "network" here is a general term that
10
- * includes hierarchical structures; a tree is represented using links from
11
- * child to parent.
12
- *
13
- * <p>Network layouts require the graph data structure to be defined using two
14
- * properties:<ul>
15
- *
16
- * <li><tt>nodes</tt> - an array of objects representing nodes. Objects in this
17
- * array must conform to the {@link pv.Layout.Network.Node} interface; which is
18
- * to say, be careful to avoid naming collisions with automatic attributes such
19
- * as <tt>index</tt> and <tt>linkDegree</tt>. If the nodes property is defined
20
- * as an array of primitives, such as numbers or strings, these primitives are
21
- * automatically wrapped in an object; the resulting object's <tt>nodeValue</tt>
22
- * attribute points to the original primitive value.
23
- *
24
- * <p><li><tt>links</tt> - an array of objects representing links. Objects in
25
- * this array must conform to the {@link pv.Layout.Network.Link} interface; at a
26
- * minimum, either <tt>source</tt> and <tt>target</tt> indexes or
27
- * <tt>sourceNode</tt> and <tt>targetNode</tt> references must be set. Note that
28
- * if the links property is defined after the nodes property, the links can be
29
- * defined in terms of <tt>this.nodes()</tt>.
30
- *
31
- * </ul>
32
- *
33
- * <p>Three standard mark prototypes are provided:<ul>
34
- *
35
- * <li><tt>node</tt> - for rendering nodes; typically a {@link pv.Dot}. The node
36
- * mark is added directly to the layout, with the data property defined via the
37
- * layout's <tt>nodes</tt> property. Properties such as <tt>strokeStyle</tt> and
38
- * <tt>fillStyle</tt> can be overridden to compute properties from node data
39
- * dynamically.
40
- *
41
- * <p><li><tt>link</tt> - for rendering links; typically a {@link pv.Line}. The
42
- * link mark is added to a child panel, whose data property is defined as
43
- * layout's <tt>links</tt> property. The link's data property is then a
44
- * two-element array of the source node and target node. Thus, poperties such as
45
- * <tt>strokeStyle</tt> and <tt>fillStyle</tt> can be overridden to compute
46
- * properties from either the node data (the first argument) or the link data
47
- * (the second argument; the parent panel data) dynamically.
48
- *
49
- * <p><li><tt>label</tt> - for rendering node labels; typically a
50
- * {@link pv.Label}. The label mark is added directly to the layout, with the
51
- * data property defined via the layout's <tt>nodes</tt> property. Properties
52
- * such as <tt>strokeStyle</tt> and <tt>fillStyle</tt> can be overridden to
53
- * compute properties from node data dynamically.
54
- *
55
- * </ul>Note that some network implementations may not support all three
56
- * standard mark prototypes; for example, space-filling hierarchical layouts
57
- * typically do not use a <tt>link</tt> prototype, as the parent-child links are
58
- * implied by the structure of the space-filling <tt>node</tt> marks. Check the
59
- * specific network layout for implementation details.
60
- *
61
- * <p>Network layout properties, including <tt>nodes</tt> and <tt>links</tt>,
62
- * are typically cached rather than re-evaluated with every call to render. This
63
- * is a performance optimization, as network layout algorithms can be
64
- * expensive. If the network structure changes, call {@link #reset} to clear the
65
- * cache before rendering. Note that although the network layout properties are
66
- * cached, child mark properties, such as the marks used to render the nodes and
67
- * links, <i>are not</i>. Therefore, non-structural changes to the network
68
- * layout, such as changing the color of a mark on mouseover, do not need to
69
- * reset the layout.
70
- *
71
- * @see pv.Layout.Hierarchy
72
- * @see pv.Layout.Force
73
- * @see pv.Layout.Matrix
74
- * @see pv.Layout.Arc
75
- * @see pv.Layout.Rollup
76
- * @extends pv.Layout
77
- */
78
- pv.Layout.Network = function() {
79
- pv.Layout.call(this);
80
- var that = this;
81
-
82
- /* @private Version tracking to cache layout state, improving performance. */
83
- this.$id = pv.id();
84
-
85
- /**
86
- * The node prototype. This prototype is intended to be used with a Dot mark
87
- * in conjunction with the link prototype.
88
- *
89
- * @type pv.Mark
90
- * @name pv.Layout.Network.prototype.node
91
- */
92
- (this.node = new pv.Mark()
93
- .data(function() { return that.nodes(); })
94
- .strokeStyle("#1f77b4")
95
- .fillStyle("#fff")
96
- .left(function(n) { return n.x; })
97
- .top(function(n) { return n.y; })).parent = this;
98
-
99
- /**
100
- * The link prototype, which renders edges between source nodes and target
101
- * nodes. This prototype is intended to be used with a Line mark in
102
- * conjunction with the node prototype.
103
- *
104
- * @type pv.Mark
105
- * @name pv.Layout.Network.prototype.link
106
- */
107
- this.link = new pv.Mark()
108
- .extend(this.node)
109
- .data(function(p) { return [p.sourceNode, p.targetNode]; })
110
- .fillStyle(null)
111
- .lineWidth(function(d, p) { return p.linkValue * 1.5; })
112
- .strokeStyle("rgba(0,0,0,.2)");
113
-
114
- this.link.add = function(type) {
115
- return that.add(pv.Panel)
116
- .data(function() { return that.links(); })
117
- .add(type)
118
- .extend(this);
119
- };
120
-
121
- /**
122
- * The node label prototype, which renders the node name adjacent to the node.
123
- * This prototype is provided as an alternative to using the anchor on the
124
- * node mark; it is primarily intended to be used with radial node-link
125
- * layouts, since it provides a convenient mechanism to set the text angle.
126
- *
127
- * @type pv.Mark
128
- * @name pv.Layout.Network.prototype.label
129
- */
130
- (this.label = new pv.Mark()
131
- .extend(this.node)
132
- .textMargin(7)
133
- .textBaseline("middle")
134
- .text(function(n) { return n.nodeName || n.nodeValue; })
135
- .textAngle(function(n) {
136
- var a = n.midAngle;
137
- return pv.Wedge.upright(a) ? a : (a + Math.PI);
138
- })
139
- .textAlign(function(n) {
140
- return pv.Wedge.upright(n.midAngle) ? "left" : "right";
141
- })).parent = this;
142
- };
143
-
144
- /**
145
- * @class Represents a node in a network layout. There is no explicit
146
- * constructor; this class merely serves to document the attributes that are
147
- * used on nodes in network layouts. (Note that hierarchical nodes place
148
- * additional requirements on node representation, vis {@link pv.Dom.Node}.)
149
- *
150
- * @see pv.Layout.Network
151
- * @name pv.Layout.Network.Node
152
- */
153
-
154
- /**
155
- * The node index, zero-based. This attribute is populated automatically based
156
- * on the index in the array returned by the <tt>nodes</tt> property.
157
- *
158
- * @type number
159
- * @name pv.Layout.Network.Node.prototype.index
160
- */
161
-
162
- /**
163
- * The link degree; the sum of link values for all incoming and outgoing links.
164
- * This attribute is populated automatically.
165
- *
166
- * @type number
167
- * @name pv.Layout.Network.Node.prototype.linkDegree
168
- */
169
-
170
- /**
171
- * The node name; optional. If present, this attribute will be used to provide
172
- * the text for node labels. If not present, the label text will fallback to the
173
- * <tt>nodeValue</tt> attribute.
174
- *
175
- * @type string
176
- * @name pv.Layout.Network.Node.prototype.nodeName
177
- */
178
-
179
- /**
180
- * The node value; optional. If present, and no <tt>nodeName</tt> attribute is
181
- * present, the node value will be used as the label text. This attribute is
182
- * also automatically populated if the nodes are specified as an array of
183
- * primitives, such as strings or numbers.
184
- *
185
- * @type object
186
- * @name pv.Layout.Network.Node.prototype.nodeValue
187
- */
188
-
189
- /**
190
- * @class Represents a link in a network layout. There is no explicit
191
- * constructor; this class merely serves to document the attributes that are
192
- * used on links in network layouts. For hierarchical layouts, this class is
193
- * used to represent the parent-child links.
194
- *
195
- * @see pv.Layout.Network
196
- * @name pv.Layout.Network.Link
197
- */
198
-
199
- /**
200
- * The link value, or weight; optional. If not specified (or not a number), the
201
- * default value of 1 is used.
202
- *
203
- * @type number
204
- * @name pv.Layout.Network.Link.prototype.linkValue
205
- */
206
-
207
- /**
208
- * The link's source node. If not set, this value will be derived from the
209
- * <tt>source</tt> attribute index.
210
- *
211
- * @type pv.Layout.Network.Node
212
- * @name pv.Layout.Network.Link.prototype.sourceNode
213
- */
214
-
215
- /**
216
- * The link's target node. If not set, this value will be derived from the
217
- * <tt>target</tt> attribute index.
218
- *
219
- * @type pv.Layout.Network.Node
220
- * @name pv.Layout.Network.Link.prototype.targetNode
221
- */
222
-
223
- /**
224
- * Alias for <tt>sourceNode</tt>, as expressed by the index of the source node.
225
- * This attribute is not populated automatically, but may be used as a more
226
- * convenient identification of the link's source, for example in a static JSON
227
- * representation.
228
- *
229
- * @type number
230
- * @name pv.Layout.Network.Link.prototype.source
231
- */
232
-
233
- /**
234
- * Alias for <tt>targetNode</tt>, as expressed by the index of the target node.
235
- * This attribute is not populated automatically, but may be used as a more
236
- * convenient identification of the link's target, for example in a static JSON
237
- * representation.
238
- *
239
- * @type number
240
- * @name pv.Layout.Network.Link.prototype.target
241
- */
242
-
243
- /**
244
- * Alias for <tt>linkValue</tt>. This attribute is not populated automatically,
245
- * but may be used instead of the <tt>linkValue</tt> attribute when specifying
246
- * links.
247
- *
248
- * @type number
249
- * @name pv.Layout.Network.Link.prototype.value
250
- */
251
-
252
- /** @private Transform nodes and links on cast. */
253
- pv.Layout.Network.prototype = pv.extend(pv.Layout)
254
- .property("nodes", function(v) {
255
- return v.map(function(d, i) {
256
- if (typeof d != "object") d = {nodeValue: d};
257
- d.index = i;
258
- return d;
259
- });
260
- })
261
- .property("links", function(v) {
262
- return v.map(function(d) {
263
- if (isNaN(d.linkValue)) d.linkValue = isNaN(d.value) ? 1 : d.value;
264
- return d;
265
- });
266
- });
267
-
268
- /**
269
- * Resets the cache, such that changes to layout property definitions will be
270
- * visible on subsequent render. Unlike normal marks (and normal layouts),
271
- * properties associated with network layouts are not automatically re-evaluated
272
- * on render; the properties are cached, and any expensive layout algorithms are
273
- * only run after the layout is explicitly reset.
274
- *
275
- * @returns {pv.Layout.Network} this.
276
- */
277
- pv.Layout.Network.prototype.reset = function() {
278
- this.$id = pv.id();
279
- return this;
280
- };
281
-
282
- /** @private Skip evaluating properties if cached. */
283
- pv.Layout.Network.prototype.buildProperties = function(s, properties) {
284
- if ((s.$id || 0) < this.$id) {
285
- pv.Layout.prototype.buildProperties.call(this, s, properties);
286
- }
287
- };
288
-
289
- /** @private Compute link degrees; map source and target indexes to nodes. */
290
- pv.Layout.Network.prototype.buildImplied = function(s) {
291
- pv.Layout.prototype.buildImplied.call(this, s);
292
- if (s.$id >= this.$id) return true;
293
- s.$id = this.$id;
294
- s.nodes.forEach(function(d) {
295
- d.linkDegree = 0;
296
- });
297
- s.links.forEach(function(d) {
298
- var v = d.linkValue;
299
- (d.sourceNode || (d.sourceNode = s.nodes[d.source])).linkDegree += v;
300
- (d.targetNode || (d.targetNode = s.nodes[d.target])).linkDegree += v;
301
- });
302
- };