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,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a new point behavior to be registered on mousemove events.
|
|
3
|
-
*
|
|
4
|
-
* @class Implements interactive fuzzy pointing, identifying marks that are in
|
|
5
|
-
* close proximity to the mouse cursor. This behavior is an alternative to the
|
|
6
|
-
* native mouseover and mouseout events, improving usability. Rather than
|
|
7
|
-
* requiring the user to mouseover a mark exactly, the mouse simply needs to
|
|
8
|
-
* move near the given mark and a "point" event is triggered. In addition, if
|
|
9
|
-
* multiple marks overlap, the point behavior can be used to identify the mark
|
|
10
|
-
* instance closest to the cursor, as opposed to the one that is rendered on
|
|
11
|
-
* top.
|
|
12
|
-
*
|
|
13
|
-
* <p>The point behavior can also identify the closest mark instance for marks
|
|
14
|
-
* that produce a continuous graphic primitive. The point behavior can thus be
|
|
15
|
-
* used to provide details-on-demand for both discrete marks (such as dots and
|
|
16
|
-
* bars), as well as continuous marks (such as lines and areas).
|
|
17
|
-
*
|
|
18
|
-
* <p>This behavior is implemented by finding the closest mark instance to the
|
|
19
|
-
* mouse cursor on every mousemove event. If this closest mark is within the
|
|
20
|
-
* given radius threshold, which defaults to 30 pixels, a "point" psuedo-event
|
|
21
|
-
* is dispatched to the given mark instance. If any mark were previously
|
|
22
|
-
* pointed, it would receive a corresponding "unpoint" event. These two
|
|
23
|
-
* psuedo-event types correspond to the native "mouseover" and "mouseout"
|
|
24
|
-
* events, respectively. To increase the radius at which the point behavior can
|
|
25
|
-
* be applied, specify an appropriate threshold to the constructor, up to
|
|
26
|
-
* <tt>Infinity</tt>.
|
|
27
|
-
*
|
|
28
|
-
* <p>By default, the standard Cartesian distance is computed. However, with
|
|
29
|
-
* some visualizations it is desirable to consider only a single dimension, such
|
|
30
|
-
* as the <i>x</i>-dimension for an independent variable. In this case, the
|
|
31
|
-
* collapse parameter can be set to collapse the <i>y</i> dimension:
|
|
32
|
-
*
|
|
33
|
-
* <pre> .event("mousemove", pv.Behavior.point(Infinity).collapse("y"))</pre>
|
|
34
|
-
*
|
|
35
|
-
* <p>This behavior only listens to mousemove events on the assigned panel,
|
|
36
|
-
* which is typically the root panel. The behavior will search recursively for
|
|
37
|
-
* descendant marks to point. If the mouse leaves the assigned panel, the
|
|
38
|
-
* behavior no longer receives mousemove events; an unpoint psuedo-event is
|
|
39
|
-
* automatically dispatched to unpoint any pointed mark. Marks may be re-pointed
|
|
40
|
-
* when the mouse reenters the panel.
|
|
41
|
-
*
|
|
42
|
-
* <p>Panels have transparent fill styles by default; this means that panels may
|
|
43
|
-
* not receive the initial mousemove event to start pointing. To fix this
|
|
44
|
-
* problem, either given the panel a visible fill style (such as "white"), or
|
|
45
|
-
* set the <tt>events</tt> property to "all" such that the panel receives events
|
|
46
|
-
* despite its transparent fill.
|
|
47
|
-
*
|
|
48
|
-
* <p>Note: this behavior does not currently wedge marks.
|
|
49
|
-
*
|
|
50
|
-
* @extends pv.Behavior
|
|
51
|
-
*
|
|
52
|
-
* @param {number} [r] the fuzzy radius threshold in pixels
|
|
53
|
-
* @see <a href="http://www.tovigrossman.com/papers/chi2005bubblecursor.pdf"
|
|
54
|
-
* >"The Bubble Cursor: Enhancing Target Acquisition by Dynamic Resizing of the
|
|
55
|
-
* Cursor's Activation Area"</a> by T. Grossman & R. Balakrishnan, CHI 2005.
|
|
56
|
-
*/
|
|
57
|
-
pv.Behavior.point = function(r) {
|
|
58
|
-
var unpoint, // the current pointer target
|
|
59
|
-
collapse = null, // dimensions to collapse
|
|
60
|
-
kx = 1, // x-dimension cost scale
|
|
61
|
-
ky = 1, // y-dimension cost scale
|
|
62
|
-
r2 = arguments.length ? r * r : 900; // fuzzy radius
|
|
63
|
-
|
|
64
|
-
/** @private Search for the mark closest to the mouse. */
|
|
65
|
-
function search(scene, index) {
|
|
66
|
-
var s = scene[index],
|
|
67
|
-
point = {cost: Infinity};
|
|
68
|
-
for (var i = 0, n = s.visible && s.children.length; i < n; i++) {
|
|
69
|
-
var child = s.children[i], mark = child.mark, p;
|
|
70
|
-
if (mark.type == "panel") {
|
|
71
|
-
mark.scene = child;
|
|
72
|
-
for (var j = 0, m = child.length; j < m; j++) {
|
|
73
|
-
mark.index = j;
|
|
74
|
-
p = search(child, j);
|
|
75
|
-
if (p.cost < point.cost) point = p;
|
|
76
|
-
}
|
|
77
|
-
delete mark.scene;
|
|
78
|
-
delete mark.index;
|
|
79
|
-
} else if (mark.$handlers.point) {
|
|
80
|
-
var v = mark.mouse();
|
|
81
|
-
for (var j = 0, m = child.length; j < m; j++) {
|
|
82
|
-
var c = child[j],
|
|
83
|
-
dx = v.x - c.left - (c.width || 0) / 2,
|
|
84
|
-
dy = v.y - c.top - (c.height || 0) / 2,
|
|
85
|
-
dd = kx * dx * dx + ky * dy * dy;
|
|
86
|
-
if (dd < point.cost) {
|
|
87
|
-
point.distance = dx * dx + dy * dy;
|
|
88
|
-
point.cost = dd;
|
|
89
|
-
point.scene = child;
|
|
90
|
-
point.index = j;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return point;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/** @private */
|
|
99
|
-
function mousemove() {
|
|
100
|
-
/* If the closest mark is far away, clear the current target. */
|
|
101
|
-
var point = search(this.scene, this.index);
|
|
102
|
-
if ((point.cost == Infinity) || (point.distance > r2)) point = null;
|
|
103
|
-
|
|
104
|
-
/* Unpoint the old target, if it's not the new target. */
|
|
105
|
-
if (unpoint) {
|
|
106
|
-
if (point
|
|
107
|
-
&& (unpoint.scene == point.scene)
|
|
108
|
-
&& (unpoint.index == point.index)) return;
|
|
109
|
-
pv.Mark.dispatch("unpoint", unpoint.scene, unpoint.index);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/* Point the new target, if there is one. */
|
|
113
|
-
if (unpoint = point) {
|
|
114
|
-
pv.Mark.dispatch("point", point.scene, point.index);
|
|
115
|
-
|
|
116
|
-
/* Unpoint when the mouse leaves the root panel. */
|
|
117
|
-
pv.listen(this.root.canvas(), "mouseout", mouseout);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/** @private */
|
|
122
|
-
function mouseout(e) {
|
|
123
|
-
if (unpoint && !pv.ancestor(this, e.relatedTarget)) {
|
|
124
|
-
pv.Mark.dispatch("unpoint", unpoint.scene, unpoint.index);
|
|
125
|
-
unpoint = null;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Sets or gets the collapse parameter. By default, the standard Cartesian
|
|
131
|
-
* distance is computed. However, with some visualizations it is desirable to
|
|
132
|
-
* consider only a single dimension, such as the <i>x</i>-dimension for an
|
|
133
|
-
* independent variable. In this case, the collapse parameter can be set to
|
|
134
|
-
* collapse the <i>y</i> dimension:
|
|
135
|
-
*
|
|
136
|
-
* <pre> .event("mousemove", pv.Behavior.point(Infinity).collapse("y"))</pre>
|
|
137
|
-
*
|
|
138
|
-
* @function
|
|
139
|
-
* @returns {pv.Behavior.point} this, or the current collapse parameter.
|
|
140
|
-
* @name pv.Behavior.point.prototype.collapse
|
|
141
|
-
* @param {string} [x] the new collapse parameter
|
|
142
|
-
*/
|
|
143
|
-
mousemove.collapse = function(x) {
|
|
144
|
-
if (arguments.length) {
|
|
145
|
-
collapse = String(x);
|
|
146
|
-
switch (collapse) {
|
|
147
|
-
case "y": kx = 1; ky = 0; break;
|
|
148
|
-
case "x": kx = 0; ky = 1; break;
|
|
149
|
-
default: kx = 1; ky = 1; break;
|
|
150
|
-
}
|
|
151
|
-
return mousemove;
|
|
152
|
-
}
|
|
153
|
-
return collapse;
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
return mousemove;
|
|
157
|
-
};
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a new resize behavior to be registered on mousedown events.
|
|
3
|
-
*
|
|
4
|
-
* @class Implements interactive resizing of a selection starting with mousedown
|
|
5
|
-
* events. Register this behavior on selection handles that should be resizeable
|
|
6
|
-
* by the user, such for brushing and linking. This behavior can be used in
|
|
7
|
-
* tandom with {@link pv.Behavior.select} and {@link pv.Behavior.drag} to allow
|
|
8
|
-
* the selected region to be selected and dragged interactively.
|
|
9
|
-
*
|
|
10
|
-
* <p>After the initial mousedown event is triggered, this behavior listens for
|
|
11
|
-
* mousemove and mouseup events on the window. This allows resizing to continue
|
|
12
|
-
* even if the mouse temporarily leaves the assigned panel, or even the root
|
|
13
|
-
* panel.
|
|
14
|
-
*
|
|
15
|
-
* <p>This behavior requires that the data associated with the mark being
|
|
16
|
-
* resized have <tt>x</tt>, <tt>y</tt>, <tt>dx</tt> and <tt>dy</tt> attributes
|
|
17
|
-
* that correspond to the mark's location and dimensions in pixels. The mark's
|
|
18
|
-
* positional properties are not set directly by this behavior; instead, the
|
|
19
|
-
* positional properties should be defined as:
|
|
20
|
-
*
|
|
21
|
-
* <pre> .left(function(d) d.x)
|
|
22
|
-
* .top(function(d) d.y)
|
|
23
|
-
* .width(function(d) d.dx)
|
|
24
|
-
* .height(function(d) d.dy)</pre>
|
|
25
|
-
*
|
|
26
|
-
* Thus, the behavior does not resize the mark directly, but instead updates the
|
|
27
|
-
* size by updating the assigned panel's underlying data. Note that if the
|
|
28
|
-
* positional properties are defined with bottom and right (rather than top and
|
|
29
|
-
* left), the resize behavior will be inverted, which will confuse users!
|
|
30
|
-
*
|
|
31
|
-
* <p>The resize behavior is bounded by the assigned mark's enclosing panel; the
|
|
32
|
-
* positional attributes are clamped such that the selection does not extend
|
|
33
|
-
* outside the panel's bounds.
|
|
34
|
-
*
|
|
35
|
-
* <p>The mark being resized is automatically re-rendered for each mouse event
|
|
36
|
-
* as part of the resize operation. This behavior may be enhanced in the future
|
|
37
|
-
* to allow more flexible configuration. In some cases, such as with parallel
|
|
38
|
-
* coordinates, resizing the selection may cause related marks to change, in
|
|
39
|
-
* which case additional marks may also need to be rendered. This can be
|
|
40
|
-
* accomplished by listening for the select psuedo-events:<ul>
|
|
41
|
-
*
|
|
42
|
-
* <li>resizestart (on mousedown)
|
|
43
|
-
* <li>resize (on mousemove)
|
|
44
|
-
* <li>resizeend (on mouseup)
|
|
45
|
-
*
|
|
46
|
-
* </ul>For example, to render the parent panel while resizing, thus
|
|
47
|
-
* re-rendering all sibling marks:
|
|
48
|
-
*
|
|
49
|
-
* <pre> .event("mousedown", pv.Behavior.resize("left"))
|
|
50
|
-
* .event("resize", function() this.parent)</pre>
|
|
51
|
-
*
|
|
52
|
-
* This behavior may be enhanced in the future to allow more flexible
|
|
53
|
-
* configuration of the selection behavior.
|
|
54
|
-
*
|
|
55
|
-
* @extends pv.Behavior
|
|
56
|
-
* @see pv.Behavior.select
|
|
57
|
-
* @see pv.Behavior.drag
|
|
58
|
-
*/
|
|
59
|
-
pv.Behavior.resize = function(side) {
|
|
60
|
-
var scene, // scene context
|
|
61
|
-
index, // scene context
|
|
62
|
-
r, // region being selected
|
|
63
|
-
m1; // initial mouse position
|
|
64
|
-
|
|
65
|
-
/** @private */
|
|
66
|
-
function mousedown(d) {
|
|
67
|
-
index = this.index;
|
|
68
|
-
scene = this.scene;
|
|
69
|
-
m1 = this.mouse();
|
|
70
|
-
r = d;
|
|
71
|
-
switch (side) {
|
|
72
|
-
case "left": m1.x = r.x + r.dx; break;
|
|
73
|
-
case "right": m1.x = r.x; break;
|
|
74
|
-
case "top": m1.y = r.y + r.dy; break;
|
|
75
|
-
case "bottom": m1.y = r.y; break;
|
|
76
|
-
}
|
|
77
|
-
pv.Mark.dispatch("resizestart", scene, index);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/** @private */
|
|
81
|
-
function mousemove() {
|
|
82
|
-
if (!scene) return;
|
|
83
|
-
scene.mark.context(scene, index, function() {
|
|
84
|
-
var m2 = this.mouse();
|
|
85
|
-
r.x = Math.max(0, Math.min(m1.x, m2.x));
|
|
86
|
-
r.y = Math.max(0, Math.min(m1.y, m2.y));
|
|
87
|
-
r.dx = Math.min(this.parent.width(), Math.max(m2.x, m1.x)) - r.x;
|
|
88
|
-
r.dy = Math.min(this.parent.height(), Math.max(m2.y, m1.y)) - r.y;
|
|
89
|
-
this.render();
|
|
90
|
-
});
|
|
91
|
-
pv.Mark.dispatch("resize", scene, index);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/** @private */
|
|
95
|
-
function mouseup() {
|
|
96
|
-
if (!scene) return;
|
|
97
|
-
pv.Mark.dispatch("resizeend", scene, index);
|
|
98
|
-
scene = null;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
pv.listen(window, "mousemove", mousemove);
|
|
102
|
-
pv.listen(window, "mouseup", mouseup);
|
|
103
|
-
return mousedown;
|
|
104
|
-
};
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a new select behavior to be registered on mousedown events.
|
|
3
|
-
*
|
|
4
|
-
* @class Implements interactive selecting starting with mousedown events.
|
|
5
|
-
* Register this behavior on panels that should be selectable by the user, such
|
|
6
|
-
* for brushing and linking. This behavior can be used in tandom with
|
|
7
|
-
* {@link pv.Behavior.drag} to allow the selected region to be dragged
|
|
8
|
-
* interactively.
|
|
9
|
-
*
|
|
10
|
-
* <p>After the initial mousedown event is triggered, this behavior listens for
|
|
11
|
-
* mousemove and mouseup events on the window. This allows selecting to continue
|
|
12
|
-
* even if the mouse temporarily leaves the assigned panel, or even the root
|
|
13
|
-
* panel.
|
|
14
|
-
*
|
|
15
|
-
* <p>This behavior requires that the data associated with the mark being
|
|
16
|
-
* dragged have <tt>x</tt>, <tt>y</tt>, <tt>dx</tt> and <tt>dy</tt> attributes
|
|
17
|
-
* that correspond to the mark's location and dimensions in pixels. The mark's
|
|
18
|
-
* positional properties are not set directly by this behavior; instead, the
|
|
19
|
-
* positional properties should be defined as:
|
|
20
|
-
*
|
|
21
|
-
* <pre> .left(function(d) d.x)
|
|
22
|
-
* .top(function(d) d.y)
|
|
23
|
-
* .width(function(d) d.dx)
|
|
24
|
-
* .height(function(d) d.dy)</pre>
|
|
25
|
-
*
|
|
26
|
-
* Thus, the behavior does not resize the mark directly, but instead updates the
|
|
27
|
-
* selection by updating the assigned panel's underlying data. Note that if the
|
|
28
|
-
* positional properties are defined with bottom and right (rather than top and
|
|
29
|
-
* left), the drag behavior will be inverted, which will confuse users!
|
|
30
|
-
*
|
|
31
|
-
* <p>The select behavior is bounded by the assigned panel; the positional
|
|
32
|
-
* attributes are clamped such that the selection does not extend outside the
|
|
33
|
-
* panel's bounds.
|
|
34
|
-
*
|
|
35
|
-
* <p>The panel being selected is automatically re-rendered for each mouse event
|
|
36
|
-
* as part of the drag operation. This behavior may be enhanced in the future to
|
|
37
|
-
* allow more flexible configuration of select behavior. In some cases, such as
|
|
38
|
-
* with parallel coordinates, making a selection may cause related marks to
|
|
39
|
-
* change, in which case additional marks may also need to be rendered. This can
|
|
40
|
-
* be accomplished by listening for the select psuedo-events:<ul>
|
|
41
|
-
*
|
|
42
|
-
* <li>selectstart (on mousedown)
|
|
43
|
-
* <li>select (on mousemove)
|
|
44
|
-
* <li>selectend (on mouseup)
|
|
45
|
-
*
|
|
46
|
-
* </ul>For example, to render the parent panel while selecting, thus
|
|
47
|
-
* re-rendering all sibling marks:
|
|
48
|
-
*
|
|
49
|
-
* <pre> .event("mousedown", pv.Behavior.drag())
|
|
50
|
-
* .event("select", function() this.parent)</pre>
|
|
51
|
-
*
|
|
52
|
-
* This behavior may be enhanced in the future to allow more flexible
|
|
53
|
-
* configuration of the selection behavior.
|
|
54
|
-
*
|
|
55
|
-
* @extends pv.Behavior
|
|
56
|
-
* @see pv.Behavior.drag
|
|
57
|
-
*/
|
|
58
|
-
pv.Behavior.select = function() {
|
|
59
|
-
var scene, // scene context
|
|
60
|
-
index, // scene context
|
|
61
|
-
r, // region being selected
|
|
62
|
-
m1; // initial mouse position
|
|
63
|
-
|
|
64
|
-
/** @private */
|
|
65
|
-
function mousedown(d) {
|
|
66
|
-
index = this.index;
|
|
67
|
-
scene = this.scene;
|
|
68
|
-
m1 = this.mouse();
|
|
69
|
-
r = d;
|
|
70
|
-
r.x = m1.x;
|
|
71
|
-
r.y = m1.y;
|
|
72
|
-
r.dx = r.dy = 0;
|
|
73
|
-
pv.Mark.dispatch("selectstart", scene, index);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** @private */
|
|
77
|
-
function mousemove() {
|
|
78
|
-
if (!scene) return;
|
|
79
|
-
scene.mark.context(scene, index, function() {
|
|
80
|
-
var m2 = this.mouse();
|
|
81
|
-
r.x = Math.max(0, Math.min(m1.x, m2.x));
|
|
82
|
-
r.y = Math.max(0, Math.min(m1.y, m2.y));
|
|
83
|
-
r.dx = Math.min(this.width(), Math.max(m2.x, m1.x)) - r.x;
|
|
84
|
-
r.dy = Math.min(this.height(), Math.max(m2.y, m1.y)) - r.y;
|
|
85
|
-
this.render();
|
|
86
|
-
});
|
|
87
|
-
pv.Mark.dispatch("select", scene, index);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** @private */
|
|
91
|
-
function mouseup() {
|
|
92
|
-
if (!scene) return;
|
|
93
|
-
pv.Mark.dispatch("selectend", scene, index);
|
|
94
|
-
scene = null;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
pv.listen(window, "mousemove", mousemove);
|
|
98
|
-
pv.listen(window, "mouseup", mouseup);
|
|
99
|
-
return mousedown;
|
|
100
|
-
};
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns a new zoom behavior to be registered on mousewheel events.
|
|
3
|
-
*
|
|
4
|
-
* @class Implements interactive zooming using mousewheel events. Register this
|
|
5
|
-
* behavior on panels to allow zooming. This behavior can be used in tandem with
|
|
6
|
-
* {@link pv.Behavior.pan} to allow both panning and zooming:
|
|
7
|
-
*
|
|
8
|
-
* <pre> .event("mousedown", pv.Behavior.pan())
|
|
9
|
-
* .event("mousewheel", pv.Behavior.zoom())</pre>
|
|
10
|
-
*
|
|
11
|
-
* The zoom behavior currently supports only mousewheel events; support for
|
|
12
|
-
* keyboard shortcuts and gesture events to improve accessibility may be added
|
|
13
|
-
* in the future.
|
|
14
|
-
*
|
|
15
|
-
* <p>The implementation of this behavior relies on the panel's
|
|
16
|
-
* <tt>transform</tt> property, which specifies a matrix transformation that is
|
|
17
|
-
* applied to child marks. Note that the transform property only affects the
|
|
18
|
-
* panel's children, but not the panel itself; therefore the panel's fill and
|
|
19
|
-
* stroke will not change when the contents are zoomed. The built-in support for
|
|
20
|
-
* transforms only supports uniform scaling and translates, which is sufficient
|
|
21
|
-
* for panning and zooming. Note that this is not a strict geometric
|
|
22
|
-
* transformation, as the <tt>lineWidth</tt> property is scale-aware: strokes
|
|
23
|
-
* are drawn at constant size independent of scale.
|
|
24
|
-
*
|
|
25
|
-
* <p>Panels have transparent fill styles by default; this means that panels may
|
|
26
|
-
* not receive mousewheel events to zoom. To fix this problem, either given the
|
|
27
|
-
* panel a visible fill style (such as "white"), or set the <tt>events</tt>
|
|
28
|
-
* property to "all" such that the panel receives events despite its transparent
|
|
29
|
-
* fill.
|
|
30
|
-
*
|
|
31
|
-
* <p>The zoom behavior has optional support for bounding. If enabled, the user
|
|
32
|
-
* will not be able to zoom out farther than the initial bounds. This feature is
|
|
33
|
-
* designed to work in conjunction with the pan behavior.
|
|
34
|
-
*
|
|
35
|
-
* @extends pv.Behavior
|
|
36
|
-
* @see pv.Panel#transform
|
|
37
|
-
* @see pv.Mark#scale
|
|
38
|
-
* @param {number} speed
|
|
39
|
-
*/
|
|
40
|
-
pv.Behavior.zoom = function(speed) {
|
|
41
|
-
var bound; // whether to bound to the panel
|
|
42
|
-
|
|
43
|
-
if (!arguments.length) speed = 1 / 48;
|
|
44
|
-
|
|
45
|
-
/** @private */
|
|
46
|
-
function mousewheel() {
|
|
47
|
-
var v = this.mouse(),
|
|
48
|
-
k = pv.event.wheel * speed,
|
|
49
|
-
m = this.transform().translate(v.x, v.y)
|
|
50
|
-
.scale((k < 0) ? (1e3 / (1e3 - k)) : ((1e3 + k) / 1e3))
|
|
51
|
-
.translate(-v.x, -v.y);
|
|
52
|
-
if (bound) {
|
|
53
|
-
m.k = Math.max(1, m.k);
|
|
54
|
-
m.x = Math.max((1 - m.k) * this.width(), Math.min(0, m.x));
|
|
55
|
-
m.y = Math.max((1 - m.k) * this.height(), Math.min(0, m.y));
|
|
56
|
-
}
|
|
57
|
-
this.transform(m).render();
|
|
58
|
-
pv.Mark.dispatch("zoom", this.scene, this.index);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Sets or gets the bound parameter. If bounding is enabled, the user will not
|
|
63
|
-
* be able to zoom out farther than the initial panel bounds. Bounding is not
|
|
64
|
-
* enabled by default. If this behavior is used in tandem with the pan
|
|
65
|
-
* behavior, both should use the same bound parameter.
|
|
66
|
-
*
|
|
67
|
-
* <p>Note: enabling bounding after zooming has already occurred will not
|
|
68
|
-
* immediately reset the transform. Bounding should be enabled before the zoom
|
|
69
|
-
* behavior is applied.
|
|
70
|
-
*
|
|
71
|
-
* @function
|
|
72
|
-
* @returns {pv.Behavior.zoom} this, or the current bound parameter.
|
|
73
|
-
* @name pv.Behavior.zoom.prototype.bound
|
|
74
|
-
* @param {boolean} [x] the new bound parameter.
|
|
75
|
-
*/
|
|
76
|
-
mousewheel.bound = function(x) {
|
|
77
|
-
if (arguments.length) {
|
|
78
|
-
bound = Boolean(x);
|
|
79
|
-
return this;
|
|
80
|
-
}
|
|
81
|
-
return Boolean(bound);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
return mousewheel;
|
|
85
|
-
};
|
|
@@ -1,598 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the {@link pv.Color} for the specified color format string. Colors
|
|
3
|
-
* may have an associated opacity, or alpha channel. Color formats are specified
|
|
4
|
-
* by CSS Color Modular Level 3, using either in RGB or HSL color space. For
|
|
5
|
-
* example:<ul>
|
|
6
|
-
*
|
|
7
|
-
* <li>#f00 // #rgb
|
|
8
|
-
* <li>#ff0000 // #rrggbb
|
|
9
|
-
* <li>rgb(255, 0, 0)
|
|
10
|
-
* <li>rgb(100%, 0%, 0%)
|
|
11
|
-
* <li>hsl(0, 100%, 50%)
|
|
12
|
-
* <li>rgba(0, 0, 255, 0.5)
|
|
13
|
-
* <li>hsla(120, 100%, 50%, 1)
|
|
14
|
-
*
|
|
15
|
-
* </ul>The SVG 1.0 color keywords names are also supported, such as "aliceblue"
|
|
16
|
-
* and "yellowgreen". The "transparent" keyword is supported for fully-
|
|
17
|
-
* transparent black.
|
|
18
|
-
*
|
|
19
|
-
* <p>If the <tt>format</tt> argument is already an instance of <tt>Color</tt>,
|
|
20
|
-
* the argument is returned with no further processing.
|
|
21
|
-
*
|
|
22
|
-
* @param {string} format the color specification string, such as "#f00".
|
|
23
|
-
* @returns {pv.Color} the corresponding <tt>Color</tt>.
|
|
24
|
-
* @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">SVG color
|
|
25
|
-
* keywords</a>
|
|
26
|
-
* @see <a href="http://www.w3.org/TR/css3-color/">CSS3 color module</a>
|
|
27
|
-
*/
|
|
28
|
-
pv.color = function(format) {
|
|
29
|
-
if (format.rgb) return format.rgb();
|
|
30
|
-
|
|
31
|
-
/* Handle hsl, rgb. */
|
|
32
|
-
var m1 = /([a-z]+)\((.*)\)/i.exec(format);
|
|
33
|
-
if (m1) {
|
|
34
|
-
var m2 = m1[2].split(","), a = 1;
|
|
35
|
-
switch (m1[1]) {
|
|
36
|
-
case "hsla":
|
|
37
|
-
case "rgba": {
|
|
38
|
-
a = parseFloat(m2[3]);
|
|
39
|
-
if (!a) return pv.Color.transparent;
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
switch (m1[1]) {
|
|
44
|
-
case "hsla":
|
|
45
|
-
case "hsl": {
|
|
46
|
-
var h = parseFloat(m2[0]), // degrees
|
|
47
|
-
s = parseFloat(m2[1]) / 100, // percentage
|
|
48
|
-
l = parseFloat(m2[2]) / 100; // percentage
|
|
49
|
-
return (new pv.Color.Hsl(h, s, l, a)).rgb();
|
|
50
|
-
}
|
|
51
|
-
case "rgba":
|
|
52
|
-
case "rgb": {
|
|
53
|
-
function parse(c) { // either integer or percentage
|
|
54
|
-
var f = parseFloat(c);
|
|
55
|
-
return (c[c.length - 1] == '%') ? Math.round(f * 2.55) : f;
|
|
56
|
-
}
|
|
57
|
-
var r = parse(m2[0]), g = parse(m2[1]), b = parse(m2[2]);
|
|
58
|
-
return pv.rgb(r, g, b, a);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/* Named colors. */
|
|
64
|
-
var named = pv.Color.names[format];
|
|
65
|
-
if (named) return named;
|
|
66
|
-
|
|
67
|
-
/* Hexadecimal colors: #rgb and #rrggbb. */
|
|
68
|
-
if (format.charAt(0) == "#") {
|
|
69
|
-
var r, g, b;
|
|
70
|
-
if (format.length == 4) {
|
|
71
|
-
r = format.charAt(1); r += r;
|
|
72
|
-
g = format.charAt(2); g += g;
|
|
73
|
-
b = format.charAt(3); b += b;
|
|
74
|
-
} else if (format.length == 7) {
|
|
75
|
-
r = format.substring(1, 3);
|
|
76
|
-
g = format.substring(3, 5);
|
|
77
|
-
b = format.substring(5, 7);
|
|
78
|
-
}
|
|
79
|
-
return pv.rgb(parseInt(r, 16), parseInt(g, 16), parseInt(b, 16), 1);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/* Otherwise, pass-through unsupported colors. */
|
|
83
|
-
return new pv.Color(format, 1);
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Constructs a color with the specified color format string and opacity. This
|
|
88
|
-
* constructor should not be invoked directly; use {@link pv.color} instead.
|
|
89
|
-
*
|
|
90
|
-
* @class Represents an abstract (possibly translucent) color. The color is
|
|
91
|
-
* divided into two parts: the <tt>color</tt> attribute, an opaque color format
|
|
92
|
-
* string, and the <tt>opacity</tt> attribute, a float in [0, 1]. The color
|
|
93
|
-
* space is dependent on the implementing class; all colors support the
|
|
94
|
-
* {@link #rgb} method to convert to RGB color space for interpolation.
|
|
95
|
-
*
|
|
96
|
-
* <p>See also the <a href="../../api/Color.html">Color guide</a>.
|
|
97
|
-
*
|
|
98
|
-
* @param {string} color an opaque color format string, such as "#f00".
|
|
99
|
-
* @param {number} opacity the opacity, in [0,1].
|
|
100
|
-
* @see pv.color
|
|
101
|
-
*/
|
|
102
|
-
pv.Color = function(color, opacity) {
|
|
103
|
-
/**
|
|
104
|
-
* An opaque color format string, such as "#f00".
|
|
105
|
-
*
|
|
106
|
-
* @type string
|
|
107
|
-
* @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">SVG color
|
|
108
|
-
* keywords</a>
|
|
109
|
-
* @see <a href="http://www.w3.org/TR/css3-color/">CSS3 color module</a>
|
|
110
|
-
*/
|
|
111
|
-
this.color = color;
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* The opacity, a float in [0, 1].
|
|
115
|
-
*
|
|
116
|
-
* @type number
|
|
117
|
-
*/
|
|
118
|
-
this.opacity = opacity;
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Returns a new color that is a brighter version of this color. The behavior of
|
|
123
|
-
* this method may vary slightly depending on the underlying color space.
|
|
124
|
-
* Although brighter and darker are inverse operations, the results of a series
|
|
125
|
-
* of invocations of these two methods might be inconsistent because of rounding
|
|
126
|
-
* errors.
|
|
127
|
-
*
|
|
128
|
-
* @param [k] {number} an optional scale factor; defaults to 1.
|
|
129
|
-
* @see #darker
|
|
130
|
-
* @returns {pv.Color} a brighter color.
|
|
131
|
-
*/
|
|
132
|
-
pv.Color.prototype.brighter = function(k) {
|
|
133
|
-
return this.rgb().brighter(k);
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Returns a new color that is a brighter version of this color. The behavior of
|
|
138
|
-
* this method may vary slightly depending on the underlying color space.
|
|
139
|
-
* Although brighter and darker are inverse operations, the results of a series
|
|
140
|
-
* of invocations of these two methods might be inconsistent because of rounding
|
|
141
|
-
* errors.
|
|
142
|
-
*
|
|
143
|
-
* @param [k] {number} an optional scale factor; defaults to 1.
|
|
144
|
-
* @see #brighter
|
|
145
|
-
* @returns {pv.Color} a darker color.
|
|
146
|
-
*/
|
|
147
|
-
pv.Color.prototype.darker = function(k) {
|
|
148
|
-
return this.rgb().darker(k);
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Constructs a new RGB color with the specified channel values.
|
|
153
|
-
*
|
|
154
|
-
* @param {number} r the red channel, an integer in [0,255].
|
|
155
|
-
* @param {number} g the green channel, an integer in [0,255].
|
|
156
|
-
* @param {number} b the blue channel, an integer in [0,255].
|
|
157
|
-
* @param {number} [a] the alpha channel, a float in [0,1].
|
|
158
|
-
* @returns pv.Color.Rgb
|
|
159
|
-
*/
|
|
160
|
-
pv.rgb = function(r, g, b, a) {
|
|
161
|
-
return new pv.Color.Rgb(r, g, b, (arguments.length == 4) ? a : 1);
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Constructs a new RGB color with the specified channel values.
|
|
166
|
-
*
|
|
167
|
-
* @class Represents a color in RGB space.
|
|
168
|
-
*
|
|
169
|
-
* @param {number} r the red channel, an integer in [0,255].
|
|
170
|
-
* @param {number} g the green channel, an integer in [0,255].
|
|
171
|
-
* @param {number} b the blue channel, an integer in [0,255].
|
|
172
|
-
* @param {number} a the alpha channel, a float in [0,1].
|
|
173
|
-
* @extends pv.Color
|
|
174
|
-
*/
|
|
175
|
-
pv.Color.Rgb = function(r, g, b, a) {
|
|
176
|
-
pv.Color.call(this, a ? ("rgb(" + r + "," + g + "," + b + ")") : "none", a);
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* The red channel, an integer in [0, 255].
|
|
180
|
-
*
|
|
181
|
-
* @type number
|
|
182
|
-
*/
|
|
183
|
-
this.r = r;
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* The green channel, an integer in [0, 255].
|
|
187
|
-
*
|
|
188
|
-
* @type number
|
|
189
|
-
*/
|
|
190
|
-
this.g = g;
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* The blue channel, an integer in [0, 255].
|
|
194
|
-
*
|
|
195
|
-
* @type number
|
|
196
|
-
*/
|
|
197
|
-
this.b = b;
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* The alpha channel, a float in [0, 1].
|
|
201
|
-
*
|
|
202
|
-
* @type number
|
|
203
|
-
*/
|
|
204
|
-
this.a = a;
|
|
205
|
-
};
|
|
206
|
-
pv.Color.Rgb.prototype = pv.extend(pv.Color);
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Constructs a new RGB color with the same green, blue and alpha channels as
|
|
210
|
-
* this color, with the specified red channel.
|
|
211
|
-
*
|
|
212
|
-
* @param {number} r the red channel, an integer in [0,255].
|
|
213
|
-
*/
|
|
214
|
-
pv.Color.Rgb.prototype.red = function(r) {
|
|
215
|
-
return pv.rgb(r, this.g, this.b, this.a);
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Constructs a new RGB color with the same red, blue and alpha channels as this
|
|
220
|
-
* color, with the specified green channel.
|
|
221
|
-
*
|
|
222
|
-
* @param {number} g the green channel, an integer in [0,255].
|
|
223
|
-
*/
|
|
224
|
-
pv.Color.Rgb.prototype.green = function(g) {
|
|
225
|
-
return pv.rgb(this.r, g, this.b, this.a);
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Constructs a new RGB color with the same red, green and alpha channels as
|
|
230
|
-
* this color, with the specified blue channel.
|
|
231
|
-
*
|
|
232
|
-
* @param {number} b the blue channel, an integer in [0,255].
|
|
233
|
-
*/
|
|
234
|
-
pv.Color.Rgb.prototype.blue = function(b) {
|
|
235
|
-
return pv.rgb(this.r, this.g, b, this.a);
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* Constructs a new RGB color with the same red, green and blue channels as this
|
|
240
|
-
* color, with the specified alpha channel.
|
|
241
|
-
*
|
|
242
|
-
* @param {number} a the alpha channel, a float in [0,1].
|
|
243
|
-
*/
|
|
244
|
-
pv.Color.Rgb.prototype.alpha = function(a) {
|
|
245
|
-
return pv.rgb(this.r, this.g, this.b, a);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Returns the RGB color equivalent to this color. This method is abstract and
|
|
250
|
-
* must be implemented by subclasses.
|
|
251
|
-
*
|
|
252
|
-
* @returns {pv.Color.Rgb} an RGB color.
|
|
253
|
-
* @function
|
|
254
|
-
* @name pv.Color.prototype.rgb
|
|
255
|
-
*/
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Returns this.
|
|
259
|
-
*
|
|
260
|
-
* @returns {pv.Color.Rgb} this.
|
|
261
|
-
*/
|
|
262
|
-
pv.Color.Rgb.prototype.rgb = function() { return this; };
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Returns a new color that is a brighter version of this color. This method
|
|
266
|
-
* applies an arbitrary scale factor to each of the three RGB components of this
|
|
267
|
-
* color to create a brighter version of this color. Although brighter and
|
|
268
|
-
* darker are inverse operations, the results of a series of invocations of
|
|
269
|
-
* these two methods might be inconsistent because of rounding errors.
|
|
270
|
-
*
|
|
271
|
-
* @param [k] {number} an optional scale factor; defaults to 1.
|
|
272
|
-
* @see #darker
|
|
273
|
-
* @returns {pv.Color.Rgb} a brighter color.
|
|
274
|
-
*/
|
|
275
|
-
pv.Color.Rgb.prototype.brighter = function(k) {
|
|
276
|
-
k = Math.pow(0.7, arguments.length ? k : 1);
|
|
277
|
-
var r = this.r, g = this.g, b = this.b, i = 30;
|
|
278
|
-
if (!r && !g && !b) return pv.rgb(i, i, i, this.a);
|
|
279
|
-
if (r && (r < i)) r = i;
|
|
280
|
-
if (g && (g < i)) g = i;
|
|
281
|
-
if (b && (b < i)) b = i;
|
|
282
|
-
return pv.rgb(
|
|
283
|
-
Math.min(255, Math.floor(r / k)),
|
|
284
|
-
Math.min(255, Math.floor(g / k)),
|
|
285
|
-
Math.min(255, Math.floor(b / k)),
|
|
286
|
-
this.a);
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Returns a new color that is a darker version of this color. This method
|
|
291
|
-
* applies an arbitrary scale factor to each of the three RGB components of this
|
|
292
|
-
* color to create a darker version of this color. Although brighter and darker
|
|
293
|
-
* are inverse operations, the results of a series of invocations of these two
|
|
294
|
-
* methods might be inconsistent because of rounding errors.
|
|
295
|
-
*
|
|
296
|
-
* @param [k] {number} an optional scale factor; defaults to 1.
|
|
297
|
-
* @see #brighter
|
|
298
|
-
* @returns {pv.Color.Rgb} a darker color.
|
|
299
|
-
*/
|
|
300
|
-
pv.Color.Rgb.prototype.darker = function(k) {
|
|
301
|
-
k = Math.pow(0.7, arguments.length ? k : 1);
|
|
302
|
-
return pv.rgb(
|
|
303
|
-
Math.max(0, Math.floor(k * this.r)),
|
|
304
|
-
Math.max(0, Math.floor(k * this.g)),
|
|
305
|
-
Math.max(0, Math.floor(k * this.b)),
|
|
306
|
-
this.a);
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Constructs a new HSL color with the specified values.
|
|
311
|
-
*
|
|
312
|
-
* @param {number} h the hue, an integer in [0, 360].
|
|
313
|
-
* @param {number} s the saturation, a float in [0, 1].
|
|
314
|
-
* @param {number} l the lightness, a float in [0, 1].
|
|
315
|
-
* @param {number} [a] the opacity, a float in [0, 1].
|
|
316
|
-
* @returns pv.Color.Hsl
|
|
317
|
-
*/
|
|
318
|
-
pv.hsl = function(h, s, l, a) {
|
|
319
|
-
return new pv.Color.Hsl(h, s, l, (arguments.length == 4) ? a : 1);
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
/**
|
|
323
|
-
* Constructs a new HSL color with the specified values.
|
|
324
|
-
*
|
|
325
|
-
* @class Represents a color in HSL space.
|
|
326
|
-
*
|
|
327
|
-
* @param {number} h the hue, an integer in [0, 360].
|
|
328
|
-
* @param {number} s the saturation, a float in [0, 1].
|
|
329
|
-
* @param {number} l the lightness, a float in [0, 1].
|
|
330
|
-
* @param {number} a the opacity, a float in [0, 1].
|
|
331
|
-
* @extends pv.Color
|
|
332
|
-
*/
|
|
333
|
-
pv.Color.Hsl = function(h, s, l, a) {
|
|
334
|
-
pv.Color.call(this, "hsl(" + h + "," + (s * 100) + "%," + (l * 100) + "%)", a);
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
* The hue, an integer in [0, 360].
|
|
338
|
-
*
|
|
339
|
-
* @type number
|
|
340
|
-
*/
|
|
341
|
-
this.h = h;
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* The saturation, a float in [0, 1].
|
|
345
|
-
*
|
|
346
|
-
* @type number
|
|
347
|
-
*/
|
|
348
|
-
this.s = s;
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* The lightness, a float in [0, 1].
|
|
352
|
-
*
|
|
353
|
-
* @type number
|
|
354
|
-
*/
|
|
355
|
-
this.l = l;
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* The opacity, a float in [0, 1].
|
|
359
|
-
*
|
|
360
|
-
* @type number
|
|
361
|
-
*/
|
|
362
|
-
this.a = a;
|
|
363
|
-
};
|
|
364
|
-
pv.Color.Hsl.prototype = pv.extend(pv.Color);
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Constructs a new HSL color with the same saturation, lightness and alpha as
|
|
368
|
-
* this color, and the specified hue.
|
|
369
|
-
*
|
|
370
|
-
* @param {number} h the hue, an integer in [0, 360].
|
|
371
|
-
*/
|
|
372
|
-
pv.Color.Hsl.prototype.hue = function(h) {
|
|
373
|
-
return pv.hsl(h, this.s, this.l, this.a);
|
|
374
|
-
};
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Constructs a new HSL color with the same hue, lightness and alpha as this
|
|
378
|
-
* color, and the specified saturation.
|
|
379
|
-
*
|
|
380
|
-
* @param {number} s the saturation, a float in [0, 1].
|
|
381
|
-
*/
|
|
382
|
-
pv.Color.Hsl.prototype.saturation = function(s) {
|
|
383
|
-
return pv.hsl(this.h, s, this.l, this.a);
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
* Constructs a new HSL color with the same hue, saturation and alpha as this
|
|
388
|
-
* color, and the specified lightness.
|
|
389
|
-
*
|
|
390
|
-
* @param {number} l the lightness, a float in [0, 1].
|
|
391
|
-
*/
|
|
392
|
-
pv.Color.Hsl.prototype.lightness = function(l) {
|
|
393
|
-
return pv.hsl(this.h, this.s, l, this.a);
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Constructs a new HSL color with the same hue, saturation and lightness as
|
|
398
|
-
* this color, and the specified alpha.
|
|
399
|
-
*
|
|
400
|
-
* @param {number} a the opacity, a float in [0, 1].
|
|
401
|
-
*/
|
|
402
|
-
pv.Color.Hsl.prototype.alpha = function(a) {
|
|
403
|
-
return pv.hsl(this.h, this.s, this.l, a);
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Returns the RGB color equivalent to this HSL color.
|
|
408
|
-
*
|
|
409
|
-
* @returns {pv.Color.Rgb} an RGB color.
|
|
410
|
-
*/
|
|
411
|
-
pv.Color.Hsl.prototype.rgb = function() {
|
|
412
|
-
var h = this.h, s = this.s, l = this.l;
|
|
413
|
-
|
|
414
|
-
/* Some simple corrections for h, s and l. */
|
|
415
|
-
h = h % 360; if (h < 0) h += 360;
|
|
416
|
-
s = Math.max(0, Math.min(s, 1));
|
|
417
|
-
l = Math.max(0, Math.min(l, 1));
|
|
418
|
-
|
|
419
|
-
/* From FvD 13.37, CSS Color Module Level 3 */
|
|
420
|
-
var m2 = (l <= .5) ? (l * (1 + s)) : (l + s - l * s);
|
|
421
|
-
var m1 = 2 * l - m2;
|
|
422
|
-
function v(h) {
|
|
423
|
-
if (h > 360) h -= 360;
|
|
424
|
-
else if (h < 0) h += 360;
|
|
425
|
-
if (h < 60) return m1 + (m2 - m1) * h / 60;
|
|
426
|
-
if (h < 180) return m2;
|
|
427
|
-
if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
|
|
428
|
-
return m1;
|
|
429
|
-
}
|
|
430
|
-
function vv(h) {
|
|
431
|
-
return Math.round(v(h) * 255);
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
return pv.rgb(vv(h + 120), vv(h), vv(h - 120), this.a);
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* @private SVG color keywords, per CSS Color Module Level 3.
|
|
439
|
-
*
|
|
440
|
-
* @see <a href="http://www.w3.org/TR/SVG/types.html#ColorKeywords">SVG color
|
|
441
|
-
* keywords</a>
|
|
442
|
-
*/
|
|
443
|
-
pv.Color.names = {
|
|
444
|
-
aliceblue: "#f0f8ff",
|
|
445
|
-
antiquewhite: "#faebd7",
|
|
446
|
-
aqua: "#00ffff",
|
|
447
|
-
aquamarine: "#7fffd4",
|
|
448
|
-
azure: "#f0ffff",
|
|
449
|
-
beige: "#f5f5dc",
|
|
450
|
-
bisque: "#ffe4c4",
|
|
451
|
-
black: "#000000",
|
|
452
|
-
blanchedalmond: "#ffebcd",
|
|
453
|
-
blue: "#0000ff",
|
|
454
|
-
blueviolet: "#8a2be2",
|
|
455
|
-
brown: "#a52a2a",
|
|
456
|
-
burlywood: "#deb887",
|
|
457
|
-
cadetblue: "#5f9ea0",
|
|
458
|
-
chartreuse: "#7fff00",
|
|
459
|
-
chocolate: "#d2691e",
|
|
460
|
-
coral: "#ff7f50",
|
|
461
|
-
cornflowerblue: "#6495ed",
|
|
462
|
-
cornsilk: "#fff8dc",
|
|
463
|
-
crimson: "#dc143c",
|
|
464
|
-
cyan: "#00ffff",
|
|
465
|
-
darkblue: "#00008b",
|
|
466
|
-
darkcyan: "#008b8b",
|
|
467
|
-
darkgoldenrod: "#b8860b",
|
|
468
|
-
darkgray: "#a9a9a9",
|
|
469
|
-
darkgreen: "#006400",
|
|
470
|
-
darkgrey: "#a9a9a9",
|
|
471
|
-
darkkhaki: "#bdb76b",
|
|
472
|
-
darkmagenta: "#8b008b",
|
|
473
|
-
darkolivegreen: "#556b2f",
|
|
474
|
-
darkorange: "#ff8c00",
|
|
475
|
-
darkorchid: "#9932cc",
|
|
476
|
-
darkred: "#8b0000",
|
|
477
|
-
darksalmon: "#e9967a",
|
|
478
|
-
darkseagreen: "#8fbc8f",
|
|
479
|
-
darkslateblue: "#483d8b",
|
|
480
|
-
darkslategray: "#2f4f4f",
|
|
481
|
-
darkslategrey: "#2f4f4f",
|
|
482
|
-
darkturquoise: "#00ced1",
|
|
483
|
-
darkviolet: "#9400d3",
|
|
484
|
-
deeppink: "#ff1493",
|
|
485
|
-
deepskyblue: "#00bfff",
|
|
486
|
-
dimgray: "#696969",
|
|
487
|
-
dimgrey: "#696969",
|
|
488
|
-
dodgerblue: "#1e90ff",
|
|
489
|
-
firebrick: "#b22222",
|
|
490
|
-
floralwhite: "#fffaf0",
|
|
491
|
-
forestgreen: "#228b22",
|
|
492
|
-
fuchsia: "#ff00ff",
|
|
493
|
-
gainsboro: "#dcdcdc",
|
|
494
|
-
ghostwhite: "#f8f8ff",
|
|
495
|
-
gold: "#ffd700",
|
|
496
|
-
goldenrod: "#daa520",
|
|
497
|
-
gray: "#808080",
|
|
498
|
-
green: "#008000",
|
|
499
|
-
greenyellow: "#adff2f",
|
|
500
|
-
grey: "#808080",
|
|
501
|
-
honeydew: "#f0fff0",
|
|
502
|
-
hotpink: "#ff69b4",
|
|
503
|
-
indianred: "#cd5c5c",
|
|
504
|
-
indigo: "#4b0082",
|
|
505
|
-
ivory: "#fffff0",
|
|
506
|
-
khaki: "#f0e68c",
|
|
507
|
-
lavender: "#e6e6fa",
|
|
508
|
-
lavenderblush: "#fff0f5",
|
|
509
|
-
lawngreen: "#7cfc00",
|
|
510
|
-
lemonchiffon: "#fffacd",
|
|
511
|
-
lightblue: "#add8e6",
|
|
512
|
-
lightcoral: "#f08080",
|
|
513
|
-
lightcyan: "#e0ffff",
|
|
514
|
-
lightgoldenrodyellow: "#fafad2",
|
|
515
|
-
lightgray: "#d3d3d3",
|
|
516
|
-
lightgreen: "#90ee90",
|
|
517
|
-
lightgrey: "#d3d3d3",
|
|
518
|
-
lightpink: "#ffb6c1",
|
|
519
|
-
lightsalmon: "#ffa07a",
|
|
520
|
-
lightseagreen: "#20b2aa",
|
|
521
|
-
lightskyblue: "#87cefa",
|
|
522
|
-
lightslategray: "#778899",
|
|
523
|
-
lightslategrey: "#778899",
|
|
524
|
-
lightsteelblue: "#b0c4de",
|
|
525
|
-
lightyellow: "#ffffe0",
|
|
526
|
-
lime: "#00ff00",
|
|
527
|
-
limegreen: "#32cd32",
|
|
528
|
-
linen: "#faf0e6",
|
|
529
|
-
magenta: "#ff00ff",
|
|
530
|
-
maroon: "#800000",
|
|
531
|
-
mediumaquamarine: "#66cdaa",
|
|
532
|
-
mediumblue: "#0000cd",
|
|
533
|
-
mediumorchid: "#ba55d3",
|
|
534
|
-
mediumpurple: "#9370db",
|
|
535
|
-
mediumseagreen: "#3cb371",
|
|
536
|
-
mediumslateblue: "#7b68ee",
|
|
537
|
-
mediumspringgreen: "#00fa9a",
|
|
538
|
-
mediumturquoise: "#48d1cc",
|
|
539
|
-
mediumvioletred: "#c71585",
|
|
540
|
-
midnightblue: "#191970",
|
|
541
|
-
mintcream: "#f5fffa",
|
|
542
|
-
mistyrose: "#ffe4e1",
|
|
543
|
-
moccasin: "#ffe4b5",
|
|
544
|
-
navajowhite: "#ffdead",
|
|
545
|
-
navy: "#000080",
|
|
546
|
-
oldlace: "#fdf5e6",
|
|
547
|
-
olive: "#808000",
|
|
548
|
-
olivedrab: "#6b8e23",
|
|
549
|
-
orange: "#ffa500",
|
|
550
|
-
orangered: "#ff4500",
|
|
551
|
-
orchid: "#da70d6",
|
|
552
|
-
palegoldenrod: "#eee8aa",
|
|
553
|
-
palegreen: "#98fb98",
|
|
554
|
-
paleturquoise: "#afeeee",
|
|
555
|
-
palevioletred: "#db7093",
|
|
556
|
-
papayawhip: "#ffefd5",
|
|
557
|
-
peachpuff: "#ffdab9",
|
|
558
|
-
peru: "#cd853f",
|
|
559
|
-
pink: "#ffc0cb",
|
|
560
|
-
plum: "#dda0dd",
|
|
561
|
-
powderblue: "#b0e0e6",
|
|
562
|
-
purple: "#800080",
|
|
563
|
-
red: "#ff0000",
|
|
564
|
-
rosybrown: "#bc8f8f",
|
|
565
|
-
royalblue: "#4169e1",
|
|
566
|
-
saddlebrown: "#8b4513",
|
|
567
|
-
salmon: "#fa8072",
|
|
568
|
-
sandybrown: "#f4a460",
|
|
569
|
-
seagreen: "#2e8b57",
|
|
570
|
-
seashell: "#fff5ee",
|
|
571
|
-
sienna: "#a0522d",
|
|
572
|
-
silver: "#c0c0c0",
|
|
573
|
-
skyblue: "#87ceeb",
|
|
574
|
-
slateblue: "#6a5acd",
|
|
575
|
-
slategray: "#708090",
|
|
576
|
-
slategrey: "#708090",
|
|
577
|
-
snow: "#fffafa",
|
|
578
|
-
springgreen: "#00ff7f",
|
|
579
|
-
steelblue: "#4682b4",
|
|
580
|
-
tan: "#d2b48c",
|
|
581
|
-
teal: "#008080",
|
|
582
|
-
thistle: "#d8bfd8",
|
|
583
|
-
tomato: "#ff6347",
|
|
584
|
-
turquoise: "#40e0d0",
|
|
585
|
-
violet: "#ee82ee",
|
|
586
|
-
wheat: "#f5deb3",
|
|
587
|
-
white: "#ffffff",
|
|
588
|
-
whitesmoke: "#f5f5f5",
|
|
589
|
-
yellow: "#ffff00",
|
|
590
|
-
yellowgreen: "#9acd32",
|
|
591
|
-
transparent: pv.Color.transparent = pv.rgb(0, 0, 0, 0)
|
|
592
|
-
};
|
|
593
|
-
|
|
594
|
-
/* Initialized named colors. */
|
|
595
|
-
(function() {
|
|
596
|
-
var names = pv.Color.names;
|
|
597
|
-
for (var name in names) names[name] = pv.color(names[name]);
|
|
598
|
-
})();
|