Giter Club home page Giter Club logo

Comments (3)

mbostock avatar mbostock commented on May 3, 2024 2

the first/last elements of tick's output should bracket start/stop

That’s not what I meant by inclusive. Ticks are inclusive in the sense that they may include the specified start and stop values if (and only if) they are exact, nicely-rounded values consistent with the determined tick step. More formally, each returned tick t satisfies startt and tstop. (If they were exclusive, then the relationship would instead be start < t and t < stop.)

Your stop of 24 is less than the next tick 25, so 25 is not included.

d3.ticks(0, 24, 4); // [0, 5, 10, 15, 20]

If you increase the bounds to [0, 25] you’ll see that it will include the upper bound exactly, thereby demonstrating that it is inclusive:

d3.ticks(0, 25, 4); // [0, 5, 10, 15, 20, 25]

As you mentioned, yes, internally, the upper bound is calculated as follows:

Math.floor(stop / step) * step + step / 2

Since the step is the result of d3.tickStep (here 5) that works out to:

Math.floor(24 / 5) * 5 + 5 / 2 // 22.5

This is less than the stop of 24, but 24 is not a multiple of the step, so it’s still correct. If the stop were a multiple of step—say if step were instead 4—then it would be greater than stop:

Math.floor(24 / 4) * 4 + 4 / 2 // 26

In other words, the greatest tick is ⌊stop / step⌋ × step (⌊24 / 5⌋ × 5 = 20). The only reason for the additional step / 2 is that d3.range, which is used internally by d3.ticks, treats stop as exclusive, unlike d3.ticks. I could have used an epsilon value instead, such as this:

Math.floor(stop / step) * step + 1e-6

But d3.ticks is intended to work for arbitrary values, so step can be arbitrarily small and it’s better to use something appropriate to the value of step.

If you want the ticks to surround start and stop, then you need the equivalent of continuous.nice from d3-scale. See linear.js for the implementation. It’s a little tricky since you need to call d3.tickStep twice, since increasing the extent (lowing the start and raising the stop) can also change the inferred step. But you can skip that step if you want different behavior:

var start = 0, stop = 24, count = 4;
var step = d3.tickStep(start, stop, count);
var ticks = d3.range(Math.floor(start / step) * step, Math.ceil(stop / step) * step + step / 2, step);

from d3-array.

fasiha avatar fasiha commented on May 3, 2024 1

Doh, many thanks for taking this much time to explain—your first paragraph, defining "inclusive" would have sufficed!

from d3-array.

fasiha avatar fasiha commented on May 3, 2024

(Sorry, my last post was completely non-sensical, so I deleted it and started again. Sorry for the barrage of emails this issue has created for you!)

I think you just switched floor and ceil there, in ticks: you want the start of the range to be (after dividing by step) rounded to -infinity, and the end of the range to be rounded to +infinity—floor and ceil respectively. With this flip-flop in place, the usual requirements of inclusivity are met: ticks(1, 24, 4) goes from 0 to 25 in steps of 5 (with the previous code, it would go from 5 to 20 in steps of 5).

The only problem with this is that it breaks one test: ticks(-10, 10, 1), in order to be inclusive, has to be [-20, -0, 20]. If this is ok, i.e., if count = 1 still requires inclusivity, then I can make a PR with the above fix, plus an adjusted test.

from d3-array.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.