# charts.ticks Where the ticks on an axis go. `niceTicks(0, 1, 10)` is `[0, 0.1, ..., 1]`, `timeTicks("2026-01-01", "2026-12-31", "month", 3)` is the four quarter starts, and `tickStep` and `timeTickInterval` say what spacing to use for about `count` ticks. This is a group: the four functions are the tick half of an axis, used with `charts.scale` and `charts.format`. ## Number ticks `tickStep` is d3-array's rule: divide the extent by `count`, take the power of ten at or below it, and round the leftover factor to 1, 2, 5 or 10 on a log scale (the cut-offs are √2, √10 and √50). `niceTicks` returns every multiple of that step between the two ends inclusive, in the direction from `start` to `stop`; the ends themselves are ticks only if they are multiples. Equal ends give `[start]` (and a step of 0). If one tick is asked for and no multiple falls inside, it tries again for two, as d3 does. The arithmetic is chosen so that the three languages print the same ticks: - The power of ten is found by multiplying whole numbers, never with `log10`, whose last bit is platform-dependent. - A fractional step is kept as a whole-number divisor: a step of 0.2 is "divide by 5", so the tick is `i / 5`, one correctly rounded division. Adding 0.1 three times gives 0.30000000000000004; here the third tenth is exactly the double 0.3. `tickStep` returns `factor / 10^k` the same way. - Tick indexes are rounded with `math.round-float` and then corrected by comparison, so a product that lands a hair either side of a whole number cannot add or lose a tick. ## Calendar ticks `timeTicks` returns the calendar boundaries inside a date range, inclusive: | interval | a tick on | `step` counts | |-----------|----------------------------------------|----------------------------------------| | `day` | days with (day of month - 1) % step = 0 | restarts each month, as d3's timeDay.every | | `week` | Mondays (ISO weeks) | whole weeks since Monday 1970-01-05 | | `month` | the 1st, (month - 1) % step = 0 | month 3 is January, April, July, October | | `quarter` | 1 January, April, July, October | quarter of the year % step = 0 | | `year` | 1 January, year % step = 0 | every fifth year is 2005, 2010, ... | Steps are anchored to the calendar, not to the first date, so an axis that pans by a day keeps the same ticks instead of shifting them all. Dates are counted as whole days (via `dates.add-days`), never through a `Date` object, so time zones and clock changes cannot move a tick. More than 10,000 ticks is an error, since it is always a wrong interval. `timeTickInterval` picks the interval for about `count` ticks the way d3's time scale does: the ideal spacing is the span in days over `count`, and it takes whichever neighbouring rung of the ladder day, 2 days, week, month (30 days), quarter (90 days), year (365 days) is nearer by ratio. Beyond a year it uses whole years in a `tickStep` of 1, 2 or 5 x 10^k. Sources: Mike Bostock, d3-array `ticks.js` (tickIncrement, ticks) and d3-scale `time.js` (tickIntervals), github.com/d3; ISO 8601 for weeks starting on Monday.