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,244 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new wedge with default properties. Wedges are not typically
|
|
3
|
-
* constructed directly, but by adding to a panel or an existing mark via
|
|
4
|
-
* {@link pv.Mark#add}.
|
|
5
|
-
*
|
|
6
|
-
* @class Represents a wedge, or pie slice. Specified in terms of start and end
|
|
7
|
-
* angle, inner and outer radius, wedges can be used to construct donut charts
|
|
8
|
-
* and polar bar charts as well. If the {@link #angle} property is used, the end
|
|
9
|
-
* angle is implied by adding this value to start angle. By default, the start
|
|
10
|
-
* angle is the previously-generated wedge's end angle. This design allows
|
|
11
|
-
* explicit control over the wedge placement if desired, while offering
|
|
12
|
-
* convenient defaults for the construction of radial graphs.
|
|
13
|
-
*
|
|
14
|
-
* <p>The center point of the circle is positioned using the standard box model.
|
|
15
|
-
* The wedge can be stroked and filled, similar to {@link pv.Bar}.
|
|
16
|
-
*
|
|
17
|
-
* <p>See also the <a href="../../api/Wedge.html">Wedge guide</a>.
|
|
18
|
-
*
|
|
19
|
-
* @extends pv.Mark
|
|
20
|
-
*/
|
|
21
|
-
pv.Wedge = function() {
|
|
22
|
-
pv.Mark.call(this);
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
pv.Wedge.prototype = pv.extend(pv.Mark)
|
|
26
|
-
.property("startAngle", Number)
|
|
27
|
-
.property("endAngle", Number)
|
|
28
|
-
.property("angle", Number)
|
|
29
|
-
.property("innerRadius", Number)
|
|
30
|
-
.property("outerRadius", Number)
|
|
31
|
-
.property("lineWidth", Number)
|
|
32
|
-
.property("strokeStyle", pv.color)
|
|
33
|
-
.property("fillStyle", pv.color);
|
|
34
|
-
|
|
35
|
-
pv.Wedge.prototype.type = "wedge";
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* The start angle of the wedge, in radians. The start angle is measured
|
|
39
|
-
* clockwise from the 3 o'clock position. The default value of this property is
|
|
40
|
-
* the end angle of the previous instance (the {@link Mark#sibling}), or -PI / 2
|
|
41
|
-
* for the first wedge; for pie and donut charts, typically only the
|
|
42
|
-
* {@link #angle} property needs to be specified.
|
|
43
|
-
*
|
|
44
|
-
* @type number
|
|
45
|
-
* @name pv.Wedge.prototype.startAngle
|
|
46
|
-
*/
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* The end angle of the wedge, in radians. If not specified, the end angle is
|
|
50
|
-
* implied as the start angle plus the {@link #angle}.
|
|
51
|
-
*
|
|
52
|
-
* @type number
|
|
53
|
-
* @name pv.Wedge.prototype.endAngle
|
|
54
|
-
*/
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* The angular span of the wedge, in radians. This property is used if end angle
|
|
58
|
-
* is not specified.
|
|
59
|
-
*
|
|
60
|
-
* @type number
|
|
61
|
-
* @name pv.Wedge.prototype.angle
|
|
62
|
-
*/
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* The inner radius of the wedge, in pixels. The default value of this property
|
|
66
|
-
* is zero; a positive value will produce a donut slice rather than a pie slice.
|
|
67
|
-
* The inner radius can vary per-wedge.
|
|
68
|
-
*
|
|
69
|
-
* @type number
|
|
70
|
-
* @name pv.Wedge.prototype.innerRadius
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* The outer radius of the wedge, in pixels. This property is required. For
|
|
75
|
-
* pies, only this radius is required; for donuts, the inner radius must be
|
|
76
|
-
* specified as well. The outer radius can vary per-wedge.
|
|
77
|
-
*
|
|
78
|
-
* @type number
|
|
79
|
-
* @name pv.Wedge.prototype.outerRadius
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* The width of stroked lines, in pixels; used in conjunction with
|
|
84
|
-
* <tt>strokeStyle</tt> to stroke the wedge's border.
|
|
85
|
-
*
|
|
86
|
-
* @type number
|
|
87
|
-
* @name pv.Wedge.prototype.lineWidth
|
|
88
|
-
*/
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* The style of stroked lines; used in conjunction with <tt>lineWidth</tt> to
|
|
92
|
-
* stroke the wedge's border. The default value of this property is null,
|
|
93
|
-
* meaning wedges are not stroked by default.
|
|
94
|
-
*
|
|
95
|
-
* @type string
|
|
96
|
-
* @name pv.Wedge.prototype.strokeStyle
|
|
97
|
-
* @see pv.color
|
|
98
|
-
*/
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* The wedge fill style; if non-null, the interior of the wedge is filled with
|
|
102
|
-
* the specified color. The default value of this property is a categorical
|
|
103
|
-
* color.
|
|
104
|
-
*
|
|
105
|
-
* @type string
|
|
106
|
-
* @name pv.Wedge.prototype.fillStyle
|
|
107
|
-
* @see pv.color
|
|
108
|
-
*/
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Default properties for wedges. By default, there is no stroke and the fill
|
|
112
|
-
* style is a categorical color.
|
|
113
|
-
*
|
|
114
|
-
* @type pv.Wedge
|
|
115
|
-
*/
|
|
116
|
-
pv.Wedge.prototype.defaults = new pv.Wedge()
|
|
117
|
-
.extend(pv.Mark.prototype.defaults)
|
|
118
|
-
.startAngle(function() {
|
|
119
|
-
var s = this.sibling();
|
|
120
|
-
return s ? s.endAngle : -Math.PI / 2;
|
|
121
|
-
})
|
|
122
|
-
.innerRadius(0)
|
|
123
|
-
.lineWidth(1.5)
|
|
124
|
-
.strokeStyle(null)
|
|
125
|
-
.fillStyle(pv.Colors.category20().by(pv.index));
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Returns the mid-radius of the wedge, which is defined as half-way between the
|
|
129
|
-
* inner and outer radii.
|
|
130
|
-
*
|
|
131
|
-
* @see #innerRadius
|
|
132
|
-
* @see #outerRadius
|
|
133
|
-
* @returns {number} the mid-radius, in pixels.
|
|
134
|
-
*/
|
|
135
|
-
pv.Wedge.prototype.midRadius = function() {
|
|
136
|
-
return (this.innerRadius() + this.outerRadius()) / 2;
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Returns the mid-angle of the wedge, which is defined as half-way between the
|
|
141
|
-
* start and end angles.
|
|
142
|
-
*
|
|
143
|
-
* @see #startAngle
|
|
144
|
-
* @see #endAngle
|
|
145
|
-
* @returns {number} the mid-angle, in radians.
|
|
146
|
-
*/
|
|
147
|
-
pv.Wedge.prototype.midAngle = function() {
|
|
148
|
-
return (this.startAngle() + this.endAngle()) / 2;
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Constructs a new wedge anchor with default properties. Wedges support five
|
|
153
|
-
* different anchors:<ul>
|
|
154
|
-
*
|
|
155
|
-
* <li>outer
|
|
156
|
-
* <li>inner
|
|
157
|
-
* <li>center
|
|
158
|
-
* <li>start
|
|
159
|
-
* <li>end
|
|
160
|
-
*
|
|
161
|
-
* </ul>In addition to positioning properties (left, right, top bottom), the
|
|
162
|
-
* anchors support text rendering properties (text-align, text-baseline,
|
|
163
|
-
* textAngle). Text is rendered to appear inside the wedge.
|
|
164
|
-
*
|
|
165
|
-
* @param {string} name the anchor name; either a string or a property function.
|
|
166
|
-
* @returns {pv.Anchor}
|
|
167
|
-
*/
|
|
168
|
-
pv.Wedge.prototype.anchor = function(name) {
|
|
169
|
-
function partial(s) { return s.innerRadius || s.angle < 2 * Math.PI; }
|
|
170
|
-
function midRadius(s) { return (s.innerRadius + s.outerRadius) / 2; }
|
|
171
|
-
function midAngle(s) { return (s.startAngle + s.endAngle) / 2; }
|
|
172
|
-
return pv.Mark.prototype.anchor.call(this, name)
|
|
173
|
-
.left(function() {
|
|
174
|
-
var s = this.scene.target[this.index];
|
|
175
|
-
if (partial(s)) switch (this.name()) {
|
|
176
|
-
case "outer": return s.left + s.outerRadius * Math.cos(midAngle(s));
|
|
177
|
-
case "inner": return s.left + s.innerRadius * Math.cos(midAngle(s));
|
|
178
|
-
case "start": return s.left + midRadius(s) * Math.cos(s.startAngle);
|
|
179
|
-
case "center": return s.left + midRadius(s) * Math.cos(midAngle(s));
|
|
180
|
-
case "end": return s.left + midRadius(s) * Math.cos(s.endAngle);
|
|
181
|
-
}
|
|
182
|
-
return s.left;
|
|
183
|
-
})
|
|
184
|
-
.top(function() {
|
|
185
|
-
var s = this.scene.target[this.index];
|
|
186
|
-
if (partial(s)) switch (this.name()) {
|
|
187
|
-
case "outer": return s.top + s.outerRadius * Math.sin(midAngle(s));
|
|
188
|
-
case "inner": return s.top + s.innerRadius * Math.sin(midAngle(s));
|
|
189
|
-
case "start": return s.top + midRadius(s) * Math.sin(s.startAngle);
|
|
190
|
-
case "center": return s.top + midRadius(s) * Math.sin(midAngle(s));
|
|
191
|
-
case "end": return s.top + midRadius(s) * Math.sin(s.endAngle);
|
|
192
|
-
}
|
|
193
|
-
return s.top;
|
|
194
|
-
})
|
|
195
|
-
.textAlign(function() {
|
|
196
|
-
var s = this.scene.target[this.index];
|
|
197
|
-
if (partial(s)) switch (this.name()) {
|
|
198
|
-
case "outer": return pv.Wedge.upright(midAngle(s)) ? "right" : "left";
|
|
199
|
-
case "inner": return pv.Wedge.upright(midAngle(s)) ? "left" : "right";
|
|
200
|
-
}
|
|
201
|
-
return "center";
|
|
202
|
-
})
|
|
203
|
-
.textBaseline(function() {
|
|
204
|
-
var s = this.scene.target[this.index];
|
|
205
|
-
if (partial(s)) switch (this.name()) {
|
|
206
|
-
case "start": return pv.Wedge.upright(s.startAngle) ? "top" : "bottom";
|
|
207
|
-
case "end": return pv.Wedge.upright(s.endAngle) ? "bottom" : "top";
|
|
208
|
-
}
|
|
209
|
-
return "middle";
|
|
210
|
-
})
|
|
211
|
-
.textAngle(function() {
|
|
212
|
-
var s = this.scene.target[this.index], a = 0;
|
|
213
|
-
if (partial(s)) switch (this.name()) {
|
|
214
|
-
case "center":
|
|
215
|
-
case "inner":
|
|
216
|
-
case "outer": a = midAngle(s); break;
|
|
217
|
-
case "start": a = s.startAngle; break;
|
|
218
|
-
case "end": a = s.endAngle; break;
|
|
219
|
-
}
|
|
220
|
-
return pv.Wedge.upright(a) ? a : (a + Math.PI);
|
|
221
|
-
});
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Returns true if the specified angle is considered "upright", as in, text
|
|
226
|
-
* rendered at that angle would appear upright. If the angle is not upright,
|
|
227
|
-
* text is rotated 180 degrees to be upright, and the text alignment properties
|
|
228
|
-
* are correspondingly changed.
|
|
229
|
-
*
|
|
230
|
-
* @param {number} angle an angle, in radius.
|
|
231
|
-
* @returns {boolean} true if the specified angle is upright.
|
|
232
|
-
*/
|
|
233
|
-
pv.Wedge.upright = function(angle) {
|
|
234
|
-
angle = angle % (2 * Math.PI);
|
|
235
|
-
angle = (angle < 0) ? (2 * Math.PI + angle) : angle;
|
|
236
|
-
return (angle < Math.PI / 2) || (angle >= 3 * Math.PI / 2);
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
/** @private Sets angle based on endAngle or vice versa. */
|
|
240
|
-
pv.Wedge.prototype.buildImplied = function(s) {
|
|
241
|
-
if (s.angle == null) s.angle = s.endAngle - s.startAngle;
|
|
242
|
-
else if (s.endAngle == null) s.endAngle = s.startAngle + s.angle;
|
|
243
|
-
pv.Mark.prototype.buildImplied.call(this, s);
|
|
244
|
-
};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new bound constraint. Before the constraint can be used, the
|
|
3
|
-
* {@link #x} and {@link #y} methods must be call to specify the bounds.
|
|
4
|
-
*
|
|
5
|
-
* @class Constrains particles to within fixed rectangular bounds. For example,
|
|
6
|
-
* this constraint can be used to constrain particles in a physics simulation
|
|
7
|
-
* within the bounds of an enclosing panel.
|
|
8
|
-
*
|
|
9
|
-
* <p>Note that the current implementation treats particles as points, with no
|
|
10
|
-
* area. If the particles are rendered as dots, be sure to include some
|
|
11
|
-
* additional padding to inset the bounds such that the edges of the dots do not
|
|
12
|
-
* get clipped by the panel bounds. If the particles have different radii, this
|
|
13
|
-
* constraint would need to be extended using a radius function, similar to
|
|
14
|
-
* {@link pv.Constraint.collision}.
|
|
15
|
-
*
|
|
16
|
-
* @see pv.Layout.Force
|
|
17
|
-
* @extends pv.Constraint
|
|
18
|
-
*/
|
|
19
|
-
pv.Constraint.bound = function() {
|
|
20
|
-
var constraint = {},
|
|
21
|
-
x,
|
|
22
|
-
y;
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Sets or gets the bounds on the x-coordinate.
|
|
26
|
-
*
|
|
27
|
-
* @function
|
|
28
|
-
* @name pv.Constraint.bound.prototype.x
|
|
29
|
-
* @param {number} min the minimum allowed x-coordinate.
|
|
30
|
-
* @param {number} max the maximum allowed x-coordinate.
|
|
31
|
-
* @returns {pv.Constraint.bound} this.
|
|
32
|
-
*/
|
|
33
|
-
constraint.x = function(min, max) {
|
|
34
|
-
if (arguments.length) {
|
|
35
|
-
x = {min: Math.min(min, max), max: Math.max(min, max)};
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
|
-
return x;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Sets or gets the bounds on the y-coordinate.
|
|
43
|
-
*
|
|
44
|
-
* @function
|
|
45
|
-
* @name pv.Constraint.bound.prototype.y
|
|
46
|
-
* @param {number} min the minimum allowed y-coordinate.
|
|
47
|
-
* @param {number} max the maximum allowed y-coordinate.
|
|
48
|
-
* @returns {pv.Constraint.bound} this.
|
|
49
|
-
*/
|
|
50
|
-
constraint.y = function(min, max) {
|
|
51
|
-
if (arguments.length) {
|
|
52
|
-
y = {min: Math.min(min, max), max: Math.max(min, max)};
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
return y;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Applies this constraint to the specified particles.
|
|
60
|
-
*
|
|
61
|
-
* @function
|
|
62
|
-
* @name pv.Constraint.bound.prototype.apply
|
|
63
|
-
* @param {pv.Particle} particles particles to which to apply this constraint.
|
|
64
|
-
*/
|
|
65
|
-
constraint.apply = function(particles) {
|
|
66
|
-
if (x) for (var p = particles; p; p = p.next) {
|
|
67
|
-
p.x = p.x < x.min ? x.min : (p.x > x.max ? x.max : p.x);
|
|
68
|
-
}
|
|
69
|
-
if (y) for (var p = particles; p; p = p.next) {
|
|
70
|
-
p.y = p.y < y.min ? y.min : (p.y > y.max ? y.max : p.y);
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return constraint;
|
|
75
|
-
};
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Constructs a new charge force, with an optional charge constant. The charge
|
|
3
|
-
* constant can be negative for repulsion (e.g., particles with electrical
|
|
4
|
-
* charge of equal sign), or positive for attraction (e.g., massive particles
|
|
5
|
-
* with mutual gravity). The default charge constant is -40.
|
|
6
|
-
*
|
|
7
|
-
* @class An n-body force, as defined by Coulomb's law or Newton's law of
|
|
8
|
-
* gravitation, inversely proportional to the square of the distance between
|
|
9
|
-
* particles. Note that the force is independent of the <i>mass</i> of the
|
|
10
|
-
* associated particles, and that the particles do not have charges of varying
|
|
11
|
-
* magnitude; instead, the attraction or repulsion of all particles is globally
|
|
12
|
-
* specified as the charge {@link #constant}.
|
|
13
|
-
*
|
|
14
|
-
* <p>This particular implementation uses the Barnes-Hut algorithm. For details,
|
|
15
|
-
* see <a
|
|
16
|
-
* href="http://www.nature.com/nature/journal/v324/n6096/abs/324446a0.html">"A
|
|
17
|
-
* hierarchical O(N log N) force-calculation algorithm"</a>, J. Barnes &
|
|
18
|
-
* P. Hut, <i>Nature</i> 1986.
|
|
19
|
-
*
|
|
20
|
-
* @name pv.Force.charge
|
|
21
|
-
* @param {number} [k] the charge constant.
|
|
22
|
-
*/
|
|
23
|
-
pv.Force.charge = function(k) {
|
|
24
|
-
var min = 2, // minimum distance at which to observe forces
|
|
25
|
-
min1 = 1 / min,
|
|
26
|
-
max = 500, // maximum distance at which to observe forces
|
|
27
|
-
max1 = 1 / max,
|
|
28
|
-
theta = .9, // Barnes-Hut theta approximation constant
|
|
29
|
-
force = {};
|
|
30
|
-
|
|
31
|
-
if (!arguments.length) k = -40; // default charge constant (repulsion)
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Sets or gets the charge constant. If an argument is specified, it is the
|
|
35
|
-
* new charge constant. The charge constant can be negative for repulsion
|
|
36
|
-
* (e.g., particles with electrical charge of equal sign), or positive for
|
|
37
|
-
* attraction (e.g., massive particles with mutual gravity). The default
|
|
38
|
-
* charge constant is -40.
|
|
39
|
-
*
|
|
40
|
-
* @function
|
|
41
|
-
* @name pv.Force.charge.prototype.constant
|
|
42
|
-
* @param {number} x the charge constant.
|
|
43
|
-
* @returns {pv.Force.charge} this.
|
|
44
|
-
*/
|
|
45
|
-
force.constant = function(x) {
|
|
46
|
-
if (arguments.length) {
|
|
47
|
-
k = Number(x);
|
|
48
|
-
return force;
|
|
49
|
-
}
|
|
50
|
-
return k;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Sets or gets the domain; specifies the minimum and maximum domain within
|
|
55
|
-
* which charge forces are applied. A minimum distance threshold avoids
|
|
56
|
-
* applying forces that are two strong (due to granularity of the simulation's
|
|
57
|
-
* numeric integration). A maximum distance threshold improves performance by
|
|
58
|
-
* skipping force calculations for particles that are far apart.
|
|
59
|
-
*
|
|
60
|
-
* <p>The default domain is [2, 500].
|
|
61
|
-
*
|
|
62
|
-
* @function
|
|
63
|
-
* @name pv.Force.charge.prototype.domain
|
|
64
|
-
* @param {number} a
|
|
65
|
-
* @param {number} b
|
|
66
|
-
* @returns {pv.Force.charge} this.
|
|
67
|
-
*/
|
|
68
|
-
force.domain = function(a, b) {
|
|
69
|
-
if (arguments.length) {
|
|
70
|
-
min = Number(a);
|
|
71
|
-
min1 = 1 / min;
|
|
72
|
-
max = Number(b);
|
|
73
|
-
max1 = 1 / max;
|
|
74
|
-
return force;
|
|
75
|
-
}
|
|
76
|
-
return [min, max];
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Sets or gets the Barnes-Hut approximation factor. The Barnes-Hut
|
|
81
|
-
* approximation criterion is the ratio of the size of the quadtree node to
|
|
82
|
-
* the distance from the point to the node's center of mass is beneath some
|
|
83
|
-
* threshold.
|
|
84
|
-
*
|
|
85
|
-
* @function
|
|
86
|
-
* @name pv.Force.charge.prototype.theta
|
|
87
|
-
* @param {number} x the new Barnes-Hut approximation factor.
|
|
88
|
-
* @returns {pv.Force.charge} this.
|
|
89
|
-
*/
|
|
90
|
-
force.theta = function(x) {
|
|
91
|
-
if (arguments.length) {
|
|
92
|
-
theta = Number(x);
|
|
93
|
-
return force;
|
|
94
|
-
}
|
|
95
|
-
return theta;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* @ignore Recursively computes the center of charge for each node in the
|
|
100
|
-
* quadtree. This is equivalent to the center of mass, assuming that all
|
|
101
|
-
* particles have unit weight.
|
|
102
|
-
*/
|
|
103
|
-
function accumulate(n) {
|
|
104
|
-
var cx = 0, cy = 0;
|
|
105
|
-
n.cn = 0;
|
|
106
|
-
function accumulateChild(c) {
|
|
107
|
-
accumulate(c);
|
|
108
|
-
n.cn += c.cn;
|
|
109
|
-
cx += c.cn * c.cx;
|
|
110
|
-
cy += c.cn * c.cy;
|
|
111
|
-
}
|
|
112
|
-
if (!n.leaf) {
|
|
113
|
-
if (n.c1) accumulateChild(n.c1);
|
|
114
|
-
if (n.c2) accumulateChild(n.c2);
|
|
115
|
-
if (n.c3) accumulateChild(n.c3);
|
|
116
|
-
if (n.c4) accumulateChild(n.c4);
|
|
117
|
-
}
|
|
118
|
-
if (n.p) {
|
|
119
|
-
n.cn += k;
|
|
120
|
-
cx += k * n.p.x;
|
|
121
|
-
cy += k * n.p.y;
|
|
122
|
-
}
|
|
123
|
-
n.cx = cx / n.cn;
|
|
124
|
-
n.cy = cy / n.cn;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* @ignore Recursively computes forces on the given particle using the given
|
|
129
|
-
* quadtree node. The Barnes-Hut approximation criterion is the ratio of the
|
|
130
|
-
* size of the quadtree node to the distance from the point to the node's
|
|
131
|
-
* center of mass is beneath some threshold.
|
|
132
|
-
*/
|
|
133
|
-
function forces(n, p, x1, y1, x2, y2) {
|
|
134
|
-
var dx = n.cx - p.x,
|
|
135
|
-
dy = n.cy - p.y,
|
|
136
|
-
dn = 1 / Math.sqrt(dx * dx + dy * dy);
|
|
137
|
-
|
|
138
|
-
/* Barnes-Hut criterion. */
|
|
139
|
-
if ((n.leaf && (n.p != p)) || ((x2 - x1) * dn < theta)) {
|
|
140
|
-
if (dn < max1) return;
|
|
141
|
-
if (dn > min1) dn = min1;
|
|
142
|
-
var kc = n.cn * dn * dn * dn,
|
|
143
|
-
fx = dx * kc,
|
|
144
|
-
fy = dy * kc;
|
|
145
|
-
p.fx += fx;
|
|
146
|
-
p.fy += fy;
|
|
147
|
-
} else if (!n.leaf) {
|
|
148
|
-
var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5;
|
|
149
|
-
if (n.c1) forces(n.c1, p, x1, y1, sx, sy);
|
|
150
|
-
if (n.c2) forces(n.c2, p, sx, y1, x2, sy);
|
|
151
|
-
if (n.c3) forces(n.c3, p, x1, sy, sx, y2);
|
|
152
|
-
if (n.c4) forces(n.c4, p, sx, sy, x2, y2);
|
|
153
|
-
if (dn < max1) return;
|
|
154
|
-
if (dn > min1) dn = min1;
|
|
155
|
-
if (n.p && (n.p != p)) {
|
|
156
|
-
var kc = k * dn * dn * dn,
|
|
157
|
-
fx = dx * kc,
|
|
158
|
-
fy = dy * kc;
|
|
159
|
-
p.fx += fx;
|
|
160
|
-
p.fy += fy;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Applies this force to the specified particles. The force is applied between
|
|
167
|
-
* all pairs of particles within the domain, using the specified quadtree to
|
|
168
|
-
* accelerate n-body force calculation using the Barnes-Hut approximation
|
|
169
|
-
* criterion.
|
|
170
|
-
*
|
|
171
|
-
* @function
|
|
172
|
-
* @name pv.Force.charge.prototype.apply
|
|
173
|
-
* @param {pv.Particle} particles particles to which to apply this force.
|
|
174
|
-
* @param {pv.Quadtree} q a quadtree for spatial acceleration.
|
|
175
|
-
*/
|
|
176
|
-
force.apply = function(particles, q) {
|
|
177
|
-
accumulate(q.root);
|
|
178
|
-
for (var p = particles; p; p = p.next) {
|
|
179
|
-
forces(q.root, p, q.xMin, q.yMin, q.xMax, q.yMax);
|
|
180
|
-
}
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
return force;
|
|
184
|
-
};
|