Visual encoding system that maps data values to visual properties like position, color, and size through various scale types.
Core encoding system for mapping data fields to visual channels.
/**
* Encodes data field to visual channel
* @param channel - Visual channel (x, y, color, size, etc.)
* @param field - Data field name or encoding function
*/
encode(channel: string, field: string | number | EncodeFunction): MarkNode;
/**
* Encoding function type for custom data transformations
*/
type EncodeFunction = (data: any, index: number, array: any[]) => any;
/**
* Available visual channels
*/
type VisualChannel =
| "x" | "y" | "z" // Position channels
| "color" | "fill" | "stroke" // Color channels
| "size" | "radius" // Size channels
| "opacity" | "fillOpacity" | "strokeOpacity" // Opacity channels
| "shape" | "symbol" // Shape channels
| "angle" | "rotate" // Rotation channels
| "text" | "href" // Content channels
| "key" | "groupKey" // Grouping channels
| "series"; // Series channelsBasic Encoding Examples:
// Position encoding
chart
.interval()
.data(salesData)
.encode("x", "month") // X position from month field
.encode("y", "revenue"); // Y position from revenue field
// Color encoding
chart
.point()
.data(dataset)
.encode("x", "height")
.encode("y", "weight")
.encode("color", "gender"); // Color by gender field
// Size encoding
chart
.point()
.data(bubbleData)
.encode("x", "gdp")
.encode("y", "lifeExpectancy")
.encode("size", "population"); // Size by populationScale system for controlling how data values map to visual properties.
/**
* Configures scale for a visual channel
* @param channel - Visual channel to configure
* @param options - Scale configuration options
*/
scale(channel: string, options: ScaleOptions): MarkNode;
interface ScaleOptions {
/** Scale type */
type?: ScaleType;
/** Input domain (data values) */
domain?: any[];
/** Output range (visual values) */
range?: any[];
/** Nice domain boundaries */
nice?: boolean;
/** Include zero in domain */
zero?: boolean;
/** Reverse the scale */
reverse?: boolean;
/** Clamp values to range */
clamp?: boolean;
/** Padding for band/point scales */
padding?: number;
/** Inner padding for band scales */
paddingInner?: number;
/** Outer padding for band scales */
paddingOuter?: number;
/** Align bands within range */
align?: number;
/** Number of ticks for continuous scales */
ticks?: number;
/** Tick values for discrete scales */
tickCount?: number;
/** Custom tick format function */
tickFormat?: (value: any) => string;
/** Label formatter */
formatter?: (value: any) => string;
}
type ScaleType =
| "linear" | "log" | "pow" | "sqrt" | "time" | "sequential" // Continuous
| "ordinal" | "band" | "point" | "threshold" // Discrete
| "identity" | "constant" | "quantile" | "quantize"; // UtilityScales for continuous data types like numbers and dates.
/**
* Linear scale for numeric data with linear progression
*/
scale(channel: string, options: {
type: "linear";
domain?: [number, number];
range?: [number, number] | string[];
nice?: boolean;
zero?: boolean;
clamp?: boolean;
}): MarkNode;
/**
* Logarithmic scale for data with exponential relationships
*/
scale(channel: string, options: {
type: "log";
base?: number;
domain?: [number, number];
range?: [number, number] | any[];
nice?: boolean;
}): MarkNode;
/**
* Power scale for data with power law relationships
*/
scale(channel: string, options: {
type: "pow";
exponent?: number;
domain?: [number, number];
range?: [number, number] | any[];
}): MarkNode;
/**
* Square root scale (power scale with exponent 0.5)
*/
scale(channel: string, options: {
type: "sqrt";
domain?: [number, number];
range?: [number, number] | any[];
}): MarkNode;
/**
* Time scale for temporal data
*/
scale(channel: string, options: {
type: "time";
domain?: [Date, Date];
range?: [number, number] | any[];
nice?: boolean;
}): MarkNode;Continuous Scale Examples:
// Linear scale with custom domain and range
chart
.point()
.data(data)
.encode("x", "income")
.scale("x", {
type: "linear",
domain: [0, 100000],
range: [0, 600],
nice: true
});
// Logarithmic scale for exponential data
chart
.point()
.data(populationData)
.encode("x", "gdp")
.encode("y", "population")
.scale("y", {
type: "log",
base: 10,
domain: [1000, 1000000000]
});
// Time scale for temporal data
chart
.line()
.data(timeSeriesData)
.encode("x", "date")
.encode("y", "value")
.scale("x", {
type: "time",
nice: true
});Scales for categorical and discrete data.
/**
* Ordinal scale for categorical data
*/
scale(channel: string, options: {
type: "ordinal";
domain?: string[];
range?: any[];
}): MarkNode;
/**
* Band scale for bar charts and categorical positioning
*/
scale(channel: string, options: {
type: "band";
domain?: string[];
range?: [number, number];
padding?: number;
paddingInner?: number;
paddingOuter?: number;
align?: number;
}): MarkNode;
/**
* Point scale for scatter plots with categorical X axis
*/
scale(channel: string, options: {
type: "point";
domain?: string[];
range?: [number, number];
padding?: number;
align?: number;
}): MarkNode;
/**
* Threshold scale for mapping continuous data to discrete ranges
*/
scale(channel: string, options: {
type: "threshold";
domain?: number[];
range?: any[];
}): MarkNode;Discrete Scale Examples:
// Ordinal color scale
chart
.point()
.data(categoricalData)
.encode("x", "value")
.encode("y", "score")
.encode("color", "category")
.scale("color", {
type: "ordinal",
domain: ["A", "B", "C"],
range: ["red", "green", "blue"]
});
// Band scale for bar chart
chart
.interval()
.data(salesData)
.encode("x", "product")
.encode("y", "sales")
.scale("x", {
type: "band",
padding: 0.1,
paddingOuter: 0.2
});
// Threshold scale for risk levels
chart
.point()
.data(riskData)
.encode("x", "exposure")
.encode("color", "riskScore")
.scale("color", {
type: "threshold",
domain: [25, 50, 75],
range: ["green", "yellow", "orange", "red"]
});Specialized scales for color encoding.
/**
* Sequential color scale for continuous data
*/
scale(channel: string, options: {
type: "sequential";
domain?: [number, number];
range?: string[];
interpolate?: string; // Color interpolation scheme
reverse?: boolean;
}): MarkNode;
/**
* Quantile scale dividing data into equal-sized groups
*/
scale(channel: string, options: {
type: "quantile";
domain?: number[];
range?: string[];
n?: number; // Number of quantiles
}): MarkNode;
/**
* Quantize scale dividing domain into uniform segments
*/
scale(channel: string, options: {
type: "quantize";
domain?: [number, number];
range?: string[];
n?: number; // Number of segments
}): MarkNode;Color Scale Examples:
// Sequential color scale for heatmap
chart
.rect()
.data(heatmapData)
.encode("x", "category")
.encode("y", "metric")
.encode("color", "value")
.scale("color", {
type: "sequential",
range: ["#f7fbff", "#08519c"],
interpolate: "blues"
});
// Quantile color scale
chart
.point()
.data(distributionData)
.encode("x", "x")
.encode("y", "y")
.encode("color", "density")
.scale("color", {
type: "quantile",
range: ["lightblue", "darkblue"],
n: 5
});Special-purpose scales for specific use cases.
/**
* Identity scale (no transformation)
*/
scale(channel: string, options: {
type: "identity";
}): MarkNode;
/**
* Constant scale (always returns same value)
*/
scale(channel: string, options: {
type: "constant";
value: any;
}): MarkNode;Custom encoding functions for complex data transformations.
/**
* Custom encoding function examples
*/
// Dynamic color based on multiple fields
chart
.point()
.data(data)
.encode("color", (d) => {
if (d.profit > 0) return "green";
if (d.profit < -1000) return "red";
return "orange";
});
// Calculated size encoding
chart
.point()
.data(data)
.encode("size", (d) => Math.sqrt(d.area / Math.PI));
// Conditional text encoding
chart
.text()
.data(data)
.encode("text", (d, i) => i % 2 === 0 ? d.label : "");
// Complex position encoding
chart
.point()
.data(data)
.encode("x", (d) => d.x + Math.random() * 10); // Add jitterUnderstanding how domains and ranges work across different scale types.
// Domain: input data values
// Range: output visual values
// Linear scale mapping
scale("x", {
type: "linear",
domain: [0, 100], // Data from 0 to 100
range: [0, 400] // Maps to pixels 0 to 400
});
// Color scale mapping
scale("color", {
type: "ordinal",
domain: ["A", "B", "C"], // Category values
range: ["red", "green", "blue"] // Color values
});
// Size scale mapping
scale("size", {
type: "linear",
domain: [1, 100], // Data range 1-100
range: [2, 20] // Pixel sizes 2-20
});Options for improving scale readability.
// Nice domains create round numbers at boundaries
scale("y", {
type: "linear",
domain: [1.2, 98.7],
nice: true // Rounds to [0, 100]
});
// Zero option includes zero in domain
scale("y", {
type: "linear",
domain: [20, 80],
zero: true // Extends to [0, 80]
});
// Combination of nice and zero
scale("y", {
type: "linear",
domain: [5, 47],
nice: true,
zero: true // Results in [0, 50]
});