A declarative visualization grammar for creating interactive data visualizations through JSON specifications.
—
Vega's specification parsing system converts JSON specifications into executable runtime objects, manages configuration merging, and provides runtime context for expression evaluation.
Main specification parser that converts JSON specs to runtime objects.
/**
* Parse a Vega specification into executable runtime objects
* @param spec - Vega specification object
* @param config - Optional configuration object to merge
* @param options - Optional parsing configuration
* @returns Parsed runtime object ready for view creation
*/
function parse(spec: Spec, config?: Config, options?: ParseOptions): Runtime;
interface Spec {
/** Schema URL for specification version */
$schema?: string;
/** Visualization description */
description?: string;
/** Visualization configuration */
config?: Config;
/** Visualization width */
width?: number | SignalRef;
/** Visualization height */
height?: number | SignalRef;
/** Padding specification */
padding?: Padding | SignalRef;
/** Autosize configuration */
autosize?: AutoSize | SignalRef;
/** Background color */
background?: Color | SignalRef;
/** Data sources */
data?: Data[];
/** Scale definitions */
scales?: Scale[];
/** Mark definitions */
marks?: Mark[];
/** Signal definitions */
signals?: Signal[];
/** Axis definitions */
axes?: Axis[];
/** Legend definitions */
legends?: Legend[];
/** Title definition */
title?: Title;
/** Projection definitions */
projections?: Projection[];
/** Layout configuration */
layout?: Layout;
/** User metadata */
usermeta?: any;
}
interface Runtime {
/** Parsed specification definition */
definition: any;
/** Dataflow operators */
operators: Operator[];
/** Event streams */
streams: EventStream[];
/** Signal registry */
signals: { [name: string]: Signal };
/** Data registry */
data: { [name: string]: Data };
/** Scale registry */
scales: { [name: string]: Scale };
}
interface ParseOptions {
/** Return AST instead of compiled runtime */
ast?: boolean;
/** Expression function registry */
functions?: { [name: string]: Function };
/** Custom operator registry */
operators?: { [name: string]: any };
}
type SignalRef = { signal: string };
type Color = string;
interface Padding {
top?: number;
bottom?: number;
left?: number;
right?: number;
}
interface AutoSize {
type?: 'pad' | 'fit' | 'fit-x' | 'fit-y' | 'none';
resize?: boolean;
contains?: 'content' | 'padding';
}Configuration management and merging utilities.
interface Config {
/** Global view configuration */
view?: ViewConfig;
/** Mark-specific configurations */
mark?: MarkConfig;
/** Axis configuration */
axis?: AxisConfig;
/** Legend configuration */
legend?: LegendConfig;
/** Title configuration */
title?: TitleConfig;
/** Scale configuration */
scale?: ScaleConfig;
/** Range configuration */
range?: RangeConfig;
/** Selection configuration */
selection?: SelectionConfig;
/** Event configuration */
events?: EventConfig;
/** Custom configuration sections */
[key: string]: any;
}
interface ViewConfig {
/** View width */
width?: number;
/** View height */
height?: number;
/** View background */
background?: Color;
/** View stroke */
stroke?: Color;
/** View stroke width */
strokeWidth?: number;
/** View fill */
fill?: Color;
/** View padding */
padding?: Padding;
/** Continuous size range */
continuousWidth?: number;
continuousHeight?: number;
/** Discrete size range */
discreteWidth?: number;
discreteHeight?: number;
}
interface MarkConfig {
/** Mark fill color */
fill?: Color;
/** Mark stroke color */
stroke?: Color;
/** Mark stroke width */
strokeWidth?: number;
/** Mark opacity */
opacity?: number;
/** Mark fill opacity */
fillOpacity?: number;
/** Mark stroke opacity */
strokeOpacity?: number;
/** Mark size */
size?: number;
/** Mark-specific configurations */
rect?: RectConfig;
circle?: CircleConfig;
line?: LineConfig;
text?: TextConfig;
[markType: string]: any;
}
interface AxisConfig {
/** Axis domain line configuration */
domain?: boolean;
domainColor?: Color;
domainWidth?: number;
/** Grid line configuration */
grid?: boolean;
gridColor?: Color;
gridWidth?: number;
gridDash?: number[];
/** Tick configuration */
ticks?: boolean;
tickColor?: Color;
tickWidth?: number;
tickSize?: number;
/** Label configuration */
labels?: boolean;
labelColor?: Color;
labelFont?: string;
labelFontSize?: number;
labelAngle?: number;
labelPadding?: number;
/** Title configuration */
title?: boolean;
titleColor?: Color;
titleFont?: string;
titleFontSize?: number;
titlePadding?: number;
}
interface RectConfig extends MarkConfig {
/** Rectangle corner radius */
cornerRadius?: number;
}
interface CircleConfig extends MarkConfig {
/** Circle radius */
radius?: number;
}
interface LineConfig extends MarkConfig {
/** Line interpolation */
interpolate?: string;
/** Line tension */
tension?: number;
/** Line stroke dash */
strokeDash?: number[];
}
interface TextConfig extends MarkConfig {
/** Text font family */
font?: string;
/** Text font size */
fontSize?: number;
/** Text font weight */
fontWeight?: string;
/** Text font style */
fontStyle?: string;
/** Text alignment */
align?: string;
/** Text baseline */
baseline?: string;
/** Text angle */
angle?: number;
}Data source specification structures.
interface Data {
/** Data source name */
name: string;
/** Data source type */
source?: string;
/** Inline data values */
values?: any[];
/** External data URL */
url?: string;
/** Data format specification */
format?: Format;
/** Data transforms */
transform?: Transform[];
/** Data selection listeners */
on?: EventListener[];
}
interface Format {
/** Data format type */
type?: 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson' | 'geojson';
/** Parse configuration */
parse?: { [field: string]: string } | 'auto';
/** Property path for nested data */
property?: string;
/** Feature property for GeoJSON */
feature?: string;
/** Mesh property for TopoJSON */
mesh?: string;
/** Field delimiter for DSV */
delimiter?: string;
/** Header row indicator */
header?: boolean;
}
interface Transform {
/** Transform type */
type: string;
/** Transform-specific parameters */
[key: string]: any;
}
interface EventListener {
/** Event trigger */
trigger: string;
/** Event handler action */
update?: string;
/** Event handler expression */
encode?: string;
}Reactive signal specification structures.
interface Signal {
/** Signal name */
name: string;
/** Initial signal value */
value?: any;
/** Signal expression */
update?: string;
/** Signal reaction triggers */
on?: SignalListener[];
/** Signal initialization */
init?: string;
/** Signal binding configuration */
bind?: Binding;
/** Signal description */
description?: string;
}
interface SignalListener {
/** Event source */
events: string | EventSelector[];
/** Update expression */
update?: string;
/** Encode expression */
encode?: string;
/** Force re-evaluation */
force?: boolean;
}
interface Binding {
/** Input type */
input: 'checkbox' | 'radio' | 'range' | 'select' | 'text' | 'number' | 'date' | 'time' | 'datetime-local' | 'tel' | 'url';
/** Input element attributes */
[attribute: string]: any;
}
interface EventSelector {
/** Event source */
source?: string;
/** Event type */
type: string;
/** Event filter */
filter?: string;
/** Debounce delay */
debounce?: number;
/** Throttle delay */
throttle?: number;
/** Event markname filter */
markname?: string;
/** Event marktype filter */
marktype?: string;
}Scale specification structures.
interface Scale {
/** Scale name */
name: string;
/** Scale type */
type: ScaleType;
/** Scale domain */
domain?: Domain;
/** Scale range */
range?: Range;
/** Scale reverse flag */
reverse?: boolean;
/** Scale rounding */
round?: boolean;
/** Scale clamping */
clamp?: boolean;
/** Scale interpolation */
interpolate?: Interpolate;
/** Scale nice boundaries */
nice?: boolean | number;
/** Scale zero baseline */
zero?: boolean;
/** Scale padding (band/point) */
padding?: number;
/** Scale inner padding (band) */
paddingInner?: number;
/** Scale outer padding (band) */
paddingOuter?: number;
/** Scale alignment (band/point) */
align?: number;
}
type ScaleType = 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'identity' | 'time' | 'utc' | 'sequential' | 'diverging' | 'quantile' | 'quantize' | 'threshold' | 'ordinal' | 'band' | 'point';
type Domain = any[] | DomainRef;
type Range = any[] | RangeRef | string;
interface DomainRef {
/** Data source reference */
data?: string;
/** Field reference */
field?: string;
/** Sort configuration */
sort?: boolean | SortOrder;
/** Union multiple data sources */
fields?: FieldRef[];
}
interface RangeRef {
/** Range scheme name */
scheme?: string;
/** Range extent */
extent?: number[];
/** Range count */
count?: number;
}
interface FieldRef {
/** Data source name */
data: string;
/** Field name */
field: string;
}
interface SortOrder {
/** Sort field */
field?: string;
/** Sort order direction */
order?: 'ascending' | 'descending';
}
interface Interpolate {
/** Interpolation type */
type?: string;
/** Interpolation gamma */
gamma?: number;
}Visual mark specification structures.
interface Mark {
/** Mark type */
type: MarkType;
/** Mark name */
name?: string;
/** Mark description */
description?: string;
/** Mark role */
role?: string;
/** Mark style */
style?: string | string[];
/** Mark group/parent */
from?: MarkFrom;
/** Mark encoding */
encode?: MarkEncode;
/** Mark transforms */
transform?: Transform[];
/** Mark sort configuration */
sort?: SortOrder;
/** Clip mark to group bounds */
clip?: boolean;
/** Mark interactive flag */
interactive?: boolean;
/** Mark key field */
key?: string;
/** Nested marks (group marks) */
marks?: Mark[];
/** Group scales */
scales?: Scale[];
/** Group axes */
axes?: Axis[];
/** Group legends */
legends?: Legend[];
}
type MarkType = 'arc' | 'area' | 'image' | 'group' | 'line' | 'path' | 'rect' | 'rule' | 'shape' | 'symbol' | 'text' | 'trail';
interface MarkFrom {
/** Data source name */
data?: string;
/** Facet configuration */
facet?: FacetMapping;
}
interface FacetMapping {
/** Facet data source */
data: string;
/** Facet field */
field?: string;
/** Facet groupby */
groupby?: string | string[];
/** Facet aggregate */
aggregate?: AggregateOp;
}
interface MarkEncode {
/** Enter encoding set */
enter?: EncodeEntry;
/** Update encoding set */
update?: EncodeEntry;
/** Exit encoding set */
exit?: EncodeEntry;
/** Hover encoding set */
hover?: EncodeEntry;
/** Select encoding set */
select?: EncodeEntry;
}
interface EncodeEntry {
/** Visual property encodings */
[property: string]: ValueRef | ProductionRule[];
}
interface ValueRef {
/** Literal value */
value?: any;
/** Field reference */
field?: string;
/** Scale reference */
scale?: string;
/** Band reference */
band?: boolean | number;
/** Offset value */
offset?: number | ValueRef;
/** Multiplication factor */
mult?: number | ValueRef;
/** Signal reference */
signal?: string;
/** Color value reference */
color?: ColorRef;
/** Gradient reference */
gradient?: string;
/** Test condition */
test?: string;
}
interface ProductionRule {
/** Test condition */
test: string;
/** Value if test passes */
value?: any;
/** Field if test passes */
field?: string;
/** Scale if test passes */
scale?: string;
/** Band if test passes */
band?: boolean | number;
/** Signal if test passes */
signal?: string;
}
interface ColorRef {
/** Color value */
value?: Color;
/** Gradient definition */
gradient?: GradientRef;
/** Color field */
field?: string;
/** Color scale */
scale?: string;
}
interface GradientRef {
/** Gradient type */
gradient: 'linear' | 'radial';
/** Color stops */
stops: GradientStop[];
/** Gradient coordinates */
x1?: number;
y1?: number;
x2?: number;
y2?: number;
r1?: number;
r2?: number;
}
interface GradientStop {
/** Stop offset (0-1) */
offset: number;
/** Stop color */
color: string;
}
type AggregateOp = 'count' | 'mean' | 'average' | 'sum' | 'min' | 'max' | 'median' | 'q1' | 'q3' | 'variance' | 'stdev' | 'stderr' | 'distinct' | 'ci0' | 'ci1' | 'missing' | 'valid';Runtime context creation for expression evaluation.
/**
* Create runtime context for expression evaluation
* @param dataflow - Dataflow instance
* @param signals - Signal registry
* @param data - Data registry
* @param mutates - Mutation tracking function
* @returns Runtime context object
*/
function runtimeContext(
dataflow: Dataflow,
signals: { [name: string]: any },
data: { [name: string]: any },
mutates?: (name: string) => boolean
): RuntimeContext;
interface RuntimeContext {
/** Dataflow instance */
dataflow: Dataflow;
/** Signal accessor */
signals: { [name: string]: any };
/** Data accessor */
data: { [name: string]: any };
/** Mutation tracker */
mutates?: (name: string) => boolean;
/** Context functions */
functions: { [name: string]: Function };
}import { parse } from "vega";
const spec = {
"$schema": "https://vega.github.io/schema/vega/v5.json",
"width": 400,
"height": 200,
"data": [
{
"name": "table",
"values": [
{"category": "A", "amount": 28},
{"category": "B", "amount": 55},
{"category": "C", "amount": 43}
]
}
],
"scales": [
{
"name": "xscale",
"type": "band",
"domain": {"data": "table", "field": "category"},
"range": "width",
"padding": 0.1
},
{
"name": "yscale",
"type": "linear",
"domain": {"data": "table", "field": "amount"},
"range": "height"
}
],
"marks": [
{
"type": "rect",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"scale": "xscale", "field": "category"},
"width": {"scale": "xscale", "band": 1},
"y": {"scale": "yscale", "field": "amount"},
"y2": {"scale": "yscale", "value": 0},
"fill": {"value": "steelblue"}
}
}
}
]
};
const runtime = parse(spec);
console.log(runtime.operators.length); // Number of created operatorsimport { parse } from "vega";
const spec = {
// ... specification
};
const config = {
view: {
width: 600,
height: 400,
background: "#f5f5f5"
},
mark: {
fill: "steelblue",
stroke: "white",
strokeWidth: 2
},
axis: {
labelFont: "Arial",
labelFontSize: 12,
titleFont: "Arial",
titleFontSize: 14
}
};
const runtime = parse(spec, config);import { parse } from "vega";
const customFunctions = {
myCustomFunction: (value) => {
return value * 2 + 10;
},
formatCurrency: (value) => {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(value);
}
};
const runtime = parse(spec, null, {
functions: customFunctions
});import { parse } from "vega";
// Parse to AST instead of executable runtime
const ast = parse(spec, null, { ast: true });
console.log(ast); // Abstract syntax tree representationconst spec = {
"data": [
{
"name": "source",
"url": "data/cars.json"
},
{
"name": "filtered",
"source": "source",
"transform": [
{"type": "filter", "expr": "datum.year > 1970"},
{"type": "aggregate", "groupby": ["origin"], "ops": ["mean"], "fields": ["mpg"], "as": ["avg_mpg"]}
]
}
],
"scales": [
{
"name": "x",
"type": "linear",
"domain": {"data": "filtered", "field": "avg_mpg"},
"range": "width"
},
{
"name": "y",
"type": "band",
"domain": {"data": "filtered", "field": "origin", "sort": {"field": "avg_mpg", "order": "descending"}},
"range": "height",
"padding": 0.1
}
]
// ... marks
};
const runtime = parse(spec);const interactiveSpec = {
"signals": [
{
"name": "selectedCategory",
"value": null,
"on": [
{"events": "rect:click", "update": "datum.category"}
]
},
{
"name": "highlightOpacity",
"value": 0.8,
"on": [
{"events": "rect:mouseover", "update": "1.0"},
{"events": "rect:mouseout", "update": "0.8"}
]
}
],
"marks": [
{
"type": "rect",
"encode": {
"enter": {
"fill": {"value": "steelblue"}
},
"update": {
"fillOpacity": [
{"test": "datum.category === selectedCategory", "value": 1.0},
{"signal": "highlightOpacity"}
]
}
}
}
]
};
const runtime = parse(interactiveSpec);const configuredSpec = {
"config": {
"mark": {
"tooltip": true
},
"rect": {
"fill": "lightblue",
"stroke": "navy",
"strokeWidth": 1,
"cornerRadius": 3
},
"text": {
"font": "Helvetica",
"fontSize": 12,
"fill": "black"
}
},
// ... rest of specification
};
const runtime = parse(configuredSpec);import { runtimeContext } from "vega";
// Create custom runtime context
const context = runtimeContext(
dataflow,
signalRegistry,
dataRegistry,
(name) => mutatingOperators.has(name)
);
// Use context for expression evaluation
const expressionResult = evaluateExpression("datum.value * signal('multiplier')", context);Install with Tessl CLI
npx tessl i tessl/npm-vega