# `Scales.MinorBreaks`
[🔗](https://github.com/giggleton/scales/blob/v0.1.0/lib/scales/minor_breaks.ex#L1)

Where a continuous axis's minor breaks go: between its breaks (`regular/3`), a number of them to
each gap (`n/3`) or every multiple of a width in each (`width/4`), and the powers of ten and
their multiples for a logarithmic axis (`log/2`).

# `log`

```elixir
@spec log({number(), number()}, keyword()) :: [float()]
```

Minor breaks for a logarithmic axis over the limits `{low, high}`, R's `minor_breaks_log()`: the
powers of ten from one below the low limit's to one above the high limit's, then five times each,
then each whole multiple from 2 to 9 of each but 5, as `detail:` asks, in that order, as R gives
them.

Where a limit is 0 or below, the powers run from ten times `smallest:` to the larger limit's
size, each kept from `smallest:` up and given either side of 0, the positive first, with 0
itself after the powers. The result may reach past the limits; which to keep is the caller's.
Limits both 0 have no powers to span, and are refused, where R fails.

## Options

* `:detail` - Which values to give, R's `detail`: the powers of ten (`10`), those and five times each (`5`), or every whole multiple of each from 1 to 9 (`1`); `:auto` chooses by the powers the limits span, `1` over 8 or fewer, `5` over 15 or fewer, else `10`. The default value is `:auto`.

* `:smallest` - Where limits reach 0 or below, the smallest size of value given either side of 0, R's `smallest`, a finite number from 1.0e-100; `:auto` is a tenth of the largest limit's size, 0.1 at most. The default value is `:auto`.

## Examples

    iex> Scales.MinorBreaks.log({1.0, 100.0}, detail: 5)
    [0.1, 1.0, 10.0, 100.0, 1000.0, 0.5, 5.0, 50.0, 500.0, 5000.0]

    iex> Scales.MinorBreaks.log({-10.0, 10.0}, detail: 10, smallest: 1)
    [1.0, 10.0, 100.0, -1.0, -10.0, -100.0, 0.0]

# `n`

```elixir
@spec n({number(), number()}, [number(), ...], non_neg_integer()) :: [float()]
```

`count` minor breaks to each gap, its ends included, on an axis showing the limits
`{low, high}` with `breaks`, R's `minor_breaks_n()`: from the low limit to the first break,
between each pair of neighbouring breaks in the order given, and from the last break to the high
limit, each gap spread evenly as R's `seq()` spreads it (`Scales.Palette.spread/2`), a value laid
twice kept the first time.

The result may reach past the limits, as breaks may; which to keep is the caller's. It takes
numbers alone: a fraction of a day is no date.

## Examples

    iex> Scales.MinorBreaks.n({0.5, 9.5}, [2.0, 4.0, 6.0, 8.0], 3)
    [0.5, 1.25, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 8.75, 9.5]

# `regular`

```elixir
@spec regular([float()], {float(), float()}, keyword()) :: [float()]
```

The minor breaks between `breaks` on an axis showing the limits `{low, high}`, R's
`regular_minor_breaks()`: each gap between neighbouring breaks, in the order given, gets a minor
break at its middle, the gap's start plus half its width, as R's `seq()` finds it. Where the
limits reach past the breaks at an end, the breaks are first extended by one more step there,
the first gap's, so minor breaks can fall between the outermost break and the edge of the axis.

The result holds the breaks themselves and the added steps too, as R's does, and may reach past
the limits; which to keep is the caller's. Fewer than two breaks have no gap, and so no minor
breaks.

## Options

* `:reverse` (`t:boolean/0`) - Whether the breaks run from high to low, as a reversing transformation's do, so the step added before the first break goes above it and the one after the last below it. The default value is `false`.

## Examples

    iex> Scales.MinorBreaks.regular([10.0, 20.0, 30.0], {5.0, 35.0})
    [0.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 40.0]

    iex> Scales.MinorBreaks.regular([30.0, 20.0, 10.0], {5.0, 35.0}, reverse: true)
    [40.0, 35.0, 30.0, 25.0, 20.0, 15.0, 10.0, 5.0, 0.0]

# `width`

```elixir
@spec width(
  {Scales.Breaks.value(), Scales.Breaks.value()},
  [Scales.Breaks.value(), ...],
  number() | Scales.Breaks.step(),
  keyword()
) :: [Scales.Breaks.value()]
```

Minor breaks `width` apart in each gap, on an axis showing the limits `{low, high}` with
`breaks`, R's `minor_breaks_width()`: `Scales.Breaks.width/3`'s breaks over the low limit and the
first break, each pair of neighbouring breaks in the order given, and the last break and the high
limit, a value laid twice kept the first time.

It takes what `Scales.Breaks.width/3` takes, numbers, dates, date-times or times of day, with
`width` a number or a step of one unit, and gives the same, where R gives a date's days or a
date-time's seconds. Its options are `Scales.Breaks.width/3`'s, `offset:` 0 or no steps unless
given, where R has no default. The result may reach past the limits, as breaks may; which to
keep is the caller's.

## Examples

    iex> Scales.MinorBreaks.width({0.5, 9.5}, [2.0, 4.0, 6.0, 8.0], 2, offset: 0.5)
    [0.5, 2.5, 4.5, 6.5, 8.5, 10.5]

    iex> Scales.MinorBreaks.width({~D[2026-01-01], ~D[2026-01-25]}, [~D[2026-01-15]], week: 1)
    [~D[2025-12-29], ~D[2026-01-05], ~D[2026-01-12], ~D[2026-01-19], ~D[2026-01-26]]

---

*Consult [api-reference.md](api-reference.md) for complete listing*
