Skip to content

Symlog and point scales

Read as Markdown

Import from @pibbl/core/viz. Each family has its own provider and hook with a fixed return type. There is no family selector or argument-dependent return.

SymlogScale(props: SymlogScaleProps): PibblNode accepts all LinearScaleProps and constant?: SignalValue<number> (default 1). id, domain, and range are required. reverse defaults to false; style and children are optional. The domain is two distinct finite numbers with a finite nonzero span; negative, zero, positive, and descending endpoints are supported. Range is "width", "height", or two finite coordinates. Reversal affects range only.

useSymlogScale(id: ScaleId): Signal<ResolvedSymlogScale> returns a stable shared readonly signal. Its frozen snapshot has type: "symlog", frozen domain and range, frame, constant, and:

  • map(value: number): number: applies sign(value) * log1p(abs(value)/constant) before linear interpolation. Near zero it is approximately linear; farther away it compresses large magnitudes. Finite values outside the domain extrapolate.
  • invert(pixel: number): number: applies the inverse signed expm1 transform. Original range endpoints return exact domain endpoints. Negative zero becomes zero.
  • ticks(count = 5): readonly number[]: readable 1/2/5 decimal ticks in data space, using linearTicks(domain, { count }). Count is a target, not exact; at most 100 values are returned. Count must be an integer 2–100. Aligned zero appears when the domain crosses zero. Endpoints appear only if aligned.

constant must be finite and positive, in the same units as the data. Changing it changes geometry; it is not only a formatting choice. No automatic nicening or clamping occurs. All provider inputs except identity/children accept the same signals as LinearScale. Changes to constant publish new snapshots. Hook .get() tracks dependencies; provider unmount releases its subscriptions.

Invalid domains, ranges, constants, nonfinite map/invert inputs or outputs, collapsed transformed domains, and collapsed-range inversion throw RangeError. A collapsed range can still map. Tick precision limits match linearTicks. Missing/mismatched hook IDs and invalid reverse/identity follow existing scale errors. Existing numeric axes, marks, ScaleAdjust, and inspection queries work with symlog, including signed coordinates and zero.

PointScale(props: PointScaleProps): PibblNode requires id, domain, and range. Domain is an ordered array of unique strings or finite numbers; numeric 1 and string "1" differ, while 0 and -0 are duplicates. Empty and singleton domains are valid. Range, reverse (default false), style, and children have the same meaning as LinearScale. padding?: SignalValue<number> defaults to zero; it is nonnegative outer spacing in step units, not pixels. Zero padding places first and last categories at the range endpoints. Categories never sort themselves; reverse the domain array to change order, or reverse the range to flip mapping.

usePointScale(id: ScaleId): Signal<ResolvedPointScale> returns a stable shared readonly signal. Snapshot fields: type: "point", frozen domain and range, frame, resolved padding, and nonnegative step. There is no bandwidth.

  • map(category: BandCategory): number | undefined: the category’s point, or undefined for an unknown category. No domain mutation occurs.
  • invert(pixel: number): BandCategory | undefined: nearest-category lookup, not a continuous inverse. Ties choose the first category in domain order; outside coordinates choose the nearest endpoint. Empty domains return undefined. Singleton or collapsed ranges choose the first category.
  • ticks(count = 5): BandDomain: at most count categories, sampled in domain order. Count is an integer 0–100; zero returns an empty frozen array, one returns the first category. Counts of two or more retain endpoints.

Empty domains have step zero; singleton categories map to the range midpoint. Collapsed ranges place all categories at that pixel. Padding arithmetic must remain finite. Invalid/duplicate categories throw TypeError; invalid padding, range/allocation, invert coordinate, or count throws RangeError. No implicit category coercion occurs. Domain, range, reverse, padding, and styles accept signals; snapshots update with allocation, and unmount releases subscriptions.

Axis ticks use the exact point (no half-band offset). ScaleAdjust accepts string/number point coordinates for ordinary custom marks; unknown categories throw RangeError. Its continuous coordinates still require numbers. Numeric LineSeries, PointSeries, PlotSeries, and numeric inspection queries do not accept PointScale: use the hook for custom mark coordinates and invert for category inspection. This preserves their numeric contracts.

The signed Census example is editable and uses both providers and hooks with real data. This minimal mount also demonstrates both families and categorical custom-mark placement:

import { Circle, Group, pibbl } from "@pibbl/core";
import { Axis, PointScale, SymlogScale, ScaleAdjust } from "@pibbl/core/viz";
export default function mount(canvas: HTMLCanvasElement) {
return pibbl(
canvas,
<Group style={{ translateX: 60, translateY: 30 }}>
<PointScale id="state" domain={["A", "B", "C"]} range={[0, 120]}>
<SymlogScale
id="change"
domain={[-100, 100]}
range={[0, 240]}
constant={10}
>
<Axis scale="state" position="left" tickValues={["A", "B", "C"]} />
<Axis scale="change" position="top" />
<ScaleAdjust x={-30} xScale="change" y="B" yScale="state">
<Circle style={{ radius: 5, fill: "teal" }} />
</ScaleAdjust>
</SymlogScale>
</PointScale>
</Group>,
);
}

Keep category identities visible when resizing. Units and the symlog transition constant belong in chart context because equal distances do not represent equal additive changes.

Scale snapshots are computed lazily. Domain/mapping validation occurs when a consumer reads the scale signal (for example, an Axis or a hook’s .get()), not merely because an otherwise unused provider appears in the tree.

Provides a named symlog mapping to descendant visualization components.

SymlogScale: (props: SymlogScaleProps) => PibblNode

Related API: SymlogScale, SymlogScaleProps, PibblNode.

Descendant content within the scale scope.

View source — packages/core/src/features/viz/lib/symlog-scale-component.ts:10

Reads an ancestor symlog scale as a stable shared readonly signal.

useSymlogScale: (id: ScaleId) => Signal<ResolvedSymlogScale>

Related API: useSymlogScale, ScaleId, Signal, ResolvedSymlogScale.

  • id — Ancestor scale identity. See ScaleId.

The reactive mapping. See ResolvedSymlogScale.

View source — packages/core/src/features/viz/lib/use-symlog-scale.ts:10

Signed logarithmic scale inputs. See LinearScaleProps.

interface SymlogScaleProps extends LinearScaleProps

Related API: SymlogScaleProps, LinearScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:253

constant (optional)
readonly constant?: SignalValue<number> | undefined

Related API: SignalValue.

Positive linear-to-log transition constant in domain units, default 1.

View source — packages/core/src/features/viz/lib/types.ts:255

id
readonly id: ScaleId

Related API: ScaleId.

Stable identifier of this resource or connection. See ScaleId.

View source — packages/core/src/features/viz/lib/types.ts:74

domain
readonly domain: SignalValue<LinearDomain>

Related API: SignalValue, LinearDomain.

Data values or endpoints accepted by the scale. See SignalValue, LinearDomain .

View source — packages/core/src/features/viz/lib/types.ts:79

range
readonly range: SignalValue<ScaleRange>

Related API: SignalValue, ScaleRange.

Logical output coordinates produced by the scale. See SignalValue, ScaleRange .

View source — packages/core/src/features/viz/lib/types.ts:84

reverse (optional)
readonly reverse?: SignalValue<boolean> | undefined

Related API: SignalValue.

Whether to reverse the direction of the mapping or guide. See SignalValue.

View source — packages/core/src/features/viz/lib/types.ts:86

style (optional)
Full type declaration
readonly style?: SignalValue<Readonly<{ left?: SignalValue<number | `${number}%` | undefined>; top?: SignalValue<number | `${number}%` | undefined>; width?: SignalValue<Length | undefined>; height?: SignalValue<Length | undefined>; alignSelf?: SignalValue<"auto" | "center" | "end" | "flex-end" | "flex-start" | "start" | "stretch" | undefined>; justifySelf?: SignalValue<"auto" | "center" | "end" | "start" | "stretch" | undefined>; flexBasis?: SignalValue<Length | undefined>; flexGrow?: SignalValue<number | undefined>; flexShrink?: SignalValue<number | undefined>; gridColumnStart?: SignalValue<number | undefined>; gridColumnSpan?: SignalValue<number | undefined>; gridRowStart?: SignalValue<number | undefined>; gridRowSpan?: SignalValue<number | undefined>; transition?: SignalValue<PibblTransitionBinding | undefined>; custom?: unknown; filter?: SignalValue<PibblFilter | readonly PibblFilter[] | undefined>; }>> | undefined

Related API: SignalValue, Length, PibblTransitionBinding, PibblFilter.

Declared presentation and layout properties. See SignalValue, SignalStyle, ScaleLayoutStyle.

View source — packages/core/src/features/viz/lib/types.ts:91

children (optional)
readonly children?: PibblNode

Related API: PibblNode.

Descendant content or the callback that supplies it. See PibblNode.

View source — packages/core/src/features/viz/lib/types.ts:93

Signed logarithmic mapping through zero. See ResolvedLinearScale.

interface ResolvedSymlogScale extends Omit<ResolvedLinearScale, "type">

Related API: ResolvedSymlogScale, ResolvedLinearScale.

View source — packages/core/src/features/viz/lib/types.ts:258

type
readonly type: "symlog"

Signed logarithmic discriminant. See SymlogScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:260

constant
readonly constant: number

Positive transition constant. See SymlogScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:262

domain
readonly domain: LinearDomain

Related API: LinearDomain.

Data values or endpoints accepted by the scale. See LinearDomain.

View source — packages/core/src/features/viz/lib/types.ts:192

range
readonly range: readonly [number, number]

Logical output coordinates produced by the scale. See ResolvedLinearScale.

View source — packages/core/src/features/viz/lib/types.ts:194

frame
readonly frame: Readonly<LayoutBox>

Related API: LayoutBox.

Resolved layout frame containing the scale. See LayoutBox.

View source — packages/core/src/features/viz/lib/types.ts:196

map
map: (value: number) => number

Maps a numeric domain value to a logical range coordinate. See ResolvedLinearScale.

  • value — Numeric domain coordinate.

The corresponding range coordinate.

View source — packages/core/src/features/viz/lib/types.ts:202

invert
invert: (pixel: number) => number

Related API: invert.

Maps a logical range coordinate back into the numeric domain. See ResolvedLinearScale .

  • pixel — Coordinate in the scale’s pixel range.

The corresponding numeric domain value.

View source — packages/core/src/features/viz/lib/types.ts:209

ticks
ticks: (count?: number) => readonly number[]

Returns representative numeric tick values for the requested count. See ResolvedLinearScale.

  • count — Suggested number of ticks.

Tick values in domain coordinates.

View source — packages/core/src/features/viz/lib/types.ts:216

Provides a named point mapping to descendant visualization components.

PointScale: (props: PointScaleProps) => PibblNode

Related API: PointScale, PointScaleProps, PibblNode.

Descendant content within the scale scope.

View source — packages/core/src/features/viz/lib/point-scale-component.ts:10

Reads an ancestor point scale as a stable shared readonly signal.

usePointScale: (id: ScaleId) => Signal<ResolvedPointScale>

Related API: usePointScale, ScaleId, Signal, ResolvedPointScale.

  • id — Ancestor scale identity. See ScaleId.

The reactive mapping. See ResolvedPointScale.

View source — packages/core/src/features/viz/lib/use-point-scale.ts:10

Equally spaced categorical positions. See LinearScaleProps.

interface PointScaleProps extends Omit<LinearScaleProps, "domain">

Related API: PointScaleProps, LinearScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:265

domain
readonly domain: SignalValue<BandDomain>

Related API: SignalValue, BandDomain.

Ordered unique string or finite numeric categories; accepts signals. See BandDomain.

View source — packages/core/src/features/viz/lib/types.ts:267

padding (optional)
readonly padding?: SignalValue<number> | undefined

Related API: SignalValue.

Nonnegative outer padding in step units, default 0.

View source — packages/core/src/features/viz/lib/types.ts:269

id
readonly id: ScaleId

Related API: ScaleId.

Stable identifier of this resource or connection. See ScaleId.

View source — packages/core/src/features/viz/lib/types.ts:74

range
readonly range: SignalValue<ScaleRange>

Related API: SignalValue, ScaleRange.

Logical output coordinates produced by the scale. See SignalValue, ScaleRange .

View source — packages/core/src/features/viz/lib/types.ts:84

reverse (optional)
readonly reverse?: SignalValue<boolean> | undefined

Related API: SignalValue.

Whether to reverse the direction of the mapping or guide. See SignalValue.

View source — packages/core/src/features/viz/lib/types.ts:86

style (optional)
Full type declaration
readonly style?: SignalValue<Readonly<{ left?: SignalValue<number | `${number}%` | undefined>; top?: SignalValue<number | `${number}%` | undefined>; width?: SignalValue<Length | undefined>; height?: SignalValue<Length | undefined>; alignSelf?: SignalValue<"auto" | "center" | "end" | "flex-end" | "flex-start" | "start" | "stretch" | undefined>; justifySelf?: SignalValue<"auto" | "center" | "end" | "start" | "stretch" | undefined>; flexBasis?: SignalValue<Length | undefined>; flexGrow?: SignalValue<number | undefined>; flexShrink?: SignalValue<number | undefined>; gridColumnStart?: SignalValue<number | undefined>; gridColumnSpan?: SignalValue<number | undefined>; gridRowStart?: SignalValue<number | undefined>; gridRowSpan?: SignalValue<number | undefined>; transition?: SignalValue<PibblTransitionBinding | undefined>; custom?: unknown; filter?: SignalValue<PibblFilter | readonly PibblFilter[] | undefined>; }>> | undefined

Related API: SignalValue, Length, PibblTransitionBinding, PibblFilter.

Declared presentation and layout properties. See SignalValue, SignalStyle, ScaleLayoutStyle.

View source — packages/core/src/features/viz/lib/types.ts:91

children (optional)
readonly children?: PibblNode

Related API: PibblNode.

Descendant content or the callback that supplies it. See PibblNode.

View source — packages/core/src/features/viz/lib/types.ts:93

Zero-width categorical point positions. See ResolvedBandScale.

interface ResolvedPointScale extends Omit<ResolvedBandScale, "type" | "bandwidth">

Related API: ResolvedPointScale, ResolvedBandScale.

View source — packages/core/src/features/viz/lib/types.ts:272

type
readonly type: "point"

Categorical point discriminant. See PointScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:274

padding
readonly padding: number

Resolved outer padding. See PointScaleProps.

View source — packages/core/src/features/viz/lib/types.ts:276

invert
invert: (pixel: number) => BandCategory | undefined

Related API: invert, BandCategory.

Finds the nearest category, clamping outside coordinates; ties choose first domain order.

  • pixel — Finite range coordinate.

Category or undefined for an empty domain. See BandCategory.

View source — packages/core/src/features/viz/lib/types.ts:282

ticks
ticks: (count?: number) => BandDomain

Related API: BandDomain.

Selects evenly spaced categories including endpoints when count permits.

  • count — Integer maximum count 0–100, default 5.

Frozen categories in domain order. See BandDomain.

View source — packages/core/src/features/viz/lib/types.ts:288

domain
readonly domain: BandDomain

Related API: BandDomain.

Data values or endpoints accepted by the scale. See BandDomain.

View source — packages/core/src/features/viz/lib/types.ts:163

range
readonly range: readonly [number, number]

Logical output coordinates produced by the scale. See ResolvedBandScale.

View source — packages/core/src/features/viz/lib/types.ts:165

frame
readonly frame: Readonly<LayoutBox>

Related API: LayoutBox.

Resolved layout frame containing the scale. See LayoutBox.

View source — packages/core/src/features/viz/lib/types.ts:167

step
readonly step: number

Distance between successive band starts. See ResolvedBandScale.

View source — packages/core/src/features/viz/lib/types.ts:171

map
map: (value: BandCategory) => number | undefined

Related API: BandCategory.

Maps a category to its band coordinate, or returns undefined for an unknown category. See ResolvedBandScale .

  • value — Category to locate in the domain. See BandCategory.

The category’s range position, or undefined if it is absent from the domain.

View source — packages/core/src/features/viz/lib/types.ts:178

Read the Data visualization companion for ownership, adaptation, failure modes, and verification. Agent start provides the version-selection workflow.

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