UNPKG

highcharts-tree

Version:
303 lines 11.6 kB
"use strict"; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __values = (this && this.__values) || function (o) { var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; if (m) return m.call(o); return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var TreeNode_1 = __importDefault(require("./TreeNode")); var Dictionary_1 = __importDefault(require("./Dictionary")); var Tree = /** @class */ (function () { function Tree(treeNode, horizontal) { if (horizontal === void 0) { horizontal = true; } this.horizontal = horizontal; this.treeMod = 0; this.root = this.buildTree(treeNode); } Tree.getTree = function (_a) { var tree = _a.tree, data = _a.data, horizontal = _a.horizontal; return tree && tree.root ? tree : new Tree(data, horizontal).build(); }; Tree.rotate = function (node) { var _a, _b; _a = __read([node.y, node.x], 2), node.x = _a[0], node.y = _a[1]; _b = __read([node.height, node.width], 2), node.width = _b[0], node.height = _b[1]; if (node.children) node.children.forEach(Tree.rotate); }; Tree.initializeNodes = function (node, depth) { var e_1, _a; if (depth === void 0) { depth = 0; } node.x = -1; node.y = depth; node.mod = 0; if (!node.toggle) return; try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; Tree.initializeNodes(child, depth + 1); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } }; Tree.checkForConflicts = function (node) { var nodeContour = new Dictionary_1.default(); Tree.getLeftContour(node, 0, nodeContour); var sibling = node.getLeftMostSibling(); var shiftValue = 0.0; while (sibling != null && sibling !== node) { var siblingContour = new Dictionary_1.default(); Tree.getRightContour(sibling, 0, siblingContour); for (var level = node.y + 1; level <= Math.min(Math.max.apply(null, siblingContour.keys()), Math.max.apply(null, nodeContour.keys())); level++) { var distance = nodeContour.get(level) - siblingContour.get(level) - Tree.nodeSize; if (distance + shiftValue < Tree.treeDistance) { shiftValue = Tree.treeDistance - distance; } } if (shiftValue > 0) { node.x += shiftValue; node.mod += shiftValue; // update the mod in nodeContour nodeContour.keys(function (key) { nodeContour.set(key, nodeContour.get(key) + shiftValue); }); Tree.centerNodesBetween(node, sibling); shiftValue = 0; } sibling = sibling.getNextSibling(); } }; Tree.getLeftContour = function (node, modSum, values) { var e_2, _a; if (!values.containsKey(node.y)) values.set(node.y, node.x + modSum); else { values.set(node.y, Math.min(values.get(node.y), node.x + modSum)); } modSum += node.mod; if (node.toggle) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; Tree.getLeftContour(child, modSum, values); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } } }; Tree.getRightContour = function (node, modSum, values) { var e_3, _a; if (!values.containsKey(node.y)) values.set(node.y, node.x + modSum); else { values.set(node.y, Math.max(values.get(node.y), node.x + modSum)); } modSum += node.mod; if (node.toggle) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; Tree.getRightContour(child, modSum, values); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_3) throw e_3.error; } } } }; Tree.centerNodesBetween = function (leftNode, rightNode) { var leftIndex = leftNode.parent.children.indexOf(rightNode); var rightIndex = leftNode.parent.children.indexOf(leftNode); var numNodesBetween = rightIndex - leftIndex - 1; if (numNodesBetween > 0) { var distanceBetweenNodes = (leftNode.x - rightNode.x) / (numNodesBetween + 1); for (var i = leftIndex + 1; i < rightIndex; i++) { var middleNode = leftNode.parent.children[i]; var desiredX = rightNode.x + distanceBetweenNodes * (i - leftIndex); var offset = desiredX - middleNode.x; middleNode.x += offset; middleNode.mod += offset; } Tree.checkForConflicts(leftNode); } }; Tree.prototype.build = function () { Tree.initializeNodes(this.root); this.calculateInitialX(this.root); this.calculateXWithMod(this.root); this.calculateFinalPositions(this.root); if (!this.horizontal) Tree.rotate(this.root); return this; }; Tree.prototype.calculateInitialX = function (node) { var e_4, _a; if (node.toggle) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; this.calculateInitialX(child); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_4) throw e_4.error; } } } if (node.isLeaf() || !node.toggle) { // if there is a previous sibling in this set, set X to previous sibling + designated distance if (!node.isLeftMost()) { node.x = node.getPreviousSibling().x + Tree.nodeSize + Tree.siblingDistance; } else node.x = 0; // if this is the first node in a set, set X to 0 } else if (node.children.length === 1) { // if this is the first node in a set, set it's X value equal to it's child's X value if (node.isLeftMost()) { node.x = node.children[0].x; } else { node.x = node.getPreviousSibling().x + Tree.nodeSize + Tree.siblingDistance; node.mod = node.x - node.children[0].x; } } else { var leftChild = node.getLeftMostChild(); var rightChild = node.getRightMostChild(); var mid = (leftChild.x + rightChild.x) / 2; if (node.isLeftMost()) { node.x = mid; } else { node.x = node.getPreviousSibling().x + Tree.nodeSize + Tree.siblingDistance; node.mod = node.x - mid; } } if (node.children.length > 0 && !node.isLeftMost() && node.toggle) { // Since subtrees can overlap, check for conflicts and shift tree right if needed Tree.checkForConflicts(node); } }; Tree.prototype.calculateXWithMod = function (node, modSum) { var e_5, _a; if (modSum === void 0) { modSum = 0; } node.x += modSum; if (node.x < 0 && node.x * -1 > this.treeMod) this.treeMod = node.x * -1; modSum += node.mod; if (node.toggle) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; this.calculateXWithMod(child, modSum); } } catch (e_5_1) { e_5 = { error: e_5_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_5) throw e_5.error; } } } }; Tree.prototype.calculateFinalPositions = function (node) { var e_6, _a; node.x += this.treeMod; if (node.toggle) { try { for (var _b = __values(node.children), _c = _b.next(); !_c.done; _c = _b.next()) { var child = _c.value; this.calculateFinalPositions(child); } } catch (e_6_1) { e_6 = { error: e_6_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_6) throw e_6.error; } } } if (node.isLeaf() || !node.toggle) { node.width = node.x; node.height = node.y; } else { var childWidths = node.children .map(function (n) { return n.width; }) .sort(function (p1, p2) { return p2 - p1; }); var childHeight = node.children .map(function (n) { return n.height; }) .sort(function (p1, p2) { return p2 - p1; }); node.width = childWidths[0]; node.height = childHeight[0]; } }; // Build tree as linked list and return root node. Tree.prototype.buildTree = function (data, parent) { var _this = this; var currentNode = new TreeNode_1.default(data, parent); currentNode.children = data.children ? data.children.map(function (childData) { return _this.buildTree(childData, currentNode); }) : []; return currentNode; }; Tree.nodeSize = 1; Tree.siblingDistance = 0.0; Tree.treeDistance = 0.0; return Tree; }()); exports.default = Tree; //# sourceMappingURL=Tree.js.map