# Numeric ticks and formatting

Import these pure helpers from `@pibbl/core/viz`. They accept ordinary values,
not signals. Read a signal with `.get()` inside a component or computed value to
reactively recompute. They create no subscriptions or resources themselves.

## Readable ticks

`linearTicks(domain: NumericDomain, options?: LinearTickOptions): readonly number[]`
returns frozen ticks at 1, 2, or 5 times a power of ten. `count` defaults to 5
and requests approximate intervals, not an exact output length. Output is capped at 100 ticks by increasing the
readable step when necessary. Only aligned
values within the domain are emitted, in domain order. Negative zero becomes
zero. The domain and scale mapping are unchanged; endpoints need not be ticks.
Existing `useLinearScale(id).get().ticks(count)` retains its evenly spaced,
endpoint-inclusive contract.

`niceLinearDomain(domain: NumericDomain, options?: LinearTickOptions): NumericDomain`
returns frozen endpoints expanded outward to these readable boundaries,
preserving ascending or descending direction. Pass the result explicitly to
`LinearScale`; axes never silently expand a domain.

Both helpers require two distinct finite endpoints with a finite span and an
integer `count` from 2 to 100. Invalid input, unrepresentable tick spacing, or
non-finite expanded bounds throws `RangeError`. Neither mutates its input.

## Number and unit formatting

`formatNumber(value: number, options?: NumberFormatOptions): string` uses
`Intl.NumberFormat`. `locale` defaults to `"en-US"`. `prefix` and `suffix`
default to empty strings and are literal (include any desired space).
All other options are standard `Intl.NumberFormatOptions`, including fraction
precision, significant digits, currency, percent, compact notation, and units.
Default decimal precision is at most three fractional digits. Rounded negative
zero displays as positive zero. Non-finite values throw `RangeError`; invalid
locale or Intl options retain the native Intl error. Results follow the host's
Intl locale data. No locale or unit is inferred from the data.

## Minimal runnable composition

The editable [minimal numeric demo](/playground/#/examples/composition/viz-numeric-axis)
and [NOAA example](/playground/#/examples/composition/viz-utc-climate) uses these
helpers with height-dependent tick density and label collision handling.
This complete mount demonstrates every helper:

```tsx
import { Group, pibbl } from "@pibbl/core";
import {
  Axis,
  LinearScale,
  linearTicks,
  niceLinearDomain,
  formatNumber,
} from "@pibbl/core/viz";

export default function mount(canvas: HTMLCanvasElement) {
  const domain = niceLinearDomain([0.13, 0.97]);
  return pibbl(
    canvas,
    <Group style={{ translateX: 24, translateY: 24 }}>
      <LinearScale id="value" domain={domain} range={[0, 240]}>
        <Axis
          scale="value"
          position="top"
          tickValues={linearTicks(domain)}
          labelOverlap="skip"
          tickFormat={(value) =>
            formatNumber(Number(value), {
              minimumFractionDigits: 1,
              maximumFractionDigits: 1,
              suffix: " ppm",
            })
          }
        />
      </LinearScale>
    </Group>,
  );
}
```

Layout belongs to the composition: leave gutters for labels and units. Use
`labelOverlap="skip"` to omit crowded labels while preserving every tick mark.

## API details from source

<span id="api-linearTicks"></span>

### linearTicks

Generates bounded ticks at readable 1, 2, or 5 × powers-of-ten intervals.
Endpoints are included only when aligned. Does not change scale geometry.

```ts
linearTicks: (domain: NumericDomain, options?: LinearTickOptions) => readonly number[]
```

Related API: [linearTicks](/reference/components/numeric-ticks/), [NumericDomain](/reference/functions/utc-domains/), [LinearTickOptions](/reference/components/numeric-ticks/).

#### Parameters

- **`domain`** — Distinct finite endpoints, ascending or descending.

- **`options`** — Target density; defaults to five intervals.

#### Returns

Frozen ticks in domain order. See [niceLinearDomain](/reference/components/numeric-ticks/).

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:39](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L39)

<span id="api-niceLinearDomain"></span>

### niceLinearDomain

Expands a linear domain to readable tick boundaries, preserving direction.

```ts
niceLinearDomain: (domain: NumericDomain, options?: LinearTickOptions) => NumericDomain
```

Related API: [niceLinearDomain](/reference/components/numeric-ticks/), [NumericDomain](/reference/functions/utc-domains/), [LinearTickOptions](/reference/components/numeric-ticks/).

#### Parameters

- **`domain`** — Distinct finite numeric endpoints; never mutated.

- **`options`** — Target density; defaults to five intervals.

#### Returns

Frozen expanded endpoints. See [linearTicks](/reference/components/numeric-ticks/).

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:51](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L51)

<span id="api-formatNumber"></span>

### formatNumber

Formats a finite number with Intl precision, currency, percent, or unit options.
Rounded negative zero is displayed as positive zero.

```ts
formatNumber: (value: number, options?: NumberFormatOptions) => string
```

Related API: [formatNumber](/reference/components/numeric-ticks/), [NumberFormatOptions](/reference/components/numeric-ticks/).

#### Parameters

- **`value`** — Finite numeric value.

- **`options`** — Intl options plus locale and literal affixes; default maximum fraction digits is 3.

#### Returns

Formatted text. Invalid Intl options retain native errors. See [NumberFormatOptions](/reference/components/numeric-ticks/).

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:73](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L73)

<span id="api-LinearTickOptions"></span>

### LinearTickOptions

Readable linear tick density. See linearTicks.

```ts
interface LinearTickOptions
```

Related API: [LinearTickOptions](/reference/components/numeric-ticks/).

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:4](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L4)

#### Properties and methods

<span id="api-LinearTickOptions-count"></span>
<details>
<summary>count (optional)</summary>


```ts
readonly count?: number | undefined
```

Target number of intervals, from 2 to 100; defaults to 5.

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:6](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L6)

</details>

<span id="api-NumberFormatOptions"></span>

### NumberFormatOptions

Number formatting with explicit locale and literal unit affixes. See formatNumber.

```ts
interface NumberFormatOptions extends Intl.NumberFormatOptions
```

Related API: [NumberFormatOptions](/reference/components/numeric-ticks/).

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:58](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L58)

#### Properties and methods

<span id="api-NumberFormatOptions-locale"></span>
<details>
<summary>locale (optional)</summary>


```ts
readonly locale?: string | undefined
```

Locale for formatting; defaults to en-US.

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:60](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L60)

</details>

<span id="api-NumberFormatOptions-prefix"></span>
<details>
<summary>prefix (optional)</summary>


```ts
readonly prefix?: string | undefined
```

Literal prefix; defaults to empty.

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:62](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L62)

</details>

<span id="api-NumberFormatOptions-suffix"></span>
<details>
<summary>suffix (optional)</summary>


```ts
readonly suffix?: string | undefined
```

Literal suffix, including any desired space; defaults to empty.

[View source — packages/core/src/features/viz/lib/numeric-ticks.ts:64](/source/packages/core/src/features/viz/lib/numeric-ticks-ts/#L64)

</details>

## Implementation guidance for agents

Read the [Authoring, signals, and lifecycle companion](/agents/topics/lifecycle/) for ownership, adaptation, failure modes, and verification. [Agent start](/agents/) provides the version-selection workflow.

## Complete minimal examples

- [Readable numeric ticks](/minimal-examples/viz/numeric-ticks/): Round a temperature range outward and format evenly spaced tick labels with units. [Plain source](/minimal/viz/numeric-ticks.ts)
## Documentation version

Documentation built with @pibbl/core 0.0.2, revision 272a94a. ALPHA — NOT FOR PRODUCTION USE.
