renderTree()

in client/client/modules/render/heatmap/renderer/dendrogram-renderer/binary-tree-graphics.js [336:457]


    renderTree(options = {}) {
        const {
            levelSize = 5
        } = options;
        const displayMode = getNodeDisplayMode(this.tree, this.axis);
        if (
            displayMode === SubTreeNodeDisplayModes.outsideViewport ||
            getNodeIsCollapsed(this.tree, this.axis)
        ) {
            this.hide();
            return true;
        }
        this.graphics.clear();
        /**
         *
         * @param {SubTreeNode} node
         * @returns {BinaryTreeGraphics}
         */
        const getChildRenderer = (node) => {
            if (node && this.children.has(node)) {
                return this.children.get(node);
            }
            return undefined;
        };
        /**
         *
         * @param {SubTreeNode} node
         * @returns {{level: number, position: number}}
         */
        const renderNode = (node) => {
            const mode = getNodeDisplayMode(node, this.axis);
            const collapsed = getNodeIsCollapsed(node, this.axis);
            const position = this.getNodePosition(node);
            if (
                mode === SubTreeNodeDisplayModes.outsideViewport ||
                collapsed
            ) {
                const subTrees = getNodeSubTrees(node);
                for (const subTree of subTrees) {
                    const renderer = getChildRenderer(subTree);
                    if (renderer) {
                        renderer.hide(true);
                    }
                }
                if (mode !== SubTreeNodeDisplayModes.outsideViewport) {
                    this.renderLeafPoint(position);
                }
                return {
                    level: 0,
                    position
                };
            }
            if (node.isLeaf && !node.hasSubTree) {
                this.renderLeafPoint(this.getNodePosition(node));
                return {
                    level: 0,
                    position
                };
            }
            const left = {
                level: 0,
                position: 0,
                visible: true,
                isLeaf: false
            };
            const right = {
                level: 0,
                position: 0,
                visible: true,
                isLeaf: false
            };
            if (
                node.isLeaf &&
                node.hasSubTree &&
                node.leftSubTree &&
                node.rightSubTree
            ) {
                const leftRenderer = getChildRenderer(node.leftSubTree);
                const rightRenderer = getChildRenderer(node.rightSubTree);
                if (leftRenderer && rightRenderer) {
                    leftRenderer.render(options);
                    rightRenderer.render(options);
                }
                left.level = node.leftSubTree.level;
                right.level = node.rightSubTree.level;
                left.position = leftRenderer.getNodePosition();
                right.position = rightRenderer.getNodePosition();
                left.visible = getNodeDisplayMode(node.leftSubTree, this.axis) !== SubTreeNodeDisplayModes.outsideViewport;
                right.visible = getNodeDisplayMode(node.rightSubTree, this.axis) !== SubTreeNodeDisplayModes.outsideViewport;
            } else {
                // not a leaf and does not have sub trees
                const {level: lLevel, position: lPosition} = renderNode(node.left);
                const {level: rLevel, position: rPosition} = renderNode(node.right);
                left.level = lLevel;
                left.position = lPosition;
                left.visible = getNodeDisplayMode(node.left, this.axis) !== SubTreeNodeDisplayModes.outsideViewport;
                right.level = rLevel;
                right.position = rPosition;
                right.visible = getNodeDisplayMode(node.right, this.axis) !== SubTreeNodeDisplayModes.outsideViewport;
            }
            const level = Math.max(
                -1,
                left.level,
                right.level
            ) + 1;
            this.renderNodeGraphics({
                level,
                levelSize,
                left,
                right
            });
            return {
                level,
                position: this.axis.getCorrectedPositionWithinAxis(
                    (left.position + right.position) / 2.0
                )
            };
        };
        const {level} = renderNode(this.tree);
        this.tree.level = level;
        this.visible = true;
    }