-
Notifications
You must be signed in to change notification settings - Fork 166
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
[feature] Improve smoothness of temporalWindow animation over short time frames #920
[feature] Improve smoothness of temporalWindow animation over short time frames #920
Conversation
3c0ae14
to
a95b7ae
Compare
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.
Thanks @hydrosquall - the animation is much smoother here 😄
See line comments below as well as:
-
Two trees don't work appropriately (the x-axis coords can get confusing here) -- e.g. load two ncov trees (see localhost link in line-comment) and modulate the date sliders (regression).
-
Sliding the max-date slider to the end doesn't clear the grey shading (regression).
-
Clearing the max date filter (via the "x" in the info box in the header of the page) doesn't clear the grey shading (regression).
-
Sometimes, when the animation is "reset" (i.e. stopped), the grey regions remain, when they should disappear (regression).
-
Behavior at the start of
/zika
animation is weird when the left grey area comes into view. Didn't happen with the ncov dataset. -
Sometimes (happens for me with /zika, but not /ncov) the grey areas remain at the end of the animation (regression).
-
Performance will need to be tested (but wouldn't expect this to add much overhead)
The animation behavior isn't easy in auspice, so don't be put off by all these regressions!
@@ -334,17 +342,20 @@ export const addGrid = function addGrid() { | |||
timerEnd("addGrid"); | |||
}; | |||
|
|||
|
|||
export const removeTemporalSlice = function removeTemporalSlice() { |
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.
This removed function is still set as a prototype in phyloTree.js
and called by the function modifySVGInStages
. This will result in a complete app crash when (e.g.) the tree layout it changed
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.
Ah, I didn't realize this was used on the outside, I should have checked given that it was export
ed. I'll bring this back.
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.
I renamed these to hideTemporalSlice
to make it clear that no DOM is being removed, just that visibility is toggled.
@@ -188,7 +196,7 @@ const computeYGridPoints = (ymin, ymax) => { | |||
*/ | |||
export const addGrid = function addGrid() { | |||
const layout = this.layout; | |||
addSVGGroupsIfNeeded(this.groups, this.svg); | |||
addSVGGroupsIfNeeded(this.groups, this.svg, this.temporalWindow); |
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.
addSVGGroupsIfNeeded
still takes only 2 arguments, but 3 are provided here
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.
I had tried an alternative solution which had involved modifying the signature, and accidentally left this in - good catch.
.attr("width", totalWidth) | ||
.attr("fill", fill) | ||
.transition('temporalWindowTransition') | ||
.attr("transform", `translate(${translateX_start},0)`); |
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.
Cool! Am i right in understanding that on each update, we modify the rect's position via the transform attr, and in-between transforms the transition smooths things?
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.
Correct, this is in contrast to the current behavior of creating a new rectangle on every frame.
Alternately, we have the option of fixing the position, and instead modifying the width on each frame. However, modifying position is cheaper to animate than modifying the width.
.attr("x", rightHandTree ? xWindow[0] : 0) | ||
.attr("width", rightHandTree ? totalWidth-xWindow[0]: xWindow[0]) | ||
.attr("y", 0) | ||
const xEnd_start = rightHandTree ? totalWidth - xWindow[0] : xWindow[0]; // ending X coordinate of the "start" rectangle |
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 important to address the case of two-trees, where the x-axis is flipped. Currently (e.g.) localhost:4000/ncov/2020-02-11:ncov/2020-02-09?dmax=2020-01-26&m=num_date is broken as somewhere in this PR (probably not this line) we are assuming x-values are left-to-right
a95b7ae
to
6ea60d0
Compare
…en appearing and disappearing, replace visibility with opacity
Thanks for the thorough feedback @jameshadfield ! I've moved your comments into a checklist for you or another reviewer to cross-validate my initial results. I believe the latest changes solve all the regressions identified, but please let me know if you end up finding a different result in your local testing.
I didn't know how to test this earlier, but I opened this up side-by-side with
This should be fixed as of the latest version, I added code to hide the regions if they don't pass the "minimum width" test.
I think this should be fixed now.
I wasn't able to reproduce this, can you let me know if you still observe this one?
I suspect this was one of the animations was animating into its initial position instead of appearing instantly, I've added some custom logic to avoid doing the interpolation when the left gray area first appears. Let me know if this reoccurs.
I think the issue was related to a change in the visibility toggling logic, I think it should be better now (I've been testing in both datasets).
To handle the edge cases at the start/end of the animation, I had to animate width for the If it's too much of a slowdown, there's another technique we can try (applying a clip path and using a fixed width panel). The problem is that we would need to figure out when to regenerate the clip path, so didn't want to pursue that approach until it becomes absolutely necessary. I didn't notice a performance degradation on the |
0b10c33
to
27bbba1
Compare
Quick note to say thanks for this & that I'll try to test / merge this as soon as possible! |
No worries/rush @jameshadfield ! Let me know if there are issues and I'm happy to go through whatever rounds of iteration are necessary. |
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.
Have tested this (reasonably) thoroughly and think it's great -- thankyou! I'll try to release this in a new version of auspice ASAP, which we'll release to dev.nextstrain.org for ~24hours of further testing before going live. Thanks again!
Motivation
Changes
d3.transition
instead of destroying/creating the rectangles on every iteration ofaddTemporalSlice
: https://a.cl.ly/jkuKeJn7Testing
Feel free to test with other layouts or datasets, I tested exclusively with
zika
andnkov
using the links provided by @trvrb here.