Skip to content

Scales

Scales map data values to visual values — turning a number like 42 into a pixel position, a color, or a band width. They are the bridge between your data domain and the visual range on screen. Ripl ships with 11 scale types covering continuous, categorical, logarithmic, quantile, and time-based mappings.

Every scale is a callable function: pass a domain value in, get a range value out. Scales also expose inverse (reverse mapping), ticks (nice axis values), includes (domain membership), and the original domain/range arrays.

NOTE

For the full API, see the Scales API Reference.

Demo

Use the controls below to explore different scale types. The scale maps a domain value (bottom axis) to a range value (left axis).

Continuous

The most common scale. Maps a numeric domain linearly to a numeric range.

ts
import {
    scaleContinuous,
} from '@ripl/web';

const x = scaleContinuous([0, 100], [0, 800]);

x(0); // 0
x(50); // 400
x(100); // 800

x.inverse(400); // 50
x.ticks(5); // [0, 25, 50, 75, 100]

Options: clamp (constrain output to range) and padToTicks (extend domain to nice tick boundaries).

Band

Divides a continuous range into evenly spaced bands for categorical data. Exposes bandwidth and step.

ts
import {
    scaleBand,
} from '@ripl/web';

const x = scaleBand(['Jan', 'Feb', 'Mar'], [0, 300], {
    innerPadding: 0.1,
    outerPadding: 0.05,
});

x('Jan'); // band start position
x.bandwidth; // width of each band
x.step; // distance between band starts

Options: innerPadding, outerPadding, alignment, round.

Discrete

Maps discrete domain values to evenly spaced positions in a numeric range.

ts
import {
    scaleDiscrete,
} from '@ripl/web';

const color = scaleDiscrete(['low', 'mid', 'high'], [0, 100]);

color('low'); // 0
color('mid'); // 50
color('high'); // 100

Diverging

Like continuous, but splits at a midpoint — useful for scales that diverge around zero (e.g. temperature anomalies, profit/loss).

ts
import {
    scaleDiverging,
} from '@ripl/web';

const x = scaleDiverging([-100, 100], [0, 800], {
    midpoint: 0,
});

x(-100); // 0
x(0); // 400
x(100); // 800

Logarithmic

Maps values using a log transformation. Useful for data spanning several orders of magnitude.

ts
import {
    scaleLog,
    scaleLogarithmic,
} from '@ripl/web';

const x = scaleLogarithmic([1, 1000], [0, 600], { base: 10 });

x(1); // 0
x(10); // 200
x(100); // 400
x(1000); // 600

// scaleLog is a shortcut for base-10
const y = scaleLog([1, 1000], [0, 600]);

Power

Maps values using an exponential transformation. exponent: 2 gives a quadratic curve, exponent: 0.5 gives a square root curve.

ts
import {
    scalePower,
    scaleSqrt,
} from '@ripl/web';

const x = scalePower([0, 100], [0, 400], { exponent: 2 });

// scaleSqrt is a shortcut for exponent 0.5
const y = scaleSqrt([0, 100], [0, 400]);

Quantile

Divides a sorted numeric domain into quantiles, each mapped to a discrete range value.

ts
import {
    scaleQuantile,
} from '@ripl/web';

const color = scaleQuantile(
    [10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
    ['low', 'medium', 'high']
);

color(15); // 'low'
color(55); // 'medium'
color(95); // 'high'

Quantize

Divides a continuous domain into uniform segments mapped to discrete range values.

ts
import {
    scaleQuantize,
} from '@ripl/web';

const rating = scaleQuantize([0, 100], ['poor', 'fair', 'good', 'excellent']);

rating(20); // 'poor'
rating(40); // 'fair'
rating(60); // 'good'
rating(90); // 'excellent'

Threshold

Maps values to range values based on threshold breakpoints.

ts
import {
    scaleThreshold,
} from '@ripl/web';

const grade = scaleThreshold([60, 70, 80, 90], ['F', 'D', 'C', 'B', 'A']);

grade(55); // 'F'
grade(65); // 'D'
grade(75); // 'C'
grade(85); // 'B'
grade(95); // 'A'

Time

Maps Date objects to a numeric range using linear interpolation of timestamps.

ts
import {
    scaleTime,
} from '@ripl/web';

const x = scaleTime(
    [new Date('2024-01-01'), new Date('2024-12-31')],
    [0, 800]
);

x(new Date('2024-07-01')); // ~400
x.inverse(400); // ≈ Date('2024-07-01')
x.ticks(6); // 6 evenly spaced dates

Common Scale Properties

Every scale function exposes:

PropertyTypeDescription
domainTDomain[]The input domain
rangeTRange[]The output range
inverse(value)(TRange) → TDomainReverse mapping
ticks(count?)(number?) → TDomain[]Generate nice tick values
includes(value)(TDomain) → booleanTest domain membership