From cc5f80a27d0b5847d7e153e0bbd9bfb7a8e3fadb Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 26 Feb 2024 22:39:57 -0500 Subject: [PATCH] Hide leaf nodes --- lib/src/components/TreePanel/TreeNodeMenu.tsx | 16 ++++- .../components/TreePanel/renderTreeCanvas.ts | 1 + lib/src/model.ts | 64 ++++++++++--------- 3 files changed, 47 insertions(+), 34 deletions(-) diff --git a/lib/src/components/TreePanel/TreeNodeMenu.tsx b/lib/src/components/TreePanel/TreeNodeMenu.tsx index 17ddd5df..2671cfa1 100644 --- a/lib/src/components/TreePanel/TreeNodeMenu.tsx +++ b/lib/src/components/TreePanel/TreeNodeMenu.tsx @@ -17,7 +17,7 @@ const TreeMenu = observer(function ({ model: MsaViewModel onClose: () => void }) { - const { selectedStructures, collapsed, structures } = model + const { selectedStructures, collapsed, collapsed2, structures } = model const nodeDetails = node ? model.getRowData(node.name) : undefined return ( @@ -56,11 +56,21 @@ const TreeMenu = observer(function ({ { - model.toggleCollapsed(node.id) + if (collapsed.includes(node.id)) { + model.toggleCollapsed(node.id) + } else { + if (node.id.endsWith('-leafnode')) { + model.toggleCollapsed2(`${node.id}`) + } else { + model.toggleCollapsed2(`${node.id}-leafnode`) + } + } onClose() }} > - {collapsed.includes(node.id) ? 'Show node' : 'Hide node'} + {collapsed.includes(node.id) || collapsed2.includes(node.id) + ? 'Show node' + : 'Hide node'} {structures[node.name]?.map(entry => diff --git a/lib/src/components/TreePanel/renderTreeCanvas.ts b/lib/src/components/TreePanel/renderTreeCanvas.ts index 6d1d5aae..4e99908e 100644 --- a/lib/src/components/TreePanel/renderTreeCanvas.ts +++ b/lib/src/components/TreePanel/renderTreeCanvas.ts @@ -90,6 +90,7 @@ export function renderNodeBubbles({ } = node const { branchset, id = '', name = '' } = data if ( + !id.endsWith('-leafnode') && branchset.length && y > offsetY - extendBounds && y < offsetY + by + extendBounds diff --git a/lib/src/model.ts b/lib/src/model.ts index f4545bf7..ac84b4ac 100644 --- a/lib/src/model.ts +++ b/lib/src/model.ts @@ -92,6 +92,21 @@ export type BasicTrack = IBoxTrack | ITextTrack */ function x() {} // eslint-disable-line @typescript-eslint/no-unused-vars +function reparseTree(tree: NodeWithIds): NodeWithIds { + return { + ...tree, + branchset: tree.branchset.map(r => + r.branchset.length + ? reparseTree(r) + : { + branchset: [r], + id: `${r.id}-leafnode`, + name: `${r.name}-hidden`, + }, + ), + } +} + export type DialogComponentType = // eslint-disable-next-line @typescript-eslint/no-explicit-any | React.LazyExoticComponent> @@ -239,12 +254,7 @@ const model = types */ collapsed: types.array(types.string), - /** - * #property - * array of leaf nodes that are 'hidden', similar to collapsed but for leaf nodes - */ - hidden: types.array(types.string), - + collapsed2: types.array(types.string), /** * #property * focus on particular subtree @@ -426,20 +436,6 @@ const model = types self.drawTree = arg }, - /** - * #action - */ - hideNode(arg: string) { - self.hidden.push(arg) - }, - - /** - * #action - */ - clearHidden() { - self.hidden.clear() - }, - /** * #action */ @@ -451,6 +447,16 @@ const model = types } }, + /** + * #action + */ + toggleCollapsed2(node: string) { + if (self.collapsed2.includes(node)) { + self.collapsed2.remove(node) + } else { + self.collapsed2.push(node) + } + }, /** * #action */ @@ -613,7 +619,7 @@ const model = types * #getter */ get _tree(): NodeWithIds { - return self.data.tree + const ret = self.data.tree ? generateNodeIds(parseNewick(self.data.tree)) : this.MSA?.getTree() || { noTree: true, @@ -621,6 +627,7 @@ const model = types id: 'empty', name: 'empty', } + return reparseTree(ret) }, /** * #getter @@ -659,18 +666,13 @@ const model = types } } - if (self.collapsed.length) { - self.collapsed + if (self.collapsed.length || self.collapsed2.length) { + ;[...self.collapsed, ...self.collapsed2] .map(collapsedId => hier.find(node => node.data.id === collapsedId)) .filter(notEmpty) .map(node => collapse(node)) } - if (self.hidden.length) { - self.hidden - .map(hiddenId => hier.find(node => node.data.id === hiddenId)) - .filter(notEmpty) - .map(node => filterHiddenLeafNodes(node.parent, node.id)) - } + return hier }, /** @@ -1093,7 +1095,7 @@ const model = types relativePxToBp(rowName: string, position: number) { const { rowNames, rows } = self const index = rowNames.indexOf(rowName) - if (index !== -1) { + if (index !== -1 && rows[index]) { const row = rows[index][1] let k = 0 @@ -1115,7 +1117,7 @@ const model = types relativePxToBp2(rowName: string, position: number) { const { rowNames, rows } = self const index = rowNames.indexOf(rowName) - if (index !== -1) { + if (index !== -1 && rows[index]) { const row = rows[index][1] let k = 0