Skip to content

Commit

Permalink
Merge pull request #1753 from nextstrain/james/fix-terminal-muts
Browse files Browse the repository at this point in the history
Restore terminal branch hover/click behaviour
  • Loading branch information
jameshadfield authored Feb 20, 2024
2 parents f025839 + e6c461c commit 68700b5
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 23 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Changelog

## version 2.52.0 - 2024/02/09

* Bugfix: Restore the intended behaviour when hovering or clicking on terminal branches. ([#1753](https://github.com/nextstrain/auspice/pull/1753))

## version 2.52.0 - 2024/02/09

* Sidebar filtering now contains all non-continuous metadata defined across the tree (i.e. all data within `node.node_attrs`). The traits listed in `meta.filters` are now only used to determine which filters to list in the footer of the page. ([#1743](https://github.com/nextstrain/auspice/pull/1743))
* The interaction between strain-selected modals and the corresponding strain-filter has been improved. We now preserve the strain filter state present before the node was clicked. ([#1749](https://github.com/nextstrain/auspice/issues/1749))
Expand Down
18 changes: 10 additions & 8 deletions src/components/tree/infoPanels/click.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,31 +247,33 @@ const NodeClickedPanel = ({selectedNode, nodes, clearSelectedNode, colorings, ob
const panelStyle = { ...infoPanelStyles.panel};
panelStyle.maxHeight = "70%";
const isTerminal = !node.hasChildren;
const title = isTerminal ?
const isTip = !selectedNode.isBranch;

const title = isTip ?
node.name :
isTerminal ?
`Branch leading to ${node.name}` :
"Internal branch";

return (
<div style={infoPanelStyles.modalContainer} onClick={() => clearSelectedNode(selectedNode, isTerminal)}>
<div style={infoPanelStyles.modalContainer} onClick={() => clearSelectedNode(selectedNode)}>
<div className={"panel"} style={panelStyle} onClick={(e) => stopProp(e)}>
<StrainName>{title}</StrainName>
<table>
<tbody>
{!isTerminal && item(t("Number of terminal tips"), node.fullTipCount)}
{isTerminal && <VaccineInfo node={node} t={t}/>}
{!isTip && item(t("Number of terminal tips"), node.fullTipCount)}
{isTip && <VaccineInfo node={node} t={t}/>}
<SampleDate isTerminal={isTerminal} node={node} t={t}/>
{!isTerminal && item("Node name", node.name)}
{isTerminal && <PublicationInfo node={node} t={t}/>}
{!isTip && item("Node name", node.name)}
{isTip && <PublicationInfo node={node} t={t}/>}
{getTraitsToDisplay(node).map((trait) => (
<Trait node={node} trait={trait} colorings={colorings} key={trait} isTerminal={isTerminal}/>
))}
{isTerminal && <AccessionAndUrl node={node}/>}
{isTip && <AccessionAndUrl node={node}/>}
{item("", "")}
</tbody>
</table>
<MutationTable node={node} geneSortFn={geneSortFn} isTip={isTerminal} observedMutations={observedMutations}/>
<MutationTable node={node} geneSortFn={geneSortFn} isTip={isTip} observedMutations={observedMutations}/>
<p style={infoPanelStyles.comment}>
{t("Click outside this box to go back to the tree")}
</p>
Expand Down
5 changes: 3 additions & 2 deletions src/components/tree/infoPanels/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,12 @@ const HoverInfoPanel = ({
t
}) => {
if (!selectedNode) return null
const node = selectedNode.n;
const node = selectedNode.node.n; // want the redux node, not the phylo node
const idxOfInViewRootNode = getIdxOfInViewRootNode(node);

return (
<Container node={node} panelDims={panelDims}>
{node.hasChildren===false ? (
{selectedNode.isBranch===false ? (
<>
<StrainName name={node.name}/>
<VaccineInfo node={node} t={t}/>
Expand Down
16 changes: 10 additions & 6 deletions src/components/tree/reactD3Interface/callbacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export const onTipHover = function onTipHover(d) {
this.state.treeToo;
phylotree.svg.select("#"+getDomId("tip", d.n.name))
.attr("r", (e) => e["r"] + 4);
this.setState({hoveredNode: d});
this.setState({
hoveredNode: {node: d, isBranch: false}
});
};

export const onTipClick = function onTipClick(d) {
Expand All @@ -22,7 +24,7 @@ export const onTipClick = function onTipClick(d) {
/* The order of these two dispatches is important: the reducer handling
`SELECT_NODE` must have access to the filtering state _prior_ to these filters
being applied */
this.props.dispatch({type: SELECT_NODE, name: d.n.name, idx: d.n.arrayIdx});
this.props.dispatch({type: SELECT_NODE, name: d.n.name, idx: d.n.arrayIdx, isBranch: false});
this.props.dispatch(applyFilter("add", strainSymbol, [d.n.name]));
};

Expand All @@ -46,7 +48,9 @@ export const onBranchHover = function onBranchHover(d) {
}

/* Set the hovered state so that an info box can be displayed */
this.setState({hoveredNode: d});
this.setState({
hoveredNode: {node: d, isBranch: true}
});
};

export const onBranchClick = function onBranchClick(d) {
Expand All @@ -56,7 +60,7 @@ export const onBranchClick = function onBranchClick(d) {
/* if a branch was clicked while holding the shift key, we instead display a node-clicked modal */
if (window.event.shiftKey) {
// no need to dispatch a filter action
this.props.dispatch({type: SELECT_NODE, name: d.n.name, idx: d.n.arrayIdx})
this.props.dispatch({type: SELECT_NODE, name: d.n.name, idx: d.n.arrayIdx, isBranch: true})
return;
}

Expand Down Expand Up @@ -120,8 +124,8 @@ export const onTipLeave = function onTipLeave(d) {
};

/* clearSelectedNode when clicking to remove the node-selected modal */
export const clearSelectedNode = function clearSelectedNode(selectedNode, isTerminal) {
if (isTerminal) {
export const clearSelectedNode = function clearSelectedNode(selectedNode) {
if (!selectedNode.isBranch) {
/* perform the filtering action (if necessary) that will restore the
filtering state of the node prior to the selection */
if (!selectedNode.existingFilterState) {
Expand Down
5 changes: 1 addition & 4 deletions src/components/tree/tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ class Tree extends React.Component {
/* pressing the escape key should dismiss an info modal (if one exists) */
this.handlekeydownEvent = (event) => {
if (event.key==="Escape" && this.props.selectedNode) {
this.clearSelectedNode(
this.props.selectedNode,
!this.props.tree.nodes[this.props.selectedNode.idx].hasChildren
);
this.clearSelectedNode(this.props.selectedNode);
}
};
}
Expand Down
2 changes: 1 addition & 1 deletion src/reducers/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ const Controls = (state: ControlsState = getDefaultControlsState(), action): Con
const existingFilterInfo = (state.filters?.[strainSymbol]||[]).find((info) => info.value===action.name);
const existingFilterState = existingFilterInfo === undefined ? null :
existingFilterInfo.active ? 'active' : 'inactive';
return {...state, selectedNode: {name: action.name, idx: action.idx, existingFilterState}};
return {...state, selectedNode: {name: action.name, idx: action.idx, existingFilterState, isBranch: action.isBranch}};
}
case types.DESELECT_NODE: {
return {...state, selectedNode: null}
Expand Down

0 comments on commit 68700b5

Please sign in to comment.