@antv/hierarchy 0.6.13 → 0.7.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 (100) hide show
  1. package/README.md +51 -3
  2. package/dist/hierarchy.es.js +2 -0
  3. package/dist/hierarchy.es.js.map +1 -0
  4. package/dist/hierarchy.umd.js +2 -0
  5. package/dist/hierarchy.umd.js.map +1 -0
  6. package/lib/compact-box.d.ts +3 -0
  7. package/lib/compact-box.d.ts.map +1 -0
  8. package/lib/dendrogram.d.ts +3 -0
  9. package/lib/dendrogram.d.ts.map +1 -0
  10. package/lib/indented.d.ts +3 -0
  11. package/lib/indented.d.ts.map +1 -0
  12. package/lib/index.d.ts +15 -0
  13. package/lib/index.d.ts.map +1 -0
  14. package/lib/layout/base.d.ts +8 -0
  15. package/lib/layout/base.d.ts.map +1 -0
  16. package/lib/layout/dendrogram.d.ts +3 -0
  17. package/lib/layout/dendrogram.d.ts.map +1 -0
  18. package/lib/layout/do-layout.d.ts +5 -0
  19. package/lib/layout/do-layout.d.ts.map +1 -0
  20. package/lib/layout/hierarchy.d.ts +3 -0
  21. package/lib/layout/hierarchy.d.ts.map +1 -0
  22. package/lib/layout/indented.d.ts +3 -0
  23. package/lib/layout/indented.d.ts.map +1 -0
  24. package/lib/layout/mindmap.d.ts +3 -0
  25. package/lib/layout/mindmap.d.ts.map +1 -0
  26. package/lib/layout/non-layered-tidy.d.ts +3 -0
  27. package/lib/layout/non-layered-tidy.d.ts.map +1 -0
  28. package/lib/layout/separate-root.d.ts +6 -0
  29. package/lib/layout/separate-root.d.ts.map +1 -0
  30. package/lib/mindmap.d.ts +3 -0
  31. package/lib/mindmap.d.ts.map +1 -0
  32. package/lib/types.d.ts +90 -0
  33. package/lib/types.d.ts.map +1 -0
  34. package/lib/util.d.ts +17 -0
  35. package/lib/util.d.ts.map +1 -0
  36. package/package.json +48 -53
  37. package/.babelrc +0 -14
  38. package/.editorconfig +0 -20
  39. package/.eslintignore +0 -7
  40. package/.eslintrc +0 -28
  41. package/.github/workflows/build.yml +0 -32
  42. package/CHANGELOG.md +0 -0
  43. package/CONTRIBUTING.md +0 -142
  44. package/CONTRIBUTING.zh-CN.md +0 -148
  45. package/assets/compact-box-bt.png +0 -0
  46. package/assets/compact-box-h.png +0 -0
  47. package/assets/compact-box-lr.png +0 -0
  48. package/assets/compact-box-rl.png +0 -0
  49. package/assets/compact-box-tb.png +0 -0
  50. package/assets/compact-box-v.png +0 -0
  51. package/assets/dendrogram-bt.png +0 -0
  52. package/assets/dendrogram-h.png +0 -0
  53. package/assets/dendrogram-lr.png +0 -0
  54. package/assets/dendrogram-rl.png +0 -0
  55. package/assets/dendrogram-tb.png +0 -0
  56. package/assets/dendrogram-v.png +0 -0
  57. package/assets/indented-h.png +0 -0
  58. package/assets/indented-lr.png +0 -0
  59. package/assets/indented-rl.png +0 -0
  60. package/assets/layered-tidy-bt.png +0 -0
  61. package/assets/layered-tidy-h.png +0 -0
  62. package/assets/layered-tidy-lr.png +0 -0
  63. package/assets/layered-tidy-rl.png +0 -0
  64. package/assets/layered-tidy-tb.png +0 -0
  65. package/assets/layered-tidy-v.png +0 -0
  66. package/assets/mindmap.png +0 -0
  67. package/bin/mkdir-dist.js +0 -8
  68. package/bin/screenshot.js +0 -81
  69. package/bin/win-dev.js +0 -14
  70. package/build/hierarchy.js +0 -1131
  71. package/build/hierarchy.js.map +0 -1
  72. package/dist/hierarchy.min.js +0 -1
  73. package/lib/compact-box.js +0 -24
  74. package/lib/dendrogram.js +0 -25
  75. package/lib/indented.js +0 -65
  76. package/lib/index.js +0 -7
  77. package/lib/layout/base.js +0 -17
  78. package/lib/layout/dendrogram.js +0 -108
  79. package/lib/layout/do-layout.js +0 -107
  80. package/lib/layout/hierarchy.js +0 -184
  81. package/lib/layout/indented.js +0 -36
  82. package/lib/layout/mindmap.js +0 -92
  83. package/lib/layout/non-layered-tidy.js +0 -236
  84. package/lib/layout/separate-root.js +0 -39
  85. package/lib/mindmap.js +0 -24
  86. package/lib/util.js +0 -18
  87. package/src/compact-box.js +0 -21
  88. package/src/dendrogram.js +0 -22
  89. package/src/indented.js +0 -52
  90. package/src/index.js +0 -9
  91. package/src/layout/base.js +0 -16
  92. package/src/layout/dendrogram.js +0 -105
  93. package/src/layout/do-layout.js +0 -106
  94. package/src/layout/hierarchy.js +0 -187
  95. package/src/layout/indented.js +0 -40
  96. package/src/layout/mindmap.js +0 -93
  97. package/src/layout/non-layered-tidy.js +0 -250
  98. package/src/layout/separate-root.js +0 -40
  99. package/src/mindmap.js +0 -21
  100. package/src/util.js +0 -16
package/src/indented.js DELETED
@@ -1,52 +0,0 @@
1
- const TreeLayout = require('./layout/base');
2
- const indentedTree = require('./layout/indented');
3
- const separateTree = require('./layout/separate-root');
4
- const util = require('./util');
5
-
6
-
7
- const VALID_DIRECTIONS = [
8
- 'LR', // left to right
9
- 'RL', // right to left
10
- 'H' // horizontal
11
- ];
12
- const DEFAULT_DIRECTION = VALID_DIRECTIONS[0];
13
-
14
- class IndentedLayout extends TreeLayout {
15
- execute() {
16
- const me = this;
17
- const options = me.options;
18
- const root = me.rootNode;
19
- options.isHorizontal = true;
20
- // default indent 20 and sink first children;
21
- const { indent = 20, dropCap = true, direction = DEFAULT_DIRECTION, align } = options;
22
- if (direction && VALID_DIRECTIONS.indexOf(direction) === -1) {
23
- throw new TypeError(`Invalid direction: ${direction}`);
24
- }
25
- if (direction === VALID_DIRECTIONS[0]) { // LR
26
- indentedTree(root, indent, dropCap, align);
27
- } else if (direction === VALID_DIRECTIONS[1]) { // RL
28
- indentedTree(root, indent, dropCap, align);
29
- root.right2left();
30
- } else if (direction === VALID_DIRECTIONS[2]) { // H
31
- // separate into left and right trees
32
- const { left, right } = separateTree(root, options);
33
- indentedTree(left, indent, dropCap, align);
34
- left.right2left();
35
- indentedTree(right, indent, dropCap, align);
36
- const bbox = left.getBoundingBox();
37
- right.translate(bbox.width, 0);
38
- root.x = right.x - root.width / 2;
39
- }
40
- return root;
41
- }
42
- }
43
-
44
- const DEFAULT_OPTIONS = {
45
- };
46
-
47
- function indentedLayout(root, options) {
48
- options = util.assign({}, DEFAULT_OPTIONS, options);
49
- return new IndentedLayout(root, options).execute();
50
- }
51
-
52
- module.exports = indentedLayout;
package/src/index.js DELETED
@@ -1,9 +0,0 @@
1
-
2
- const hierarchy = {
3
- compactBox: require('./compact-box'),
4
- dendrogram: require('./dendrogram'),
5
- indented: require('./indented'),
6
- mindmap: require('./mindmap')
7
- };
8
-
9
- module.exports = hierarchy;
@@ -1,16 +0,0 @@
1
-
2
- const hierarchy = require('./hierarchy');
3
-
4
- class Layout {
5
- constructor(root, options = {}) {
6
- const me = this;
7
- me.options = options;
8
- me.rootNode = hierarchy(root, options);
9
- }
10
-
11
- execute() {
12
- throw new Error('please override this method');
13
- }
14
- }
15
-
16
- module.exports = Layout;
@@ -1,105 +0,0 @@
1
- // wrap tree node
2
- // TODO considering size
3
- const util = require('../util');
4
-
5
- function WrappedTree(height = 0, children = []) {
6
- const me = this;
7
- me.x = me.y = 0;
8
- me.leftChild = me.rightChild = null;
9
- me.height = 0;
10
- me.children = children;
11
- }
12
-
13
- const DEFAULT_OPTIONS = {
14
- isHorizontal: true,
15
- nodeSep: 20,
16
- nodeSize: 20,
17
- rankSep: 200,
18
- subTreeSep: 10
19
- };
20
-
21
- function convertBack(converted/* WrappedTree */, root/* TreeNode */, isHorizontal) {
22
- if (isHorizontal) {
23
- root.x = converted.x;
24
- root.y = converted.y;
25
- } else {
26
- root.x = converted.y;
27
- root.y = converted.x;
28
- }
29
- converted.children.forEach((child, i) => {
30
- convertBack(child, root.children[i], isHorizontal);
31
- });
32
- }
33
-
34
- module.exports = (root, options = {}) => {
35
- options = util.assign({}, DEFAULT_OPTIONS, options);
36
-
37
- let maxDepth = 0;
38
- function wrappedTreeFromNode(n) {
39
- if (!n) return null;
40
- n.width = 0;
41
- if (n.depth && n.depth > maxDepth) {
42
- maxDepth = n.depth; // get the max depth
43
- }
44
- const children = n.children;
45
- const childrenCount = children.length;
46
- const t = new WrappedTree(n.height, []);
47
- children.forEach((child, i) => {
48
- const childWT = wrappedTreeFromNode(child);
49
- t.children.push(childWT);
50
- if (i === 0) {
51
- // t.leftChild = childWT.leftChild ? childWT.leftChild : childWT
52
- t.leftChild = childWT;
53
- }
54
- if (i === (childrenCount - 1)) {
55
- // t.rightChild = childWT.rightChild ? childWT.rightChild : childWT
56
- t.rightChild = childWT;
57
- }
58
- });
59
- t.originNode = n;
60
- t.isLeaf = n.isLeaf();
61
- return t;
62
- }
63
-
64
- function getDrawingDepth(t) {
65
- if (t.isLeaf || t.children.length === 0) {
66
- t.drawingDepth = maxDepth;
67
- } else {
68
- const depths = t.children.map(child => getDrawingDepth(child));
69
- const minChildDepth = Math.min.apply(null, depths);
70
- t.drawingDepth = minChildDepth - 1;
71
- }
72
- return t.drawingDepth;
73
- }
74
-
75
- let prevLeaf;
76
-
77
- function position(t) {
78
- t.x = t.drawingDepth * options.rankSep;
79
- if (t.isLeaf) {
80
- t.y = 0;
81
- if (prevLeaf) {
82
- t.y = prevLeaf.y + prevLeaf.height + options.nodeSep;
83
- if (t.originNode.parent !== prevLeaf.originNode.parent) {
84
- t.y += options.subTreeSep;
85
- }
86
- }
87
- prevLeaf = t;
88
- } else {
89
- t.children.forEach(child => {
90
- position(child);
91
- });
92
- t.y = (t.leftChild.y + t.rightChild.y) / 2;
93
- }
94
- }
95
-
96
- // wrap node
97
- const wt = wrappedTreeFromNode(root);
98
- // get depth for drawing
99
- getDrawingDepth(wt);
100
- // get position
101
- position(wt);
102
- // get x, y
103
- convertBack(wt, root, options.isHorizontal);
104
- return root;
105
- };
@@ -1,106 +0,0 @@
1
- const separateTree = require('./separate-root');
2
- const VALID_DIRECTIONS = [
3
- 'LR', // left to right
4
- 'RL', // right to left
5
- 'TB', // top to bottom
6
- 'BT', // bottom to top
7
- 'H', // horizontal
8
- 'V' // vertical
9
- ];
10
- const HORIZONTAL_DIRECTIONS = [
11
- 'LR',
12
- 'RL',
13
- 'H'
14
- ];
15
- const isHorizontal = direction => HORIZONTAL_DIRECTIONS.indexOf(direction) > -1;
16
- const DEFAULT_DIRECTION = VALID_DIRECTIONS[0];
17
-
18
- module.exports = (root, options, layoutAlgrithm) => {
19
- const direction = options.direction || DEFAULT_DIRECTION;
20
- options.isHorizontal = isHorizontal(direction);
21
- if (direction && VALID_DIRECTIONS.indexOf(direction) === -1) {
22
- throw new TypeError(`Invalid direction: ${direction}`);
23
- }
24
-
25
- if (direction === VALID_DIRECTIONS[0]) {
26
- // LR
27
- layoutAlgrithm(root, options);
28
- } else if (direction === VALID_DIRECTIONS[1]) {
29
- // RL
30
- layoutAlgrithm(root, options);
31
- root.right2left();
32
- } else if (direction === VALID_DIRECTIONS[2]) {
33
- // TB
34
- layoutAlgrithm(root, options);
35
- } else if (direction === VALID_DIRECTIONS[3]) {
36
- // BT
37
- layoutAlgrithm(root, options);
38
- root.bottom2top();
39
- } else if (direction === VALID_DIRECTIONS[4] || direction === VALID_DIRECTIONS[5]) {
40
- // H or V
41
- // separate into left and right trees
42
- const { left, right } = separateTree(root, options);
43
- // do layout for left and right trees
44
- layoutAlgrithm(left, options);
45
- layoutAlgrithm(right, options);
46
- options.isHorizontal ? (left.right2left()) : (left.bottom2top());
47
- // combine left and right trees
48
- right.translate(left.x - right.x, left.y - right.y);
49
- // translate root
50
- root.x = left.x;
51
- root.y = right.y;
52
- const bb = root.getBoundingBox();
53
- if (options.isHorizontal) {
54
- if (bb.top < 0) {
55
- root.translate(0, -bb.top);
56
- }
57
- } else {
58
- if (bb.left < 0) {
59
- root.translate(-bb.left, 0);
60
- }
61
- }
62
- }
63
- // fixed root position, default value is true
64
- let fixedRoot = options.fixedRoot;
65
- if (fixedRoot === undefined) fixedRoot = true;
66
- if (fixedRoot) {
67
- root.translate(-(root.x + root.width / 2 + root.hgap), -(root.y + root.height / 2 + root.vgap));
68
- }
69
-
70
- reassignXYIfRadial(root, options);
71
-
72
- return root;
73
- };
74
-
75
-
76
- function reassignXYIfRadial(root, options) {
77
- if (options.radial) {
78
- const [ rScale, radScale ] = options.isHorizontal ? [ "x", "y" ] : [ "y", "x" ];
79
-
80
- const min = { x: Infinity, y: Infinity };
81
- const max = { x: -Infinity, y: -Infinity };
82
-
83
- let count = 0;
84
- root.DFTraverse((node) => {
85
- count++;
86
- const { x, y } = node;
87
- min.x = Math.min(min.x, x);
88
- min.y = Math.min(min.y, y);
89
- max.x = Math.max(max.x, x);
90
- max.y = Math.max(max.y, y);
91
- });
92
-
93
- const radDiff = max[radScale] - min[radScale];
94
- if (radDiff === 0) return;
95
-
96
- const avgRad = (Math.PI * 2) / count;
97
- root.DFTraverse((node) => {
98
- const rad =
99
- ((node[radScale] - min[radScale]) / radDiff) * (Math.PI * 2 - avgRad) +
100
- avgRad;
101
- const r = node[rScale] - root[rScale];
102
- node.x = Math.cos(rad) * r;
103
- node.y = Math.sin(rad) * r;
104
- });
105
- }
106
- }
@@ -1,187 +0,0 @@
1
- /* eslint-disable no-cond-assign */
2
- const util = require('../util');
3
-
4
- const PEM = 18;
5
- const DEFAULT_HEIGHT = PEM * 2;
6
- const DEFAULT_GAP = PEM;
7
-
8
- const DEFAULT_OPTIONS = {
9
- getId(d) {
10
- return d.id || d.name;
11
- },
12
- getPreH(d) {
13
- return d.preH || 0;
14
- },
15
- getPreV(d) {
16
- return d.preV || 0;
17
- },
18
- getHGap(d) {
19
- return d.hgap || DEFAULT_GAP;
20
- },
21
- getVGap(d) {
22
- return d.vgap || DEFAULT_GAP;
23
- },
24
- getChildren(d) {
25
- return d.children;
26
- },
27
- getHeight(d) {
28
- return d.height || DEFAULT_HEIGHT;
29
- },
30
- getWidth(d) {
31
- const label = d.label || ' ';
32
- return d.width || (label.split('').length * PEM); // FIXME DO NOT get width like this
33
- }
34
- };
35
-
36
- function Node(data, options) {
37
- const me = this;
38
- me.vgap = me.hgap = 0;
39
- if (data instanceof Node) return data;
40
- me.data = data;
41
- /*
42
- * Gaps: filling space between nodes
43
- * (x, y) ----------------------
44
- * | vgap |
45
- * | -------------------- h
46
- * | h | | e
47
- * | g | | i
48
- * | a | | g
49
- * | p | | h
50
- * | --------------------- t
51
- * | |
52
- * -----------width------------
53
- */
54
- const hgap = options.getHGap(data);
55
- const vgap = options.getVGap(data);
56
- me.preH = options.getPreH(data);
57
- me.preV = options.getPreV(data);
58
- me.width = options.getWidth(data);
59
- me.height = options.getHeight(data);
60
- me.width += me.preH;
61
- me.height += me.preV;
62
- me.id = options.getId(data);
63
- me.x = me.y = 0;
64
- me.depth = 0;
65
- if (!me.children) {
66
- me.children = [];
67
- }
68
- me.addGap(hgap, vgap);
69
- return me;
70
- }
71
-
72
- util.assign(Node.prototype, {
73
- isRoot() {
74
- return (this.depth === 0);
75
- },
76
-
77
- isLeaf() {
78
- return (this.children.length === 0);
79
- },
80
-
81
- addGap(hgap, vgap) {
82
- const me = this;
83
- me.hgap += hgap;
84
- me.vgap += vgap;
85
- me.width += 2 * hgap;
86
- me.height += 2 * vgap;
87
- },
88
-
89
- eachNode(callback) { // Depth First traverse
90
- const me = this;
91
- let nodes = [ me ];
92
- let current;
93
- while (current = nodes.shift()) {
94
- callback(current);
95
- nodes = current.children.concat(nodes);
96
- }
97
- },
98
-
99
- DFTraverse(callback) { // Depth First traverse
100
- this.eachNode(callback);
101
- },
102
-
103
- BFTraverse(callback) { // Breadth First traverse
104
- const me = this;
105
- let nodes = [ me ];
106
- let current;
107
- while (current = nodes.shift()) {
108
- callback(current);
109
- nodes = nodes.concat(current.children);
110
- }
111
- },
112
-
113
- getBoundingBox() {
114
- // BBox for just one tree node
115
- const bb = {
116
- left: Number.MAX_VALUE,
117
- top: Number.MAX_VALUE,
118
- width: 0,
119
- height: 0
120
- };
121
- this.eachNode(node => {
122
- bb.left = Math.min(bb.left, node.x);
123
- bb.top = Math.min(bb.top, node.y);
124
- bb.width = Math.max(bb.width, node.x + node.width);
125
- bb.height = Math.max(bb.height, node.y + node.height);
126
- });
127
- return bb;
128
- },
129
-
130
- // translate
131
- translate(tx = 0, ty = 0) {
132
- this.eachNode(node => {
133
- node.x += tx;
134
- node.y += ty;
135
- node.x += node.preH;
136
- node.y += node.preV;
137
- });
138
- },
139
-
140
- right2left() {
141
- const me = this;
142
- const bb = me.getBoundingBox();
143
- me.eachNode(node => {
144
- node.x = node.x - (node.x - bb.left) * 2 - node.width;
145
- // node.x = - node.x;
146
- });
147
- me.translate(bb.width, 0);
148
- },
149
-
150
- bottom2top() {
151
- const me = this;
152
- const bb = me.getBoundingBox();
153
- me.eachNode(node => {
154
- node.y = node.y - (node.y - bb.top) * 2 - node.height;
155
- // node.y = - node.y;
156
- });
157
- me.translate(0, bb.height);
158
- }
159
- });
160
-
161
- function hierarchy(data, options = {}, isolated) {
162
- options = util.assign({}, DEFAULT_OPTIONS, options);
163
- const root = new Node(data, options);
164
- const nodes = [ root ];
165
- let node;
166
- if (!isolated && !data.collapsed) {
167
- while (node = nodes.shift()) {
168
- if (!node.data.collapsed) {
169
- const children = options.getChildren(node.data);
170
- const length = children ? children.length : 0;
171
- node.children = new Array(length);
172
- if (children && length) {
173
- for (let i = 0; i < length; i++) {
174
- const child = new Node(children[i], options);
175
- node.children[i] = child;
176
- nodes.push(child);
177
- child.parent = node;
178
- child.depth = node.depth + 1;
179
- }
180
- }
181
- }
182
- }
183
- }
184
- return root;
185
- }
186
-
187
- module.exports = hierarchy;
@@ -1,40 +0,0 @@
1
- const util = require("../util");
2
-
3
- function positionNode(node, previousNode, indent, dropCap, align) {
4
- // caculate the node's horizontal offset DX, dx's type might be number or function
5
- const displacementX =
6
- typeof indent === "function" ? indent(node) : indent * node.depth;
7
-
8
- if (!dropCap) {
9
- try {
10
- if (node.id === node.parent.children[0].id) {
11
- node.x += displacementX;
12
- node.y = previousNode ? previousNode.y : 0;
13
- return;
14
- }
15
- } catch (e) {
16
- // skip to normal when a node has no parent
17
- }
18
- }
19
-
20
- node.x += displacementX;
21
- if (previousNode) {
22
- node.y = previousNode.y + util.getHeight(previousNode, node, align);
23
- if (previousNode.parent && node.parent.id !== previousNode.parent.id) {
24
- // previous node has different parent
25
- const prevParent = previousNode.parent;
26
- const preY = prevParent.y + util.getHeight(prevParent, node, align);
27
- node.y = preY > node.y ? preY : node.y;
28
- }
29
- } else {
30
- node.y = 0;
31
- }
32
- return;
33
- }
34
- module.exports = (root, indent, dropCap, align) => {
35
- let previousNode = null;
36
- root.eachNode((node) => {
37
- positionNode(node, previousNode, indent, dropCap, align);
38
- previousNode = node;
39
- });
40
- };
@@ -1,93 +0,0 @@
1
- const util = require('../util');
2
-
3
- function secondWalk(node, options) {
4
- let totalHeight = 0;
5
- if (!node.children.length) {
6
- totalHeight = node.height;
7
- } else {
8
- node.children.forEach(c => {
9
- totalHeight += secondWalk(c, options);
10
- });
11
- }
12
- node._subTreeSep = options.getSubTreeSep(node.data);
13
- node.totalHeight = Math.max(node.height, totalHeight) + 2 * node._subTreeSep;
14
- return node.totalHeight;
15
- }
16
-
17
- function thirdWalk(node) {
18
- const children = node.children;
19
- const len = children.length;
20
- if (len) {
21
- children.forEach(c => {
22
- thirdWalk(c);
23
- });
24
- const first = children[0];
25
- const last = children[len - 1];
26
- const childrenHeight = last.y - first.y + last.height;
27
- let childrenTotalHeight = 0;
28
- children.forEach(child => {
29
- childrenTotalHeight += child.totalHeight;
30
- });
31
- if (childrenHeight > node.height) {
32
- // 当子节点总高度大于父节点高度
33
- node.y = first.y + childrenHeight / 2 - node.height / 2;
34
- } else if (children.length !== 1 || node.height > childrenTotalHeight) {
35
- // 多于一个子节点或者父节点大于所有子节点的总高度
36
- const offset = node.y + (node.height - childrenHeight) / 2 - first.y;
37
- children.forEach(c => {
38
- c.translate(0, offset);
39
- });
40
- } else {
41
- // 只有一个子节点
42
- node.y = (first.y + first.height / 2 + last.y + last.height / 2) / 2 - node.height / 2;
43
- }
44
- }
45
- }
46
-
47
- const DEFAULT_OPTIONS = {
48
- getSubTreeSep() {
49
- return 0;
50
- }
51
- };
52
-
53
- module.exports = (root, options = {}) => {
54
- options = util.assign({}, DEFAULT_OPTIONS, options);
55
- root.parent = {
56
- x: 0,
57
- width: 0,
58
- height: 0,
59
- y: 0
60
- };
61
- // first walk
62
- root.BFTraverse(node => {
63
- node.x = node.parent.x + node.parent.width; // simply get x
64
- });
65
- root.parent = null;
66
- // second walk
67
- secondWalk(root, options); // assign sub tree totalHeight
68
- // adjusting
69
- // separating nodes
70
- root.startY = 0;
71
- root.y = root.totalHeight / 2 - root.height / 2;
72
- root.eachNode(node => {
73
- const children = node.children;
74
- const len = children.length;
75
- if (len) {
76
- const first = children[0];
77
- first.startY = node.startY + node._subTreeSep;
78
- if (len === 1) {
79
- first.y = node.y + node.height / 2 - first.height / 2;
80
- } else {
81
- first.y = first.startY + first.totalHeight / 2 - first.height / 2;
82
- for (let i = 1; i < len; i++) {
83
- const c = children[i];
84
- c.startY = children[i - 1].startY + children[i - 1].totalHeight;
85
- c.y = c.startY + c.totalHeight / 2 - c.height / 2;
86
- }
87
- }
88
- }
89
- });
90
-
91
- // third walk
92
- thirdWalk(root);
93
- };