Skip to content

Commit fe01851

Browse files
authored
Merge pull request #20 from antvis/0.6.9
fix: indented layout with different node heights
2 parents 26bd3e5 + f1f1dd9 commit fe01851

File tree

4 files changed

+40
-12
lines changed

4 files changed

+40
-12
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@antv/hierarchy",
3-
"version": "0.6.8",
3+
"version": "0.6.9",
44
"description": "layout algorithms for visualizing hierarchical data",
55
"main": "build/hierarchy.js",
66
"browser": "build/hierarchy.js",

src/indented.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,21 @@ class IndentedLayout extends TreeLayout {
1818
const root = me.rootNode;
1919
options.isHorizontal = true;
2020
// default indent 20 and sink first children;
21-
const { indent = 20, dropCap = true } = options;
22-
const direction = options.direction || DEFAULT_DIRECTION;
21+
const { indent = 20, dropCap = true, direction = DEFAULT_DIRECTION, align } = options;
2322
if (direction && VALID_DIRECTIONS.indexOf(direction) === -1) {
2423
throw new TypeError(`Invalid direction: ${direction}`);
2524
}
2625
if (direction === VALID_DIRECTIONS[0]) { // LR
27-
indentedTree(root, indent, dropCap);
26+
indentedTree(root, indent, dropCap, align);
2827
} else if (direction === VALID_DIRECTIONS[1]) { // RL
29-
indentedTree(root, indent, dropCap);
28+
indentedTree(root, indent, dropCap, align);
3029
root.right2left();
3130
} else if (direction === VALID_DIRECTIONS[2]) { // H
3231
// separate into left and right trees
3332
const { left, right } = separateTree(root, options);
34-
indentedTree(left, indent, dropCap);
33+
indentedTree(left, indent, dropCap, align);
3534
left.right2left();
36-
indentedTree(right, indent, dropCap);
35+
indentedTree(right, indent, dropCap, align);
3736
const bbox = left.getBoundingBox();
3837
right.translate(bbox.width, 0);
3938
root.x = right.x - root.width / 2;

src/layout/indented.js

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
function positionNode(node, previousNode, indent, dropCap) {
1+
const util = require('../util');
2+
3+
function positionNode(node, previousNode, indent, dropCap, align) {
24
// caculate the node's horizontal offset DX, dx's type might be number or function
35
const displacementX = typeof indent === 'function' ? indent(node) : indent * node.depth;
46

@@ -15,13 +17,26 @@ function positionNode(node, previousNode, indent, dropCap) {
1517
}
1618

1719
node.x += displacementX;
18-
node.y = previousNode ? previousNode.y + previousNode.height : 0;
20+
if (previousNode) {
21+
node.y = previousNode.y + util.getHeight(previousNode, node, align);
22+
if (node.parent.id !== previousNode.parent?.id) {
23+
// previous node has different parent
24+
const index = node.parent.children.findIndex(n => n.id === node.id);
25+
const preNode = node.parent.children[index - 1];
26+
if (preNode) {
27+
const preY = preNode.y + util.getHeight(preNode, node, align);
28+
node.y = preY > node.y ? preY : node.y;
29+
}
30+
}
31+
} else {
32+
node.y = 0;
33+
}
1934
return;
2035
}
21-
module.exports = (root, indent, dropCap) => {
36+
module.exports = (root, indent, dropCap, align) => {
2237
let previousNode = null;
2338
root.eachNode(node => {
24-
positionNode(node, previousNode, indent, dropCap);
39+
positionNode(node, previousNode, indent, dropCap, align);
2540
previousNode = node;
2641
});
2742
};

src/util.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
11
const { mix } = require('@antv/util');
2+
3+
/**
4+
* Get average height or height for node's position calculation, according to align.
5+
* @param {*} preNode previous node
6+
* @param {*} node current node, whose position is going to be calculated
7+
* @param {'center' | undefined} align 'center' means nodes align at the center, other value means align at the left-top
8+
* @param {string} heightField field name for height value on preNode and node
9+
* @return {number} the height for calculation
10+
*/
11+
function getHeight(preNode, node, align, heightField = 'height') {
12+
return align === 'center' ? (preNode[heightField] + node[heightField]) / 2 : preNode.height;
13+
}
14+
215
module.exports = {
3-
assign: mix
16+
assign: mix,
17+
getHeight
418
};

0 commit comments

Comments
 (0)