Comments (9)
So the problem with applying zero-duration transitions immediately is that:
.transition()
.duration(0)
// transition operations
would be different to:
.transition()
// transition operations
.duration(0)
?
Would it be possible to apply all the "pending" transition operations immediately in the latter case?
Another problem is that I suppose in theory a subsequent non-zero .duration()
call should override previous ones? But I guess zero-durations could be a special case.
from d3.
That's an interesting thought. I'd guess the likelihood of setting the duration more than once is low, so it might be reasonable to apply those pending transitions immediately. Something like this:
.transition()
// operators pending
.duration(0) // pending operators applied immediately
// subsequent operators applied immediately
.duration(500)
// subsequent operators transition over 500ms
That's perhaps a bit complicated, but at least it's predictable. A simpler option would be to ignore attempts to set the duration to non-zero, after setting it to zero.
.transition()
// operators pending
.duration(0) // pending operators applied immediately
// subsequent operators applied immediately
.duration(500) // ignored
// subsequent operators applied immediately
from d3.
How about throwing an error if multiple durations are set, instead of ignoring? Conceptually it seems like a particular transition should only have a single duration. If two durations are required, then it just means an extra line to call .transition()
again to create a separate one.
Perhaps there is a benefit to declaring multiple transitions in one chain though?
from d3.
Well, the default duration is set internally when the transition is created, using duration(250)
.
I don't generally like throwing errors because they end up being seen by the user… as far as user interfaces go, it's better to degrade gracefully with reasonable behavior than to crash. It wouldn't hurt to console.warn
, assuming that's available on the target platform.
You can't derive a new transition from an existing transition at the moment. You can derive multiple transitions from the same selection, though, so it wouldn't be hard to add. But the important thing is that they can't be concurrent—only one transition gets run on any given node at any given time. You can, however, schedule multiple non-overlapping transitions using delays, as the stream/stack example does.
from d3.
Jason came up with a neat wrapper solution:
function transition(selection, duration) {
return duration ? selection.transition(duration) : duration;
}
We could potentially incorporate the same behavior in selection.transition(duration)
, where it returns the selection is the duration is zero. Of course, this doesn't handle the case where the duration is zero but the delay is non-zero, or the duration is specified as a function.
Another thought is to have an explicit start()
method for transitions, but that's rather tedious for the common case. On the other hand, maybe transitions still start by default, but a start()
method could be used to force zero-delay and zero-duration transitions to be applied immediately. (The method would have no effect if there is a delay or duration.)
from d3.
I like the idea of start()
being an optional way to force immediate application for the relatively rare scenarios.
I was thinking that another option could be to require transitions be added via call
:
selection.call(d3.transition().attr("foo", 1).delay(0).duration(0));
This seems too verbose though. I prefer start()
:-)
from d3.
I like the idea of an optional start
method, but the other consideration is whether there are potentially multiple transitions you create as part of responding to an event (or a timer), and you want to start them all. So, starting a specific transition doesn't seem like a great solution, because then you have to call start
on multiple transitions (or risk some of your transitions starting, out of sync with others).
Perhaps the right solution is a way to force an immediate invocation of d3_timer_step
, after the event is handled. It'd be nice if this happened automatically as part of the normal event cycle, but that doesn't handle other cases where you might want to force an invocation of the timer… Or at least, it'd be good if calling d3_timer_step
multiple times as part of the same event cycle had no effect.
from d3.
Sounds like a good way to handle it!
The only other consideration I can think of is that perhaps only immediate transition callbacks should be handled when the immediate invocation of d3_timer_step
is forced, as anything with a non-zero delay should really be handled in the next event loop step (in case the setup phase takes several milliseconds since non-zero delay callbacks were registered, in which case you probably want to give the event loop some breathing space).
It wasn't too hard to implement so I had a go in #126 (minus the automatic firing for event handlers), let me know what you think :-) I think calling multiple times in the same event handler shouldn't have any effect.
from d3.
Added in 1.15.0 as d3.timer.flush()
.
from d3.
Related Issues (20)
- Security vulnerability issues HOT 1
- Add harmonic mean and geometric mean HOT 1
- API doc links in example notebooks still point to README HOT 5
- searching “range” or “extent” doesn't find the expected page
- How to build this chart
- d3.min and d3.least don't always ignore nulls HOT 4
- Adopt a monorepo
- grid color not applied for the left axis column number 1
- cycle at stratify err
- D3 graph into Flutter web
- Remember ui State across reloads HOT 1
- Nodes arrange
- Replace Math.random() with crypto function HOT 4
- Non english language texts being cut off HOT 4
- Zoom and click on d3 Sankey
- What does mean the sample code?
- #How to remove spaces between bar in d3.js grouped bar chart.
- d3 hierarchy: node visibility parameter to control either to show node in visualization or hide it.
- the wrong parameter name at Binning data of d3-array documentation
- Upgrading from v3 to v7 requires additional renders for my custom gauge
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from d3.