Scales are functions that map abstract data dimensions to visual representations. Axes create human-readable reference marks for scales. Together they form the foundation for creating meaningful data visualizations with proper scaling and labeling.
Continuous scales with linear mathematical relationships between domain and range.
/**
* Create a continuous linear scale
* @returns Linear scale function
*/
function scaleLinear(): ScaleLinear<number, number, never>;
interface ScaleLinear<Domain extends NumberValue, Range, Output> {
/**
* Scale a value from domain to range
* @param value - Input value in domain
* @returns Scaled value in range
*/
(value: Domain): Output;
/**
* Invert a value from range back to domain
* @param value - Value in range to invert
* @returns Original domain value
*/
invert(value: Range): Domain;
/**
* Get or set the input domain
* @param domain - Array of domain values [min, max]
* @returns Scale for chaining or current domain
*/
domain(): Domain[];
domain(domain: Iterable<Domain>): ScaleLinear<Domain, Range, Output>;
/**
* Get or set the output range
* @param range - Array of range values [min, max]
* @returns Scale for chaining or current range
*/
range(): Range[];
range(range: Iterable<Range>): ScaleLinear<Domain, Range, Output>;
/**
* Set range and enable rounding to integers
* @param range - Array of range values
* @returns Scale for chaining
*/
rangeRound(range: Iterable<Range>): ScaleLinear<Domain, Range, Output>;
/**
* Enable or disable clamping to domain/range bounds
* @param clamp - Whether to enable clamping
* @returns Scale for chaining or current clamp setting
*/
clamp(): boolean;
clamp(clamp: boolean): ScaleLinear<Domain, Range, Output>;
/**
* Generate representative values from domain
* @param count - Approximate number of ticks
* @returns Array of tick values
*/
ticks(count?: number): Domain[];
/**
* Format tick values for human consumption
* @param count - Number of ticks for formatting hints
* @param specifier - Format specifier string
* @returns Formatting function
*/
tickFormat(count?: number, specifier?: string): (d: Domain) => string;
/**
* Extend domain to nice round numbers
* @param count - Target number of ticks
* @returns Scale for chaining
*/
nice(count?: number): ScaleLinear<Domain, Range, Output>;
/**
* Create a copy of this scale
* @returns New scale with same configuration
*/
copy(): ScaleLinear<Domain, Range, Output>;
}
/**
* Create identity scale where domain equals range
* @returns Identity scale
*/
function scaleIdentity(): ScaleLinear<number, number, number>;
/**
* Create radial scale (like linear, but sqrt transform on range)
* @returns Radial scale
*/
function scaleRadial(): ScaleRadial<number, number, number>;Usage Examples:
import { scaleLinear } from "d3";
// Basic linear scale
const xScale = scaleLinear()
.domain([0, 100]) // Input domain
.range([0, 500]); // Output range
console.log(xScale(50)); // 250 (middle of range)
console.log(xScale.invert(250)); // 50 (back to domain)
// Scale with nice domain
const yScale = scaleLinear()
.domain([0.201, 0.956])
.range([300, 0]) // Flipped for SVG coordinates
.nice(); // Rounds domain to [0.2, 1]Non-linear scales for exponential and logarithmic data relationships.
/**
* Create power scale (y = mx^k + b)
* @returns Power scale
*/
function scalePow(): ScalePower<number, number, never>;
/**
* Create square root scale (power scale with exponent 0.5)
* @returns Square root scale
*/
function scaleSqrt(): ScalePower<number, number, never>;
interface ScalePower<Domain extends NumberValue, Range, Output> extends ScaleLinear<Domain, Range, Output> {
/**
* Get or set the power exponent
* @param exponent - Power exponent (default 1)
* @returns Scale for chaining or current exponent
*/
exponent(): number;
exponent(exponent: number): ScalePower<Domain, Range, Output>;
}
/**
* Create logarithmic scale
* @returns Logarithmic scale
*/
function scaleLog(): ScaleLogarithmic<number, number, never>;
interface ScaleLogarithmic<Domain extends NumberValue, Range, Output> extends ScaleLinear<Domain, Range, Output> {
/**
* Get or set the logarithm base
* @param base - Logarithm base (default 10)
* @returns Scale for chaining or current base
*/
base(): number;
base(base: number): ScaleLogarithmic<Domain, Range, Output>;
}
/**
* Create symmetric logarithmic scale
* @returns Symlog scale
*/
function scaleSymlog(): ScaleSymLog<number, number, never>;
interface ScaleSymLog<Domain extends NumberValue, Range, Output> extends ScaleLinear<Domain, Range, Output> {
/**
* Get or set the symlog constant
* @param constant - Linear threshold constant
* @returns Scale for chaining or current constant
*/
constant(): number;
constant(constant: number): ScaleSymLog<Domain, Range, Output>;
}Scales for temporal data with time-specific ticking and formatting.
/**
* Create time scale for local time
* @returns Time scale
*/
function scaleTime(): ScaleTime<Date, number, never>;
/**
* Create time scale for UTC time
* @returns UTC time scale
*/
function scaleUtc(): ScaleTime<Date, number, never>;
interface ScaleTime<Domain extends Date, Range, Output> {
(value: Domain): Output;
invert(value: Range): Domain;
domain(): Domain[];
domain(domain: Iterable<Domain>): ScaleTime<Domain, Range, Output>;
range(): Range[];
range(range: Iterable<Range>): ScaleTime<Domain, Range, Output>;
/**
* Generate time-based ticks
* @param count - Target number of ticks
* @returns Array of Date tick values
*/
ticks(count?: number): Domain[];
ticks(interval: TimeInterval): Domain[];
/**
* Format time tick values
* @param count - Number of ticks for formatting hints
* @param specifier - Time format specifier
* @returns Time formatting function
*/
tickFormat(count?: number, specifier?: string): (d: Domain) => string;
/**
* Extend domain to nice time boundaries
* @param count - Target number of ticks
* @returns Scale for chaining
*/
nice(count?: number): ScaleTime<Domain, Range, Output>;
nice(interval: TimeInterval): ScaleTime<Domain, Range, Output>;
copy(): ScaleTime<Domain, Range, Output>;
}Scales for discrete data with categorical domains and discrete or continuous ranges.
/**
* Create ordinal scale for categorical data
* @returns Ordinal scale
*/
function scaleOrdinal<Domain extends string = string, Range = string>(): ScaleOrdinal<Domain, Range, never>;
interface ScaleOrdinal<Domain, Range, Output> {
(value: Domain): Output;
/**
* Get or set the discrete domain
* @param domain - Array of discrete domain values
* @returns Scale for chaining or current domain
*/
domain(): Domain[];
domain(domain: Iterable<Domain>): ScaleOrdinal<Domain, Range, Output>;
/**
* Get or set the discrete range
* @param range - Array of discrete range values
* @returns Scale for chaining or current range
*/
range(): Range[];
range(range: Iterable<Range>): ScaleOrdinal<Domain, Range, Output>;
/**
* Get or set unknown value handler
* @param value - Value to return for unknown domain values
* @returns Scale for chaining or current unknown value
*/
unknown(): Output;
unknown(value: Output): ScaleOrdinal<Domain, Range, Output>;
copy(): ScaleOrdinal<Domain, Range, Output>;
}
/**
* Create band scale for creating bars/columns with spacing
* @returns Band scale
*/
function scaleBand(): ScaleBand<string>;
interface ScaleBand<Domain extends string> {
(value: Domain): number | undefined;
domain(): Domain[];
domain(domain: Iterable<Domain>): ScaleBand<Domain>;
range(): [number, number];
range(range: [number, number]): ScaleBand<Domain>;
/**
* Get the bandwidth (width of each band)
* @returns Width of each band
*/
bandwidth(): number;
/**
* Get the step (distance between band starts)
* @returns Distance between start of adjacent bands
*/
step(): number;
/**
* Get or set inner padding between bands
* @param padding - Padding as fraction of step
* @returns Scale for chaining or current padding
*/
paddingInner(): number;
paddingInner(padding: number): ScaleBand<Domain>;
/**
* Get or set outer padding before first and after last band
* @param padding - Padding as fraction of step
* @returns Scale for chaining or current padding
*/
paddingOuter(): number;
paddingOuter(padding: number): ScaleBand<Domain>;
/**
* Set inner and outer padding simultaneously
* @param padding - Padding as fraction of step
* @returns Scale for chaining
*/
padding(padding: number): ScaleBand<Domain>;
copy(): ScaleBand<Domain>;
}
/**
* Create point scale for positioning elements along a line
* @returns Point scale
*/
function scalePoint(): ScalePoint<string>;
interface ScalePoint<Domain extends string> {
(value: Domain): number | undefined;
domain(): Domain[];
domain(domain: Iterable<Domain>): ScalePoint<Domain>;
range(): [number, number];
range(range: [number, number]): ScalePoint<Domain>;
/**
* Get the step (distance between points)
* @returns Distance between adjacent points
*/
step(): number;
/**
* Get or set padding before first and after last point
* @param padding - Padding as fraction of step
* @returns Scale for chaining or current padding
*/
padding(): number;
padding(padding: number): ScalePoint<Domain>;
copy(): ScalePoint<Domain>;
}Scales that map continuous domains to discrete ranges through quantization.
/**
* Create quantize scale (uniform quantization)
* @returns Quantize scale
*/
function scaleQuantize<Range = number>(): ScaleQuantize<Range>;
interface ScaleQuantize<Range> {
(value: number): Range;
/**
* Get domain values corresponding to given range value
* @param value - Range value to invert
* @returns Domain interval [x0, x1]
*/
invertExtent(value: Range): [number, number] | [undefined, undefined];
domain(): [number, number];
domain(domain: [number, number]): ScaleQuantize<Range>;
range(): Range[];
range(range: Iterable<Range>): ScaleQuantize<Range>;
/**
* Get array of threshold values
* @returns Array of threshold values
*/
thresholds(): number[];
copy(): ScaleQuantize<Range>;
}
/**
* Create quantile scale (quantile-based quantization)
* @returns Quantile scale
*/
function scaleQuantile<Range = number>(): ScaleQuantile<Range>;
interface ScaleQuantile<Range> {
(value: number): Range;
invertExtent(value: Range): [number, number] | [undefined, undefined];
domain(): number[];
domain(domain: Iterable<number>): ScaleQuantile<Range>;
range(): Range[];
range(range: Iterable<Range>): ScaleQuantile<Range>;
/**
* Get quantile thresholds
* @returns Array of quantile thresholds
*/
quantiles(): number[];
copy(): ScaleQuantile<Range>;
}
/**
* Create threshold scale (arbitrary thresholds)
* @returns Threshold scale
*/
function scaleThreshold<Domain extends number | string | Date, Range = number>(): ScaleThreshold<Domain, Range>;
interface ScaleThreshold<Domain, Range> {
(value: Domain): Range;
invertExtent(value: Range): [Domain, Domain] | [undefined, undefined];
domain(): Domain[];
domain(domain: Iterable<Domain>): ScaleThreshold<Domain, Range>;
range(): Range[];
range(range: Iterable<Range>): ScaleThreshold<Domain, Range>;
copy(): ScaleThreshold<Domain, Range>;
}Functions that create SVG axis elements with ticks, labels, and gridlines.
/**
* Create top-oriented axis (ticks above horizontal line)
* @param scale - Scale function for the axis
* @returns Axis generator function
*/
function axisTop<Domain>(scale: AxisScale<Domain>): Axis<Domain>;
/**
* Create right-oriented axis (ticks right of vertical line)
* @param scale - Scale function for the axis
* @returns Axis generator function
*/
function axisRight<Domain>(scale: AxisScale<Domain>): Axis<Domain>;
/**
* Create bottom-oriented axis (ticks below horizontal line)
* @param scale - Scale function for the axis
* @returns Axis generator function
*/
function axisBottom<Domain>(scale: AxisScale<Domain>): Axis<Domain>;
/**
* Create left-oriented axis (ticks left of vertical line)
* @param scale - Scale function for the axis
* @returns Axis generator function
*/
function axisLeft<Domain>(scale: AxisScale<Domain>): Axis<Domain>;
interface Axis<Domain> {
/**
* Render the axis to a selection
* @param context - Selection to render axis into
*/
(context: Selection<any, any, any, any>): void;
/**
* Get or set the scale for this axis
* @param scale - Scale function
* @returns Axis for chaining or current scale
*/
scale(): AxisScale<Domain>;
scale(scale: AxisScale<Domain>): Axis<Domain>;
/**
* Set tick count and format simultaneously
* @param count - Number of ticks
* @param specifier - Format specifier
* @returns Axis for chaining
*/
ticks(count?: number, specifier?: string): Axis<Domain>;
ticks(interval: any, specifier?: string): Axis<Domain>;
/**
* Set arguments passed to scale.ticks and scale.tickFormat
* @param args - Arguments for tick generation
* @returns Axis for chaining
*/
tickArguments(): any[];
tickArguments(args: any[]): Axis<Domain>;
/**
* Set explicit tick values
* @param values - Array of tick values, or null for scale default
* @returns Axis for chaining or current tick values
*/
tickValues(): Domain[] | null;
tickValues(values: Iterable<Domain> | null): Axis<Domain>;
/**
* Set explicit tick format function
* @param format - Format function, or null for scale default
* @returns Axis for chaining or current format function
*/
tickFormat(): ((d: Domain, i: number) => string) | null;
tickFormat(format: (d: Domain, i: number) => string | null): Axis<Domain>;
/**
* Set size of inner and outer ticks
* @param size - Tick size in pixels
* @returns Axis for chaining or current tick size
*/
tickSize(): number;
tickSize(size: number): Axis<Domain>;
/**
* Set size of inner ticks only
* @param size - Inner tick size in pixels
* @returns Axis for chaining or current inner tick size
*/
tickSizeInner(): number;
tickSizeInner(size: number): Axis<Domain>;
/**
* Set size of outer ticks only (domain path ends)
* @param size - Outer tick size in pixels
* @returns Axis for chaining or current outer tick size
*/
tickSizeOuter(): number;
tickSizeOuter(size: number): Axis<Domain>;
/**
* Set padding between ticks and labels
* @param padding - Padding in pixels
* @returns Axis for chaining or current padding
*/
tickPadding(): number;
tickPadding(padding: number): Axis<Domain>;
/**
* Set pixel offset for crisp edges
* @param offset - Pixel offset
* @returns Axis for chaining or current offset
*/
offset(): number;
offset(offset: number): Axis<Domain>;
}Usage Examples:
import { scaleLinear, axisBottom, axisLeft } from "d3";
// Create scales
const xScale = scaleLinear()
.domain([0, 100])
.range([0, 400]);
const yScale = scaleLinear()
.domain([0, 50])
.range([300, 0]);
// Create axes
const xAxis = axisBottom(xScale)
.ticks(5)
.tickFormat(d => d + "%");
const yAxis = axisLeft(yScale)
.ticks(4)
.tickSize(-400); // Negative size creates gridlines
// Apply to selections
svg.append("g")
.attr("transform", "translate(0, 300)")
.call(xAxis);
svg.append("g")
.call(yAxis);// Core scale types
type NumberValue = number | { valueOf(): number; };
type AxisScale<Domain> = {
(x: Domain): number | undefined;
domain(): Domain[];
range(): number[];
copy(): AxisScale<Domain>;
bandwidth?(): number;
ticks?(count?: number): Domain[];
tickFormat?(count?: number, specifier?: string): (d: Domain) => string;
};
// Time interval type for time scales
interface TimeInterval {
(date: Date): Date;
floor(date: Date): Date;
ceil(date: Date): Date;
round(date: Date): Date;
offset(date: Date, step?: number): Date;
range(start: Date, stop: Date, step?: number): Date[];
}
// Scale domains and ranges
type ScaleContinuousNumeric<Range, Output> = ScaleLinear<number, Range, Output>;
type ScaleSequential<Output> = (t: number) => Output;
type ScaleDiverging<Output> = (t: number) => Output;