Skip to content

Commit

Permalink
Merge pull request #20 from antvis/0.6.9
Browse files Browse the repository at this point in the history
fix: indented layout with different node heights
  • Loading branch information
Yanyan-Wang authored Jan 19, 2023
2 parents 26bd3e5 + f1f1dd9 commit fe01851
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/hierarchy",
"version": "0.6.8",
"version": "0.6.9",
"description": "layout algorithms for visualizing hierarchical data",
"main": "build/hierarchy.js",
"browser": "build/hierarchy.js",
Expand Down
11 changes: 5 additions & 6 deletions src/indented.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,21 @@ class IndentedLayout extends TreeLayout {
const root = me.rootNode;
options.isHorizontal = true;
// default indent 20 and sink first children;
const { indent = 20, dropCap = true } = options;
const direction = options.direction || DEFAULT_DIRECTION;
const { indent = 20, dropCap = true, direction = DEFAULT_DIRECTION, align } = options;
if (direction && VALID_DIRECTIONS.indexOf(direction) === -1) {
throw new TypeError(`Invalid direction: ${direction}`);
}
if (direction === VALID_DIRECTIONS[0]) { // LR
indentedTree(root, indent, dropCap);
indentedTree(root, indent, dropCap, align);
} else if (direction === VALID_DIRECTIONS[1]) { // RL
indentedTree(root, indent, dropCap);
indentedTree(root, indent, dropCap, align);
root.right2left();
} else if (direction === VALID_DIRECTIONS[2]) { // H
// separate into left and right trees
const { left, right } = separateTree(root, options);
indentedTree(left, indent, dropCap);
indentedTree(left, indent, dropCap, align);
left.right2left();
indentedTree(right, indent, dropCap);
indentedTree(right, indent, dropCap, align);
const bbox = left.getBoundingBox();
right.translate(bbox.width, 0);
root.x = right.x - root.width / 2;
Expand Down
23 changes: 19 additions & 4 deletions src/layout/indented.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
function positionNode(node, previousNode, indent, dropCap) {
const util = require('../util');

function positionNode(node, previousNode, indent, dropCap, align) {
// caculate the node's horizontal offset DX, dx's type might be number or function
const displacementX = typeof indent === 'function' ? indent(node) : indent * node.depth;

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

node.x += displacementX;
node.y = previousNode ? previousNode.y + previousNode.height : 0;
if (previousNode) {
node.y = previousNode.y + util.getHeight(previousNode, node, align);
if (node.parent.id !== previousNode.parent?.id) {
// previous node has different parent
const index = node.parent.children.findIndex(n => n.id === node.id);
const preNode = node.parent.children[index - 1];
if (preNode) {
const preY = preNode.y + util.getHeight(preNode, node, align);
node.y = preY > node.y ? preY : node.y;
}
}
} else {
node.y = 0;
}
return;
}
module.exports = (root, indent, dropCap) => {
module.exports = (root, indent, dropCap, align) => {
let previousNode = null;
root.eachNode(node => {
positionNode(node, previousNode, indent, dropCap);
positionNode(node, previousNode, indent, dropCap, align);
previousNode = node;
});
};
16 changes: 15 additions & 1 deletion src/util.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
const { mix } = require('@antv/util');

/**
* Get average height or height for node's position calculation, according to align.
* @param {*} preNode previous node
* @param {*} node current node, whose position is going to be calculated
* @param {'center' | undefined} align 'center' means nodes align at the center, other value means align at the left-top
* @param {string} heightField field name for height value on preNode and node
* @return {number} the height for calculation
*/
function getHeight(preNode, node, align, heightField = 'height') {
return align === 'center' ? (preNode[heightField] + node[heightField]) / 2 : preNode.height;
}

module.exports = {
assign: mix
assign: mix,
getHeight
};

0 comments on commit fe01851

Please sign in to comment.