-
Notifications
You must be signed in to change notification settings - Fork 168
Ignore hidden nodes in domain #1951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
jameshadfield
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested using https://nextstrain-s-nextstrain-wqnhof.herokuapp.com/community/victorlin/nextstrain-test@1d26348/ebola/all-outbreaks and it works well. Note that radial & unrooted layouts aren't improved by this PR - up to you whether you want to address them here or leave them unchanged.
| /* In rectangular mode, if the tree has been zoomed, leave some room to display the (clade's) root branch */ | ||
| if (this.layout==="rect" && this.zoomNode.n.arrayIdx!==0) { | ||
| // FIXME: is this right? | ||
| if (this.layout==="rect" && this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the intention of this change? Is the change meant for non-rectangular trees only (if so, I'd add a this.layout!=='rect' conditional)? Or were you intending
if (this.layout==="rect" && (this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden"))which would add LHS padding when the root was hidden.
P.S. This entire aspect of Auspice is very ad-hoc and could use broader improvements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's meant for rectangular trees only, so yes to your code snippet. I forgot to test other layouts, will take a look to see if it's easy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the condition to your code snippet:
| if (this.layout==="rect" && (this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden")) { |
b757680 to
29b03a9
Compare
| /* In rectangular mode, if the tree has been zoomed, leave some room to display the (clade's) root branch */ | ||
| if (this.layout==="rect" && this.zoomNode.n.arrayIdx!==0) { | ||
| // FIXME: is this right? | ||
| if (this.layout==="rect" && this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the condition to your code snippet:
| if (this.layout==="rect" && (this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Started addressing radial layout in 29b03a9 but still needs some work.
Offset from the smallest visible branch depth rather than the depth of the root node since it may be hidden.
Offset from the smallest visible branch depth rather than the depth of the root node since it may be hidden.
29b03a9 to
b4d8081
Compare
|
@jameshadfield could you help with me radial and unrooted layouts if you get the chance? I don't quite understand how they work, but would like to sort them out in this PR if it doesn't require too many code changes. I've pushed what I have so far. Rect works well, radial is half-baked, and unrooted looks the same as before. |
|
Revisiting this afresh with new eyes after a couple of months. If we take a dataset such as your ebola all-outbreaks one, the aim of this PR is to take the current view (screenshot) and instead restrict the x-domain to (roughly) the dashed box:
Focusing on the west-african outbreak, we can see the subtlety involved in #1950 which stated "Hidden nodes are considered in calculation of X domain". The hidden node contributes to the x-domain in the sense that it defines the origin value for the visible branch. (We don't want to hide
This PR's implementation (for rect trees) calculates the domain by excluding hidden nodes, i.e. considering the west-african subtree the domain would start at around 2007.5, and then 5% of the domain span is added to the LHS to accomodate branch labels. This seems appropriate but I'd go further and change the rendering of branches which are children of hidden nodes so that they no longer render their stem, which this patch will do: diff --git a/src/components/tree/phyloTree/renderers.ts b/src/components/tree/phyloTree/renderers.ts
index 35128add..2d3503bc 100644
--- a/src/components/tree/phyloTree/renderers.ts
+++ b/src/components/tree/phyloTree/renderers.ts
@@ -330,7 +330,11 @@ export const drawBranches = function drawBranches(this: PhyloTreeType): void {
})
.style("stroke-linecap", "round")
.style("stroke-width", (d) => d['stroke-width'] || params.branchStrokeWidth)
- .style("visibility", getBranchVisibility)
+ .style("visibility", (d) => {
+ // hide the stem between a hidden parent and a visible child
+ if (getBranchVisibility(d.n.parent.shell)==='hidden') return 'hidden'
+ return getBranchVisibility(d)
+ })
.style("cursor", (d) => d.visibility === NODE_VISIBLE ? "pointer" : "default")
.style("pointer-events", "auto")
.on("mouseover", this.callbacks.onBranchHover)
which results in a tree like so:
Note: this patch is a proof-of-principle. There are bugs when you interact with the tree (zooming, layout changes) that we need to track down. Alternatively you can filter the nodes (instead of hiding the stems), which may or may not be better. In radial trees, the above patch improves things a bunch but the tee-paths are still incorrectly calculated, most obviously seen on branches which sweep a large
This can be fixed by updating the diff --git a/src/components/tree/phyloTree/layouts.ts b/src/components/tree/phyloTree/layouts.ts
index 07e4141b..873e7815 100644
--- a/src/components/tree/phyloTree/layouts.ts
+++ b/src/components/tree/phyloTree/layouts.ts
@@ -513,7 +522,8 @@ export const mapToScreen = function mapToScreen(this: PhyloTreeType): void {
}
});
} else if (this.layout==="radial") {
- const offset = this.nodes[0].depth;
+ const visibleNodes = this.nodes.filter((d) => getBranchVisibility(d) === "visible");
+ const offset = Math.min(...visibleNodes.map((d) => d.depth));
const stem_offset_radial = this.nodes.map((d) => {return (0.5*(stemParent(d.n).shell["stroke-width"] - d["stroke-width"]) || 0.0);});
this.nodes.forEach((d, i) => {
d.branch =[For unrooted layouts I would be very careful with changes to the (x) domain. There is an inherent conflict here as trees are always rooted as per the JSON format, and hidden nodes somewhat depend on the tree being rooted, but we have an unrooted layout. Specifically, ignoring basal nodes in unrooted layouts is going to shift the (visible) subclades closer together thus making them seem genetically/temporally more closely related than they are. My advice would be to not change them as part of this PR (beyond hiding branches, as discussed above). A few other things I noticed while exploring this - all of which are beyond this PR, so I'll turn them into issues afterwards:
/* In rectangular mode, if the tree has been zoomed, leave some room to display the (clade's) root branch */
if (this.layout==="rect" && (this.zoomNode.n.arrayIdx!==0 || getBranchVisibility(this.zoomNode) === "hidden")) {
minX -= (maxX-minX)/20; // 5%
}
|





Description of proposed changes
draft; see linked issue for context
Related issue(s)
Checklist