cytoscape-tidytree
Version:
Cytoscape.js layout extension for positioning trees
50 lines (49 loc) • 1.81 kB
JavaScript
import { Tree } from "./tree.js";
export class Layout {
options;
constructor(options) {
this.options = {
horizontalSpacing: 10,
verticalSpacing: 20,
lineWidth: 3,
layerHeight: undefined,
...options
};
}
run(data) {
const tree = this.makeTree(data, data.customY);
tree.layout();
this.setLayoutResult(data, tree);
return tree;
}
makeTree(data, root_y = 0) {
const outerWidth = data.w + this.options.horizontalSpacing;
let outerHeight = data.h + this.options.verticalSpacing;
let extraSpacing = data.extraVerticalSpacing ?? 0;
const layerHeight = this.options.layerHeight;
if (layerHeight !== undefined) {
outerHeight = Math.ceil(outerHeight / layerHeight) * layerHeight;
extraSpacing = Math.round(extraSpacing / layerHeight) * layerHeight;
}
if (data.customY !== undefined) {
extraSpacing = data.customY - root_y;
data.y = root_y + extraSpacing;
}
data.y = root_y + extraSpacing;
const vertex = new Tree(outerWidth, outerHeight, data.y, data.children.map((child) => this.makeTree(child, data.y + outerHeight)));
if (extraSpacing < 0) {
console.warn("Node has negative extra space, ignoring", data);
}
if (extraSpacing > 0) {
return new Tree(this.options.lineWidth, extraSpacing, root_y, [vertex], true);
}
return vertex;
}
setLayoutResult(data, tree) {
if (tree.isExtra) {
tree = tree.c[0];
}
data.x = tree.x + this.options.horizontalSpacing / 2;
data.children.forEach((child, i) => this.setLayoutResult(child, tree.c[i]));
}
}