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,264 @@
1
+ import {Orientation, Alignment, LayoutType, Errors, ItemType, Direction} from "../util/Constants";
2
+ import { normalizeAngle } from "../util/DataUtil";
3
+ import { getLeafMarks } from "../util/ItemUtil";
4
+ import Layout from "./Layout";
5
+
6
+ export default class StackLayout extends Layout {
7
+
8
+ constructor(args) {
9
+ super();
10
+ this.type = LayoutType.Stack;
11
+ this._orientation = args.orientation;
12
+ this._direction = args.direction;
13
+ this._left = args.left;
14
+ this._top = args.top;
15
+ this._horzCellAlignment = "horzCellAlignment" in args && args["horzCellAlignment"] ? args.horzCellAlignment : Alignment.Left;
16
+ this._vertCellAlignment = "vertCellAlignment" in args && args["vertCellAlignment"] ? args.vertCellAlignment : Alignment.Bottom;
17
+ this._gap = "gap" in args ? args.gap : 0;
18
+ }
19
+
20
+ // toJSON() {
21
+ // let json = {args: {}};
22
+ // json.type = this.type;
23
+ // json.args.orientation = this._orientation;
24
+ // json.args.direction = this._direction;
25
+ // json.args.left = this._left;
26
+ // json.args.top = this._top;
27
+ // json.args.gap = this._gap;
28
+ // json.args.horzCellAlignment = this._horzCellAlignment;
29
+ // json.args.vertCellAlignment = this._vertCellAlignment;
30
+ // return json;
31
+ // }
32
+
33
+ clone() {
34
+ let s = new StackLayout({orientation: this._orientation, direction: this._direction, left: this._left, top: this._top});
35
+ s._horzCellAlignment = this._horzCellAlignment;
36
+ s._vertCellAlignment = this._vertCellAlignment;
37
+ return s;
38
+ }
39
+
40
+ _stackAreasVert() {
41
+ let areas = this.group.children, gb = this.group.bounds,
42
+ start = this._vertCellAlignment === Alignment.Top ? gb.top : gb.bottom,
43
+ dir = this._vertCellAlignment === Alignment.Top ? 1 : -1;
44
+ let vCnt = areas[0].vertices.length/2,
45
+ cumuHts = new Array(vCnt).fill(0);
46
+ for (let area of areas) {
47
+ for (let i = 0; i < vCnt; i++) {
48
+ let v1 = area.vertices[i],
49
+ v2 = area.vertices[vCnt*2 - i - 1],
50
+ ht = Math.abs(v1.y - v2.y);
51
+ let y1 = start + cumuHts[i] * dir, y2 = start + (cumuHts[i] + ht) * dir;
52
+ v1._doTranslate(0, y1 - v1.y);
53
+ v2._doTranslate(0, y2 - v2.y);
54
+ cumuHts[i] += ht;
55
+ }
56
+ area._updateBounds();
57
+ }
58
+ if (this.vertCellAlignment === Alignment.Middle) {
59
+ for (let area of areas) {
60
+ for (let i = 0; i < vCnt; i++) {
61
+ let v1 = area.vertices[i],
62
+ v2 = area.vertices[vCnt*2 - i - 1];
63
+ let b = gb.middle + cumuHts[i]/2;
64
+ v1._doTranslate(0, b - gb.bottom);
65
+ v2._doTranslate(0, b - gb.bottom);
66
+ }
67
+ area._updateBounds();
68
+ }
69
+ }
70
+ this.group._updateBounds();
71
+ }
72
+
73
+ _stackAreasHorz() {
74
+ let areas = this.group.children, gb = this.group.bounds,
75
+ start = this._horzCellAlignment === Alignment.Right ? gb.right : gb.left,
76
+ dir = this._horzCellAlignment === Alignment.Right ? -1 : 1;
77
+ let vCnt = areas[0].vertices.length/2,
78
+ cumuWds = new Array(vCnt).fill(0);
79
+ for (let area of areas) {
80
+ for (let i = 0; i < vCnt; i++) {
81
+ let v1 = area.vertices[i],
82
+ v2 = area.vertices[vCnt*2 - i - 1],
83
+ wd = Math.abs(v1.x - v2.x);
84
+ let y1 = start + cumuWds[i] * dir, y2 = start + (cumuWds[i] + wd) * dir;
85
+ v1._doTranslate(0, y1 - v1.y);
86
+ v2._doTranslate(0, y2 - v2.y);
87
+ cumuWds[i] += wd;
88
+ }
89
+ area._updateBounds();
90
+ }
91
+ if (this._horzCellAlignment === Alignment.Center) {
92
+ for (let area of areas) {
93
+ for (let i = 0; i < vCnt; i++) {
94
+ let v1 = area.vertices[i],
95
+ v2 = area.vertices[vCnt*2 - i - 1];
96
+ let l = gb.center - cumuWds[i]/2;
97
+ v1._doTranslate(0, l - gb.left);
98
+ v2._doTranslate(0, l - gb.left);
99
+ }
100
+ area._updateBounds();
101
+ }
102
+ }
103
+ this.group._updateBounds();
104
+ }
105
+
106
+ _stackAreas() {
107
+ let area = this.group.children[0];
108
+ if (area.orientation === Orientation.Horizontal) {
109
+ this._stackAreasVert();
110
+ } else {
111
+ this._stackAreasHorz();
112
+ }
113
+ }
114
+
115
+ _stackArcs() {
116
+ let group = this.group;
117
+ if (this._orientation === Orientation.Angular) {
118
+ let startAngle = this.startAngle ? this.startAngle : 90,
119
+ dir = this._direction ? this._direction : Direction.Clockwise;
120
+ if (dir === Direction.Clockwise) {
121
+ for (let c of group.children) {
122
+ let temp = normalizeAngle(startAngle - c.angle);
123
+ c.adjustAngle(temp, startAngle);
124
+ startAngle = temp;
125
+ }
126
+ } else {
127
+ for (let c of group.children) {
128
+ let temp = normalizeAngle(startAngle + c.angle);
129
+ c.adjustAngle(startAngle, temp);
130
+ startAngle = temp;
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ _stackRects() {
137
+ let scene = this.group.getScene();
138
+ let group = this.group, o = this._orientation;
139
+ let bounds = group.children.map(d => d.bounds);
140
+ let lefts = bounds.map(d => d.left),
141
+ tops = bounds.map(d => d.top),
142
+ wds = bounds.map(d => d.width),
143
+ hts = bounds.map(d => d.height);
144
+ let left = this._left == undefined ? Math.min(...lefts) : this._left,
145
+ top = this._top == undefined ? Math.min(...tops) : this._top;
146
+
147
+ let maxWd = Math.max(...wds), maxHt = Math.max(...hts);
148
+ if (o == Orientation.Vertical) {
149
+ let centerX = left + maxWd/2;
150
+ for (let i = 0; i < group.children.length; i++) {
151
+ let c = group.children[i];
152
+ let dx = centerX - c.bounds.x,
153
+ dy = top + c.bounds.height/2 - c.bounds.y;
154
+ top += c.bounds.height + this._gap;
155
+ c._doTranslate(dx, dy);
156
+ //alignment
157
+ let cdx = 0, cdy = 0;
158
+ let xEnc = scene.getEncodingByItem(c, "x");
159
+ if (!xEnc) {
160
+ switch (this._horzCellAlignment) {
161
+ case Alignment.Left:
162
+ cdx = left - c.bounds.left;
163
+ break;
164
+ case Alignment.Center:
165
+ cdx = left + maxWd/2 - c.bounds.x;
166
+ break;
167
+ case Alignment.Right:
168
+ cdx = left + maxWd - c.bounds.right;
169
+ break;
170
+ }
171
+ }
172
+ c._doTranslate(cdx, cdy);
173
+ }
174
+ } else {
175
+ let centerY = top + maxHt/2;
176
+ for (let i = 0; i < group.children.length; i++) {
177
+ let c = group.children[i];
178
+ let dx = left + c.bounds.width/2 - c.bounds.x,
179
+ dy = centerY - c.bounds.y;
180
+ left += c.bounds.width + this._gap;
181
+ c._doTranslate(dx, dy);
182
+
183
+ //TODO: alignment
184
+ let cdx = 0, cdy = 0;
185
+ let yEnc = scene.getEncodingByItem(c, "y");
186
+ if (!yEnc) {
187
+ switch (this._vertCellAlignment) {
188
+ case Alignment.Top:
189
+ cdy = top - c.bounds.top;
190
+ break;
191
+ case Alignment.Middle:
192
+ cdy = top + maxHt/2 - c.bounds.y;
193
+ break;
194
+ case Alignment.Bottom:
195
+ cdy = top + maxHt - c.bounds.bottom;
196
+ break;
197
+ }
198
+ }
199
+ c._doTranslate(cdx, cdy);
200
+ }
201
+ }
202
+ this.group._updateBounds();
203
+ }
204
+
205
+ run() {
206
+ if (this.group == undefined || !this.group.children || this.group.children.length === 0)
207
+ return;
208
+ let leafMark = getLeafMarks(this.group)[0];
209
+ switch (leafMark.type) {
210
+ case ItemType.Area:
211
+ this._stackAreas();
212
+ break;
213
+ case ItemType.Arc:
214
+ case ItemType.Pie:
215
+ if (leafMark.parent === this.group)
216
+ this._stackArcs();
217
+ break;
218
+ case ItemType.Rect:
219
+ case ItemType.Image:
220
+ case ItemType.Circle:
221
+ this._stackRects();
222
+ break;
223
+ default:
224
+ break;
225
+ }
226
+ }
227
+
228
+ set vertCellAlignment(v) {
229
+ if (v != Alignment.Top && v != Alignment.Bottom && v != Alignment.Middle) {
230
+ throw Errors.UNKOWN_ALIGNMENT;
231
+ }
232
+ this._vertCellAlignment = v;
233
+ this.run();
234
+ }
235
+
236
+ get vertCellAlignment() {
237
+ return this._vertCellAlignment;
238
+ }
239
+
240
+ set horzCellAlignment(h) {
241
+ if (h != Alignment.Left && h != Alignment.Center && h != Alignment.Right) {
242
+ throw Errors.UNKOWN_ALIGNMENT;
243
+ }
244
+ this._horzCellAlignment = h;
245
+ this.run();
246
+ }
247
+
248
+ get horzCellAlignment() {
249
+ return this._horzCellAlignment;
250
+ }
251
+
252
+ get cellBounds() {
253
+ return this.group.children.map(d => d.bounds);
254
+ }
255
+
256
+ get orientation() {
257
+ return this._orientation;
258
+ }
259
+
260
+ set orientation(o) {
261
+ this._orientation = o;
262
+ this.run();
263
+ }
264
+ }
@@ -0,0 +1,88 @@
1
+ import { Direction, ItemType, LayoutType, nodeId } from "../util/Constants";
2
+ import { normalizeAngle } from "../util/DataUtil";
3
+ import Layout from "./Layout";
4
+
5
+ export default class StrataLayout extends Layout {
6
+
7
+ constructor(args) {
8
+ super();
9
+ this.type = LayoutType.Strata;
10
+ this._direction = args.direction;
11
+ this._rootMark = args.rootMark;
12
+ this._gap = "gap" in args ? args.gap : 0;
13
+ }
14
+
15
+ toJSON() {
16
+ let json = {args: {}};
17
+ json.type = this.type;
18
+ json.args.direction = this._direction;
19
+ json.args.rootMark = this._rootMark.id;
20
+ json.args.gap = this._gap;
21
+ return json;
22
+ }
23
+
24
+ clone() {
25
+
26
+ }
27
+
28
+ run() {
29
+ if (this.group == undefined || !this.group.children || this.group.children.length === 0)
30
+ return;
31
+
32
+ let tree = this.group.firstChild.dataScope.dataTable.tree;
33
+ if (!tree) return;
34
+
35
+ let nodeId2mark = {};
36
+ for (let item of this.group.children) {
37
+ nodeId2mark[item.dataScope.getFieldValue(nodeId)] = item;
38
+ }
39
+
40
+ if (this._rootMark.type === ItemType.Rect) {
41
+ this._layoutRects(tree.getRoot(), tree, nodeId2mark);
42
+ } else if (this._rootMark.type === ItemType.Circle) {
43
+ this._layoutArcs(tree.getRoot(), tree, nodeId2mark);
44
+ }
45
+ }
46
+
47
+ _layoutArcs(node, tree, node2mark) {
48
+ let childrenNodes = tree.getChildren(node);
49
+ if (childrenNodes.length === 0) return;
50
+ let parentMark = node2mark[node[nodeId]];
51
+ let startAngle = parentMark.type == ItemType.Arc || parentMark.type == ItemType.Pie ? parentMark.startAngle : 90;
52
+ for (let i = 0; i < childrenNodes.length; i++) {
53
+ let cn = childrenNodes[i],
54
+ mark = node2mark[cn[nodeId]];
55
+ if (mark.type === ItemType.Arc) {
56
+ let temp = normalizeAngle(startAngle + mark.angle);
57
+ // console.log(mark.dataScope.getFieldValue("event_attribute"), mark.startAngle, mark.endAngle, mark.angle);
58
+
59
+ mark.adjustAngle(startAngle, temp);
60
+ startAngle = temp;
61
+ }
62
+ this._layoutArcs(cn, tree, node2mark);
63
+ }
64
+ //console.log("-------------");
65
+ }
66
+
67
+ _layoutRects(node, tree, node2mark) {
68
+ let childrenNodes = tree.getChildren(node);
69
+ if (childrenNodes.length === 0) return;
70
+ let parentMark = node2mark[node[nodeId]];
71
+ let x, y;
72
+ switch (this._direction) {
73
+ case Direction.Down:
74
+ default:
75
+ x = parentMark.left;
76
+ y = parentMark.bottom;
77
+ break;
78
+ }
79
+ for (let i = 0; i < childrenNodes.length; i++) {
80
+ let cn = childrenNodes[i],
81
+ mark = node2mark[cn[nodeId]];
82
+
83
+ mark._doTranslate(x - mark.left , y - mark.top);
84
+ x += mark.width;
85
+ this._layoutRects(cn, tree, node2mark);
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,59 @@
1
+ // import { dagStratify, decrossOpt, sugiyama } from "d3-dag";
2
+ import { LayoutType, nodeId } from "../util/Constants";
3
+ import Layout from "./Layout";
4
+ import * as dagre from "dagre";
5
+
6
+ export default class SugiyamaLayout extends Layout {
7
+
8
+ constructor(args) {
9
+ super();
10
+ this.type = LayoutType.Sugiyama;
11
+ this._width = "width" in args ? args["width"] : 500;
12
+ this._height = "height" in args ? args["height"] : 300;
13
+ this._top = "top" in args ? args["top"] : 0;
14
+ this._left = "left" in args ? args["left"] : 0;
15
+ this._edgeSep = "edgeSep" in args? args["edgeSep"] : 50;
16
+ }
17
+
18
+ toJSON() {
19
+ let json = {args: {}};
20
+ json.type = this.type;
21
+ return json;
22
+ }
23
+
24
+ run() {
25
+ let graph = this.group.children[0].dataScope._dt.graph;
26
+ if (!graph) return;
27
+
28
+ var g = new dagre.graphlib.Graph();
29
+ g.setGraph({edgesep: this._edgeSep});
30
+ g.setDefaultEdgeLabel(function() { return {}; });
31
+
32
+ //in case the node ids in the input graph file are integers
33
+ let nodeIdHash = new Map();
34
+ for (let n of this.group.children) {
35
+ let id = n.dataScope.getFieldValue(nodeId);
36
+ nodeIdHash.set(id, id + "");
37
+ g.setNode(id, {label: n.text ? n.text : "", width: n.bounds.width, height: n.bounds.height});
38
+ }
39
+ for (let l of graph.links) {
40
+ g.setEdge(l.source, l.target);
41
+ }
42
+ dagre.layout(g);
43
+
44
+ const nid2pos = {};
45
+ let t = Math.min(...g.nodes().map(d => g.node(d).y)), l = Math.min(...g.nodes().map(d => g.node(d).x));
46
+ let dx = this._left - l, dy = this._top - t;
47
+ for (const id of g.nodes()) {
48
+ nid2pos[id] = {x: g.node(id).x + dx, y: g.node(id).y + dy};
49
+ }
50
+
51
+ for (let node of this.group.children) {
52
+ let nid = node.dataScope.getFieldValue(nodeId);
53
+ node.x = nid2pos[nodeIdHash.get(nid)].x;
54
+ node.y = nid2pos[nodeIdHash.get(nid)].y;
55
+ }
56
+ this.group._updateBounds();
57
+ this.group.getScene()._updateAncestorBounds(this.group);
58
+ }
59
+ }
@@ -0,0 +1,105 @@
1
+ import Layout from "./Layout";
2
+ import * as d3 from "d3";
3
+ import { Errors, LayoutType, nodeId, Orientation } from "../util/Constants";
4
+
5
+ export default class TidyTreeLayout extends Layout {
6
+
7
+ constructor(args) {
8
+ super();
9
+ this.type = LayoutType.TidyTree;
10
+ this._width = "width" in args ? args.width : 500;
11
+ this._height = "height" in args ? args.height : 500;
12
+ this._left = "left" in args ? args.left : 100;
13
+ this._top = "top" in args ? args.top : 100;
14
+ this._orientation = "orientation" in args ? args.orientation : Orientation.Horizontal;
15
+ }
16
+
17
+ toJSON() {
18
+ let json = {args: {}};
19
+ json.args.type = this.type;
20
+ json.args.orientation = this._orientation;
21
+ json.args.left = this._left;
22
+ json.args.top = this._top;
23
+ json.args.width = this._width;
24
+ json.args.height = this._height;
25
+ return json;
26
+ }
27
+
28
+ run() {
29
+ if (this.group == undefined)
30
+ return;
31
+ let dt = this.group.children[0].dataScope._dt;
32
+ if (dt.tree) {
33
+ let hierarchy = d3.hierarchy(dt.tree._data);
34
+ let wd = Math.max(...this.group.children.map(d => d.bounds.width)), ht = Math.max(...this.group.children.map(d => d.bounds.height));
35
+ let size = this._orientation == Orientation.Horizontal ? [this._height, this._width] : [this._width, this._height];
36
+ let tree = d3.tree().nodeSize([wd, ht]).size(size)(hierarchy);
37
+ this._apply(tree, this.group);
38
+ this.group._updateBounds();
39
+ this.group.getScene()._updateAncestorBounds(this.group);
40
+ } else {
41
+ throw Errors.LAYOUT_WITHOUT_TREE;
42
+ }
43
+ }
44
+
45
+ _apply(d3Tree, coll) {
46
+ let mark = coll.children.filter(d => d.dataScope.getFieldValue(nodeId) == d3Tree.data[nodeId])[0];
47
+
48
+ let x, y;
49
+ switch (this._orientation) {
50
+ case Orientation.Horizontal:
51
+ x = d3Tree.y + this._left;
52
+ y = d3Tree.x + this._top;
53
+ break;
54
+ case Orientation.Vertical:
55
+ x = d3Tree.x + this._left;
56
+ y = this._top + d3Tree.y;
57
+ break;
58
+ }
59
+
60
+ mark.x = x;
61
+ mark.y = y;
62
+
63
+ if (d3Tree.children && d3Tree.children.length > 0) {
64
+ for (let c of d3Tree.children)
65
+ this._apply(c, coll);
66
+ }
67
+ }
68
+
69
+ get orientation() {
70
+ return this._orientation;
71
+ }
72
+
73
+ set orientation(o) {
74
+ this._orientation = o;
75
+ this.run();
76
+ }
77
+
78
+ get width() {
79
+ return this._width;
80
+ }
81
+
82
+ set width(w) {
83
+ this._width = w;
84
+ this.run();
85
+ }
86
+
87
+ get height() {
88
+ return this._width;
89
+ }
90
+
91
+ set height(h) {
92
+ this._height = h;
93
+ this.run();
94
+ }
95
+
96
+ get size() {
97
+ return [this._width, this._height];
98
+ }
99
+
100
+ set size(s) {
101
+ this._width = s[0];
102
+ this._height = s[1];
103
+ this.run();
104
+ }
105
+ }
@@ -0,0 +1,87 @@
1
+ import * as d3 from "d3";
2
+ import Layout from "./Layout";
3
+
4
+ export default class TreemapLayout extends Layout {
5
+
6
+ constructor(args) {
7
+ super();
8
+ this.type = "treemap";
9
+ this._width = args["width"];
10
+ this._height = args["height"];
11
+ this._top = args["top"];
12
+ this._left = args["left"];
13
+ }
14
+
15
+ toJSON() {
16
+ let json = {args: {}};
17
+ json.type = this.type;
18
+ json.args.left = this._left;
19
+ json.args.top = this._top;
20
+ json.args.width = this._width;
21
+ json.args.height = this._height;
22
+ return json;
23
+ }
24
+
25
+ clone() {
26
+ return new TreemapLayout({width: this._width, height: this._height, top: this._top, left: this._left});
27
+ }
28
+
29
+ run() {
30
+ if (this.group == undefined || !this.group.children || this.group.children.length == 0)
31
+ return;
32
+ let w = this._width ? this._width : this.group.bounds.width,
33
+ h = this._height ? this._height : this.group.bounds.height,
34
+ top = this._top === undefined ? this.group.bounds.top : this._top,
35
+ left = this._left === undefined ? this.group.bounds.left : this._left;
36
+ let hierarchy = d3.hierarchy((this.group)).sum(d => d.type == "rect" ? d.bounds.width * d.bounds.height : 0);
37
+ d3.treemap().size([w,h])(hierarchy);
38
+ this._apply(hierarchy, left, top);
39
+ this.group.getScene()._updateAncestorBounds(hierarchy.leaves()[0].data);
40
+ }
41
+
42
+ _apply(node, left, top) {
43
+ if (node.data.type == "collection" && node.children) {
44
+ for (let c of node.children)
45
+ this._apply(c, left, top);
46
+ } else if (node.data.type == "rect") {
47
+ node.data.resize(node.x1 - node.x0, node.y1 - node.y0);
48
+ node.data._doTranslate(node.x0 + left - node.data.bounds.left, node.y0 + top - node.data.bounds.top);
49
+ }
50
+ }
51
+
52
+ get width() {
53
+ return this._width;
54
+ }
55
+
56
+ set width(w) {
57
+ this._width = w;
58
+ this.run();
59
+ }
60
+
61
+ get height() {
62
+ return this._width;
63
+ }
64
+
65
+ set height(h) {
66
+ this._height = h;
67
+ this.run();
68
+ }
69
+
70
+ get top() {
71
+ return this._top;
72
+ }
73
+
74
+ set top(t) {
75
+ this._top = t;
76
+ this.run();
77
+ }
78
+
79
+ get left() {
80
+ return this._left;
81
+ }
82
+
83
+ set left(l) {
84
+ this._left = l;
85
+ this.run();
86
+ }
87
+ }