-
Notifications
You must be signed in to change notification settings - Fork 286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2.2 #156
Conversation
We’re almost there. Before, this hack (which didn’t work with descending domains): z = d3.scaleLog()
.domain(domain)
.interpolate(() => d3.interpolateBlues) After, with sequential.transform: z = d3.scaleSequential(d3.interpolateBlues)
.transform(d3.transformLog)
.domain(domain) This is not ideal, though, since the sequential scale has linear ticks and it’s more verbose. So we could have a dedicated sequential-log class as a convenient way of setting the transform and tick/nice method: z = d3.scaleSequentialLog(d3.interpolateBlues)
.domain(domain) That’s probably a good idea anyway because scaleSequentialLog would choose between transformLog and transformLogn automatically based on the domain. With a convenience constructor, this is even shorter: z = d3.scaleSequentialLog(domain, d3.interpolateBlues) And we’d need scaleSequentialPow and scaleSequentialSqrt aliases too, and diverging ones, which is kind of a combinatorial explosion, but I think at least we could minimize the code duplication in the implementations. |
It’s confusing that scaleLog supports scale.transform, given that setting the base or domain of a log scale will reset the transform back to transformLog or transformLogn. It maybe makes sense to hide scale.transform on scaleLog, but then what if you want to use transformSymlog with log ticks? (You probably don’t, since you’ll get no ticks if the domain spans zero, and if it doesn’t span zero, you probably don’t need the symlog transform.) Similarly, it’s confusing that scaleLinear supports scale.transform, since if you set the transform to anything other than the identity transform, it’s no longer a true linear scale. Unless we mean that the ticks are uniformly-spaced, but that’s not a reasonable definition. On the other hand, it seems reasonable to support scale.transform on scaleTime, since nothing in the name suggests that it’s linear. There’s still no obvious way to have log ticks on a time scale, but if you want a log transform, presumably you want scaleLog anyway? Perhaps we should be thinking about this in terms of four orthogonal scale characteristics:
So, if our current transforms are fixed, we have:
(We can treat scaleSqrt as a special case of scalePow and scaleDiverging as a special case of scaleSequential.) If we don’t expose configurable transforms, we could still add:
I’m not sure whether it makes sense to offer transformed versions of scaleQuantize. At any rate, it feels pretty niche. It’s probably better to start with specific transformed implementations (e.g., scaleSequentialPow, scaleSymlog), and we can expose custom transformations in the future when the value of that feature is more apparent. |
Webber, 2012. A Bi-Symmetric Log transformation for wide-range data. Measurement Science and Technology.
Fixes #62 - implements transforms on other scale types.
Fixes #93 - scaleSequentialQuantile computes p-quantile.
Fixes #97 - adds scale.unknown to all scale types.
Fixes #102 - allow unlimited band.paddingOuter and point.padding.
Fixes #105 - implements symlog transform.
Fixes #117 - use midpoint of domain or range when collapsed.
Fixes #123 - documents that quantize.domain must be ascending.
Fixes #132 - clarifies documentation for band.paddingOuter.
Fixes #148 - exposes d3.tickFormat.
Fixes #157 - adds convenience constructors for scales.
Fixes #159 - adds default constructors for sequential and diverging scales.
TODO
Transforms on scaleQuantize?No; seems too niche.Transforms on scaleQuantile?No; transforms are assumed to be monotonic.Transforms on scaleThreshold?No; transforms are assumed to be monotonic.Transforms on scaleIdentity?No; nonsensical.