mascot-vis 2.1.0 → 3.0.0

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.
Files changed (158) hide show
  1. package/README.md +4 -3
  2. package/dist/mascot-es.js +27745 -0
  3. package/dist/mascot-min.js +186 -199
  4. package/dist/mascot-umd.js +27781 -0
  5. package/js/depGraphVis.js +66 -0
  6. package/package.json +23 -15
  7. package/src-new-ts/action/createElement.ts +91 -0
  8. package/src-new-ts/action/encode.js +20 -0
  9. package/src-new-ts/action/repeat.js +128 -0
  10. package/src-new-ts/action/traverseScene.js +41 -0
  11. package/src-new-ts/data/Network.js +2 -0
  12. package/src-new-ts/data/Scope.js +135 -0
  13. package/src-new-ts/data/Table.js +263 -0
  14. package/src-new-ts/data/Tree.js +3 -0
  15. package/src-new-ts/data/field.ts +115 -0
  16. package/src-new-ts/data/import.ts +96 -0
  17. package/src-new-ts/data/predicate.ts +82 -0
  18. package/src-new-ts/depgraph/DepGraph.js +178 -0
  19. package/src-new-ts/depgraph/Edge.js +9 -0
  20. package/src-new-ts/depgraph/SceneGraph2DepGraph.js +110 -0
  21. package/src-new-ts/depgraph/Signal.js +12 -0
  22. package/src-new-ts/depgraph/operator/BoundsEvaluator.js +30 -0
  23. package/src-new-ts/depgraph/operator/Dataflow.js +41 -0
  24. package/src-new-ts/depgraph/operator/DomainBuilder.js +50 -0
  25. package/src-new-ts/depgraph/updateDepGraph.js +45 -0
  26. package/src-new-ts/depgraph/variable/BoundsVar.js +81 -0
  27. package/src-new-ts/depgraph/variable/ChannelVar.js +17 -0
  28. package/src-new-ts/depgraph/variable/DataScopeVar.js +12 -0
  29. package/src-new-ts/depgraph/variable/DomainVar.js +15 -0
  30. package/src-new-ts/depgraph/variable/FieldVar.js +17 -0
  31. package/src-new-ts/depgraph/variable/LayoutParameter.js +8 -0
  32. package/src-new-ts/depgraph/variable/ScaleVar.js +13 -0
  33. package/src-new-ts/depgraph/variable/Variable.js +39 -0
  34. package/src-new-ts/element/gradient/LinearGradient.js +37 -0
  35. package/src-new-ts/element/group/Collection.js +109 -0
  36. package/src-new-ts/element/group/Group.js +307 -0
  37. package/src-new-ts/element/group/Scene.js +98 -0
  38. package/src-new-ts/element/mark/CircleMark.ts +85 -0
  39. package/src-new-ts/element/mark/Mark.ts +233 -0
  40. package/src-new-ts/element/mark/PathMark.js +483 -0
  41. package/src-new-ts/element/mark/Segment.js +29 -0
  42. package/src-new-ts/element/mark/Vertex.js +118 -0
  43. package/src-new-ts/encode/Scale.ts +115 -0
  44. package/src-new-ts/index.ts +19 -0
  45. package/src-new-ts/layout/Layout.ts +3 -0
  46. package/src-new-ts/render/CanvasRenderer.ts +24 -0
  47. package/src-new-ts/render/SVGRenderer.js +316 -0
  48. package/src-new-ts/util.ts +3 -0
  49. package/src-old/action/Classify.js +53 -0
  50. package/src-old/action/Densify.js +199 -0
  51. package/src-old/action/Partition.js +531 -0
  52. package/src-old/action/Repeat.js +106 -0
  53. package/src-old/action/Repopulate.js +44 -0
  54. package/src-old/action/Stratify.js +156 -0
  55. package/src-old/basic/Gradient.js +37 -0
  56. package/src-old/basic/Point.js +51 -0
  57. package/src-old/basic/Rectangle.js +63 -0
  58. package/src-old/bind/bindToAngle.js +56 -0
  59. package/src-old/bind/bindToAreaMark.js +360 -0
  60. package/src-old/bind/bindToColor.js +114 -0
  61. package/src-old/bind/bindToLink.js +81 -0
  62. package/src-old/bind/bindToPosition.js +283 -0
  63. package/src-old/bind/bindToRadialDistance.js +62 -0
  64. package/src-old/bind/bindToSize.js +235 -0
  65. package/src-old/bind/bindToText.js +60 -0
  66. package/src-old/bind/bindToThickness.js +100 -0
  67. package/src-old/constraint/AffixConstraint.js +129 -0
  68. package/src-old/constraint/AlignConstraint.js +58 -0
  69. package/src-old/core/Encoding.js +336 -0
  70. package/src-old/core/Scale.js +322 -0
  71. package/src-old/core/SceneLoader.js +290 -0
  72. package/src-old/core/SceneValidator.js +232 -0
  73. package/src-old/core/SpecExecutor.js +113 -0
  74. package/src-old/core/SpecGenerator.js +350 -0
  75. package/src-old/data/DataImporter.js +64 -0
  76. package/src-old/data/DataScope.js +124 -0
  77. package/src-old/data/DataTable.js +338 -0
  78. package/src-old/data/Network.js +106 -0
  79. package/src-old/data/Tree.js +251 -0
  80. package/src-old/data/transform/Bin.js +46 -0
  81. package/src-old/data/transform/Filter.js +48 -0
  82. package/src-old/data/transform/Groupby.js +18 -0
  83. package/src-old/data/transform/KDE.js +58 -0
  84. package/src-old/data/transform/Sort.js +14 -0
  85. package/src-old/data/transform/Split.js +5 -0
  86. package/src-old/data/transform/partition.js +46 -0
  87. package/src-old/history/UndoRedoStack +0 -0
  88. package/src-old/index.js +271 -0
  89. package/src-old/indexSVG.js +259 -0
  90. package/src-old/interaction/Interaction.js +91 -0
  91. package/src-old/interaction/MouseEvent.js +8 -0
  92. package/src-old/interaction/Selection.js +9 -0
  93. package/src-old/interaction/brush.js +362 -0
  94. package/src-old/item/Segment.js +29 -0
  95. package/src-old/item/Vertex.js +118 -0
  96. package/src-old/item/composite/Collection.js +106 -0
  97. package/src-old/item/composite/Glyph.js +19 -0
  98. package/src-old/item/composite/Group.js +310 -0
  99. package/src-old/item/composite/Scene.js +1251 -0
  100. package/src-old/item/mark/ArcPath.js +181 -0
  101. package/src-old/item/mark/AreaPath.js +78 -0
  102. package/src-old/item/mark/CirclePath.js +102 -0
  103. package/src-old/item/mark/EllipsePath.js +5 -0
  104. package/src-old/item/mark/Image.js +101 -0
  105. package/src-old/item/mark/LinkPath.js +118 -0
  106. package/src-old/item/mark/Mark.js +163 -0
  107. package/src-old/item/mark/Path.js +494 -0
  108. package/src-old/item/mark/PointText.js +201 -0
  109. package/src-old/item/mark/PolygonPath.js +64 -0
  110. package/src-old/item/mark/RectPath.js +88 -0
  111. package/src-old/item/mark/RingPath.js +92 -0
  112. package/src-old/item/refs/Axis.js +362 -0
  113. package/src-old/item/refs/EncodingAxis.js +515 -0
  114. package/src-old/item/refs/Gridlines.js +144 -0
  115. package/src-old/item/refs/LayoutAxis.js +316 -0
  116. package/src-old/item/refs/Legend.js +273 -0
  117. package/src-old/layout/Circular.js +95 -0
  118. package/src-old/layout/Force.js +52 -0
  119. package/src-old/layout/Grid.js +423 -0
  120. package/src-old/layout/Layout.js +13 -0
  121. package/src-old/layout/Packing.js +56 -0
  122. package/src-old/layout/Stack.js +264 -0
  123. package/src-old/layout/Strata.js +88 -0
  124. package/src-old/layout/Sugiyama.js +59 -0
  125. package/src-old/layout/TidyTree.js +105 -0
  126. package/src-old/layout/Treemap.js +87 -0
  127. package/src-old/renderer/SVGInteractionHandler.js +241 -0
  128. package/src-old/renderer/SVGRenderer.js +325 -0
  129. package/src-old/renderer/WebGLRenderer.js +1097 -0
  130. package/src-old/renderer/WebGLRenderer2.js +249 -0
  131. package/src-old/renderer/threejs/Line2.js +18 -0
  132. package/src-old/renderer/threejs/LineGeometry.js +77 -0
  133. package/src-old/renderer/threejs/LineMaterial.js +605 -0
  134. package/src-old/renderer/threejs/LineSegments2.js +281 -0
  135. package/src-old/renderer/threejs/LineSegmentsGeometry.js +226 -0
  136. package/src-old/renderer/threejs/Wireframe.js +51 -0
  137. package/src-old/renderer/threejs/WireframeGeometry2.js +16 -0
  138. package/src-old/scale/areaSize.js +0 -0
  139. package/src-old/scale/domain.js +38 -0
  140. package/src-old/util/Constants.js +180 -0
  141. package/src-old/util/DataUtil.js +35 -0
  142. package/src-old/util/ItemUtil.js +586 -0
  143. package/src-old/util/Numerical.js +33 -0
  144. package/tests/demo-tests/README.md +80 -0
  145. package/tests/demo-tests/SVG2PNG.js +56 -0
  146. package/tests/demo-tests/demos2CanvasPNGs.js +69 -0
  147. package/tests/demo-tests/demos2ScenesSVGs.js +100 -0
  148. package/tests/demo-tests/pathElementWorker.js +91 -0
  149. package/tests/demo-tests/pixelTest.js +62 -0
  150. package/tests/demo-tests/renderDemos.html +132 -0
  151. package/tests/demo-tests/serializationTest.js +36 -0
  152. package/tests/demo-tests/serializeDemos.html +134 -0
  153. package/tests/unit-tests/README.md +4 -0
  154. package/tests/unit-tests/jasmine-browser.json +21 -0
  155. package/tests/unit-tests/jasmine.json +14 -0
  156. package/tests/unit-tests/testSpec.js +274 -0
  157. package/dist/mascot.js +0 -24920
  158. package/interactive.html +0 -592
@@ -0,0 +1,163 @@
1
+ // Based on item.Item.js, as part of Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
2
+ // http://paperjs.org/
3
+ // Copyright (c) 2011 - 2019, Juerg Lehni & Jonathan Puckey
4
+ // http://scratchdisk.com/ & https://puckey.studio/
5
+ //
6
+ // Distributed under the MIT license. See LICENSE file for detail
7
+ //
8
+ // All rights reserved.
9
+
10
+ import LinearGradient from "../../basic/Gradient";
11
+ import {Style2SVG, ItemType} from "../../util/Constants";
12
+ import { CanvasProvider } from "../../util/ItemUtil";
13
+
14
+ export default class Mark {
15
+
16
+ constructor(args) {
17
+ this._dataScope = undefined;
18
+ this._id = undefined;
19
+
20
+ this.attrs = {};
21
+ this.styles = {};
22
+ this.staticProperties = {};
23
+
24
+ if (args !== undefined) {
25
+ for (let s in Style2SVG) {
26
+ if (s in args) {
27
+ this.styles[s] = args[s];
28
+ }
29
+ }
30
+ }
31
+ }
32
+
33
+ get id() {
34
+ return this._id;
35
+ }
36
+
37
+ set id(id) {
38
+ if (this.getScene()){
39
+ delete this.getScene()._itemMap[this._id];
40
+ this._id = id;
41
+ this.getScene()._itemMap[id] = this;
42
+ } else {
43
+ this._id = id;
44
+ }
45
+ }
46
+
47
+ //TODO: implement winding contribution, see paper.js PathItem.Boolean.js
48
+ contains(px, py) {
49
+ if (!this._bounds)
50
+ return false;
51
+ if (!this._bounds.contains(px, py))
52
+ return false;
53
+ switch (this.type) {
54
+ case ItemType.Rect:
55
+ case ItemType.PointText:
56
+ return true;
57
+ case ItemType.Circle: {
58
+ let dist = Math.sqrt(Math.pow(px - this.x, 2) + Math.pow(py - this.y, 2));
59
+ return dist <= this.radius + this.strokeWidth;
60
+ }
61
+ case ItemType.Path: {
62
+ let ctx = CanvasProvider.getContext(),
63
+ p = new Path2D(this.getSVGPathData());
64
+ ctx.lineWidth = Math.max(this.strokeWidth, 2.5);
65
+ ctx.stroke(p);
66
+ if (this.closed) {
67
+ return ctx.isPointInPath(p, px, py);
68
+ } else {
69
+ return ctx.isPointInStroke(p, px, py);
70
+ }
71
+ }
72
+ case ItemType.Line: {
73
+ let ctx = CanvasProvider.getContext(),
74
+ p = new Path2D(this.getSVGPathData());
75
+ ctx.lineWidth = Math.max(this.strokeWidth, 2.5);
76
+ ctx.stroke(p);
77
+ return ctx.isPointInStroke(p, px, py);
78
+ }
79
+ default: {
80
+ let ctx = CanvasProvider.getContext(),
81
+ p = new Path2D(this.getSVGPathData());
82
+ return ctx.isPointInPath(p, px, py);
83
+ }
84
+ }
85
+ }
86
+
87
+ toJSON() {
88
+ let json = {};
89
+ json.type = this.type;
90
+ json.id = this.id;
91
+ if (this.classId)
92
+ json.classId = this.classId;
93
+ if (this._dataScope)
94
+ json.dataScope = this._dataScope.toJSON();
95
+ json.args = {};
96
+ for (let s in this.attrs) {
97
+ json.args[s] = this.attrs[s];
98
+ }
99
+
100
+ for (let s in this.styles) {
101
+ if (s.indexOf("Color") > 0 && this.styles[s] instanceof LinearGradient) {
102
+ json.args[s] = this.styles[s].toJSON();
103
+ } else {
104
+ json.args[s] = this.styles[s];
105
+ }
106
+ }
107
+ return json;
108
+ }
109
+
110
+ getScene() {
111
+ let p = this;
112
+ while (p) {
113
+ if (p.type == ItemType.Scene)
114
+ return p;
115
+ else
116
+ p = p.parent;
117
+ }
118
+ }
119
+
120
+ set dataScope(ds) {
121
+ this._dataScope = ds;
122
+ }
123
+
124
+ get dataScope() {
125
+ return this._dataScope;
126
+ }
127
+
128
+ duplicate() {
129
+ let scene = this.getScene();
130
+ let m = scene.mark(this.type);
131
+ this.copyPropertiesTo(m);
132
+ m.classId = this.classId;
133
+ if (this._dataScope) {
134
+ m._dataScope = this._dataScope.clone();
135
+ }
136
+ return m;
137
+ }
138
+
139
+ // eslint-disable-next-line no-unused-vars
140
+ _doTranslate(dx, dy){
141
+ //child classes have their own implementations
142
+ }
143
+
144
+ set visibility(v) {
145
+ this.styles["visibility"] = v;
146
+ }
147
+
148
+ get visibility() {
149
+ if (!this.styles["visibility"])
150
+ return "visible";
151
+ return this.styles["visibility"];
152
+ }
153
+
154
+ get opacity() {
155
+ if (!("opacity" in this.styles))
156
+ return 1;
157
+ return this.styles["opacity"];
158
+ }
159
+
160
+ set opacity(c) {
161
+ this.styles["opacity"] = c;
162
+ }
163
+ }
@@ -0,0 +1,494 @@
1
+ import Mark from "./Mark";
2
+ import Vertex from "../Vertex";
3
+ import Segment from "../Segment";
4
+ import Rectangle from "../../basic/Rectangle";
5
+ import Point from "../../basic/Point";
6
+ import {ItemType, CurveMode} from "../../util/Constants"
7
+ import * as d3 from 'd3';
8
+
9
+ export default class Path extends Mark {
10
+
11
+ constructor(args) {
12
+ super(args);
13
+ this.type = "type" in args ? args.type : ItemType.Path;
14
+
15
+ if (!("strokeColor" in this.styles))
16
+ this.styles["strokeColor"] = "#ccc";
17
+ if (!("strokeWidth" in this.styles))
18
+ this.styles["strokeWidth"] = 1;
19
+ if (!("strokeDash" in this.styles))
20
+ this.styles["strokeDash"] = "none";
21
+
22
+ this.vertices = [];
23
+ this.vertexCounter = 0; //for assigning vertex ids
24
+ this.segmentCounter = 0;
25
+ this.segments = [];
26
+
27
+ this.anchor = undefined;
28
+
29
+ this.closed = false;
30
+
31
+ this.curveMode = "linear";
32
+
33
+ //when a path encodes data using its width or height, its geometric bounds may not be the same as its orginal bounds without encoding applied
34
+ this.boundsOffsets = {top: 0, bottom: 0, left: 0, right: 0};
35
+
36
+ this._vxShape = undefined;
37
+ this._vxWidth = 0;
38
+ this._vxHeight = 0;
39
+ this._vxRadius = 0;
40
+ this._vxFillColor = "#555555";
41
+ this._vxStrokeColor = "#aaaaaa";
42
+ this._vxStrokeWidth = 0;
43
+ this._vxOpacity = 1;
44
+
45
+ if (args !== undefined) {
46
+ for (let vs of Vertex.styles){
47
+ if (vs in args)
48
+ this["_" + vs] = args[vs];
49
+ }
50
+
51
+ if ("vertices" in args) {
52
+ this._setVertices(args["vertices"]);
53
+ }
54
+ }
55
+ }
56
+
57
+ toJSON() {
58
+ let json = super.toJSON();
59
+ json.type = this.type;
60
+ json.id = this.id;
61
+ switch (this.type) {
62
+ case ItemType.Rect:
63
+ json.args.width = this.width;
64
+ json.args.height = this.height;
65
+ json.args.top = this.top;
66
+ json.args.left = this.left;
67
+ break;
68
+ case ItemType.Circle:
69
+ json.args.x = this.x;
70
+ json.args.y = this.y;
71
+ json.args.radius = this.radius;
72
+ break;
73
+ case ItemType.Arc:
74
+ case ItemType.Pie:
75
+ json.args.x = this._x;
76
+ json.args.y = this._y;
77
+ json.args.innerRadius = this._innerRadius;
78
+ json.args.outerRadius = this._outerRadius;
79
+ json.args.startAngle = this._startAngle;
80
+ json.args.endAngle = this._endAngle;
81
+ break;
82
+ case ItemType.Link:
83
+ json.args.mode = this.mode;
84
+ json.args.directed = this.directed;
85
+ json.args.sourceAnchor = this.sourceAnchor;
86
+ json.args.targetAnchor = this.targetAnchor;
87
+ json.args.sourceOffset = this.sourceOffset;
88
+ json.args.targetOffset = this.targetOffset;
89
+ json.args.source = this.source.id;
90
+ json.args.target = this.target.id;
91
+ break;
92
+ default:
93
+ json.vertices = [];
94
+ for (let v of this.vertices)
95
+ json.vertices.push(v.toJSON());
96
+ if (this.type === ItemType.Polygon) {
97
+ json.args.x = this._x;
98
+ json.args.y = this._y;
99
+ json.args.radius = this._radius;
100
+ } else if (this.type === ItemType.Area) {
101
+ json.args.baseline = this._baseline;
102
+ json.args.orientation = this._orientation;
103
+ }
104
+ break;
105
+ }
106
+ // if (this.type === ItemType.Rect) {
107
+ // json.args.width = this.width;
108
+ // json.args.height = this.height;
109
+ // json.args.top = this.top;
110
+ // json.args.left = this.left;
111
+ // } else if (this.type === ItemType.Circle) {
112
+ // json.args.x = this.x;
113
+ // json.args.y = this.y;
114
+ // json.args.radius = this.radius;
115
+ // } else if (this.type === ItemType.Arc) {
116
+ // json.args.x = this._x;
117
+ // json.args.y = this._y;
118
+ // json.args.innerRadius = this._innerRadius;
119
+ // json.args.outerRadius = this._outerRadius;
120
+ // json.args.startAngle = this._startAngle;
121
+ // json.args.endAngle = this._endAngle;
122
+ // } else if (this.type === ItemType.Pie) {
123
+ // json.args.x = this._x;
124
+ // json.args.y = this._y;
125
+ // json.args.radius = this.radius;
126
+ // json.args.startAngle = this.startAngleDeg;
127
+ // json.args.endAngle = this.endAngleDeg;
128
+ // } else {
129
+ // json.vertices = [];
130
+ // for (let v of this.vertices)
131
+ // json.vertices.push(v.toJSON());
132
+ // if (this.type === ItemType.Polygon) {
133
+ // json.args.x = this._x;
134
+ // json.args.y = this._y;
135
+ // json.args.radius = this._radius;
136
+ // } else if (this.type === ItemType.Area) {
137
+ // json.args.baseline = this._baseline;
138
+ // json.args.orientation = this._orientation;
139
+ // }
140
+ // }
141
+ json.vertexCounter = this.vertexCounter;
142
+ json.segmentCounter = this.segmentCounter;
143
+ //do not save segments, anchor and closed for now
144
+ json.curveMode = this.curveMode;
145
+ if (this._bounds)
146
+ json.bounds = this._bounds.toJSON();
147
+ json.boundsOffsets = this.boundsOffsets;
148
+ for (let s of Vertex.styles) {
149
+ json.args[s] = this[s];
150
+ }
151
+ return json;
152
+ }
153
+
154
+ _setVertices(vertices) {
155
+ let vertex, point;
156
+ this.vertices = [];
157
+ this.segments = [];
158
+ for (let i = 0; i < vertices.length; i++) {
159
+
160
+ if (i == vertices.length - 1 && vertices[i][0] === vertices[0][0] && vertices[i][1] === vertices[0][1] && this.type === ItemType.Path) {
161
+ continue;
162
+ }
163
+
164
+ point = new Point(vertices[i][0], vertices[i][1]);
165
+
166
+ vertex = new Vertex(point, this, this.vertexCounter++);
167
+
168
+ for (let vs of Vertex.styles){
169
+ if (this[vs]){
170
+ let temp = vs.replace("vx", "");
171
+ vertex[temp[0].toLowerCase() + temp.slice(1)] = this[vs];
172
+ }
173
+ }
174
+
175
+ this.vertices.push(vertex);
176
+ if (i > 0)
177
+ this.segments.push(new Segment(this.vertices[i-1], this.vertices[i], this, this.segmentCounter++));
178
+ }
179
+ //if the first vertex has the same position as the last, this path is closed
180
+ let first = vertices[0], last = vertices[vertices.length - 1];
181
+ if ((first[0] === last[0] && first[1] === last[1]) || this.type === ItemType.Rect) {
182
+ this.closed = true;
183
+ if (!("fillColor" in this.styles))
184
+ this.styles["fillColor"] = "#fff";
185
+ this.segments.push(new Segment(this.vertices[this.vertices.length-1], this.vertices[0], this, this.segmentCounter++));
186
+ }
187
+ }
188
+
189
+ copyPropertiesTo(target) {
190
+ target.attrs = Object.assign({}, this.attrs);
191
+ target.styles = Object.assign({}, this.styles);
192
+ for (let vs of Vertex.styles){
193
+ if (this["_"+vs])
194
+ target["_"+vs] = this["_"+vs];
195
+ }
196
+ if (this._dataScope)
197
+ target._dataScope = this._dataScope.clone();
198
+ target.closed = this.closed;
199
+ target.curveMode = this.curveMode;
200
+ target.vertices = [];
201
+ target.segments = [];
202
+ for (let v of this.vertices) {
203
+ target.vertices.push(v._clone(target));
204
+ }
205
+ target.segmentCounter = 0;
206
+ for (let i = 1; i < target.vertices.length; i++) {
207
+ target.segments.push(new Segment(target.vertices[i-1], target.vertices[i], target, target.segmentCounter++));
208
+ }
209
+ if (target.closed)
210
+ target.segments.push(new Segment(target.vertices[target.vertices.length-1], target.vertices[0], target, target.segmentCounter++));
211
+ }
212
+
213
+ /*
214
+ * returns the bounds without incorporating transformations involving rotation
215
+ */
216
+ get bounds() {
217
+ if (!this._bounds)
218
+ this._updateBounds();
219
+ return this._bounds;
220
+ }
221
+
222
+ /**
223
+ * return the bounds as if the path does not encode data
224
+ */
225
+ get refBounds() {
226
+ if (!this._bounds)
227
+ this._updateBounds();
228
+ let ht = (this._bounds.bottom + this.boundsOffsets.bottom) - (this._bounds.top - this.boundsOffsets.top),
229
+ wd = this._bounds.right + this.boundsOffsets.right - (this._bounds.left - this.boundsOffsets.left);
230
+ return new Rectangle(this._bounds.left - this.boundsOffsets.left, this._bounds.top - this.boundsOffsets.top, wd, ht);
231
+ }
232
+
233
+ get x() {
234
+ return this.bounds.x;
235
+ }
236
+
237
+ get y() {
238
+ return this.bounds.y;
239
+ }
240
+
241
+ get strokeColor() {
242
+ return this.styles["strokeColor"];
243
+ }
244
+
245
+ set strokeColor(c) {
246
+ this.styles["strokeColor"] = c;
247
+ }
248
+
249
+ get strokeWidth() {
250
+ return this.styles["strokeWidth"];
251
+ }
252
+
253
+ set strokeWidth(c) {
254
+ this.styles["strokeWidth"] = c;
255
+ }
256
+
257
+ get fillColor() {
258
+ return this.styles["fillColor"];
259
+ }
260
+
261
+ set fillColor(c) {
262
+ this.styles["fillColor"] = c;
263
+ }
264
+
265
+ get strokeDash() {
266
+ return this.styles["strokeDash"];
267
+ }
268
+
269
+ set strokeDash(c) {
270
+ this.styles["strokeDash"] = c;
271
+ }
272
+
273
+ _doTranslate(dx, dy) {
274
+ for (let v of this.vertices) {
275
+ v._doTranslate(dx, dy);
276
+ }
277
+ this._updateBounds();
278
+ }
279
+
280
+ //by default, with respect to the center of bounds
281
+ resize(wd, ht, xRef, yRef) {
282
+ let bounds = this.bounds, bWidth = bounds.width === 0 ? 1 : bounds.width, bHeight = bounds.height === 0 ? 1 : bounds.height;
283
+ if (xRef === "right") {
284
+ for (let v of this.vertices) {
285
+ v.x = bounds.right - (wd/bWidth) * (bounds.right - v.x);
286
+ }
287
+ } else {
288
+ for (let v of this.vertices) {
289
+ v.x = bounds.left + (wd/bWidth) * (v.x - bounds.left);
290
+ }
291
+ }
292
+ if (yRef === "top") {
293
+ for (let v of this.vertices) {
294
+ v.y = bounds.top + (ht/bHeight) * (v.y - bounds.top);
295
+ }
296
+ } else {
297
+ for (let v of this.vertices) {
298
+ v.y = bounds.bottom - (ht/bHeight) * (bounds.bottom - v.y);
299
+ }
300
+ }
301
+ this._updateBounds();
302
+ }
303
+
304
+ _updateBounds() {
305
+ let vx = this.vertices.map(d => d.x),
306
+ vy = this.vertices.map(d => d.y);
307
+
308
+ let left = Math.min(...vx), top = Math.min(...vy), right = Math.max(...vx), btm = Math.max(...vy);
309
+
310
+ this._bounds = new Rectangle(left, top, right - left, btm - top);
311
+ if (this.type === ItemType.Line || this.type === ItemType.Path) {
312
+ let sw = this.styles["strokeWidth"] ? this.styles["strokeWidth"] : 1;
313
+ if (left === right)
314
+ this._bounds = new Rectangle(left - sw/2, top, right - left + sw, btm - top);
315
+ else if (top === btm)
316
+ this._bounds = new Rectangle(left, top - sw/2, right - left, btm - top + sw);
317
+ }
318
+ }
319
+
320
+ addVertex(x, y, i) {
321
+ let vertex = new Vertex(new Point(x, y), this, this.vertexCounter++);
322
+ this.vertices.splice(i, 0, vertex);
323
+ //TODO: handle segments
324
+ }
325
+
326
+ sortVertices(channel, descending) {
327
+ this.vertices.sort((a,b) => a[channel] - b[channel]);
328
+ if (descending)
329
+ this.vertices.reverse();
330
+ for (let i = 0; i < this.segments.length; i++) {
331
+ let segment = this.segments[i];
332
+ segment.vertex1 = this.vertices[i];
333
+ segment.vertex2 = this.vertices[(i+1)%this.vertices.length];
334
+ }
335
+ }
336
+
337
+ sortVerticesByData(field, descending, order) {
338
+ let f;
339
+ if (order)
340
+ f = (a, b) => order.indexOf(a.dataScope.getFieldValue(field)) - order.indexOf(b.dataScope.getFieldValue(field));
341
+ else
342
+ f = (a, b) => (a.dataScope.getFieldValue(field) < b.dataScope.getFieldValue(field) ? -1 : 1 );
343
+ this.vertices.sort(f);
344
+ if (descending)
345
+ this.vertices.reverse();
346
+ for (let i = 0; i < this.segments.length; i++) {
347
+ let segment = this.segments[i];
348
+ segment.vertex1 = this.vertices[i];
349
+ segment.vertex2 = this.vertices[(i+1)%this.vertices.length];
350
+ }
351
+ }
352
+
353
+ getSVGPathData() {
354
+ let p = d3.path();
355
+ let curve = this._getD3CurveFunction(this.curveMode)(p);
356
+ curve.lineStart();
357
+ for (let vertex of this.vertices) {
358
+ curve.point(vertex.x, vertex.y);
359
+ }
360
+ if (this.closed)
361
+ curve.point(this.vertices[0].x, this.vertices[0].y);
362
+ curve.lineEnd();
363
+
364
+ return p._;
365
+ }
366
+
367
+ // toSVG() {
368
+
369
+ // }
370
+
371
+ // fromSVG() {
372
+
373
+ // }
374
+
375
+ get firstVertex() {
376
+ return this.vertices[0];
377
+ }
378
+
379
+ get firstSegment() {
380
+ return this.segments[0];
381
+ }
382
+
383
+ get lastVertex() {
384
+ return this.vertices[this.vertices.length - 1];
385
+ }
386
+
387
+ get lastSegment() {
388
+ return this.segments[this.segments.length - 1];
389
+ }
390
+
391
+ _getD3CurveFunction(v){
392
+ switch(v) {
393
+ case CurveMode.Natural:
394
+ return d3.curveNatural;
395
+ case CurveMode.Basis:
396
+ return d3.curveBasis;
397
+ case CurveMode.BumpX:
398
+ return d3.curveBumpX;
399
+ case CurveMode.BumpY:
400
+ return d3.curveBumpY;
401
+ case CurveMode.Linear:
402
+ return d3.curveLinear;
403
+ case CurveMode.Step:
404
+ return d3.curveStep;
405
+ case CurveMode.CatmullRom:
406
+ return d3.curveCatmullRom;
407
+ case CurveMode.Cardinal:
408
+ return d3.curveCardinal;
409
+ default:
410
+ return d3.curveLinear;
411
+ }
412
+ }
413
+
414
+ get vxShape(){
415
+ return this._vxShape;
416
+ }
417
+
418
+ set vxShape(s){
419
+ this._vxShape = s;
420
+ for (let v of this.vertices)
421
+ v.shape = s;
422
+ }
423
+
424
+ get vxWidth(){
425
+ return this._vxWidth;
426
+ }
427
+
428
+ set vxWidth(s){
429
+ this._vxWidth = s;
430
+ for (let v of this.vertices)
431
+ v.width = s;
432
+ }
433
+
434
+ get vxHeight(){
435
+ return this._vxHeight;
436
+ }
437
+
438
+ set vxHeight(s){
439
+ this._vxHeight = s;
440
+ for (let v of this.vertices)
441
+ v.height = s;
442
+ }
443
+
444
+ get vxRadius(){
445
+ return this._vxRadius;
446
+ }
447
+
448
+ set vxRadius(s){
449
+ this._vxRadius = s;
450
+ for (let v of this.vertices)
451
+ v.radius = s;
452
+ }
453
+
454
+ get vxFillColor(){
455
+ return this._vxFillColor;
456
+ }
457
+
458
+ set vxFillColor(s){
459
+ this._vxFillColor = s;
460
+ for (let v of this.vertices)
461
+ v.fillColor = s;
462
+ }
463
+
464
+ get vxStrokeColor(){
465
+ return this._vxStrokeColor;
466
+ }
467
+
468
+ set vxStrokeColor(s){
469
+ this._vxStrokeColor = s;
470
+ for (let v of this.vertices)
471
+ v.strokeColor = s;
472
+ }
473
+
474
+ get vxStrokeWidth(){
475
+ return this._vxStrokeWidth;
476
+ }
477
+
478
+ set vxStrokeWidth(s){
479
+ this._vxStrokeWidth = s;
480
+ for (let v of this.vertices)
481
+ v.strokeWidth = s;
482
+ }
483
+
484
+ get vxOpacity(){
485
+ return this._vxOpacity;
486
+ }
487
+
488
+ set vxOpacity(s){
489
+ this._vxOpacity = s;
490
+ for (let v of this.vertices)
491
+ v.opacity = s;
492
+ }
493
+
494
+ }