rubyvis 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +13 -0
  4. data/Gemfile +8 -0
  5. data/Gemfile.lock +37 -0
  6. data/History.txt +6 -0
  7. data/LICENSE.txt +23 -0
  8. data/{README.txt → README.md} +15 -12
  9. data/Rakefile +4 -11
  10. data/lib/rubyvis.rb +1 -1
  11. data/lib/rubyvis/scale/quantitative.rb +14 -18
  12. data/lib/rubyvis/scene/svg_label.rb +1 -1
  13. data/rubyvis.gemspec +21 -0
  14. data/spec/anchor_spec.rb +2 -1
  15. data/spec/line_spec.rb +2 -2
  16. data/spec/scale_linear_datetime_spec.rb +23 -8
  17. data/spec/spec_helper.rb +2 -1
  18. metadata +31 -214
  19. data/.gemtest +0 -0
  20. data/vendor/protovis/protovis-r3.3.js +0 -287
  21. data/vendor/protovis/src/behavior/Behavior.js +0 -32
  22. data/vendor/protovis/src/behavior/Drag.js +0 -112
  23. data/vendor/protovis/src/behavior/Pan.js +0 -110
  24. data/vendor/protovis/src/behavior/Point.js +0 -157
  25. data/vendor/protovis/src/behavior/Resize.js +0 -104
  26. data/vendor/protovis/src/behavior/Select.js +0 -100
  27. data/vendor/protovis/src/behavior/Zoom.js +0 -85
  28. data/vendor/protovis/src/color/Color.js +0 -598
  29. data/vendor/protovis/src/color/Colors.js +0 -135
  30. data/vendor/protovis/src/color/Ramp.js +0 -17
  31. data/vendor/protovis/src/data/Arrays.js +0 -277
  32. data/vendor/protovis/src/data/Dom.js +0 -380
  33. data/vendor/protovis/src/data/Flatten.js +0 -146
  34. data/vendor/protovis/src/data/Histogram.js +0 -120
  35. data/vendor/protovis/src/data/LinearScale.js +0 -54
  36. data/vendor/protovis/src/data/LogScale.js +0 -142
  37. data/vendor/protovis/src/data/Nest.js +0 -257
  38. data/vendor/protovis/src/data/Numbers.js +0 -313
  39. data/vendor/protovis/src/data/Objects.js +0 -78
  40. data/vendor/protovis/src/data/OrdinalScale.js +0 -267
  41. data/vendor/protovis/src/data/QuantileScale.js +0 -180
  42. data/vendor/protovis/src/data/QuantitativeScale.js +0 -440
  43. data/vendor/protovis/src/data/RootScale.js +0 -55
  44. data/vendor/protovis/src/data/Scale.js +0 -86
  45. data/vendor/protovis/src/data/Transform.js +0 -109
  46. data/vendor/protovis/src/data/Tree.js +0 -124
  47. data/vendor/protovis/src/data/Vector.js +0 -118
  48. data/vendor/protovis/src/geo/Geo.js +0 -5
  49. data/vendor/protovis/src/geo/GeoScale.js +0 -307
  50. data/vendor/protovis/src/geo/LatLng.js +0 -23
  51. data/vendor/protovis/src/geo/Projection.js +0 -43
  52. data/vendor/protovis/src/geo/Projections.js +0 -117
  53. data/vendor/protovis/src/lang/Array.js +0 -112
  54. data/vendor/protovis/src/lang/init.js +0 -26
  55. data/vendor/protovis/src/layout/Arc.js +0 -178
  56. data/vendor/protovis/src/layout/Bullet.js +0 -164
  57. data/vendor/protovis/src/layout/Cluster.js +0 -205
  58. data/vendor/protovis/src/layout/Force.js +0 -309
  59. data/vendor/protovis/src/layout/Grid.js +0 -119
  60. data/vendor/protovis/src/layout/Hierarchy.js +0 -249
  61. data/vendor/protovis/src/layout/Horizon.js +0 -159
  62. data/vendor/protovis/src/layout/Indent.js +0 -83
  63. data/vendor/protovis/src/layout/Layout.js +0 -56
  64. data/vendor/protovis/src/layout/Matrix.js +0 -177
  65. data/vendor/protovis/src/layout/Network.js +0 -302
  66. data/vendor/protovis/src/layout/Pack.js +0 -323
  67. data/vendor/protovis/src/layout/Partition.js +0 -203
  68. data/vendor/protovis/src/layout/Rollup.js +0 -203
  69. data/vendor/protovis/src/layout/Stack.js +0 -391
  70. data/vendor/protovis/src/layout/Tree.js +0 -282
  71. data/vendor/protovis/src/layout/Treemap.js +0 -347
  72. data/vendor/protovis/src/mark/Anchor.js +0 -81
  73. data/vendor/protovis/src/mark/Area.js +0 -268
  74. data/vendor/protovis/src/mark/Bar.js +0 -93
  75. data/vendor/protovis/src/mark/Dot.js +0 -212
  76. data/vendor/protovis/src/mark/Ease.js +0 -150
  77. data/vendor/protovis/src/mark/Image.js +0 -154
  78. data/vendor/protovis/src/mark/Label.js +0 -155
  79. data/vendor/protovis/src/mark/Line.js +0 -195
  80. data/vendor/protovis/src/mark/Mark.js +0 -1237
  81. data/vendor/protovis/src/mark/Panel.js +0 -273
  82. data/vendor/protovis/src/mark/Rule.js +0 -143
  83. data/vendor/protovis/src/mark/Transient.js +0 -7
  84. data/vendor/protovis/src/mark/Transition.js +0 -195
  85. data/vendor/protovis/src/mark/Wedge.js +0 -244
  86. data/vendor/protovis/src/physics/BoundConstraint.js +0 -75
  87. data/vendor/protovis/src/physics/ChargeForce.js +0 -184
  88. data/vendor/protovis/src/physics/CollisionConstraint.js +0 -113
  89. data/vendor/protovis/src/physics/Constraint.js +0 -26
  90. data/vendor/protovis/src/physics/DragForce.js +0 -49
  91. data/vendor/protovis/src/physics/Force.js +0 -25
  92. data/vendor/protovis/src/physics/Particle.js +0 -81
  93. data/vendor/protovis/src/physics/PositionConstraint.js +0 -72
  94. data/vendor/protovis/src/physics/Quadtree.js +0 -195
  95. data/vendor/protovis/src/physics/Simulation.js +0 -159
  96. data/vendor/protovis/src/physics/SpringForce.js +0 -141
  97. data/vendor/protovis/src/pv-internals.js +0 -154
  98. data/vendor/protovis/src/pv.js +0 -95
  99. data/vendor/protovis/src/scene/SvgArea.js +0 -172
  100. data/vendor/protovis/src/scene/SvgBar.js +0 -28
  101. data/vendor/protovis/src/scene/SvgCurve.js +0 -354
  102. data/vendor/protovis/src/scene/SvgDot.js +0 -81
  103. data/vendor/protovis/src/scene/SvgImage.js +0 -45
  104. data/vendor/protovis/src/scene/SvgLabel.js +0 -46
  105. data/vendor/protovis/src/scene/SvgLine.js +0 -159
  106. data/vendor/protovis/src/scene/SvgPanel.js +0 -126
  107. data/vendor/protovis/src/scene/SvgRule.js +0 -26
  108. data/vendor/protovis/src/scene/SvgScene.js +0 -185
  109. data/vendor/protovis/src/scene/SvgWedge.js +0 -66
  110. data/vendor/protovis/src/text/DateFormat.js +0 -262
  111. data/vendor/protovis/src/text/Format.js +0 -78
  112. data/vendor/protovis/src/text/NumberFormat.js +0 -227
  113. data/vendor/protovis/src/text/TimeFormat.js +0 -115
@@ -1,81 +0,0 @@
1
- pv.SvgScene.dot = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
- var fill = s.fillStyle, stroke = s.strokeStyle;
9
- if (!fill.opacity && !stroke.opacity) continue;
10
-
11
- /* points */
12
- var radius = s.shapeRadius, path = null;
13
- switch (s.shape) {
14
- case "cross": {
15
- path = "M" + -radius + "," + -radius
16
- + "L" + radius + "," + radius
17
- + "M" + radius + "," + -radius
18
- + "L" + -radius + "," + radius;
19
- break;
20
- }
21
- case "triangle": {
22
- var h = radius, w = radius * 1.1547; // 2 / Math.sqrt(3)
23
- path = "M0," + h
24
- + "L" + w +"," + -h
25
- + " " + -w + "," + -h
26
- + "Z";
27
- break;
28
- }
29
- case "diamond": {
30
- radius *= Math.SQRT2;
31
- path = "M0," + -radius
32
- + "L" + radius + ",0"
33
- + " 0," + radius
34
- + " " + -radius + ",0"
35
- + "Z";
36
- break;
37
- }
38
- case "square": {
39
- path = "M" + -radius + "," + -radius
40
- + "L" + radius + "," + -radius
41
- + " " + radius + "," + radius
42
- + " " + -radius + "," + radius
43
- + "Z";
44
- break;
45
- }
46
- case "tick": {
47
- path = "M0,0L0," + -s.shapeSize;
48
- break;
49
- }
50
- case "bar": {
51
- path = "M0," + (s.shapeSize / 2) + "L0," + -(s.shapeSize / 2);
52
- break;
53
- }
54
- }
55
-
56
- /* Use <circle> for circles, <path> for everything else. */
57
- var svg = {
58
- "shape-rendering": s.antialias ? null : "crispEdges",
59
- "pointer-events": s.events,
60
- "cursor": s.cursor,
61
- "fill": fill.color,
62
- "fill-opacity": fill.opacity || null,
63
- "stroke": stroke.color,
64
- "stroke-opacity": stroke.opacity || null,
65
- "stroke-width": stroke.opacity ? s.lineWidth / this.scale : null
66
- };
67
- if (path) {
68
- svg.transform = "translate(" + s.left + "," + s.top + ")";
69
- if (s.shapeAngle) svg.transform += " rotate(" + 180 * s.shapeAngle / Math.PI + ")";
70
- svg.d = path;
71
- e = this.expect(e, "path", svg);
72
- } else {
73
- svg.cx = s.left;
74
- svg.cy = s.top;
75
- svg.r = radius;
76
- e = this.expect(e, "circle", svg);
77
- }
78
- e = this.append(e, scenes, i);
79
- }
80
- return e;
81
- };
@@ -1,45 +0,0 @@
1
- pv.SvgScene.image = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
-
9
- /* fill */
10
- e = this.fill(e, scenes, i);
11
-
12
- /* image */
13
- if (s.image) {
14
- e = this.expect(e, "foreignObject", {
15
- "cursor": s.cursor,
16
- "x": s.left,
17
- "y": s.top,
18
- "width": s.width,
19
- "height": s.height
20
- });
21
- var c = e.firstChild || e.appendChild(document.createElementNS(this.xhtml, "canvas"));
22
- c.$scene = {scenes:scenes, index:i};
23
- c.style.width = s.width;
24
- c.style.height = s.height;
25
- c.width = s.imageWidth;
26
- c.height = s.imageHeight;
27
- c.getContext("2d").putImageData(s.image, 0, 0);
28
- } else {
29
- e = this.expect(e, "image", {
30
- "preserveAspectRatio": "none",
31
- "cursor": s.cursor,
32
- "x": s.left,
33
- "y": s.top,
34
- "width": s.width,
35
- "height": s.height
36
- });
37
- e.setAttributeNS(this.xlink, "href", s.url);
38
- }
39
- e = this.append(e, scenes, i);
40
-
41
- /* stroke */
42
- e = this.stroke(e, scenes, i);
43
- }
44
- return e;
45
- };
@@ -1,46 +0,0 @@
1
- pv.SvgScene.label = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
- var fill = s.textStyle;
9
- if (!fill.opacity || !s.text) continue;
10
-
11
- /* text-baseline, text-align */
12
- var x = 0, y = 0, dy = 0, anchor = "start";
13
- switch (s.textBaseline) {
14
- case "middle": dy = ".35em"; break;
15
- case "top": dy = ".71em"; y = s.textMargin; break;
16
- case "bottom": y = "-" + s.textMargin; break;
17
- }
18
- switch (s.textAlign) {
19
- case "right": anchor = "end"; x = "-" + s.textMargin; break;
20
- case "center": anchor = "middle"; break;
21
- case "left": x = s.textMargin; break;
22
- }
23
-
24
- e = this.expect(e, "text", {
25
- "pointer-events": s.events,
26
- "cursor": s.cursor,
27
- "x": x,
28
- "y": y,
29
- "dy": dy,
30
- "transform": "translate(" + s.left + "," + s.top + ")"
31
- + (s.textAngle ? " rotate(" + 180 * s.textAngle / Math.PI + ")" : "")
32
- + (this.scale != 1 ? " scale(" + 1 / this.scale + ")" : ""),
33
- "fill": fill.color,
34
- "fill-opacity": fill.opacity || null,
35
- "text-anchor": anchor
36
- }, {
37
- "font": s.font,
38
- "text-shadow": s.textShadow,
39
- "text-decoration": s.textDecoration
40
- });
41
- if (e.firstChild) e.firstChild.nodeValue = s.text;
42
- else e.appendChild(document.createTextNode(s.text));
43
- e = this.append(e, scenes, i);
44
- }
45
- return e;
46
- };
@@ -1,159 +0,0 @@
1
- pv.SvgScene.line = function(scenes) {
2
- var e = scenes.$g.firstChild;
3
- if (scenes.length < 2) return e;
4
- var s = scenes[0];
5
-
6
- /* segmented */
7
- if (s.segmented) return this.lineSegment(scenes);
8
-
9
- /* visible */
10
- if (!s.visible) return e;
11
- var fill = s.fillStyle, stroke = s.strokeStyle;
12
- if (!fill.opacity && !stroke.opacity) return e;
13
-
14
- /* points */
15
- var d = "M" + s.left + "," + s.top;
16
-
17
- if (scenes.length > 2 && (s.interpolate == "basis" || s.interpolate == "cardinal" || s.interpolate == "monotone")) {
18
- switch (s.interpolate) {
19
- case "basis": d += this.curveBasis(scenes); break;
20
- case "cardinal": d += this.curveCardinal(scenes, s.tension); break;
21
- case "monotone": d += this.curveMonotone(scenes); break;
22
- }
23
- } else {
24
- for (var i = 1; i < scenes.length; i++) {
25
- d += this.pathSegment(scenes[i - 1], scenes[i]);
26
- }
27
- }
28
-
29
- e = this.expect(e, "path", {
30
- "shape-rendering": s.antialias ? null : "crispEdges",
31
- "pointer-events": s.events,
32
- "cursor": s.cursor,
33
- "d": d,
34
- "fill": fill.color,
35
- "fill-opacity": fill.opacity || null,
36
- "stroke": stroke.color,
37
- "stroke-opacity": stroke.opacity || null,
38
- "stroke-width": stroke.opacity ? s.lineWidth / this.scale : null,
39
- "stroke-linejoin": s.lineJoin
40
- });
41
- return this.append(e, scenes, 0);
42
- };
43
-
44
- pv.SvgScene.lineSegment = function(scenes) {
45
- var e = scenes.$g.firstChild;
46
-
47
- var s = scenes[0];
48
- var paths;
49
- switch (s.interpolate) {
50
- case "basis": paths = this.curveBasisSegments(scenes); break;
51
- case "cardinal": paths = this.curveCardinalSegments(scenes, s.tension); break;
52
- case "monotone": paths = this.curveMonotoneSegments(scenes); break;
53
- }
54
-
55
- for (var i = 0, n = scenes.length - 1; i < n; i++) {
56
- var s1 = scenes[i], s2 = scenes[i + 1];
57
-
58
- /* visible */
59
- if (!s1.visible || !s2.visible) continue;
60
- var stroke = s1.strokeStyle, fill = pv.Color.transparent;
61
- if (!stroke.opacity) continue;
62
-
63
- /* interpolate */
64
- var d;
65
- if ((s1.interpolate == "linear") && (s1.lineJoin == "miter")) {
66
- fill = stroke;
67
- stroke = pv.Color.transparent;
68
- d = this.pathJoin(scenes[i - 1], s1, s2, scenes[i + 2]);
69
- } else if(paths) {
70
- d = paths[i];
71
- } else {
72
- d = "M" + s1.left + "," + s1.top + this.pathSegment(s1, s2);
73
- }
74
-
75
- e = this.expect(e, "path", {
76
- "shape-rendering": s1.antialias ? null : "crispEdges",
77
- "pointer-events": s1.events,
78
- "cursor": s1.cursor,
79
- "d": d,
80
- "fill": fill.color,
81
- "fill-opacity": fill.opacity || null,
82
- "stroke": stroke.color,
83
- "stroke-opacity": stroke.opacity || null,
84
- "stroke-width": stroke.opacity ? s1.lineWidth / this.scale : null,
85
- "stroke-linejoin": s1.lineJoin
86
- });
87
- e = this.append(e, scenes, i);
88
- }
89
- return e;
90
- };
91
-
92
- /** @private Returns the path segment for the specified points. */
93
- pv.SvgScene.pathSegment = function(s1, s2) {
94
- var l = 1; // sweep-flag
95
- switch (s1.interpolate) {
96
- case "polar-reverse":
97
- l = 0;
98
- case "polar": {
99
- var dx = s2.left - s1.left,
100
- dy = s2.top - s1.top,
101
- e = 1 - s1.eccentricity,
102
- r = Math.sqrt(dx * dx + dy * dy) / (2 * e);
103
- if ((e <= 0) || (e > 1)) break; // draw a straight line
104
- return "A" + r + "," + r + " 0 0," + l + " " + s2.left + "," + s2.top;
105
- }
106
- case "step-before": return "V" + s2.top + "H" + s2.left;
107
- case "step-after": return "H" + s2.left + "V" + s2.top;
108
- }
109
- return "L" + s2.left + "," + s2.top;
110
- };
111
-
112
- /** @private Line-line intersection, per Akenine-Moller 16.16.1. */
113
- pv.SvgScene.lineIntersect = function(o1, d1, o2, d2) {
114
- return o1.plus(d1.times(o2.minus(o1).dot(d2.perp()) / d1.dot(d2.perp())));
115
- }
116
-
117
- /** @private Returns the miter join path for the specified points. */
118
- pv.SvgScene.pathJoin = function(s0, s1, s2, s3) {
119
- /*
120
- * P1-P2 is the current line segment. V is a vector that is perpendicular to
121
- * the line segment, and has length lineWidth / 2. ABCD forms the initial
122
- * bounding box of the line segment (i.e., the line segment if we were to do
123
- * no joins).
124
- */
125
- var p1 = pv.vector(s1.left, s1.top),
126
- p2 = pv.vector(s2.left, s2.top),
127
- p = p2.minus(p1),
128
- v = p.perp().norm(),
129
- w = v.times(s1.lineWidth / (2 * this.scale)),
130
- a = p1.plus(w),
131
- b = p2.plus(w),
132
- c = p2.minus(w),
133
- d = p1.minus(w);
134
-
135
- /*
136
- * Start join. P0 is the previous line segment's start point. We define the
137
- * cutting plane as the average of the vector perpendicular to P0-P1, and
138
- * the vector perpendicular to P1-P2. This insures that the cross-section of
139
- * the line on the cutting plane is equal if the line-width is unchanged.
140
- * Note that we don't implement miter limits, so these can get wild.
141
- */
142
- if (s0 && s0.visible) {
143
- var v1 = p1.minus(s0.left, s0.top).perp().norm().plus(v);
144
- d = this.lineIntersect(p1, v1, d, p);
145
- a = this.lineIntersect(p1, v1, a, p);
146
- }
147
-
148
- /* Similarly, for end join. */
149
- if (s3 && s3.visible) {
150
- var v2 = pv.vector(s3.left, s3.top).minus(p2).perp().norm().plus(v);
151
- c = this.lineIntersect(p2, v2, c, p);
152
- b = this.lineIntersect(p2, v2, b, p);
153
- }
154
-
155
- return "M" + a.x + "," + a.y
156
- + "L" + b.x + "," + b.y
157
- + " " + c.x + "," + c.y
158
- + " " + d.x + "," + d.y;
159
- };
@@ -1,126 +0,0 @@
1
- pv.SvgScene.panel = function(scenes) {
2
- var g = scenes.$g, e = g && g.firstChild;
3
- for (var i = 0; i < scenes.length; i++) {
4
- var s = scenes[i];
5
-
6
- /* visible */
7
- if (!s.visible) continue;
8
-
9
- /* svg */
10
- if (!scenes.parent) {
11
- s.canvas.style.display = "inline-block";
12
- if (g && (g.parentNode != s.canvas)) {
13
- g = s.canvas.firstChild;
14
- e = g && g.firstChild;
15
- }
16
- if (!g) {
17
- g = s.canvas.appendChild(this.create("svg"));
18
- g.setAttribute("font-size", "10px");
19
- g.setAttribute("font-family", "sans-serif");
20
- g.setAttribute("fill", "none");
21
- g.setAttribute("stroke", "none");
22
- g.setAttribute("stroke-width", 1.5);
23
- for (var j = 0; j < this.events.length; j++) {
24
- g.addEventListener(this.events[j], this.dispatch, false);
25
- }
26
- e = g.firstChild;
27
- }
28
- scenes.$g = g;
29
- g.setAttribute("width", s.width + s.left + s.right);
30
- g.setAttribute("height", s.height + s.top + s.bottom);
31
- }
32
-
33
- /* clip (nest children) */
34
- if (s.overflow == "hidden") {
35
- var id = pv.id().toString(36),
36
- c = this.expect(e, "g", {"clip-path": "url(#" + id + ")"});
37
- if (!c.parentNode) g.appendChild(c);
38
- scenes.$g = g = c;
39
- e = c.firstChild;
40
-
41
- e = this.expect(e, "clipPath", {"id": id});
42
- var r = e.firstChild || e.appendChild(this.create("rect"));
43
- r.setAttribute("x", s.left);
44
- r.setAttribute("y", s.top);
45
- r.setAttribute("width", s.width);
46
- r.setAttribute("height", s.height);
47
- if (!e.parentNode) g.appendChild(e);
48
- e = e.nextSibling;
49
- }
50
-
51
- /* fill */
52
- e = this.fill(e, scenes, i);
53
-
54
- /* transform (push) */
55
- var k = this.scale,
56
- t = s.transform,
57
- x = s.left + t.x,
58
- y = s.top + t.y;
59
- this.scale *= t.k;
60
-
61
- /* children */
62
- for (var j = 0; j < s.children.length; j++) {
63
- s.children[j].$g = e = this.expect(e, "g", {
64
- "transform": "translate(" + x + "," + y + ")"
65
- + (t.k != 1 ? " scale(" + t.k + ")" : "")
66
- });
67
- this.updateAll(s.children[j]);
68
- if (!e.parentNode) g.appendChild(e);
69
- e = e.nextSibling;
70
- }
71
-
72
- /* transform (pop) */
73
- this.scale = k;
74
-
75
- /* stroke */
76
- e = this.stroke(e, scenes, i);
77
-
78
- /* clip (restore group) */
79
- if (s.overflow == "hidden") {
80
- scenes.$g = g = c.parentNode;
81
- e = c.nextSibling;
82
- }
83
- }
84
- return e;
85
- };
86
-
87
- pv.SvgScene.fill = function(e, scenes, i) {
88
- var s = scenes[i], fill = s.fillStyle;
89
- if (fill.opacity || s.events == "all") {
90
- e = this.expect(e, "rect", {
91
- "shape-rendering": s.antialias ? null : "crispEdges",
92
- "pointer-events": s.events,
93
- "cursor": s.cursor,
94
- "x": s.left,
95
- "y": s.top,
96
- "width": s.width,
97
- "height": s.height,
98
- "fill": fill.color,
99
- "fill-opacity": fill.opacity,
100
- "stroke": null
101
- });
102
- e = this.append(e, scenes, i);
103
- }
104
- return e;
105
- };
106
-
107
- pv.SvgScene.stroke = function(e, scenes, i) {
108
- var s = scenes[i], stroke = s.strokeStyle;
109
- if (stroke.opacity || s.events == "all") {
110
- e = this.expect(e, "rect", {
111
- "shape-rendering": s.antialias ? null : "crispEdges",
112
- "pointer-events": s.events == "all" ? "stroke" : s.events,
113
- "cursor": s.cursor,
114
- "x": s.left,
115
- "y": s.top,
116
- "width": Math.max(1E-10, s.width),
117
- "height": Math.max(1E-10, s.height),
118
- "fill": null,
119
- "stroke": stroke.color,
120
- "stroke-opacity": stroke.opacity,
121
- "stroke-width": s.lineWidth / this.scale
122
- });
123
- e = this.append(e, scenes, i);
124
- }
125
- return e;
126
- };