Skip to content

Commit

Permalink
Add transition.textTween.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Nov 17, 2019
1 parent 495efc2 commit ac4e423
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 1 deletion.
16 changes: 15 additions & 1 deletion README.md
Expand Up @@ -293,7 +293,21 @@ This method is useful to specify a custom interpolator, such as with *data inter

For each selected element, sets the [text content](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) to the specified target *value* when the transition starts. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The function’s return value is then used to set each element’s text content. A null value will clear the content.

To interpolate text rather than to set it on start, use [*transition*.tween](#transition_tween) ([for example](http://bl.ocks.org/mbostock/7004f92cac972edef365)) or append a replacement element and cross-fade opacity ([for example](http://bl.ocks.org/mbostock/f7dcecb19c4af317e464)). Text is not interpolated by default because it is usually undesirable.
To interpolate text rather than to set it on start, use [*transition*.textTween](#transition_textTween) ([for example](http://bl.ocks.org/mbostock/7004f92cac972edef365)) or append a replacement element and cross-fade opacity ([for example](http://bl.ocks.org/mbostock/f7dcecb19c4af317e464)). Text is not interpolated by default because it is usually undesirable.

<a name="transition_textTween" href="#transition_textTween">#</a> <i>transition</i>.<b>textTween</b>(<i>factory</i>) [<>](https://github.com/d3/d3-transition/blob/master/src/transition/textTween.js "Source")

If *factory* is specified and not null, assigns the text [tween](#transition_tween) to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the text. The interpolator must return a string.

For example, to interpolate the text with integers from 0 to 100:

```js
transition.textTween(function() {
return d3.interpolateRound(0, 100);
});
```

If the specified *factory* is null, removes the previously-assigned text tween, if any. If *factory* is not specified, returns the current interpolator factory for text, or undefined if no such tween exists.

<a name="transition_remove" href="#transition_remove">#</a> <i>transition</i>.<b>remove</b>() [<>](https://github.com/d3/d3-transition/blob/master/src/transition/remove.js "Source")

Expand Down
2 changes: 2 additions & 0 deletions src/transition/index.js
Expand Up @@ -14,6 +14,7 @@ import transition_selection from "./selection.js";
import transition_style from "./style.js";
import transition_styleTween from "./styleTween.js";
import transition_text from "./text.js";
import transition_textTween from "./textTween.js";
import transition_transition from "./transition.js";
import transition_tween from "./tween.js";
import transition_end from "./end.js";
Expand Down Expand Up @@ -57,6 +58,7 @@ Transition.prototype = transition.prototype = {
style: transition_style,
styleTween: transition_styleTween,
text: transition_text,
textTween: transition_textTween,
remove: transition_remove,
tween: transition_tween,
delay: transition_delay,
Expand Down
24 changes: 24 additions & 0 deletions src/transition/textTween.js
@@ -0,0 +1,24 @@
function textInterpolate(i) {
return function(t) {
this.textContent = i(t);
};
}

function textTween(value) {
var t0, i0;
function tween() {
var i = value.apply(this, arguments);
if (i !== i0) t0 = (i0 = i) && textInterpolate(i);
return t0;
}
tween._value = value;
return tween;
}

export default function(value) {
var key = "text";
if (arguments.length < 1) return (key = this.tween(key)) && key._value;
if (value == null) return this.tween(key, null);
if (typeof value !== "function") throw new Error;
return this.tween(key, textTween(value));
}
38 changes: 38 additions & 0 deletions test/transition/textTween-test.js
@@ -0,0 +1,38 @@
var tape = require("tape"),
jsdom = require("../jsdom"),
d3_ease = require("d3-ease"),
d3_timer = require("d3-timer"),
d3_interpolate = require("d3-interpolate"),
d3_selection = require("d3-selection"),
state = require("./state");

require("../../");

tape("transition.textTween(value) defines a text tween using the interpolator returned by the specified function", function(test) {
var root = jsdom().documentElement,
interpolate = d3_interpolate.interpolateHcl("red", "blue"),
ease = d3_ease.easeCubic,
transition = d3_selection.select(root).transition().textTween(function() { return interpolate; });

d3_timer.timeout(function(elapsed) {
test.deepEqual(root.textContent, interpolate(ease(elapsed / 250)));
test.end();
}, 125);
});

tape("transition.textTween() returns the existing text tween", function(test) {
var root = jsdom().documentElement,
factory = function() {},
transition = d3_selection.select(root).transition().textTween(factory);
test.strictEqual(transition.textTween(), factory);
test.end();
});

tape("transition.textTween(null) removes an existing text tween", function(test) {
var root = jsdom().documentElement,
factory = function() {},
transition = d3_selection.select(root).transition().textTween(factory);
transition.textTween(undefined);
test.strictEqual(transition.textTween(), null);
test.end();
});

0 comments on commit ac4e423

Please sign in to comment.