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,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new, empty grid 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 grid layout with regularly-sized rows and columns. The
|
|
7
|
-
* number of rows and columns are determined from their respective
|
|
8
|
-
* properties. For example, the 2×3 array:
|
|
9
|
-
*
|
|
10
|
-
* <pre>1 2 3
|
|
11
|
-
* 4 5 6</pre>
|
|
12
|
-
*
|
|
13
|
-
* can be represented using the <tt>rows</tt> property as:
|
|
14
|
-
*
|
|
15
|
-
* <pre>[[1, 2, 3], [4, 5, 6]]</pre>
|
|
16
|
-
*
|
|
17
|
-
* If your data is in column-major order, you can equivalently use the
|
|
18
|
-
* <tt>columns</tt> property. If the <tt>rows</tt> property is an array, it
|
|
19
|
-
* takes priority over the <tt>columns</tt> property. The data is implicitly
|
|
20
|
-
* transposed, as if the {@link pv.transpose} operator were applied.
|
|
21
|
-
*
|
|
22
|
-
* <p>This layout exports a single <tt>cell</tt> mark prototype, which is
|
|
23
|
-
* intended to be used with a bar, panel, layout, or subclass thereof. The data
|
|
24
|
-
* property of the cell prototype is defined as the elements in the array. For
|
|
25
|
-
* example, if the array is a two-dimensional array of values in the range
|
|
26
|
-
* [0,1], a simple heatmap can be generated as:
|
|
27
|
-
*
|
|
28
|
-
* <pre>vis.add(pv.Layout.Grid)
|
|
29
|
-
* .rows(arrays)
|
|
30
|
-
* .cell.add(pv.Bar)
|
|
31
|
-
* .fillStyle(pv.ramp("white", "black"))</pre>
|
|
32
|
-
*
|
|
33
|
-
* The grid subdivides the full width and height of the parent panel into equal
|
|
34
|
-
* rectangles. Note, however, that for large, interactive, or animated heatmaps,
|
|
35
|
-
* you may see significantly better performance through dynamic {@link pv.Image}
|
|
36
|
-
* generation.
|
|
37
|
-
*
|
|
38
|
-
* <p>For irregular grids using value-based spatial partitioning, see {@link
|
|
39
|
-
* pv.Layout.Treemap}.
|
|
40
|
-
*
|
|
41
|
-
* @extends pv.Layout
|
|
42
|
-
*/
|
|
43
|
-
pv.Layout.Grid = function() {
|
|
44
|
-
pv.Layout.call(this);
|
|
45
|
-
var that = this;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* The cell prototype. This prototype is intended to be used with a bar,
|
|
49
|
-
* panel, or layout (or subclass thereof) to render the grid cells.
|
|
50
|
-
*
|
|
51
|
-
* @type pv.Mark
|
|
52
|
-
* @name pv.Layout.Grid.prototype.cell
|
|
53
|
-
*/
|
|
54
|
-
(this.cell = new pv.Mark()
|
|
55
|
-
.data(function() {
|
|
56
|
-
return that.scene[that.index].$grid;
|
|
57
|
-
})
|
|
58
|
-
.width(function() {
|
|
59
|
-
return that.width() / that.cols();
|
|
60
|
-
})
|
|
61
|
-
.height(function() {
|
|
62
|
-
return that.height() / that.rows();
|
|
63
|
-
})
|
|
64
|
-
.left(function() {
|
|
65
|
-
return this.width() * (this.index % that.cols());
|
|
66
|
-
})
|
|
67
|
-
.top(function() {
|
|
68
|
-
return this.height() * Math.floor(this.index / that.cols());
|
|
69
|
-
})).parent = this;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
pv.Layout.Grid.prototype = pv.extend(pv.Layout)
|
|
73
|
-
.property("rows")
|
|
74
|
-
.property("cols");
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Default properties for grid layouts. By default, there is one row and one
|
|
78
|
-
* column, and the data is the propagated to the child cell.
|
|
79
|
-
*
|
|
80
|
-
* @type pv.Layout.Grid
|
|
81
|
-
*/
|
|
82
|
-
pv.Layout.Grid.prototype.defaults = new pv.Layout.Grid()
|
|
83
|
-
.extend(pv.Layout.prototype.defaults)
|
|
84
|
-
.rows(1)
|
|
85
|
-
.cols(1);
|
|
86
|
-
|
|
87
|
-
/** @private */
|
|
88
|
-
pv.Layout.Grid.prototype.buildImplied = function(s) {
|
|
89
|
-
pv.Layout.prototype.buildImplied.call(this, s);
|
|
90
|
-
var r = s.rows, c = s.cols;
|
|
91
|
-
if (typeof c == "object") r = pv.transpose(c);
|
|
92
|
-
if (typeof r == "object") {
|
|
93
|
-
s.$grid = pv.blend(r);
|
|
94
|
-
s.rows = r.length;
|
|
95
|
-
s.cols = r[0] ? r[0].length : 0;
|
|
96
|
-
} else {
|
|
97
|
-
s.$grid = pv.repeat([s.data], r * c);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* The number of rows. This property can also be specified as the data in
|
|
103
|
-
* row-major order; in this case, the rows property is implicitly set to the
|
|
104
|
-
* length of the array, and the cols property is set to the length of the first
|
|
105
|
-
* element in the array.
|
|
106
|
-
*
|
|
107
|
-
* @type number
|
|
108
|
-
* @name pv.Layout.Grid.prototype.rows
|
|
109
|
-
*/
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* The number of columns. This property can also be specified as the data in
|
|
113
|
-
* column-major order; in this case, the cols property is implicitly set to the
|
|
114
|
-
* length of the array, and the rows property is set to the length of the first
|
|
115
|
-
* element in the array.
|
|
116
|
-
*
|
|
117
|
-
* @type number
|
|
118
|
-
* @name pv.Layout.Grid.prototype.cols
|
|
119
|
-
*/
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new, empty hierarchy 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 Represents an abstract layout for hierarchy diagrams. This class is a
|
|
7
|
-
* specialization of {@link pv.Layout.Network}, providing the basic structure
|
|
8
|
-
* for both hierarchical node-link diagrams (such as Reingold-Tilford trees) and
|
|
9
|
-
* space-filling hierarchy diagrams (such as sunbursts and treemaps).
|
|
10
|
-
*
|
|
11
|
-
* <p>Unlike general network layouts, the <tt>links</tt> property need not be
|
|
12
|
-
* defined explicitly. Instead, the links are computed implicitly from the
|
|
13
|
-
* <tt>parentNode</tt> attribute of the node objects, as defined by the
|
|
14
|
-
* <tt>nodes</tt> property. This implementation is also available as
|
|
15
|
-
* {@link #links}, for reuse with non-hierarchical layouts; for example, to
|
|
16
|
-
* render a tree using force-directed layout.
|
|
17
|
-
*
|
|
18
|
-
* <p>Correspondingly, the <tt>nodes</tt> property is represented as a union of
|
|
19
|
-
* {@link pv.Layout.Network.Node} and {@link pv.Dom.Node}. To construct a node
|
|
20
|
-
* hierarchy from a simple JSON map, use the {@link pv.Dom} operator; this
|
|
21
|
-
* operator also provides an easy way to sort nodes before passing them to the
|
|
22
|
-
* layout.
|
|
23
|
-
*
|
|
24
|
-
* <p>For more details on how to use this layout, see
|
|
25
|
-
* {@link pv.Layout.Network}.
|
|
26
|
-
*
|
|
27
|
-
* @see pv.Layout.Cluster
|
|
28
|
-
* @see pv.Layout.Partition
|
|
29
|
-
* @see pv.Layout.Tree
|
|
30
|
-
* @see pv.Layout.Treemap
|
|
31
|
-
* @see pv.Layout.Indent
|
|
32
|
-
* @see pv.Layout.Pack
|
|
33
|
-
* @extends pv.Layout.Network
|
|
34
|
-
*/
|
|
35
|
-
pv.Layout.Hierarchy = function() {
|
|
36
|
-
pv.Layout.Network.call(this);
|
|
37
|
-
this.link.strokeStyle("#ccc");
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
pv.Layout.Hierarchy.prototype = pv.extend(pv.Layout.Network);
|
|
41
|
-
|
|
42
|
-
/** @private Compute the implied links. (Links are null by default.) */
|
|
43
|
-
pv.Layout.Hierarchy.prototype.buildImplied = function(s) {
|
|
44
|
-
if (!s.links) s.links = pv.Layout.Hierarchy.links.call(this);
|
|
45
|
-
pv.Layout.Network.prototype.buildImplied.call(this, s);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
/** The implied links; computes links using the <tt>parentNode</tt> attribute. */
|
|
49
|
-
pv.Layout.Hierarchy.links = function() {
|
|
50
|
-
return this.nodes()
|
|
51
|
-
.filter(function(n) { return n.parentNode; })
|
|
52
|
-
.map(function(n) {
|
|
53
|
-
return {
|
|
54
|
-
sourceNode: n,
|
|
55
|
-
targetNode: n.parentNode,
|
|
56
|
-
linkValue: 1
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
/** @private Provides standard node-link layout based on breadth & depth. */
|
|
62
|
-
pv.Layout.Hierarchy.NodeLink = {
|
|
63
|
-
|
|
64
|
-
/** @private */
|
|
65
|
-
buildImplied: function(s) {
|
|
66
|
-
var nodes = s.nodes,
|
|
67
|
-
orient = s.orient,
|
|
68
|
-
horizontal = /^(top|bottom)$/.test(orient),
|
|
69
|
-
w = s.width,
|
|
70
|
-
h = s.height;
|
|
71
|
-
|
|
72
|
-
/* Compute default inner and outer radius. */
|
|
73
|
-
if (orient == "radial") {
|
|
74
|
-
var ir = s.innerRadius, or = s.outerRadius;
|
|
75
|
-
if (ir == null) ir = 0;
|
|
76
|
-
if (or == null) or = Math.min(w, h) / 2;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** @private Returns the radius of the given node. */
|
|
80
|
-
function radius(n) {
|
|
81
|
-
return n.parentNode ? (n.depth * (or - ir) + ir) : 0;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/** @private Returns the angle of the given node. */
|
|
85
|
-
function midAngle(n) {
|
|
86
|
-
return (n.parentNode ? (n.breadth - .25) * 2 * Math.PI : 0);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** @private */
|
|
90
|
-
function x(n) {
|
|
91
|
-
switch (orient) {
|
|
92
|
-
case "left": return n.depth * w;
|
|
93
|
-
case "right": return w - n.depth * w;
|
|
94
|
-
case "top": return n.breadth * w;
|
|
95
|
-
case "bottom": return w - n.breadth * w;
|
|
96
|
-
case "radial": return w / 2 + radius(n) * Math.cos(n.midAngle);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** @private */
|
|
101
|
-
function y(n) {
|
|
102
|
-
switch (orient) {
|
|
103
|
-
case "left": return n.breadth * h;
|
|
104
|
-
case "right": return h - n.breadth * h;
|
|
105
|
-
case "top": return n.depth * h;
|
|
106
|
-
case "bottom": return h - n.depth * h;
|
|
107
|
-
case "radial": return h / 2 + radius(n) * Math.sin(n.midAngle);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
for (var i = 0; i < nodes.length; i++) {
|
|
112
|
-
var n = nodes[i];
|
|
113
|
-
n.midAngle = orient == "radial" ? midAngle(n)
|
|
114
|
-
: horizontal ? Math.PI / 2 : 0;
|
|
115
|
-
n.x = x(n);
|
|
116
|
-
n.y = y(n);
|
|
117
|
-
if (n.firstChild) n.midAngle += Math.PI;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
/** @private Provides standard space-filling layout based on breadth & depth. */
|
|
123
|
-
pv.Layout.Hierarchy.Fill = {
|
|
124
|
-
|
|
125
|
-
/** @private */
|
|
126
|
-
constructor: function() {
|
|
127
|
-
this.node
|
|
128
|
-
.strokeStyle("#fff")
|
|
129
|
-
.fillStyle("#ccc")
|
|
130
|
-
.width(function(n) { return n.dx; })
|
|
131
|
-
.height(function(n) { return n.dy; })
|
|
132
|
-
.innerRadius(function(n) { return n.innerRadius; })
|
|
133
|
-
.outerRadius(function(n) { return n.outerRadius; })
|
|
134
|
-
.startAngle(function(n) { return n.startAngle; })
|
|
135
|
-
.angle(function(n) { return n.angle; });
|
|
136
|
-
|
|
137
|
-
this.label
|
|
138
|
-
.textAlign("center")
|
|
139
|
-
.left(function(n) { return n.x + (n.dx / 2); })
|
|
140
|
-
.top(function(n) { return n.y + (n.dy / 2); });
|
|
141
|
-
|
|
142
|
-
/* Hide unsupported link. */
|
|
143
|
-
delete this.link;
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
/** @private */
|
|
147
|
-
buildImplied: function(s) {
|
|
148
|
-
var nodes = s.nodes,
|
|
149
|
-
orient = s.orient,
|
|
150
|
-
horizontal = /^(top|bottom)$/.test(orient),
|
|
151
|
-
w = s.width,
|
|
152
|
-
h = s.height,
|
|
153
|
-
depth = -nodes[0].minDepth;
|
|
154
|
-
|
|
155
|
-
/* Compute default inner and outer radius. */
|
|
156
|
-
if (orient == "radial") {
|
|
157
|
-
var ir = s.innerRadius, or = s.outerRadius;
|
|
158
|
-
if (ir == null) ir = 0;
|
|
159
|
-
if (ir) depth *= 2; // use full depth step for root
|
|
160
|
-
if (or == null) or = Math.min(w, h) / 2;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** @private Scales the specified depth for a space-filling layout. */
|
|
164
|
-
function scale(d, depth) {
|
|
165
|
-
return (d + depth) / (1 + depth);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/** @private */
|
|
169
|
-
function x(n) {
|
|
170
|
-
switch (orient) {
|
|
171
|
-
case "left": return scale(n.minDepth, depth) * w;
|
|
172
|
-
case "right": return (1 - scale(n.maxDepth, depth)) * w;
|
|
173
|
-
case "top": return n.minBreadth * w;
|
|
174
|
-
case "bottom": return (1 - n.maxBreadth) * w;
|
|
175
|
-
case "radial": return w / 2;
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
/** @private */
|
|
180
|
-
function y(n) {
|
|
181
|
-
switch (orient) {
|
|
182
|
-
case "left": return n.minBreadth * h;
|
|
183
|
-
case "right": return (1 - n.maxBreadth) * h;
|
|
184
|
-
case "top": return scale(n.minDepth, depth) * h;
|
|
185
|
-
case "bottom": return (1 - scale(n.maxDepth, depth)) * h;
|
|
186
|
-
case "radial": return h / 2;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/** @private */
|
|
191
|
-
function dx(n) {
|
|
192
|
-
switch (orient) {
|
|
193
|
-
case "left":
|
|
194
|
-
case "right": return (n.maxDepth - n.minDepth) / (1 + depth) * w;
|
|
195
|
-
case "top":
|
|
196
|
-
case "bottom": return (n.maxBreadth - n.minBreadth) * w;
|
|
197
|
-
case "radial": return n.parentNode ? (n.innerRadius + n.outerRadius) * Math.cos(n.midAngle) : 0;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/** @private */
|
|
202
|
-
function dy(n) {
|
|
203
|
-
switch (orient) {
|
|
204
|
-
case "left":
|
|
205
|
-
case "right": return (n.maxBreadth - n.minBreadth) * h;
|
|
206
|
-
case "top":
|
|
207
|
-
case "bottom": return (n.maxDepth - n.minDepth) / (1 + depth) * h;
|
|
208
|
-
case "radial": return n.parentNode ? (n.innerRadius + n.outerRadius) * Math.sin(n.midAngle) : 0;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/** @private */
|
|
213
|
-
function innerRadius(n) {
|
|
214
|
-
return Math.max(0, scale(n.minDepth, depth / 2)) * (or - ir) + ir;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/** @private */
|
|
218
|
-
function outerRadius(n) {
|
|
219
|
-
return scale(n.maxDepth, depth / 2) * (or - ir) + ir;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/** @private */
|
|
223
|
-
function startAngle(n) {
|
|
224
|
-
return (n.parentNode ? n.minBreadth - .25 : 0) * 2 * Math.PI;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
/** @private */
|
|
228
|
-
function angle(n) {
|
|
229
|
-
return (n.parentNode ? n.maxBreadth - n.minBreadth : 1) * 2 * Math.PI;
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
for (var i = 0; i < nodes.length; i++) {
|
|
233
|
-
var n = nodes[i];
|
|
234
|
-
n.x = x(n);
|
|
235
|
-
n.y = y(n);
|
|
236
|
-
if (orient == "radial") {
|
|
237
|
-
n.innerRadius = innerRadius(n);
|
|
238
|
-
n.outerRadius = outerRadius(n);
|
|
239
|
-
n.startAngle = startAngle(n);
|
|
240
|
-
n.angle = angle(n);
|
|
241
|
-
n.midAngle = n.startAngle + n.angle / 2;
|
|
242
|
-
} else {
|
|
243
|
-
n.midAngle = horizontal ? -Math.PI / 2 : 0;
|
|
244
|
-
}
|
|
245
|
-
n.dx = dx(n);
|
|
246
|
-
n.dy = dy(n);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
};
|
|
@@ -1,159 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new, empty horizon 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 horizon layout, which is a variation of a single-series
|
|
7
|
-
* area chart where the area is folded into multiple bands. Color is used to
|
|
8
|
-
* encode band, allowing the size of the chart to be reduced significantly
|
|
9
|
-
* without impeding readability. This layout algorithm is based on the work of
|
|
10
|
-
* J. Heer, N. Kong and M. Agrawala in <a
|
|
11
|
-
* href="http://hci.stanford.edu/publications/2009/heer-horizon-chi09.pdf">"Sizing
|
|
12
|
-
* the Horizon: The Effects of Chart Size and Layering on the Graphical
|
|
13
|
-
* Perception of Time Series Visualizations"</a>, CHI 2009.
|
|
14
|
-
*
|
|
15
|
-
* <p>This layout exports a single <tt>band</tt> mark prototype, which is
|
|
16
|
-
* intended to be used with an area mark. The band mark is contained in a panel
|
|
17
|
-
* which is replicated per band (and for negative/positive bands). For example,
|
|
18
|
-
* to create a simple horizon graph given an array of numbers:
|
|
19
|
-
*
|
|
20
|
-
* <pre>vis.add(pv.Layout.Horizon)
|
|
21
|
-
* .bands(n)
|
|
22
|
-
* .band.add(pv.Area)
|
|
23
|
-
* .data(data)
|
|
24
|
-
* .left(function() this.index * 35)
|
|
25
|
-
* .height(function(d) d * 40);</pre>
|
|
26
|
-
*
|
|
27
|
-
* The layout can be further customized by changing the number of bands, and
|
|
28
|
-
* toggling whether the negative bands are mirrored or offset. (See the
|
|
29
|
-
* above-referenced paper for guidance.)
|
|
30
|
-
*
|
|
31
|
-
* <p>The <tt>fillStyle</tt> of the area can be overridden, though typically it
|
|
32
|
-
* is easier to customize the layout's behavior through the custom
|
|
33
|
-
* <tt>backgroundStyle</tt>, <tt>positiveStyle</tt> and <tt>negativeStyle</tt>
|
|
34
|
-
* properties. By default, the background is white, positive bands are blue, and
|
|
35
|
-
* negative bands are red. For the most accurate presentation, use fully-opaque
|
|
36
|
-
* colors of equal intensity for the negative and positive bands.
|
|
37
|
-
*
|
|
38
|
-
* @extends pv.Layout
|
|
39
|
-
*/
|
|
40
|
-
pv.Layout.Horizon = function() {
|
|
41
|
-
pv.Layout.call(this);
|
|
42
|
-
var that = this,
|
|
43
|
-
bands, // cached bands
|
|
44
|
-
mode, // cached mode
|
|
45
|
-
size, // cached height
|
|
46
|
-
fill, // cached background style
|
|
47
|
-
red, // cached negative color (ramp)
|
|
48
|
-
blue, // cached positive color (ramp)
|
|
49
|
-
buildImplied = this.buildImplied;
|
|
50
|
-
|
|
51
|
-
/** @private Cache the layout state to optimize properties. */
|
|
52
|
-
this.buildImplied = function(s) {
|
|
53
|
-
buildImplied.call(this, s);
|
|
54
|
-
bands = s.bands;
|
|
55
|
-
mode = s.mode;
|
|
56
|
-
size = Math.round((mode == "color" ? .5 : 1) * s.height);
|
|
57
|
-
fill = s.backgroundStyle;
|
|
58
|
-
red = pv.ramp(fill, s.negativeStyle).domain(0, bands);
|
|
59
|
-
blue = pv.ramp(fill, s.positiveStyle).domain(0, bands);
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
var bands = new pv.Panel()
|
|
63
|
-
.data(function() { return pv.range(bands * 2); })
|
|
64
|
-
.overflow("hidden")
|
|
65
|
-
.height(function() { return size; })
|
|
66
|
-
.top(function(i) { return mode == "color" ? (i & 1) * size : 0; })
|
|
67
|
-
.fillStyle(function(i) { return i ? null : fill; });
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* The band prototype. This prototype is intended to be used with an Area
|
|
71
|
-
* mark to render the horizon bands.
|
|
72
|
-
*
|
|
73
|
-
* @type pv.Mark
|
|
74
|
-
* @name pv.Layout.Horizon.prototype.band
|
|
75
|
-
*/
|
|
76
|
-
this.band = new pv.Mark()
|
|
77
|
-
.top(function(d, i) {
|
|
78
|
-
return mode == "mirror" && i & 1
|
|
79
|
-
? (i + 1 >> 1) * size
|
|
80
|
-
: null;
|
|
81
|
-
})
|
|
82
|
-
.bottom(function(d, i) {
|
|
83
|
-
return mode == "mirror"
|
|
84
|
-
? (i & 1 ? null : (i + 1 >> 1) * -size)
|
|
85
|
-
: ((i & 1 || -1) * (i + 1 >> 1) * size);
|
|
86
|
-
})
|
|
87
|
-
.fillStyle(function(d, i) {
|
|
88
|
-
return (i & 1 ? red : blue)((i >> 1) + 1);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
this.band.add = function(type) {
|
|
92
|
-
return that.add(pv.Panel).extend(bands).add(type).extend(this);
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
pv.Layout.Horizon.prototype = pv.extend(pv.Layout)
|
|
97
|
-
.property("bands", Number)
|
|
98
|
-
.property("mode", String)
|
|
99
|
-
.property("backgroundStyle", pv.color)
|
|
100
|
-
.property("positiveStyle", pv.color)
|
|
101
|
-
.property("negativeStyle", pv.color);
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Default properties for horizon layouts. By default, there are two bands, the
|
|
105
|
-
* mode is "offset", the background style is "white", the positive style is
|
|
106
|
-
* blue, negative style is red.
|
|
107
|
-
*
|
|
108
|
-
* @type pv.Layout.Horizon
|
|
109
|
-
*/
|
|
110
|
-
pv.Layout.Horizon.prototype.defaults = new pv.Layout.Horizon()
|
|
111
|
-
.extend(pv.Layout.prototype.defaults)
|
|
112
|
-
.bands(2)
|
|
113
|
-
.mode("offset")
|
|
114
|
-
.backgroundStyle("white")
|
|
115
|
-
.positiveStyle("#1f77b4")
|
|
116
|
-
.negativeStyle("#d62728");
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* The horizon mode: offset, mirror, or color. The default is "offset".
|
|
120
|
-
*
|
|
121
|
-
* @type string
|
|
122
|
-
* @name pv.Layout.Horizon.prototype.mode
|
|
123
|
-
*/
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* The number of bands. Must be at least one. The default value is two.
|
|
127
|
-
*
|
|
128
|
-
* @type number
|
|
129
|
-
* @name pv.Layout.Horizon.prototype.bands
|
|
130
|
-
*/
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* The positive band color; if non-null, the interior of positive bands are
|
|
134
|
-
* filled with the specified color. The default value of this property is blue.
|
|
135
|
-
* For accurate blending, this color should be fully opaque.
|
|
136
|
-
*
|
|
137
|
-
* @type pv.Color
|
|
138
|
-
* @name pv.Layout.Horizon.prototype.positiveStyle
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* The negative band color; if non-null, the interior of negative bands are
|
|
143
|
-
* filled with the specified color. The default value of this property is red.
|
|
144
|
-
* For accurate blending, this color should be fully opaque.
|
|
145
|
-
*
|
|
146
|
-
* @type pv.Color
|
|
147
|
-
* @name pv.Layout.Horizon.prototype.negativeStyle
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* The background color. The panel background is filled with the specified
|
|
152
|
-
* color, and the negative and positive bands are filled with an interpolated
|
|
153
|
-
* color between this color and the respective band color. The default value of
|
|
154
|
-
* this property is white. For accurate blending, this color should be fully
|
|
155
|
-
* opaque.
|
|
156
|
-
*
|
|
157
|
-
* @type pv.Color
|
|
158
|
-
* @name pv.Layout.Horizon.prototype.backgroundStyle
|
|
159
|
-
*/
|