This commit allows you to reselect elements with scheduled transitions
and redefine associated tweens; this enables "post-selection" to
customize the behavior of reusable components undergoing transitions,
such as an axis. This commit also makes it much easier to sequence
transitions.
Previously, a transition's tweens were stored privately by the
transition and could only be accessed through the transition. This
made it impossible to modify transitions created by components: the
transition is not accessible externally, and cannot be reselected from
the document. Consider the following snippet:
If `g` is a selection, then this code alters the appearance of the
axis as expected. However, if `g` is a transition, then
transition.selectAll creates a new concurrent transition, and now
multiple tweens compete to set the "dy" attribute. Oy!
Under the new design, an element's scheduled tweens are stored
semi-privately on the node (in the existing node.__transition__).
Transition parameters can thus be reselected and modified by
transitions that share the same id. If you now reselect a
transitioning element, you modify the transition rather creating a
competing transition; this should be less surprising and allow greater
control.
As a side-effect of this change, it is no longer possible to schedule
concurrent transitions on the same element, even with the same id:
only one transition may be active on a given element at any time.
(Note that you can still schedule multiple future transitions on the
same element, and concurrent transitions on different elements.) For
example, you could previously schedule overlapping transitions with
different easing functions, delays or durations, provided you were
careful to avoid conflict. This seems like a relatively obscure
use-case compared to modifying a transition, so I believe this is a
reasonable change.
This commit also changes transition.transition, such that the returned
transition starts at the end of the originating transition, rather
than overlapping. This makes it much easier to schedule sequenced
transitions without the complexity of transition.each("end") and
d3.select(this).
Also, transitions are now simply arrays of nodes, consistent with selections!
Here's a code snippet showing sequenced transitions:
<<
For
example, you could previously schedule overlapping transitions with
different easing functions, delays or durations, provided you were
careful to avoid conflict. This seems like a relatively obscure
use-case compared to modifying a transition, so I believe this is a
reasonable change.
I'm using that to dynamically/conditionally rescale a moving sparkline
based on min/max of dataset in view while also moving the line to the
left (scrolling)
So if this breaks it, how would we go about doing this when we need to
apply rescale and movement in overlapping transitions?
graph.selectAll("path")
.data([viewData]) // set the new data
.attr("transform", "translate(" + x(1) + ")")
.transition()
.duration(1000)
.attr("d", lineAdj)
.transition()
.ease("linear")
.duration(1000)
.attr("transform", "translate(" + x(0) + ")")e
> This commit allows you to reselect elements with scheduled transitions
> and redefine associated tweens; this enables "post-selection" to
> customize the behavior of reusable components undergoing transitions,
> such as an axis. This commit also makes it much easier to sequence
> transitions.
> Previously, a transition's tweens were stored privately by the
> transition and could only be accessed through the transition. This
> made it impossible to modify transitions created by components: the
> transition is not accessible externally, and cannot be reselected from
> the document. Consider the following snippet:
> If `g` is a selection, then this code alters the appearance of the
> axis as expected. However, if `g` is a transition, then
> transition.selectAll creates a new concurrent transition, and now
> multiple tweens compete to set the "dy" attribute. Oy!
> Under the new design, an element's scheduled tweens are stored
> semi-privately on the node (in the existing node.__transition__).
> Transition parameters can thus be reselected and modified by
> transitions that share the same id. If you now reselect a
> transitioning element, you modify the transition rather creating a
> competing transition; this should be less surprising and allow greater
> control.
> As a side-effect of this change, it is no longer possible to schedule
> concurrent transitions on the same element, even with the same id:
> only one transition may be active on a given element at any time.
> (Note that you can still schedule multiple future transitions on the
> same element, and concurrent transitions on different elements.) For
> example, you could previously schedule overlapping transitions with
> different easing functions, delays or durations, provided you were
> careful to avoid conflict. This seems like a relatively obscure
> use-case compared to modifying a transition, so I believe this is a
> reasonable change.
> This commit also changes transition.transition, such that the returned
> transition starts at the end of the originating transition, rather
> than overlapping. This makes it much easier to schedule sequenced
> transitions without the complexity of transition.each("end") and
> d3.select(this).
> Also, transitions are now simply arrays of nodes, consistent with selections!
> Here's a code snippet showing sequenced transitions:
> So if this breaks it, how would we go about doing this when we need to
> apply rescale and movement in overlapping transitions?
In your case, I'd recommend one transition on a parent <g> element to
translate the sparkline (or sparklines), and a child transition on the
path elements to change the path data.
Alternatively you could use a single transition with linear easing. If
you wanted, you could define a custom attr tween to add cubic easing
to just the d attribute.
On Fri, Oct 5, 2012 at 2:15 PM, Mike Bostock <mbost...@gmail.com> wrote:
>> So if this breaks it, how would we go about doing this when we need to
>> apply rescale and movement in overlapping transitions?
> In your case, I'd recommend one transition on a parent <g> element to
> translate the sparkline (or sparklines), and a child transition on the
> path elements to change the path data.
> Alternatively you could use a single transition with linear easing. If
> you wanted, you could define a custom attr tween to add cubic easing
> to just the d attribute.
On Fri, Oct 5, 2012 at 2:23 PM, marc fawzi <marc.fa...@gmail.com> wrote:
> The single transition with linear easing worked great. Just tried it.
> No idea why I thought I needed two transitions.
> Thanks Mike, and the proposal sounds like it will refine things.
> On Fri, Oct 5, 2012 at 2:15 PM, Mike Bostock <mbost...@gmail.com> wrote:
>>> So if this breaks it, how would we go about doing this when we need to
>>> apply rescale and movement in overlapping transitions?
>> In your case, I'd recommend one transition on a parent <g> element to
>> translate the sparkline (or sparklines), and a child transition on the
>> path elements to change the path data.
>> Alternatively you could use a single transition with linear easing. If
>> you wanted, you could define a custom attr tween to add cubic easing
>> to just the d attribute.
On Fri, Oct 05, 2012 at 02:03:39PM -0700, Mike Bostock wrote:
> g.select(".x.axis")
> .call(xAxis)
> .selectAll("text")
> .attr("dy", null);
> If `g` is a selection, then this code alters the appearance of the
> axis as expected. However, if `g` is a transition, then
> transition.selectAll creates a new concurrent transition, and now
> multiple tweens compete to set the "dy" attribute. Oy!
Excellent! So the snippet above is an example of overriding the default
d3.svg.axis "dy" attribute on the text elements, which was previously
impossible to do properly if there was a transition occurring, but will
work with this proposal.
This will make using transitions with reusable charts and components
much easier.
> As a side-effect of this change, it is no longer possible to schedule
> concurrent transitions on the same element, even with the same id:
> only one transition may be active on a given element at any time.
> (Note that you can still schedule multiple future transitions on the
> same element, and concurrent transitions on different elements.) For
> example, you could previously schedule overlapping transitions with
> different easing functions, delays or durations, provided you were
> careful to avoid conflict. This seems like a relatively obscure
> use-case compared to modifying a transition, so I believe this is a
> reasonable change.
I think it's quite rare for this to really be necessary. In d3-parsets
[1], the ribbon paths can transition independently in both x- and
y-directions, for example if you drag a category it will animate all the
other categories bouncing into their new positions, and if you quickly
reorder the dimensions too, they will simultaneously animate into their
new y-positions. Even this wouldn't be affected though, since these
independent transitions are scheduled on different elements.
> This commit also changes transition.transition, such that the returned
> transition starts at the end of the originating transition, rather
> than overlapping. This makes it much easier to schedule sequenced
> transitions without the complexity of transition.each("end") and
> d3.select(this).
> This commit allows you to reselect elements with scheduled transitions > and redefine associated tweens; this enables "post-selection" to > customize the behavior of reusable components undergoing transitions, > such as an axis. This commit also makes it much easier to sequence > transitions.
> Previously, a transition's tweens were stored privately by the > transition and could only be accessed through the transition. This > made it impossible to modify transitions created by components: the > transition is not accessible externally, and cannot be reselected from > the document. Consider the following snippet:
> If `g` is a selection, then this code alters the appearance of the > axis as expected. However, if `g` is a transition, then > transition.selectAll creates a new concurrent transition, and now > multiple tweens compete to set the "dy" attribute. Oy!
> Under the new design, an element's scheduled tweens are stored > semi-privately on the node (in the existing node.__transition__). > Transition parameters can thus be reselected and modified by > transitions that share the same id. If you now reselect a > transitioning element, you modify the transition rather creating a > competing transition; this should be less surprising and allow greater > control.
> As a side-effect of this change, it is no longer possible to schedule > concurrent transitions on the same element, even with the same id: > only one transition may be active on a given element at any time. > (Note that you can still schedule multiple future transitions on the > same element, and concurrent transitions on different elements.) For > example, you could previously schedule overlapping transitions with > different easing functions, delays or durations, provided you were > careful to avoid conflict. This seems like a relatively obscure > use-case compared to modifying a transition, so I believe this is a > reasonable change.
> This commit also changes transition.transition, such that the returned > transition starts at the end of the originating transition, rather > than overlapping. This makes it much easier to schedule sequenced > transitions without the complexity of transition.each("end") and > d3.select(this).
> Also, transitions are now simply arrays of nodes, consistent with > selections!
> Here's a code snippet showing sequenced transitions:
By reselecting transitioning elements, you can change the delay,
duration and even easing.
Related: I'm rebuilding the "introductory" examples for D3 and porting
them to http://bl.ocks.org. The current examples in the git repository
are a mix of manual tests, demonstrations of functionality, and
flexing (e.g., showreel). I'd like introductory examples to be as
simple as possible while still representative of real-world usage. So,
for example, I've replaced synthetic data (such as a sine wave) with
real data loaded from a file, e.g.,
On Sat, Oct 13, 2012 at 12:18 PM, Mike Bostock <mbost...@gmail.com> wrote:
> Here's a nice demo showing how you can now apply staggered delays to
> ordinal axis transitions:
> By reselecting transitioning elements, you can change the delay,
> duration and even easing.
> Related: I'm rebuilding the "introductory" examples for D3 and porting
> them to http://bl.ocks.org. The current examples in the git repository
> are a mix of manual tests, demonstrations of functionality, and
> flexing (e.g., showreel). I'd like introductory examples to be as
> simple as possible while still representative of real-world usage. So,
> for example, I've replaced synthetic data (such as a sine wave) with
> real data loaded from a file, e.g.,
> I was going to look into a 1-D force layout after initial placement,
> but if you have a good solution, it's a nice way to label line charts.
I've solved that problem in the past using constraints relaxation;
I'll make a demo if I have time. The strategy is to detect overlapping
labels and then push them apart slightly, and then iterate a few
times.
> Also how do you upload pngs to gist? I've got thumbnails ready to go.
Use the git interface rather than the web interface. This script might help you:
While not a perfect solution, the force_labels plugin ( https://github.com/d3/d3-plugins/tree/master/force_labels) might help reducing label crowding. Simply define a label force with the appropriate parameters and .call(labelForce.update) on whatever svg objects you want as anchors. The .__data__ attribute will subsequently contain an updated labelPos attribute for the corresponding label. Positioning of the anchor is assumed to be center of the SVG bounding box of each supplied anchor object..
> I was going to look into a 1-D force layout after initial placement, > but if you have a good solution, it's a nice way to label line charts.
> Also how do you upload pngs to gist? I've got thumbnails ready to go.
> On Sat, Oct 13, 2012 at 12:18 PM, Mike Bostock <mbos...@gmail.com<javascript:>> > wrote: > > Here's a nice demo showing how you can now apply staggered delays to > > ordinal axis transitions:
> > By reselecting transitioning elements, you can change the delay, > > duration and even easing.
> > Related: I'm rebuilding the "introductory" examples for D3 and porting > > them to http://bl.ocks.org. The current examples in the git repository > > are a mix of manual tests, demonstrations of functionality, and > > flexing (e.g., showreel). I'd like introductory examples to be as > > simple as possible while still representative of real-world usage. So, > > for example, I've replaced synthetic data (such as a sine wave) with > > real data loaded from a file, e.g.,
<ziggy.jonsson....@gmail.com> wrote:
> While not a perfect solution, the force_labels plugin
> (https://github.com/d3/d3-plugins/tree/master/force_labels) might help
> reducing label crowding.
> Simply define a label force with the appropriate parameters and
> .call(labelForce.update) on whatever svg objects you want as anchors.
> The .__data__ attribute will subsequently contain an updated labelPos
> attribute for the corresponding label.
> Positioning of the anchor is assumed to be center of the SVG bounding box of
> each supplied anchor object..
>> I was going to look into a 1-D force layout after initial placement,
>> but if you have a good solution, it's a nice way to label line charts.
>> Also how do you upload pngs to gist? I've got thumbnails ready to go.
>> On Sat, Oct 13, 2012 at 12:18 PM, Mike Bostock <mbos...@gmail.com> wrote:
>> > Here's a nice demo showing how you can now apply staggered delays to
>> > ordinal axis transitions:
>> > By reselecting transitioning elements, you can change the delay,
>> > duration and even easing.
>> > Related: I'm rebuilding the "introductory" examples for D3 and porting
>> > them to http://bl.ocks.org. The current examples in the git repository
>> > are a mix of manual tests, demonstrations of functionality, and
>> > flexing (e.g., showreel). I'd like introductory examples to be as
>> > simple as possible while still representative of real-world usage. So,
>> > for example, I've replaced synthetic data (such as a sine wave) with
>> > real data loaded from a file, e.g.,
If anything was "stolen", it was from Mike :) The plugin is just a quick boilerplate wrapper around the force layout (responsible for the results). I'm sure that more simple constraints relaxations as Mike suggested might be better and more lightweight in many instances, but the force layout has proven to be extremely flexible in my experience.
The only "issue" I have had, is that I'm using the same .__data__ object for both the anchor and the label (the magic of the plugin), and therefore it's not obvious how to set the anchor charges to zero (when needed) as .charge(function(...)) is based on the data object not the svg.
On Monday, October 15, 2012 4:26:05 PM UTC-4, Kai Chang wrote:
> I knew I had stolen the idea from somewhere. I merged force_labels 2 > months ago and totally forgot about it. Thanks Ziggy!
> On Mon, Oct 15, 2012 at 1:18 PM, Ziggy Jonsson > <ziggy.jo...@gmail.com <javascript:>> wrote: > > While not a perfect solution, the force_labels plugin > > (https://github.com/d3/d3-plugins/tree/master/force_labels) might help > > reducing label crowding. > > Simply define a label force with the appropriate parameters and > > .call(labelForce.update) on whatever svg objects you want as anchors. > > The .__data__ attribute will subsequently contain an updated labelPos > > attribute for the corresponding label. > > Positioning of the anchor is assumed to be center of the SVG bounding > box of > > each supplied anchor object..
> >> I was going to look into a 1-D force layout after initial placement, > >> but if you have a good solution, it's a nice way to label line charts.
> >> Also how do you upload pngs to gist? I've got thumbnails ready to go.
> >> On Sat, Oct 13, 2012 at 12:18 PM, Mike Bostock <mbos...@gmail.com> > wrote: > >> > Here's a nice demo showing how you can now apply staggered delays to > >> > ordinal axis transitions:
> >> > By reselecting transitioning elements, you can change the delay, > >> > duration and even easing.
> >> > Related: I'm rebuilding the "introductory" examples for D3 and > porting > >> > them to http://bl.ocks.org. The current examples in the git > repository > >> > are a mix of manual tests, demonstrations of functionality, and > >> > flexing (e.g., showreel). I'd like introductory examples to be as > >> > simple as possible while still representative of real-world usage. > So, > >> > for example, I've replaced synthetic data (such as a sine wave) with > >> > real data loaded from a file, e.g.,
One additional question about the proposal that just occurred to me. Does this change the behavior of interrupting/clobbering transitions at all? For example, if I'm running a transition on set of elements and then I use a completely new selection to select those elements and create a new transition (assume conflicting delay, duration and so on), will it still clobber the original transition and prevent that transition's remove() and each("end",...) from being run?
My impression from your description is that transition modification is only possible from the original transition instance (with the same id) but I wanted to make sure.
> My impression from your description is that transition modification is only
> possible from the original transition instance (with the same id) but I
> wanted to make sure.
Your interpretation is correct; this behavior is unchanged.
This tutorial covers many of the changes to transitions in the
forthcoming 3.0 release, and hopefully it will help shed some light on
how to implement transitions. Let me know if I can clarify anything
further.
Also, regarding "JavaScript formats small numbers in exponential notation, which unfortunately is not supported by CSS" -- would it be possible for d3 to (performantly) detect when this happens and convert the number to something that CSS can handle? It would be great if this problem were encapsulated by d3, so users didn't have to stumble into it and then try to remember to always use 1e-6 instead of 0.
On Thu, Oct 25, 2012 at 11:48 AM, Peter Rust <pe...@cornerstonenw.com> wrote:
> Excellent tutorial!
> One errata:
>> Transitions have a four-phrase life cycle
> should be "four-phase".
> Also, regarding "JavaScript formats small numbers in exponential notation,
> which unfortunately is not supported by CSS" -- would it be possible for d3
> to (performantly) detect when this happens and convert the number to
> something that CSS can handle? It would be great if this problem were
> encapsulated by d3, so users didn't have to stumble into it and then try to
> remember to always use 1e-6 instead of 0.