d3-scale provides comprehensive scale functions that serve as the fundamental abstraction for mapping dimensions of abstract data to visual representations in data visualization. It offers multiple scale types including continuous scales (linear, time, logarithmic), sequential and diverging scales for color encoding, quantize and quantile scales for categorical data transformation, threshold scales for custom boundaries, and ordinal scales (including band and point scales) for discrete data mapping.
npm install d3-scaleimport { scaleLinear, scaleBand, scaleOrdinal } from "d3-scale";For CommonJS:
const { scaleLinear, scaleBand, scaleOrdinal } = require("d3-scale");Import all scales:
import * as d3 from "d3-scale";import { scaleLinear, scaleBand, scaleSequential } from "d3-scale";
// Linear scale for quantitative data
const xScale = scaleLinear()
.domain([0, 100]) // Input data range
.range([0, 500]); // Output pixel range
console.log(xScale(50)); // 250 - maps to middle of range
// Band scale for categorical data
const yScale = scaleBand()
.domain(['A', 'B', 'C']) // Categories
.range([0, 300]) // Available space
.padding(0.1); // Space between bands
console.log(yScale('B')); // ~100 - position of category B
console.log(yScale.bandwidth()); // ~90 - width of each band
// Sequential color scale
const colorScale = scaleSequential()
.domain([0, 1])
.interpolator(d3.interpolateViridis); // Requires d3-interpolate
console.log(colorScale(0.5)); // Color halfway through viridis paletted3-scale is built around several key components:
domain(), range(), copy()) with specialized methods per scale typeLinear, logarithmic, power, and time-based scales for mapping continuous data to visual dimensions. Essential for position encoding and quantitative visualizations.
function scaleLinear(): LinearScale;
function scaleLog(): LogScale;
function scalePow(): PowerScale;
function scaleSqrt(): PowerScale;
function scaleSymlog(): SymlogScale;
function scaleTime(): TimeScale;
function scaleUtc(): TimeScale;
function scaleIdentity(): IdentityScale;
function scaleRadial(): RadialScale;Color and interpolation scales that map continuous domains to smooth gradients or sequences. Perfect for heatmaps, choropleth maps, and continuous color encoding.
function scaleSequential(interpolator?: InterpolatorFunction): SequentialScale;
function scaleSequentialLog(interpolator?: InterpolatorFunction): SequentialScale;
function scaleSequentialPow(interpolator?: InterpolatorFunction): SequentialScale;
function scaleSequentialSqrt(interpolator?: InterpolatorFunction): SequentialScale;
function scaleSequentialSymlog(interpolator?: InterpolatorFunction): SequentialScale;
function scaleSequentialQuantile(interpolator?: InterpolatorFunction): SequentialQuantileScale;Three-point color scales ideal for data with meaningful center points (e.g., correlation, deviation from average). Maps continuous domains through a central neutral point to contrasting extremes.
function scaleDiverging(interpolator?: InterpolatorFunction): DivergingScale;
function scaleDivergingLog(interpolator?: InterpolatorFunction): DivergingScale;
function scaleDivergingPow(interpolator?: InterpolatorFunction): DivergingScale;
function scaleDivergingSqrt(interpolator?: InterpolatorFunction): DivergingScale;
function scaleDivergingSymlog(interpolator?: InterpolatorFunction): DivergingScale;Ordinal, band, point, and quantized scales for categorical data and discrete mappings. Essential for bar charts, categorical axes, and discrete color schemes.
function scaleOrdinal(range?: any[]): OrdinalScale;
function scaleBand(): BandScale;
function scalePoint(): PointScale;
function scaleQuantile(): QuantileScale;
function scaleQuantize(): QuantizeScale;
function scaleThreshold(): ThresholdScale;Helper functions and constants for scale operations and formatting.
function tickFormat(start: number, stop: number, count: number, specifier?: string): (n: number) => string;
const scaleImplicit: symbol;All scales implement a consistent interface with these universal methods:
interface Scale<Domain, Range> {
/** Apply the scale transformation to a domain value */
(value: Domain): Range;
/** Get or set the input domain */
domain(): Domain[];
domain(domain: Domain[]): this;
/** Get or set the output range */
range(): Range[];
range(range: Range[]): this;
/** Create an independent copy of this scale */
copy(): Scale<Domain, Range>;
/** Get or set the value returned for unknown domain inputs */
unknown(): any;
unknown(value: any): this;
}type InterpolatorFunction = (t: number) => any;
type InterpolatorFactory = (a: any, b: any) => InterpolatorFunction;
type ComparisonFunction<T> = (a: T, b: T) => number;
type KeyFunction<T> = (d: T, i: number, data: T[]) => any;
interface BandScale {
(value: any): number | undefined;
domain(): any[];
domain(domain: any[]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
bandwidth(): number;
step(): number;
round(): boolean;
round(round: boolean): this;
padding(): number;
padding(padding: number): this;
paddingInner(): number;
paddingInner(padding: number): this;
paddingOuter(): number;
paddingOuter(padding: number): this;
align(): number;
align(align: number): this;
copy(): BandScale;
}
interface PointScale {
(value: any): number | undefined;
domain(): any[];
domain(domain: any[]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
step(): number;
round(): boolean;
round(round: boolean): this;
padding(): number;
padding(padding: number): this;
align(): number;
align(align: number): this;
copy(): PointScale;
}
interface LinearScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolate(): InterpolatorFactory;
interpolate(interpolate: InterpolatorFactory): this;
unknown(): any;
unknown(value: any): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): LinearScale;
}
interface LogScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolate(): InterpolatorFactory;
interpolate(interpolate: InterpolatorFactory): this;
unknown(): any;
unknown(value: any): this;
base(): number;
base(base: number): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(): this;
copy(): LogScale;
}
interface PowerScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolate(): InterpolatorFactory;
interpolate(interpolate: InterpolatorFactory): this;
unknown(): any;
unknown(value: any): this;
exponent(): number;
exponent(exponent: number): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): PowerScale;
}
interface SymlogScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolate(): InterpolatorFactory;
interpolate(interpolate: InterpolatorFactory): this;
unknown(): any;
unknown(value: any): this;
constant(): number;
constant(constant: number): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): SymlogScale;
}
interface TimeScale {
(value: Date): number;
invert(value: number): Date;
domain(): [Date, Date];
domain(domain: [Date, Date]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolate(): InterpolatorFactory;
interpolate(interpolate: InterpolatorFactory): this;
unknown(): any;
unknown(value: any): this;
ticks(interval?: any): Date[];
tickFormat(count?: number, specifier?: string): (date: Date) => string;
nice(interval?: any): this;
copy(): TimeScale;
}
interface IdentityScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
unknown(): any;
unknown(value: any): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): IdentityScale;
}
interface RadialScale {
(value: number): number;
invert(value: number): number;
domain(): [number, number];
domain(domain: [number, number]): this;
range(): [number, number];
range(range: [number, number]): this;
rangeRound(range: [number, number]): this;
round(): boolean;
round(round: boolean): this;
clamp(): boolean;
clamp(clamp: boolean): this;
unknown(): any;
unknown(value: any): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): RadialScale;
}
interface OrdinalScale {
(value: any): any;
domain(): any[];
domain(domain: any[]): this;
range(): any[];
range(range: any[]): this;
unknown(): any;
unknown(value: any): this;
copy(): OrdinalScale;
}
interface QuantileScale {
(value: number): any;
invertExtent(value: any): [number, number];
domain(): number[];
domain(domain: number[]): this;
range(): any[];
range(range: any[]): this;
unknown(): any;
unknown(value: any): this;
quantiles(): number[];
copy(): QuantileScale;
}
interface QuantizeScale {
(value: number): any;
invertExtent(value: any): [number, number];
domain(): [number, number];
domain(domain: [number, number]): this;
range(): any[];
range(range: any[]): this;
unknown(): any;
unknown(value: any): this;
thresholds(): number[];
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): QuantizeScale;
}
interface ThresholdScale {
(value: number): any;
invertExtent(value: any): [number, number];
domain(): number[];
domain(domain: number[]): this;
range(): any[];
range(range: any[]): this;
unknown(): any;
unknown(value: any): this;
copy(): ThresholdScale;
}
interface SequentialScale {
(value: number): any;
domain(): [number, number];
domain(domain: [number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolator(): InterpolatorFunction;
interpolator(interpolator: InterpolatorFunction): this;
range(): [any, any];
range(range: [any, any]): this;
rangeRound(range: [number, number]): this;
unknown(): any;
unknown(value: any): this;
ticks(count?: number): number[];
tickFormat(count?: number, specifier?: string): (n: number) => string;
nice(count?: number): this;
copy(): SequentialScale;
}
interface SequentialQuantileScale {
(value: number): any;
domain(): number[];
domain(domain: number[]): this;
interpolator(): InterpolatorFunction;
interpolator(interpolator: InterpolatorFunction): this;
range(): any[];
quantiles(): number[];
copy(): SequentialQuantileScale;
}
interface DivergingScale {
(value: number): any;
domain(): [number, number, number];
domain(domain: [number, number, number]): this;
clamp(): boolean;
clamp(clamp: boolean): this;
interpolator(): InterpolatorFunction;
interpolator(interpolator: InterpolatorFunction): this;
range(): [any, any, any];
range(range: [any, any, any]): this;
rangeRound(range: [number, number, number]): this;
unknown(): any;
unknown(value: any): this;
copy(): DivergingScale;
}