This also tweaks the array conversion slightly so that it is called by
selection.selectAll rather than d3_selectAll; this guarantees that the selection
groups are always arrays, even when a function selector is used.
The click event is prevented from propagating when a drag has occurred
i.e. the mouse has moved between mousedown and mouseup. This is because
a click event will be triggered after a mousedown and mouseup have
occurred on the same element. However, we were cancelling the next
click event *anywhere*, regardless of whether mousedown and mouseup
occurred on the same element or not.
As a sanity check, we also check that the click event was triggered on
the same element that mousedown *and* mouseup occurred on, before
cancelling it. Just in case!
This adds support for filtering the log ticks, such that fewer ticks can be
generated to fit in a small space. This can be used in conjunction with a
custom tick format as well. This commit also changes the default log tick format
to be exponential rather than precision, for consistency.
NodeList doesn't support .sort() directly, so we need to convert to a
real Array first. I've done this in selectAll for efficiency i.e. this
avoids a new Array being created every time the same selection is
sorted. However, it may be slightly more efficient to create the Array
only when sorting, to avoid unnecessary Array creation when sorting
isn't used, which is probably the common case.
Unfortunately it's difficult to test this because JSDOM uses a real
Array instead of a NodeList!
Rather than have a treshold in transitions, we now clamp the easing functions.
This guarantees that when the transition ends, the tweens will be called with
t=1, and produce clean output values. Previously, that was not the case for
certain easing functions, such as exp-out and elastic.
IE9 does not string-coerce values, instead throwing an error. We now wrap IE9's
implementation to force string coercion. While it would be simpler to turn on
string-coercion for all browsers inside D3's style operator, this approach
avoids penalizing standards-compliant browsers.
This commit also moves language-compatibility code to a separate directory, and
deletes the obsolete Object.create polyfill, which is no longer needed by D3.
This improves the performance of transitions that have already ended (those with
zero duration), as the transition can end immediately on start rather than
waiting for a second tick.
Fixes#274. String coerce for uniqueness, but store the original input types in
the domain for subsequent retrieval. This way, you can more easily use
non-strings as domain values (such as dates or numbers).
As of 2.0.0, it's possible to have multiple transitions running concurrently
with the same id. Thus, it is no longer sufficient to check the transition id
to decide whether to delete the transition lock. We now use reference counting
to determine the number of transitions that are scheduled on a given element;
when that number drops to zero, we can delete the transition lock.
This fixes a breakage on IE9, which doesn't support array subclassing through
prototype injection. On IE9, we then use direct extension of the prototype, but
this can only be done after the prototype is fully-defined.
We were mistakenly binding Firefox's DOMMouseScroll to dblclick rather than
mousewheel. Also, there's no acceleration on these events, so we need to make
them faster to match the typical behavior of mousewheel.
Previously, the start time for a transition could be slightly different for
different elements, even when the transition was created at the same time. This
commit allows timers to be created with an explicit reference time (then),
allowing a transition to be temporaly consistent across elements.
They weren't being invoked with the correct syntax (being passed the data and
index, with the current node as the context). This commit also removes the
d3_array wrapper, which does not appear to be necessary; I've forgotten why it
was there in the first place.
This also fixes a few bugs in the new implementation, restoring support for the
offset between the mouse and the dragged element by reporting a delta rather
than an absolute offset. Also, this fixes an infinite loop when an element is
removed from the DOM.
I'm including the axis component in the core build because it should be useful
in many different visualization types, similar to the other svg components. The
chart module contains a hodgepodge of more obscure visualization types, and
there's no reason to pull those in for more common visualizations. Perhaps most
importantly, the axis component isn't a chart type!
This means that you can now extend D3's selections and transitions with custom
functionality! Also, you can use now instanceof to see whether something is an
instanceof d3.selection or d3.transition.
Also fix a bug where it would be possible for an earlier to transition to become
the lock owner. We now guarantee that the lock owner can only increase while
transitions are scheduled on an element.
This caught a couple bugs in the previous commit. First, I wasn't sending the
correct index (i) to the "end" event listeners, because it was being masked by
a local variable. Second, the transition lock was being incorrectly deleted when
a transition is inherited on the same node and there is zero delay and
d3.timer.flush is called. There was potentially a related bug where the active
field was not being cleared on the transition lock. Yay tests!
This changes the core implementation of selections and transitions to use
prototype injection rather than direct extension. This offers better performance
by eliminating per-instance overhead from closures and assignment. On browsers
that don't support prototype injection, we fall back to direct extension.
This commit isn't just about performance, though; the code ends up being a lot
cleaner and more separable if we force methods to rely solely on `this`, rather
than capturing surrounding variables with closures.
Most importantly, transitions are now "transparent", like selections. Rather
than opaque objects, transitions are now arrays of nodes, similar to selections.
The nodes are wrapped in an object that stores the delay and duration, which
means you can now inspect the computed delay and duration. (This was the
original motivation for this commit, and will allow chart components to be
call'd on transitions as well as selections.)
Transitions now support the `each` operator with one argument, which has the
same behavior as on selections. The `each` operator now passes a third argument
containing the group index (`j`). Transitions now also support a `tween`
operator, which is a generic mechanism for doing things during a transition; use
this in place of a "tick" event.
This commit also fixes a few bugs. The enter selection now supports the empty
operator; we can add other operators in the future more easily, if we so choose.
Transition's attr operator now supports namespaced attributes. Selection's
property operator no longer parses property namespaces.
This returns a copy of the scale, such that future modifications to the scale's
domain or range (or other attributes) are isolated from the copy. This is useful
for transitions where you may want to make a copy of a scale before it changes,
such that entering elements can be initialized using the previous copy.
You can now specify the domain of the quadtree upon construction, such that you
can add points to the quadtree dynamically later. The quadtree example now also
shows how to do a quick rectangular search using the quadtree.
This commit adds a new static function for computing the extent (min and max) of
a scale's domain, simplifying the logic in the ticks functions and ensuring
standard behavior (such as repeated values). Also, the linear ticks function is
extracted for reuse by the pow scale.
I opted not to reverse the tick order for descending domains; this might be nice
but it doesn't seem required, so we might as well keep the code small.
There's already a tension parameter, and it seems reasonable to overload this
parameter (originally intended for cardinal splines) to also apply to bundle
splines. The new "bundle" interpolation is identical to "basis" interpolation;
the only difference is that the tension parameter is used to straighten the
basis spline.
The input to the layout is now an array of edges to bundle, rather than nodes.
This eliminates the need for an `outgoing` accessor, since the links are passed
to the bundle layout directly.
The svg line generator now supports a beta (straightening; bundle strength)
parameter. I haven't decided if this is the right place or the right name for
it, but it seems like a reasonable starting point. I'm not happy with the cos &
sin needed to produce radial lines (both here and for the diagonal projection in
other examples), but I don't have a good alternative yet.
This commit also tries to make the construction of the links from the layout
nodes a bit easier to follow. The previous code was used another intermediate
representation, and I think it's cleaner to construct the default format
expected by the layouts. However, there's still a good chunk of code required to
massage the JSON format into a node hierarchy and array of dependencies, so I'd
like to find a way to simplify that, too.
Previously, if you instantiated the enter selection via append or insert, you'd
have to re-select to unify the enter and update selection (the post-transform
nodes). Now, simply by appending or inserting the entering nodes, the update
selection automatically refreshes, obviating the need for a reselect. If you
still want to perform actions only on the updating nodes, you can do so by
performing these actions before instantiating the enter selection.
This way, people can play with superformulas if they want them, but we keep the
core library small. If we want to replace the default symbol implementation with
superformulas in the future, we can do that too. For now, be conservative.
This is useful when other modules want to register interpolators for
d3.interpolate without adding an explicit dependency to d3.core. The
interpolators are applied in reverse order, and the first one that returns
a function is used.
(This commit was authored by @jasondavies and cherry picked.)
If the tween function returns null, then no tween will be applied for the
specified element. The default tween function now returns null if the start and
end value are the same, thus avoiding redundant interpolation.
We can't just rebind the internal linear scale's nice function because the
linear scale's domain is the exponentiated pow domain, so the actual pow domain
would most likely be fractional as the linear scale will round to the nearest
integer exponentiation.
Based on the Protovis implementation. Includes tests. I'm not sure [10.9, 1.1]
should be "niced" to [10, 10] but this is also the behaviour in Protovis at the
moment.
Unlike Math.min and Math.max, it doesn't make sense to return negative or
positive infinity for d3.min and d3.max; the D3 functions return the minimum
value according to an arbitrary ordering, not by numeric value. Instead, the
minimum or maximum of an empty array, or an array that contains only degenerate
values, should always be undefined.
* The returned array should be truncated to the length of the shortest argument.
* With no arguments it should return an empty array.
I've updated the unit tests to be more verbose to detect the array of
single-element arrays returned for a single argument.
I removed the `F`, `G` and `E` types, since these are redundant and we don't
have to be slavishly-compatible with Python. Also, I simplified the
implementation of `g`, `e` and `f` so that they use JavaScript's built-in
`toPrecision`, `toExponential` and `toFixed`, respectively. The existing
implementations weren't exactly compatible with Python, anyway, so we might as
well default to using JavaScript's built-ins.
This is similar to pv.search, but more closely modeled after Python's bisect
methods to provide the desired flexibility in searching slices of arrays. This
includes good tests for bisect, and better tests for polylinear and quantile
scales (both of which now use bisect).
`F` is an alias for `f`. `r` is a new format type that rounds the input number,
treating the precision field as the desired number of significant digits. This
is similar to `g`, except it never uses exponent notation. `p` is equivalent to
`r`, except it outputs a percentage, as with `%`.
* "e": exponent notation.
* "E": same as "e", except uses "E" as a separator.
* "g": precision is interpreted as signficant digits.
* "G": same as "g" but uses "E" instead of "e".
* "n": equivalent to ",g".
* "%": percentages.
Fixes#149.
This doesn't quite seem like the right place for it, but it seems to work when
using "touchstart", "touchmove" and "touchend" handlers without any adverse
effects on "true" mouse event handlers.
See <http://www.jasondavies.com/apollonian-gasket/> to see an example of
combined touch/mouse handlers working with this change.
This commit adds a d3_uninterpolate method (private, for now), which is
essentially the inverse of d3.interpolate. It's used to map a value in the
domain to the unit range [0,1], which can then be passed to an interpolator.
Mainly, I fixed a bug where the coordinates could get set to NaN if two
successive points have the same x-coordinate. But I also cleaned up the
implementation slightly, and compute the initial tangents using finite
differences.
We can take advantage of JavaScript's invisible hoisting of variables to set
them before they are defined. This simplifies the code for the various special
cases in the `classed` operator, such as for SVG elements and browsers that
support the tokenized class list.
This turns out to be slightly faster than using structs (`{}`) and is bit
cleaner. You can now also do:
d3.rgb(r, g, b).hsl()
and:
d3.hsl(h, s, l).rgb()
to convert between RGB and HSL.