From 2332920cdaadd64d558d9da5431d4bc1e9eb75e5 Mon Sep 17 00:00:00 2001 From: Jover Date: Fri, 18 Dec 2020 16:21:32 -0800 Subject: [PATCH 1/2] Update filters to hide ancestral nodes before last common ancestor Before this commit, filters determined visibility by: 1. Finding all terminal nodes in view window that match the filters and mark them as visible. 2. Recursively marking all parent nodes of these terminal nodes visible, all the way up to the root of the tree. This commit adds an additional step to hide ancestral nodes before the last common ancestor of visible terminal nodes. Starting from the root of the tree, recursively hide each node if it does not have more than one child node that is visible. --- src/util/treeVisibilityHelpers.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/util/treeVisibilityHelpers.js b/src/util/treeVisibilityHelpers.js index b08670049..6340982b7 100644 --- a/src/util/treeVisibilityHelpers.js +++ b/src/util/treeVisibilityHelpers.js @@ -93,6 +93,21 @@ const makeParentVisible = (visArray, node) => { makeParentVisible(visArray, node.parent); }; +/* Recursively hide nodes that do not have more than one child node in + * the param visArray. + * Relies on visArray having been updated by `makeParentVisible` */ +const hideNodeIfOnlyOneChildVisible = (visArray, node) => { + if (!node.hasChildren) { + return; // Terminal node without children + } + const visibleChildren = node.children.filter((child) => visArray[child.arrayIdx]); + if (visibleChildren.length > 1) { + return; // This is the common ancestor of visible children + } + visArray[node.arrayIdx] = false; + visibleChildren.forEach((child) => hideNodeIfOnlyOneChildVisible(visArray, child)); +}; + /* calcVisibility USES: inView: attribute of phyloTree.nodes, but accessible through redux.tree.nodes[idx].shell.inView @@ -154,6 +169,9 @@ export const calcVisibility = (tree, controls, dates) => { for (let i = 0; i < idxsOfFilteredTips.length; i++) { makeParentVisible(filtered, tree.nodes[idxsOfFilteredTips[i]]); } + /* Recursivley hide ancestor nodes that are not the last common + * ancestor of selected nodes, starting from the root of the tree */ + hideNodeIfOnlyOneChildVisible(filtered, tree.nodes[0]); } /* intersect the various arrays contributing to visibility */ const visibility = tree.nodes.map((node, idx) => { From 727d87a86c4ac7162874dc574085b08598e125bb Mon Sep 17 00:00:00 2001 From: Jover Date: Mon, 21 Dec 2020 10:55:46 -0800 Subject: [PATCH 2/2] Rename function `hideNodeIfOnlyONeChildVisbile` Renamed to `hideNodesAboveVisibleCommonAncestor` to be clearer purpose of the function. --- src/util/treeVisibilityHelpers.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/util/treeVisibilityHelpers.js b/src/util/treeVisibilityHelpers.js index 6340982b7..4d7b313de 100644 --- a/src/util/treeVisibilityHelpers.js +++ b/src/util/treeVisibilityHelpers.js @@ -96,7 +96,7 @@ const makeParentVisible = (visArray, node) => { /* Recursively hide nodes that do not have more than one child node in * the param visArray. * Relies on visArray having been updated by `makeParentVisible` */ -const hideNodeIfOnlyOneChildVisible = (visArray, node) => { +const hideNodesAboveVisibleCommonAncestor = (visArray, node) => { if (!node.hasChildren) { return; // Terminal node without children } @@ -105,7 +105,7 @@ const hideNodeIfOnlyOneChildVisible = (visArray, node) => { return; // This is the common ancestor of visible children } visArray[node.arrayIdx] = false; - visibleChildren.forEach((child) => hideNodeIfOnlyOneChildVisible(visArray, child)); + visibleChildren.forEach((child) => hideNodesAboveVisibleCommonAncestor(visArray, child)); }; /* calcVisibility @@ -171,7 +171,7 @@ export const calcVisibility = (tree, controls, dates) => { } /* Recursivley hide ancestor nodes that are not the last common * ancestor of selected nodes, starting from the root of the tree */ - hideNodeIfOnlyOneChildVisible(filtered, tree.nodes[0]); + hideNodesAboveVisibleCommonAncestor(filtered, tree.nodes[0]); } /* intersect the various arrays contributing to visibility */ const visibility = tree.nodes.map((node, idx) => {