mascot-vis 3.0.0 → 3.0.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.
Files changed (152) hide show
  1. package/package.json +1 -2
  2. package/js/depGraphVis.js +0 -66
  3. package/src-new-ts/action/createElement.ts +0 -91
  4. package/src-new-ts/action/encode.js +0 -20
  5. package/src-new-ts/action/repeat.js +0 -128
  6. package/src-new-ts/action/traverseScene.js +0 -41
  7. package/src-new-ts/data/Network.js +0 -2
  8. package/src-new-ts/data/Scope.js +0 -135
  9. package/src-new-ts/data/Table.js +0 -263
  10. package/src-new-ts/data/Tree.js +0 -3
  11. package/src-new-ts/data/field.ts +0 -115
  12. package/src-new-ts/data/import.ts +0 -96
  13. package/src-new-ts/data/predicate.ts +0 -82
  14. package/src-new-ts/depgraph/DepGraph.js +0 -178
  15. package/src-new-ts/depgraph/Edge.js +0 -9
  16. package/src-new-ts/depgraph/SceneGraph2DepGraph.js +0 -110
  17. package/src-new-ts/depgraph/Signal.js +0 -12
  18. package/src-new-ts/depgraph/operator/BoundsEvaluator.js +0 -30
  19. package/src-new-ts/depgraph/operator/Dataflow.js +0 -41
  20. package/src-new-ts/depgraph/operator/DomainBuilder.js +0 -50
  21. package/src-new-ts/depgraph/updateDepGraph.js +0 -45
  22. package/src-new-ts/depgraph/variable/BoundsVar.js +0 -81
  23. package/src-new-ts/depgraph/variable/ChannelVar.js +0 -17
  24. package/src-new-ts/depgraph/variable/DataScopeVar.js +0 -12
  25. package/src-new-ts/depgraph/variable/DomainVar.js +0 -15
  26. package/src-new-ts/depgraph/variable/FieldVar.js +0 -17
  27. package/src-new-ts/depgraph/variable/LayoutParameter.js +0 -8
  28. package/src-new-ts/depgraph/variable/ScaleVar.js +0 -13
  29. package/src-new-ts/depgraph/variable/Variable.js +0 -39
  30. package/src-new-ts/element/gradient/LinearGradient.js +0 -37
  31. package/src-new-ts/element/group/Collection.js +0 -109
  32. package/src-new-ts/element/group/Group.js +0 -307
  33. package/src-new-ts/element/group/Scene.js +0 -98
  34. package/src-new-ts/element/mark/CircleMark.ts +0 -85
  35. package/src-new-ts/element/mark/Mark.ts +0 -233
  36. package/src-new-ts/element/mark/PathMark.js +0 -483
  37. package/src-new-ts/element/mark/Segment.js +0 -29
  38. package/src-new-ts/element/mark/Vertex.js +0 -118
  39. package/src-new-ts/encode/Scale.ts +0 -115
  40. package/src-new-ts/index.ts +0 -19
  41. package/src-new-ts/layout/Layout.ts +0 -3
  42. package/src-new-ts/render/CanvasRenderer.ts +0 -24
  43. package/src-new-ts/render/SVGRenderer.js +0 -316
  44. package/src-new-ts/util.ts +0 -3
  45. package/src-old/action/Classify.js +0 -53
  46. package/src-old/action/Densify.js +0 -199
  47. package/src-old/action/Partition.js +0 -531
  48. package/src-old/action/Repeat.js +0 -106
  49. package/src-old/action/Repopulate.js +0 -44
  50. package/src-old/action/Stratify.js +0 -156
  51. package/src-old/basic/Gradient.js +0 -37
  52. package/src-old/basic/Point.js +0 -51
  53. package/src-old/basic/Rectangle.js +0 -63
  54. package/src-old/bind/bindToAngle.js +0 -56
  55. package/src-old/bind/bindToAreaMark.js +0 -360
  56. package/src-old/bind/bindToColor.js +0 -114
  57. package/src-old/bind/bindToLink.js +0 -81
  58. package/src-old/bind/bindToPosition.js +0 -283
  59. package/src-old/bind/bindToRadialDistance.js +0 -62
  60. package/src-old/bind/bindToSize.js +0 -235
  61. package/src-old/bind/bindToText.js +0 -60
  62. package/src-old/bind/bindToThickness.js +0 -100
  63. package/src-old/constraint/AffixConstraint.js +0 -129
  64. package/src-old/constraint/AlignConstraint.js +0 -58
  65. package/src-old/core/Encoding.js +0 -336
  66. package/src-old/core/Scale.js +0 -322
  67. package/src-old/core/SceneLoader.js +0 -290
  68. package/src-old/core/SceneValidator.js +0 -232
  69. package/src-old/core/SpecExecutor.js +0 -113
  70. package/src-old/core/SpecGenerator.js +0 -350
  71. package/src-old/data/DataImporter.js +0 -64
  72. package/src-old/data/DataScope.js +0 -124
  73. package/src-old/data/DataTable.js +0 -338
  74. package/src-old/data/Network.js +0 -106
  75. package/src-old/data/Tree.js +0 -251
  76. package/src-old/data/transform/Bin.js +0 -46
  77. package/src-old/data/transform/Filter.js +0 -48
  78. package/src-old/data/transform/Groupby.js +0 -18
  79. package/src-old/data/transform/KDE.js +0 -58
  80. package/src-old/data/transform/Sort.js +0 -14
  81. package/src-old/data/transform/Split.js +0 -5
  82. package/src-old/data/transform/partition.js +0 -46
  83. package/src-old/history/UndoRedoStack +0 -0
  84. package/src-old/index.js +0 -271
  85. package/src-old/indexSVG.js +0 -259
  86. package/src-old/interaction/Interaction.js +0 -91
  87. package/src-old/interaction/MouseEvent.js +0 -8
  88. package/src-old/interaction/Selection.js +0 -9
  89. package/src-old/interaction/brush.js +0 -362
  90. package/src-old/item/Segment.js +0 -29
  91. package/src-old/item/Vertex.js +0 -118
  92. package/src-old/item/composite/Collection.js +0 -106
  93. package/src-old/item/composite/Glyph.js +0 -19
  94. package/src-old/item/composite/Group.js +0 -310
  95. package/src-old/item/composite/Scene.js +0 -1251
  96. package/src-old/item/mark/ArcPath.js +0 -181
  97. package/src-old/item/mark/AreaPath.js +0 -78
  98. package/src-old/item/mark/CirclePath.js +0 -102
  99. package/src-old/item/mark/EllipsePath.js +0 -5
  100. package/src-old/item/mark/Image.js +0 -101
  101. package/src-old/item/mark/LinkPath.js +0 -118
  102. package/src-old/item/mark/Mark.js +0 -163
  103. package/src-old/item/mark/Path.js +0 -494
  104. package/src-old/item/mark/PointText.js +0 -201
  105. package/src-old/item/mark/PolygonPath.js +0 -64
  106. package/src-old/item/mark/RectPath.js +0 -88
  107. package/src-old/item/mark/RingPath.js +0 -92
  108. package/src-old/item/refs/Axis.js +0 -362
  109. package/src-old/item/refs/EncodingAxis.js +0 -515
  110. package/src-old/item/refs/Gridlines.js +0 -144
  111. package/src-old/item/refs/LayoutAxis.js +0 -316
  112. package/src-old/item/refs/Legend.js +0 -273
  113. package/src-old/layout/Circular.js +0 -95
  114. package/src-old/layout/Force.js +0 -52
  115. package/src-old/layout/Grid.js +0 -423
  116. package/src-old/layout/Layout.js +0 -13
  117. package/src-old/layout/Packing.js +0 -56
  118. package/src-old/layout/Stack.js +0 -264
  119. package/src-old/layout/Strata.js +0 -88
  120. package/src-old/layout/Sugiyama.js +0 -59
  121. package/src-old/layout/TidyTree.js +0 -105
  122. package/src-old/layout/Treemap.js +0 -87
  123. package/src-old/renderer/SVGInteractionHandler.js +0 -241
  124. package/src-old/renderer/SVGRenderer.js +0 -325
  125. package/src-old/renderer/WebGLRenderer.js +0 -1097
  126. package/src-old/renderer/WebGLRenderer2.js +0 -249
  127. package/src-old/renderer/threejs/Line2.js +0 -18
  128. package/src-old/renderer/threejs/LineGeometry.js +0 -77
  129. package/src-old/renderer/threejs/LineMaterial.js +0 -605
  130. package/src-old/renderer/threejs/LineSegments2.js +0 -281
  131. package/src-old/renderer/threejs/LineSegmentsGeometry.js +0 -226
  132. package/src-old/renderer/threejs/Wireframe.js +0 -51
  133. package/src-old/renderer/threejs/WireframeGeometry2.js +0 -16
  134. package/src-old/scale/areaSize.js +0 -0
  135. package/src-old/scale/domain.js +0 -38
  136. package/src-old/util/Constants.js +0 -180
  137. package/src-old/util/DataUtil.js +0 -35
  138. package/src-old/util/ItemUtil.js +0 -586
  139. package/src-old/util/Numerical.js +0 -33
  140. package/tests/demo-tests/README.md +0 -80
  141. package/tests/demo-tests/SVG2PNG.js +0 -56
  142. package/tests/demo-tests/demos2CanvasPNGs.js +0 -69
  143. package/tests/demo-tests/demos2ScenesSVGs.js +0 -100
  144. package/tests/demo-tests/pathElementWorker.js +0 -91
  145. package/tests/demo-tests/pixelTest.js +0 -62
  146. package/tests/demo-tests/renderDemos.html +0 -132
  147. package/tests/demo-tests/serializationTest.js +0 -36
  148. package/tests/demo-tests/serializeDemos.html +0 -134
  149. package/tests/unit-tests/README.md +0 -4
  150. package/tests/unit-tests/jasmine-browser.json +0 -21
  151. package/tests/unit-tests/jasmine.json +0 -14
  152. package/tests/unit-tests/testSpec.js +0 -274
@@ -1,1097 +0,0 @@
1
- import * as PIXI from "pixi.js";
2
- import { Container, Graphics, TextStyle } from "pixi.js";
3
- import { ItemType, Errors } from "../util/Constants";
4
- import * as D3 from "d3";
5
-
6
-
7
- let DEG2RAD = Math.PI / 180;
8
- export default class WebGLRenderer {
9
-
10
- constructor(canvasId) {
11
- this._canvasId = canvasId;
12
- this._doesCollectionHaveBounds = false;
13
- this._app = new PIXI.Application({
14
- antialias: true, // default: false
15
- width: 1600,
16
- height: 1000,
17
- view: document.getElementById(this._canvasId)
18
- });
19
- this._app.renderer.autoResize = true;
20
- }
21
-
22
- /**
23
- * @param {Scene} scene
24
- * @param {string} id
25
- * @param {*} args
26
- */
27
- render(scene, params) {
28
- let args = params ? params : {};
29
- this._app.renderer.backgroundColor = toHexColor(scene.fillColor ? scene.fillColor : "#fff");
30
- this._doesCollectionHaveBounds = !!args.collectionBounds;
31
- this._app.stage.removeChildren();
32
- this._app.renderer.clear();
33
- let final = this._renderItem(scene);
34
- this._app.stage.addChild(final);
35
- }
36
-
37
- // VM2356:14 Uncaught (in promise) TypeError: renderer.clear is not a function at eval (eval at loadScript (demoLoader.js:25:15), <anonymous>:14:32)
38
- clear() {
39
- }
40
-
41
- _renderItem(item) {
42
- switch (item.type) {
43
- case ItemType.Ellipse:
44
- case ItemType.LinearGradient:
45
- throwError("mark", item, Errors.FEATURE_NOT_IMPLEMENTED);
46
- break;
47
-
48
- case ItemType.Circle:
49
- return this._renderCircle(item);
50
-
51
- case ItemType.Pie:
52
- return this._renderArc(item);
53
-
54
- case ItemType.Area:
55
- return this._renderArea(item);
56
-
57
- case ItemType.Polygon:
58
- return this._renderPolygon(item);
59
-
60
- case ItemType.Axis:
61
- return this._renderAxis(item);
62
-
63
- case ItemType.Collection:
64
- return this._renderCollection(item);
65
-
66
- case ItemType.Glyph:
67
- case ItemType.Group:
68
- case ItemType.Gridlines:
69
- case ItemType.Legend:
70
- case ItemType.Scene:
71
- return this._renderGroup(item);
72
-
73
- case ItemType.Path:
74
- return this._renderPath(item);
75
-
76
- case ItemType.Line:
77
- return this._renderLinearPath(item);
78
-
79
- case ItemType.Rect:
80
- return this._renderRectangle(item);
81
-
82
- case ItemType.PointText:
83
- return this._renderText(item);
84
-
85
- case ItemType.Arc:
86
- return this._renderArc(item);
87
-
88
- case ItemType.Image:
89
- return this._renderImage(item);
90
-
91
- case ItemType.Link:
92
- return this._renderLink(item);
93
-
94
- case ItemType.Ring:
95
- return this._renderRing(item);
96
-
97
- default:
98
- console.log(item.type);
99
- throw new Error(`Expect: itemType, Actual: ${item}\nWait that's illegal`)
100
- }
101
- }
102
-
103
- /**
104
- * @param {RectPath} rect
105
- * @returns {PIXI.Rectangle}
106
- */
107
- _renderRectangle(rect) {
108
- let rectangle = new Graphics();
109
- decorate(rectangle, rect.styles);
110
- rectangle.lineStyle(
111
- rect.styles["strokeWidth"],
112
- toHexColor(rect.styles["strokeColor"])
113
- );
114
- beginGradientOrColorFill(rect.styles, rectangle, rect.height);
115
- rectangle.drawRect(0, 0, rect.width, rect.height);
116
- rectangle.x = rect.left;
117
- rectangle.y = rect.top;
118
- rectangle.endFill();
119
- return rectangle;
120
- }
121
-
122
- /**
123
- * @param {PointText} pointText
124
- * @returns {PIXI.Text}
125
- */
126
- _renderText(pointText) {
127
- let style = new TextStyle({
128
- fontSize: pointText.styles["fontSize"],
129
- fontFamily: pointText.styles["fontFamily"],
130
- fontWeight: styleFontWeight2PixiFontWeight(pointText.styles["fontWeight"]),
131
- fill: toHexColor(pointText.styles["fillColor"]),
132
- })
133
-
134
- //// PIXI.Text converts each 1em into 12px, which is not what we want.
135
- // Therefore, here, we convert each 1em into 16px:
136
- let fontSize = style.fontSize;
137
- if (typeof fontSize === 'string' || fontSize instanceof String) {
138
- if ((/^\d+em$/).test(fontSize)) {
139
- let number = parseInt(style.fontSize.substring(0, style.fontSize.length - 2));
140
- number *= 16 ; // 1em = 16px
141
- fontSize = number.toString().concat("px");
142
- }
143
- }
144
- style.fontSize = fontSize;
145
- /////
146
-
147
- let pixiText = new PIXI.Text(pointText.text, style);
148
- let container = new Container();
149
- decorate(pixiText, pointText.styles);
150
-
151
- pixiText.x = pointText.x;
152
- pixiText.y = pointText.y;
153
-
154
- pixiText.anchor.set(... styleAnchor2PixiAnchor(pointText.anchor));
155
- container.addChild(pixiText);
156
-
157
- let pivot = rotation2PixiPivot(pointText._rotate);
158
- container.pivot.set(pivot[0], pivot[1]);
159
- container.angle = rotation2PixiAngle(pointText._rotate);
160
- container.position.set(pivot[0], pivot[1]);
161
-
162
- return container;
163
- }
164
-
165
- /**
166
- * @param {Group} group
167
- * @returns {Container}
168
- */
169
- _renderGroup(group) {
170
- let container = new Container();
171
- for (const item of group.children) {
172
- let t = this._renderItem(item);
173
- if (t == undefined) throw new Error();
174
- container.addChild(t);
175
- }
176
-
177
- return container;
178
- }
179
-
180
- /**
181
- *
182
- * @param {Group} axis
183
- * @returns
184
- */
185
- _renderAxis(axis) {
186
- let container = this._renderGroup(axis);
187
- let pivot = rotation2PixiPivot(axis._rotate);
188
- container.pivot.set(pivot[0], pivot[1]);
189
- container.angle = rotation2PixiAngle(axis._rotate);
190
- container.position.set(pivot[0], pivot[1]);
191
- return container;
192
- }
193
-
194
- /**
195
- * @param {Collection} collection
196
- * @returns {Container}
197
- */
198
- _renderCollection(collection) {
199
- let container = new Container();
200
- let group = this._renderGroup(collection);
201
- container.addChild(group);
202
-
203
- // ------------------ Render Bounds -----------------------------------
204
-
205
- if (!this._doesCollectionHaveBounds) return container;
206
-
207
- let contour = new Graphics();
208
- // short for leading dash relative start position
209
- let leadDashRelStrtPos = 0;
210
- let bounds = collection.bounds;
211
- let l = bounds.left;
212
- let r = bounds.right;
213
- let t = bounds.top;
214
- let b = bounds.bottom;
215
- let style = {
216
- strokeWidth: 1,
217
- color: 0x1ecb40,
218
- dashLength: 5,
219
- dashSpacing: 5
220
- }
221
-
222
- leadDashRelStrtPos = drawDash(l, r, t, leadDashRelStrtPos, style, contour);
223
- leadDashRelStrtPos = drawDash(t, b, -r, leadDashRelStrtPos, style, contour);
224
- leadDashRelStrtPos = drawDash(r, l, b, leadDashRelStrtPos, style, contour);
225
- drawDash(b, t, -l, leadDashRelStrtPos, style, contour);
226
-
227
- container.addChild(contour);
228
- return container;
229
-
230
- // ------------------ End ---------------------------------------------
231
-
232
- /**
233
- * @param {Graphics} graphics
234
- * @param {Number} leadDashRelStrtPos the projected start position of a leading dash.
235
- * for example, if a dash is broken by the end of last edge,
236
- * the leading dash of next edge is incomplete and thus, the projected start point would be beyond
237
- * the start point. Therefore, it is marked with a negative value, RELATIVE to the starting point
238
- * V the starting point of this dash is thus -1
239
- * |---- -|--- ----
240
- * @param {Number} dimensionalConstrain it can be x or y, depends on which dimension remains unchanged
241
- * positive values indicate an horizontal edge
242
- * negative values indicate a vertical edge
243
- * @returns {Number} leading dash start position for next edge
244
- */
245
- function drawDash(start, end, dimensionalConstrain, leadDashRelStrtPos, style, graphics) {
246
- // if the dash line is going left -> right, then direction = +1. v.v.
247
- let dir = start <= end ? 1 : -1;
248
-
249
- // if the dash is a remain of last cut-off dash, it actually starts at the starting point
250
- // otherwise just use the start position
251
- // note here next.point is a reference,
252
- // it is a hack so that changes to next.point can be reflected to p as well
253
- let next = leadDashRelStrtPos >= 0 ?
254
- {point: start + leadDashRelStrtPos * dir} :
255
- {point: start};
256
-
257
- // p stands for pointer. It's used as an abstraction
258
- // so that this function can be applied to both horizontal and vertical scenarios
259
- let p = dimensionalConstrain > 0 ?
260
- [next, { point: dimensionalConstrain }] :
261
- [{ point: -dimensionalConstrain }, next];
262
-
263
- graphics.lineStyle({
264
- width: style.strokeWidth,
265
- color: style.color
266
- })
267
- // move to the actual start
268
- graphics.moveTo(p[0].point, p[1].point);
269
- // set the next point to the end of first dash (regardless of whether it's complete)
270
- next.point = leadDashRelStrtPos * dir + start + style.dashLength * dir;
271
- graphics.lineTo(p[0].point, p[1].point);
272
-
273
- let isDrawing = false;
274
- // move next point to (the start position)of the second dash
275
- next.point += style.dashLength * dir;
276
- // if the next point is with the range from start to end
277
- while (next.point * dir <= end * dir) {
278
- if (isDrawing) {
279
- graphics.lineTo(p[0].point, p[1].point);
280
- isDrawing = false;
281
- next.point += style.dashSpacing * dir;
282
- } else {
283
- graphics.moveTo(p[0].point, p[1].point);
284
- isDrawing = true;
285
- next.point += style.dashLength * dir;
286
- }
287
- }
288
-
289
- // finish the last dash
290
- // if it's still drawing, cut it off (and continue it in the next edge)
291
- if (isDrawing) {
292
- // handle the horizontal and vertical cases
293
- if (dimensionalConstrain > 0) graphics.lineTo(end, dimensionalConstrain);
294
- else graphics.lineTo(-dimensionalConstrain, end);
295
- return (end - next.point) * dir;
296
- // otherwise it's fine, let the math handle it automagically
297
- } else {
298
- return (next.point - end) * dir;
299
- }
300
- }
301
- }
302
-
303
- /**
304
- * @param {AreaPath} areaPath
305
- */
306
- _renderArea(areaPath) {
307
- switch (areaPath.curveMode) {
308
- case "linear":
309
- return this._renderPolygon(areaPath);
310
-
311
- case "basis":
312
- return this._renderBezierArea(areaPath);
313
-
314
- default:
315
- return throwError("areaPath", areaPath, Errors.FEATURE_NOT_IMPLEMENTED);
316
- }
317
- }
318
-
319
- _renderBezierArea(areaPath) {
320
- let area = new Graphics();
321
- decorate(area, areaPath.styles);
322
- area.lineStyle({
323
- width: areaPath.styles["strokeWidth"],
324
- color: toHexColor(areaPath.styles["strokeColor"])
325
- })
326
- let pathData = areaPath.getSVGPathData();
327
- let pathJSON = parseDPath(pathData);
328
-
329
- beginGradientOrColorFill(areaPath.styles, area, areaPath.bounds.height);
330
- drawOnGraphicsFromJSONData(area, pathJSON);
331
- area.endFill();
332
-
333
- return area;
334
- }
335
-
336
- /**
337
- * @param {PolygonPath} polygonPath
338
- */
339
- _renderPolygon(polygonPath) {
340
- let container = new PIXI.Container();
341
-
342
- // ------------------ Contour -----------------------------------------
343
-
344
- let contour = this._renderLinearPath(polygonPath);
345
- contour.getChildAt(0).lineTo(
346
- polygonPath.vertices[0].x,
347
- polygonPath.vertices[0].y
348
- );
349
-
350
- // ------------------ Fill --------------------------------------------
351
-
352
- let polygonFill = new PIXI.Graphics();
353
- decorate(polygonFill, polygonPath.styles);
354
- let path = [];
355
- for (const vertex of polygonPath.vertices) {
356
- path.push(vertex.x - polygonPath.bounds.left);
357
- path.push(vertex.y - polygonPath.bounds.top);
358
- }
359
- //polygonFill.beginFill(toHexColor(polygonPath.styles["fillColor"]));
360
- beginGradientOrColorFill(polygonPath.styles, polygonFill, polygonPath.bounds.height);
361
- polygonFill.drawPolygon(path);
362
- polygonFill.x += polygonPath.bounds.left;
363
- polygonFill.y += polygonPath.bounds.top;
364
- polygonFill.endFill();
365
-
366
- // ------------------ Finalize ----------------------------------------
367
-
368
- container.addChild(polygonFill);
369
- container.addChild(contour);
370
- return container;
371
- }
372
-
373
- /**
374
- * @param {Path} path
375
- * @returns {Container}
376
- */
377
- _renderPath(path) {
378
-
379
- switch (path.curveMode) {
380
- case "linear":
381
- return this._renderLinearPath(path);
382
-
383
- case "bumpX":
384
- case "natural":
385
- return this._renderBezierPath(path);
386
-
387
- default:
388
- throwError("path", path, Errors.FEATURE_NOT_IMPLEMENTED);
389
- break;
390
- }
391
-
392
- // ------------------ End ---------------------------------------------
393
-
394
- }
395
-
396
- /**
397
- *
398
- * @param {Path} path
399
- * @returns
400
- */
401
- _renderLinearPath(path) {
402
- let container = new Container();
403
- let line = new Graphics();
404
- let isContinuous = path.styles["strokeDash"] == "none";
405
- decorate(line, path.styles);
406
- let vertex0 = path.vertices[0];
407
- line.lineStyle({
408
- width: path.styles["strokeWidth"],
409
- color: toHexColor(path.styles["strokeColor"])
410
- })
411
-
412
- line.moveTo(vertex0.x, vertex0.y);
413
- if (isContinuous) {
414
- for (let i = 1; i < path.vertices.length; i++) {
415
- const vertex = path.vertices[i];
416
- line.lineTo(vertex.x, vertex.y);
417
- }
418
- } else {
419
- drawDashLine(path.vertices, path.styles["strokeDash"], line);
420
- }
421
-
422
- container.addChild(line);
423
-
424
- // ------------------ Render vertices ---------------------------------
425
-
426
- for (let i = 0; i < path.vertices.length; i++) {
427
- let vertex = path.vertices[i];
428
- let renderedVertex = this._renderVertex(vertex);
429
- if (renderedVertex != null) container.addChild(renderedVertex);
430
- }
431
-
432
- return container;
433
- }
434
-
435
- /**
436
- * @param {Path} path
437
- */
438
- _renderBezierPath(path) {
439
- let container = new Container();
440
- let graphics = new Graphics();
441
- decorate(graphics, path.styles);
442
- graphics.lineStyle({
443
- width: path.styles["strokeWidth"],
444
- color: toHexColor(path.styles["strokeColor"])
445
- })
446
- let pathData = path.getSVGPathData();
447
- let pathJSON = parseDPath(pathData);
448
- drawOnGraphicsFromJSONData(graphics, pathJSON);
449
- container.addChild(graphics);
450
-
451
- // ------------------ Render vertices ---------------------------------
452
-
453
- for (let i = 0; i < path.vertices.length; i++) {
454
- let vertex = path.vertices[i];
455
- let renderedVertex = this._renderVertex(vertex);
456
- if (renderedVertex != null) container.addChild(renderedVertex);
457
- }
458
-
459
- return container;
460
- }
461
-
462
- /**
463
- * NULLABLE!!!
464
- * @param {Vertex} vertex
465
- * @returns {Container} null if vertex shape is undefined
466
- */
467
- _renderVertex(vertex) {
468
- switch (vertex.shape) {
469
- case "rect":
470
- return renderRectVertex(vertex);
471
-
472
- case "circle":
473
- return renderCircleVertex(vertex);
474
-
475
- case undefined:
476
- return null;
477
-
478
- default:
479
- throwError("vertex shape", vertex.shape, Errors.FEATURE_NOT_IMPLEMENTED);
480
- }
481
-
482
- function renderRectVertex(vertex) {
483
- let rectVertex = new PIXI.Graphics();
484
- rectVertex.lineStyle({
485
- width: vertex.strokeWidth,
486
- color: toHexColor(vertex.strokeColor)
487
- })
488
- rectVertex.beginFill(toHexColor(vertex.fillColor))
489
- rectVertex.drawRect(
490
- vertex.x - vertex.width / 2,
491
- vertex.y - vertex.height / 2,
492
- vertex.width,
493
- vertex.height);
494
- rectVertex.endFill();
495
-
496
- return rectVertex;
497
- }
498
-
499
- function renderCircleVertex(vertex) {
500
- let circle = new PIXI.Graphics();
501
- circle.lineStyle({
502
- width: vertex.strokeWidth,
503
- color: toHexColor(vertex.strokeColor)
504
- })
505
- circle.alpha = vertex.opacity;
506
- circle.beginFill(toHexColor(vertex.fillColor));
507
- circle.drawCircle(vertex.x, vertex.y, vertex.radius);
508
- circle.endFill();
509
-
510
- return circle;
511
- }
512
- }
513
-
514
- /**
515
- * @param {CirclePath} circPath
516
- * @returns {PIXI.Rectangle}
517
- */
518
- _renderCircle(circPath) {
519
- let circle = new Graphics();
520
- decorate(circle, circPath.styles);
521
- circle.lineStyle(
522
- circPath.styles["strokeWidth"],
523
- toHexColor(circPath.styles["strokeColor"])
524
- );
525
- beginGradientOrColorFill(circPath.styles, circle, circPath.height);
526
- circle.drawCircle(
527
- circPath.x,
528
- circPath.y,
529
- circPath.radius
530
- );
531
- circle.endFill();
532
- return circle;
533
- }
534
-
535
- /**
536
- * @param {RingPath} ringPath
537
- * @returns {PIXI.Rectangle}
538
- */
539
- _renderRing(ringPath) {
540
- let ring = new Graphics();
541
- //decorate(ring, ringPath.styles);
542
- ring.lineStyle(
543
- (ringPath.outerRadius - ringPath.innerRadius),
544
- toHexColor(ringPath.styles["fillColor"])
545
- );
546
- //beginGradientOrColorFill(ringPath.styles, ring, ringPath.height);
547
- ring.drawCircle(
548
- ringPath.x,
549
- ringPath.y,
550
- (ringPath.innerRadius + ringPath.outerRadius)/2
551
- );
552
- ring.endFill();
553
- return ring;
554
- }
555
-
556
- // /**
557
- // * @param {PiePath} piePath
558
- // */
559
- // _renderPiePath(piePath) {
560
- // let arc = new PIXI.Graphics();
561
- // arc.lineStyle({
562
- // color: toHexColor(piePath.styles["strokeColor"]),
563
- // width: piePath.styles["strokeWidth"]
564
- // })
565
- // arc.beginFill(toHexColor(piePath.styles["fillColor"]))
566
- // arc.moveTo(piePath.x, piePath.y);
567
- // arc.arc(
568
- // piePath.x,
569
- // piePath.y,
570
- // piePath.radius,
571
- // -piePath.endAngleRad,
572
- // -piePath.startAngleRad,
573
- // );
574
-
575
- // arc.lineTo(piePath.x, piePath.y);
576
- // arc.endFill();
577
-
578
- // return arc;
579
- // }
580
-
581
- /**
582
- * @param {ArcPath} arcPath
583
- */
584
- _renderArc(arcPath) {
585
- let arc = new Graphics();
586
- arc.lineStyle({
587
- color: toHexColor(arcPath.styles["strokeColor"]),
588
- width: arcPath.styles["strokeWidth"]
589
- })
590
- arc.beginFill(toHexColor(arcPath.styles["fillColor"]));
591
- //arc.moveTo(arcPath.x, arcPath.y);
592
- arc.arc(
593
- arcPath.x,
594
- arcPath.y,
595
- arcPath.outerRadius,
596
- -arcPath.endAngle * DEG2RAD,
597
- -arcPath.startAngle * DEG2RAD,
598
- );
599
-
600
- arc.arc(
601
- arcPath.x,
602
- arcPath.y,
603
- arcPath.innerRadius,
604
- -arcPath.startAngle * DEG2RAD,
605
- -arcPath.endAngle * DEG2RAD,
606
- true
607
- );
608
-
609
- //arc.lineTo(arcPath.x, arcPath.y);
610
- arc.endFill();
611
-
612
- return arc;
613
- }
614
-
615
- /**
616
- * @param {Image} image
617
- */
618
- _renderImage(image) {
619
- let sprite = PIXI.Sprite.from(image.src);
620
- sprite.x = image.x;
621
- sprite.y = image.y;
622
- sprite.width = image.width;
623
- sprite.height = image.height;
624
-
625
- return sprite;
626
- }
627
-
628
- /**
629
- * @param {Link} link
630
- */
631
- _renderLink(link) {
632
- switch (link.linkMode) {
633
- case "arcClockwise":
634
- case "curveVertical":
635
- case "arcAntiClockwise":
636
- case "linear":
637
- return renderLinearLink(link);
638
-
639
- default:
640
- throwError("link", link.curveMode, "unexpected curvemode")
641
- }
642
-
643
- /**
644
- * @param {Link} link
645
- */
646
- function renderLinearLink(link) {
647
- let graphics = new Graphics();
648
- decorate(graphics, link.styles);
649
- graphics.lineStyle({
650
- color: toHexColor(link.styles["strokeColor"]),
651
- width: link.styles["strokeWidth"]
652
- })
653
- drawOnGraphicsFromJSONData(graphics, parseDPath(link.getSVGPathData()));
654
-
655
- return graphics;
656
- }
657
- }
658
- }
659
-
660
- /**
661
- * Set visibility and alpha
662
- * @param {DisplayObject} displayObject
663
- * @param {*} styles
664
- */
665
- function decorate(displayObject, styles) {
666
- displayObject.visible = styleVisiblity2PixiVisible(styles["visibility"]);
667
- displayObject.alpha = styleOpacity2PixiAlpha(styles["opacity"]);
668
- }
669
-
670
- function styleFontWeight2PixiFontWeight(fontWeight) {
671
- switch (fontWeight) {
672
- case "regular":
673
- case "normal":
674
- return "normal";
675
-
676
- case "bold":
677
- return "bold";
678
-
679
- default:
680
- console.log(fontWeight);
681
- throwError("font weight", fontWeight, Errors.FEATURE_NOT_IMPLEMENTED);
682
- }
683
- }
684
-
685
- function styleAnchor2PixiAnchor(anchor) {
686
- let horizontal, vertical;
687
-
688
- switch (anchor[0]) {
689
- case "left":
690
- horizontal = 0.0;
691
- break;
692
-
693
- case "center":
694
- horizontal = 0.5;
695
- break;
696
-
697
- case "right":
698
- horizontal = 1.0;
699
- break;
700
-
701
- default:
702
- throwError("x anchor", anchor[0], Errors.UNKNOWN_ANCHOR);
703
- }
704
-
705
- switch (anchor[1]) {
706
- // TODO: hanging is actually not quite the same as top
707
- case "hanging":
708
- case "top":
709
- vertical = 0.0;
710
- break;
711
- // TODO: central is not quite the same as middle
712
- case "central":
713
- case "middle":
714
- vertical = 0.5;
715
- break;
716
- case "bottom":
717
- vertical = 1.0;
718
- break;
719
- default:
720
- throwError("y anchor", anchor[1], Errors.UNKNOWN_ANCHOR);
721
- }
722
-
723
- return [horizontal, vertical];
724
- }
725
-
726
- /**
727
- * @param {string} cssColor
728
- * @returns {number}
729
- */
730
- function toHexColor(cssColor) {
731
- let d3Color = D3.color(cssColor);
732
- if (d3Color == null) {
733
- return null;
734
- } else {
735
- let hexString = d3Color.formatHex();
736
- return PIXI.utils.string2hex(hexString);
737
- }
738
- }
739
-
740
- function styleVisiblity2PixiVisible(visibility) {
741
- switch (visibility) {
742
- case "hidden":
743
- return false;
744
- case null:
745
- case undefined:
746
- case "visible":
747
- default:
748
- return true;
749
- }
750
- }
751
-
752
- function rotation2PixiAngle(rotation) {
753
- if (rotation === undefined || typeof rotation[0] != "number") {
754
- return 0
755
- } else {
756
- return rotation[0];
757
- }
758
- }
759
-
760
- function rotation2PixiPivot(rotation) {
761
- if (rotation === undefined || typeof rotation[0] != "number") {
762
- return [0, 0];
763
- } else {
764
- return rotation.slice(1);
765
- }
766
- }
767
-
768
- function styleOpacity2PixiAlpha(opacity) {
769
- switch (opacity) {
770
- case undefined:
771
- case null:
772
- return 1;
773
-
774
- default:
775
- return opacity;
776
- }
777
- }
778
-
779
- function throwError(name, value, err) {
780
- console.log(value);
781
- throw new Error(`${err}. Source: ${name}, Actual: `);
782
- }
783
-
784
- /**
785
- * Can fill graphic with color or linear gradient accordingly.
786
- * Can also handle transparency
787
- * @param {Graphics} graphics
788
- */
789
- function beginGradientOrColorFill(styles, graphics, height) {
790
- let fillColor = styles["fillColor"];
791
-
792
- // if no fill color
793
- if (fillColor == "none") return;
794
-
795
- let hexColor = toHexColor(fillColor);
796
- // if valid color
797
- if (hexColor != null) {
798
- graphics.beginFill(hexColor);
799
- // then it must be texture
800
- } else {
801
- graphics.beginTextureFill({
802
- color: 0xffffff,
803
- texture: createLinearGradientTexture(height, fillColor.stops, fillColor.y1 > fillColor.y2)
804
- });
805
- }
806
- }
807
-
808
- function createLinearGradientTexture(height, stops, isReversed) {
809
-
810
- const canvas = document.createElement("canvas");
811
- canvas.height = height;
812
- canvas.width = 1;
813
- const ctx = canvas.getContext("2d");
814
-
815
- const grd = ctx.createLinearGradient(0, 0, 0, height);
816
- for (let i = 0; i < stops.length; i++) {
817
- if (isReversed) {
818
- grd.addColorStop(1 - stops[i].offset / 100, stops[i].color);
819
- } else {
820
- grd.addColorStop(stops[i].offset / 100, stops[i].color);
821
- }
822
- }
823
-
824
- ctx.fillStyle = grd;
825
- ctx.fillRect(0, 0, 1, height);
826
-
827
- return PIXI.Texture.from(canvas);
828
- }
829
-
830
- /**
831
- * @param {Graphics} graphics
832
- * @param {Array} json
833
- */
834
- function drawOnGraphicsFromJSONData(graphics, json) {
835
-
836
- // Draw a closed shape accordingly
837
- let last = json.pop();
838
- let callBack = () => {};
839
- if (last.code.toUpperCase() == "Z") {
840
- callBack = () => graphics.lineTo(json[0].end.x, json[0].end.y);
841
- } else {
842
- json.push(last);
843
- }
844
-
845
- // Actual drawing
846
- for (const data of json) {
847
- draw(data, graphics);
848
- }
849
-
850
- callBack();
851
- }
852
-
853
- /**
854
- * @param {Graphics} graphics
855
- * @returns {Graphics}
856
- */
857
- function draw(data, graphics) {
858
- switch (data.code.toUpperCase()) {
859
- case "M":
860
- graphics.moveTo(data.end.x, data.end.y);
861
- break;
862
-
863
- case "L":
864
- graphics.lineTo(data.end.x, data.end.y);
865
- break;
866
-
867
- case "Q":
868
- graphics.bezierCurveTo(
869
- data.cp1.x,
870
- data.cp1.y,
871
- data.cp1.x,
872
- data.cp1.y,
873
- data.end.x,
874
- data.end.y
875
- );
876
- break;
877
-
878
- case "C":
879
- graphics.bezierCurveTo(
880
- data.cp1.x,
881
- data.cp1.y,
882
- data.cp2.x,
883
- data.cp2.y,
884
- data.end.x,
885
- data.end.y
886
- );
887
- break;
888
-
889
- case "Z":
890
- throw new Error("Unexpected \"z\" marker. There's something wrong, I can feel it");
891
- case "A":
892
-
893
- graphics.endFill(); // to undo moveTo(), to avoid straight lines between vertices
894
-
895
- // the SVG command , like M 250 460 A 7.5 7.5 0 0 1 265 460, has rotation in degrees.
896
- // ...converting rotation to radians
897
- const degrees = data.rotation;
898
- const radians = degrees * (Math.PI / 180);
899
-
900
- graphics.arc(data.end.x - data.radii.x, data.end.y, data.radii.y, 0 + radians, Math.PI + radians, data.clockwise);
901
- break;
902
- default:
903
- return throwError("data", data, Errors.FEATURE_NOT_IMPLEMENTED);
904
- }
905
- }
906
-
907
- // Adapted from https://codepen.io/unrealnl/pen/aYaxBW
908
- function drawDashLine(vertices, strokeDash, graphics) {
909
- let i;
910
- let p1;
911
- let p2;
912
- let dashLeft = 0;
913
- let gapLeft = 0;
914
- let dashAndGap = strokeDash.split(" ");
915
- let dash = Number(dashAndGap[0]);
916
- let gap = Number(dashAndGap[1]);
917
-
918
- for (i = 0; i < vertices.length; i++) {
919
- p1 = vertices[i];
920
- if (i == vertices.length - 1) break;
921
- else p2 = vertices[i + 1];
922
-
923
- let dx = p2.x - p1.x;
924
- let dy = p2.y - p1.y;
925
- let len = Math.sqrt(dx * dx + dy * dy);
926
- let normal = { x: dx / len, y: dy / len };
927
- let progressOnLine = 0;
928
- graphics.moveTo(p1.x + gapLeft * normal.x, p1.y + gapLeft * normal.y);
929
-
930
- while (progressOnLine <= len) {
931
- progressOnLine += gapLeft;
932
- if (dashLeft > 0) progressOnLine += dashLeft;
933
- else progressOnLine += dash;
934
- if (progressOnLine > len) {
935
- dashLeft = progressOnLine - len;
936
- progressOnLine = len;
937
- } else {
938
- dashLeft = 0;
939
- }
940
- graphics.lineTo(p1.x + progressOnLine * normal.x, p1.y + progressOnLine * normal.y);
941
- progressOnLine += gap;
942
- if (progressOnLine > len && dashLeft == 0) {
943
- gapLeft = progressOnLine - len;
944
- } else {
945
- gapLeft = 0;
946
- graphics.moveTo(p1.x + progressOnLine * normal.x, p1.y + progressOnLine * normal.y);
947
- }
948
- }
949
- }
950
- }
951
-
952
- // Adapted from d-path-parser under MIT license
953
- // GitHub Repository: https://github.com/MaxArt2501/d-path-parser
954
- function parseDPath(d) {
955
- let re = {
956
- command: /\s*([achlmqstvz])/gi,
957
- number: /\s*([+-]?\d*\.?\d+(?:e[+-]?\d+)?)/gi,
958
- comma: /\s*(?:(,)|\s)/g,
959
- flag: /\s*([01])/g
960
- };
961
- let matchers = {
962
- "number": function(must) {
963
- return +get("number", must);
964
- },
965
- "coordinate pair": function(must) {
966
- let x = get("number", must);
967
- if (x === null && !must) return null;
968
- get("comma");
969
- let y = get("number", true);
970
- return { x: +x, y: +y };
971
- },
972
- "arc definition": function(must) {
973
- let radii = matchers["coordinate pair"](must);
974
- if (!radii && !must) return null;
975
- get("comma");
976
- let rotation = +get("number", true);
977
- get("comma", true);
978
- let large = !!+get("flag", true);
979
- get("comma");
980
- let clockwise = !!+get("flag", true);
981
- get("comma");
982
- let end = matchers["coordinate pair"](true);
983
- return {
984
- radii: radii,
985
- rotation: rotation,
986
- large: large,
987
- clockwise: clockwise,
988
- end: end
989
- };
990
- }
991
- }
992
- let index = 0;
993
- let commands = [];
994
-
995
- while (index < d.length) {
996
- let cmd = get("command");
997
- let upcmd = cmd.toUpperCase();
998
- let relative = cmd !== upcmd;
999
- let sequence;
1000
- switch (upcmd) {
1001
- case "M":
1002
- sequence = getSequence("coordinate pair").map(function(coords, i) {
1003
- if (i === 1) cmd = relative ? "l" : "L";
1004
- return makeCommand({ end: coords }, cmd, relative);
1005
- });
1006
- break;
1007
- case "L":
1008
- case "T":
1009
- sequence = getSequence("coordinate pair").map(function(coords) {
1010
- return makeCommand({ end: coords }, cmd, relative);
1011
- });
1012
- break;
1013
- case "C":
1014
- sequence = getSequence("coordinate pair");
1015
- if (sequence.length % 3)
1016
- throw Error("Expected coordinate pair triplet at position " + index);
1017
-
1018
- sequence = sequence.reduce(function(seq, coords, i) {
1019
- let rest = i % 3;
1020
- if (!rest) {
1021
- seq.push(makeCommand({ cp1: coords }, cmd, relative));
1022
- } else {
1023
- let last = seq[seq.length - 1];
1024
- last[rest === 1 ? "cp2" : "end"] = coords;
1025
- }
1026
- return seq;
1027
- }, []);
1028
-
1029
- break;
1030
- case "Q":
1031
- case "S":
1032
- sequence = getSequence("coordinate pair");
1033
- if (sequence.length & 1)
1034
- throw Error("Expected coordinate pair couple at position " + index);
1035
-
1036
- sequence = sequence.reduce(function(seq, coords, i) {
1037
- let odd = i & 1;
1038
- if (!odd) {
1039
- seq.push(makeCommand({ cp: coords }, cmd, relative));
1040
- } else {
1041
- let last = seq[seq.length - 1];
1042
- last.end = coords;
1043
- }
1044
- return seq;
1045
- }, []);
1046
-
1047
- break;
1048
- case "H":
1049
- case "V":
1050
- sequence = getSequence("number").map(function(value) {
1051
- return makeCommand({ value: value }, cmd, relative);
1052
- });
1053
- break;
1054
- case "A":
1055
- sequence = getSequence("arc definition");
1056
- sequence = sequence.map(obj => makeCommand(obj, cmd, relative))
1057
- break;
1058
- case "Z":
1059
- sequence = [ { code: "Z" } ];
1060
- break;
1061
- }
1062
- commands.push.apply(commands, sequence);
1063
- }
1064
-
1065
- return commands;
1066
-
1067
- function makeCommand(obj, cmd, relative) {
1068
- obj.code = cmd;
1069
- obj.relative = relative;
1070
-
1071
- return obj;
1072
- }
1073
- function get(what, must) {
1074
- re[what].lastIndex = index;
1075
- let res = re[what].exec(d);
1076
- if (!res || res.index !== index) {
1077
- if (!must) return null;
1078
- throw Error("Expected " + what + " at position " + index);
1079
- }
1080
-
1081
- index = re[what].lastIndex;
1082
-
1083
- return res[1];
1084
- }
1085
-
1086
- function getSequence(what) {
1087
- let sequence = [];
1088
- let matched;
1089
- let must = true;
1090
- while ((matched = matchers[what](must)) !== null) {
1091
- sequence.push(matched);
1092
- must = !!get("comma");
1093
- }
1094
-
1095
- return sequence;
1096
- }
1097
- }