Fixes#1550. By using the copy of the new scale (which we make anyway for a
snapshot) we avoid polluting the scale’s domain with the old values when using
the scale as the key function for the tick data-join.
Previously we were using string coercion as the key function for axis ticks.
However, when the stringified value of the tick does not fully capture the
representation (such as a date with millisecond precision, whose string form
only has second precision; fixes#1529), string coercion is insufficient.
Fortunately, there is an equivalently-simple key function for tick identity: the
scale! If the scale does not return a unique position for the given tick, then
the tick would be overlapping, so it serves perfectly as the key function.
In addition to ordinal scales, quantile, quantize and threshold scales don’t
define a ticks method. Unlike ordinal scales, however, these quantitative scales
also don’t define a rangeBand method, so the axis was crashing trying to render
these scales. This fixes#1367 by checking for the required rangeBand method
rather than assuming scales without a ticks method define a rangeBand.
Note, however, that even with this change you probably still want to define tick
values explicitly when using one of these scales with an axis. That’s because
each tick in the axis represents a span of values in the domain; you can use the
invertExtent method to get the span for each tick value.
You can now pass a format specifier to scale.tickFormat (for linear, pow and
identity scales). If the format specifier doesn't have a defined precision, the
precision will be set automatically by the scale, returning the appropriate
format. This provides a convenient, declarative way of specifying a format whose
precision will be automatically set by the scale.
This works with axes, too! For example, `axis.ticks(10, "%")` will now use a
percentage format rather than the default format, while still computing the
appropriate precision.
This commit also includes a fix to make d3.format more robust when unreasonable
precisions are specified. Rather than throwing an error, the nearest reasonable
value is used instead.
Fixes#912.
In future we may want to generate some kind of loop, but it's not clear
what orientation such a loop should have, so perhaps a "non-line" like
this is better as a default.
Previously, if you set the brush extent externally, the extent could drift
slightly because it was internally stored in pixel space rather than in data
space. To avoid drift, the brush now preserves the extent exactly as-set, only
nullifying the externally-set extent when the brush is moved.
This fixes a crash with the symbol type "hasOwnProperty", rather than defaulting
to "circle". This commit also adds new map methods to retrieve the keys, values
and entries. The map class now uses non-enumerable properties (if supported).
Rather than producing separate files for each module, the default build now
produces a single file. This should encourage better page-load performance as
the files were relatively small. Also, it's easier to deal with only one file
rather than many, especially if you're not quite sure what the dependencies are.
You may still create minimized builds, if you don't want every feature.
This commit also demotes the chart components to the examples directory, rather
than keeping them as part of the core library. As always, D3 is not a charting
library, and these were ever only intended to serve as examples.
You can now change the orientation and the axis will redraw correctly. When an
axis is applied by a transition, the subtransitions will properly inherit the
transition id, allowing transitions on reselected elements to continue.
When computing the reversed baseline, we need to switch between step-before and
step-after, since the points are in reverse order. Otherwise, we're effectively
filling the gap between step-before and step-after.
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!