or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-loading.mddataflow.mdevents.mdexpressions.mdindex.mdparsing.mdscales.mdscenegraph.mdstatistics.mdtime.mdutilities.mdview.md

parsing.mddocs/

0

# Specification Parsing

1

2

Vega's specification parsing system converts JSON specifications into executable runtime objects, manages configuration merging, and provides runtime context for expression evaluation.

3

4

## Capabilities

5

6

### Core Parsing

7

8

Main specification parser that converts JSON specs to runtime objects.

9

10

```typescript { .api }

11

/**

12

* Parse a Vega specification into executable runtime objects

13

* @param spec - Vega specification object

14

* @param config - Optional configuration object to merge

15

* @param options - Optional parsing configuration

16

* @returns Parsed runtime object ready for view creation

17

*/

18

function parse(spec: Spec, config?: Config, options?: ParseOptions): Runtime;

19

20

interface Spec {

21

/** Schema URL for specification version */

22

$schema?: string;

23

24

/** Visualization description */

25

description?: string;

26

27

/** Visualization configuration */

28

config?: Config;

29

30

/** Visualization width */

31

width?: number | SignalRef;

32

33

/** Visualization height */

34

height?: number | SignalRef;

35

36

/** Padding specification */

37

padding?: Padding | SignalRef;

38

39

/** Autosize configuration */

40

autosize?: AutoSize | SignalRef;

41

42

/** Background color */

43

background?: Color | SignalRef;

44

45

/** Data sources */

46

data?: Data[];

47

48

/** Scale definitions */

49

scales?: Scale[];

50

51

/** Mark definitions */

52

marks?: Mark[];

53

54

/** Signal definitions */

55

signals?: Signal[];

56

57

/** Axis definitions */

58

axes?: Axis[];

59

60

/** Legend definitions */

61

legends?: Legend[];

62

63

/** Title definition */

64

title?: Title;

65

66

/** Projection definitions */

67

projections?: Projection[];

68

69

/** Layout configuration */

70

layout?: Layout;

71

72

/** User metadata */

73

usermeta?: any;

74

}

75

76

interface Runtime {

77

/** Parsed specification definition */

78

definition: any;

79

80

/** Dataflow operators */

81

operators: Operator[];

82

83

/** Event streams */

84

streams: EventStream[];

85

86

/** Signal registry */

87

signals: { [name: string]: Signal };

88

89

/** Data registry */

90

data: { [name: string]: Data };

91

92

/** Scale registry */

93

scales: { [name: string]: Scale };

94

}

95

96

interface ParseOptions {

97

/** Return AST instead of compiled runtime */

98

ast?: boolean;

99

100

/** Expression function registry */

101

functions?: { [name: string]: Function };

102

103

/** Custom operator registry */

104

operators?: { [name: string]: any };

105

}

106

107

type SignalRef = { signal: string };

108

type Color = string;

109

110

interface Padding {

111

top?: number;

112

bottom?: number;

113

left?: number;

114

right?: number;

115

}

116

117

interface AutoSize {

118

type?: 'pad' | 'fit' | 'fit-x' | 'fit-y' | 'none';

119

resize?: boolean;

120

contains?: 'content' | 'padding';

121

}

122

```

123

124

### Configuration System

125

126

Configuration management and merging utilities.

127

128

```typescript { .api }

129

interface Config {

130

/** Global view configuration */

131

view?: ViewConfig;

132

133

/** Mark-specific configurations */

134

mark?: MarkConfig;

135

136

/** Axis configuration */

137

axis?: AxisConfig;

138

139

/** Legend configuration */

140

legend?: LegendConfig;

141

142

/** Title configuration */

143

title?: TitleConfig;

144

145

/** Scale configuration */

146

scale?: ScaleConfig;

147

148

/** Range configuration */

149

range?: RangeConfig;

150

151

/** Selection configuration */

152

selection?: SelectionConfig;

153

154

/** Event configuration */

155

events?: EventConfig;

156

157

/** Custom configuration sections */

158

[key: string]: any;

159

}

160

161

interface ViewConfig {

162

/** View width */

163

width?: number;

164

165

/** View height */

166

height?: number;

167

168

/** View background */

169

background?: Color;

170

171

/** View stroke */

172

stroke?: Color;

173

174

/** View stroke width */

175

strokeWidth?: number;

176

177

/** View fill */

178

fill?: Color;

179

180

/** View padding */

181

padding?: Padding;

182

183

/** Continuous size range */

184

continuousWidth?: number;

185

continuousHeight?: number;

186

187

/** Discrete size range */

188

discreteWidth?: number;

189

discreteHeight?: number;

190

}

191

192

interface MarkConfig {

193

/** Mark fill color */

194

fill?: Color;

195

196

/** Mark stroke color */

197

stroke?: Color;

198

199

/** Mark stroke width */

200

strokeWidth?: number;

201

202

/** Mark opacity */

203

opacity?: number;

204

205

/** Mark fill opacity */

206

fillOpacity?: number;

207

208

/** Mark stroke opacity */

209

strokeOpacity?: number;

210

211

/** Mark size */

212

size?: number;

213

214

/** Mark-specific configurations */

215

rect?: RectConfig;

216

circle?: CircleConfig;

217

line?: LineConfig;

218

text?: TextConfig;

219

[markType: string]: any;

220

}

221

222

interface AxisConfig {

223

/** Axis domain line configuration */

224

domain?: boolean;

225

domainColor?: Color;

226

domainWidth?: number;

227

228

/** Grid line configuration */

229

grid?: boolean;

230

gridColor?: Color;

231

gridWidth?: number;

232

gridDash?: number[];

233

234

/** Tick configuration */

235

ticks?: boolean;

236

tickColor?: Color;

237

tickWidth?: number;

238

tickSize?: number;

239

240

/** Label configuration */

241

labels?: boolean;

242

labelColor?: Color;

243

labelFont?: string;

244

labelFontSize?: number;

245

labelAngle?: number;

246

labelPadding?: number;

247

248

/** Title configuration */

249

title?: boolean;

250

titleColor?: Color;

251

titleFont?: string;

252

titleFontSize?: number;

253

titlePadding?: number;

254

}

255

256

interface RectConfig extends MarkConfig {

257

/** Rectangle corner radius */

258

cornerRadius?: number;

259

}

260

261

interface CircleConfig extends MarkConfig {

262

/** Circle radius */

263

radius?: number;

264

}

265

266

interface LineConfig extends MarkConfig {

267

/** Line interpolation */

268

interpolate?: string;

269

270

/** Line tension */

271

tension?: number;

272

273

/** Line stroke dash */

274

strokeDash?: number[];

275

}

276

277

interface TextConfig extends MarkConfig {

278

/** Text font family */

279

font?: string;

280

281

/** Text font size */

282

fontSize?: number;

283

284

/** Text font weight */

285

fontWeight?: string;

286

287

/** Text font style */

288

fontStyle?: string;

289

290

/** Text alignment */

291

align?: string;

292

293

/** Text baseline */

294

baseline?: string;

295

296

/** Text angle */

297

angle?: number;

298

}

299

```

300

301

### Data Definitions

302

303

Data source specification structures.

304

305

```typescript { .api }

306

interface Data {

307

/** Data source name */

308

name: string;

309

310

/** Data source type */

311

source?: string;

312

313

/** Inline data values */

314

values?: any[];

315

316

/** External data URL */

317

url?: string;

318

319

/** Data format specification */

320

format?: Format;

321

322

/** Data transforms */

323

transform?: Transform[];

324

325

/** Data selection listeners */

326

on?: EventListener[];

327

}

328

329

interface Format {

330

/** Data format type */

331

type?: 'json' | 'csv' | 'tsv' | 'dsv' | 'topojson' | 'geojson';

332

333

/** Parse configuration */

334

parse?: { [field: string]: string } | 'auto';

335

336

/** Property path for nested data */

337

property?: string;

338

339

/** Feature property for GeoJSON */

340

feature?: string;

341

342

/** Mesh property for TopoJSON */

343

mesh?: string;

344

345

/** Field delimiter for DSV */

346

delimiter?: string;

347

348

/** Header row indicator */

349

header?: boolean;

350

}

351

352

interface Transform {

353

/** Transform type */

354

type: string;

355

356

/** Transform-specific parameters */

357

[key: string]: any;

358

}

359

360

interface EventListener {

361

/** Event trigger */

362

trigger: string;

363

364

/** Event handler action */

365

update?: string;

366

367

/** Event handler expression */

368

encode?: string;

369

}

370

```

371

372

### Signal Definitions

373

374

Reactive signal specification structures.

375

376

```typescript { .api }

377

interface Signal {

378

/** Signal name */

379

name: string;

380

381

/** Initial signal value */

382

value?: any;

383

384

/** Signal expression */

385

update?: string;

386

387

/** Signal reaction triggers */

388

on?: SignalListener[];

389

390

/** Signal initialization */

391

init?: string;

392

393

/** Signal binding configuration */

394

bind?: Binding;

395

396

/** Signal description */

397

description?: string;

398

}

399

400

interface SignalListener {

401

/** Event source */

402

events: string | EventSelector[];

403

404

/** Update expression */

405

update?: string;

406

407

/** Encode expression */

408

encode?: string;

409

410

/** Force re-evaluation */

411

force?: boolean;

412

}

413

414

interface Binding {

415

/** Input type */

416

input: 'checkbox' | 'radio' | 'range' | 'select' | 'text' | 'number' | 'date' | 'time' | 'datetime-local' | 'tel' | 'url';

417

418

/** Input element attributes */

419

[attribute: string]: any;

420

}

421

422

interface EventSelector {

423

/** Event source */

424

source?: string;

425

426

/** Event type */

427

type: string;

428

429

/** Event filter */

430

filter?: string;

431

432

/** Debounce delay */

433

debounce?: number;

434

435

/** Throttle delay */

436

throttle?: number;

437

438

/** Event markname filter */

439

markname?: string;

440

441

/** Event marktype filter */

442

marktype?: string;

443

}

444

```

445

446

### Scale Definitions

447

448

Scale specification structures.

449

450

```typescript { .api }

451

interface Scale {

452

/** Scale name */

453

name: string;

454

455

/** Scale type */

456

type: ScaleType;

457

458

/** Scale domain */

459

domain?: Domain;

460

461

/** Scale range */

462

range?: Range;

463

464

/** Scale reverse flag */

465

reverse?: boolean;

466

467

/** Scale rounding */

468

round?: boolean;

469

470

/** Scale clamping */

471

clamp?: boolean;

472

473

/** Scale interpolation */

474

interpolate?: Interpolate;

475

476

/** Scale nice boundaries */

477

nice?: boolean | number;

478

479

/** Scale zero baseline */

480

zero?: boolean;

481

482

/** Scale padding (band/point) */

483

padding?: number;

484

485

/** Scale inner padding (band) */

486

paddingInner?: number;

487

488

/** Scale outer padding (band) */

489

paddingOuter?: number;

490

491

/** Scale alignment (band/point) */

492

align?: number;

493

}

494

495

type ScaleType = 'linear' | 'log' | 'pow' | 'sqrt' | 'symlog' | 'identity' | 'time' | 'utc' | 'sequential' | 'diverging' | 'quantile' | 'quantize' | 'threshold' | 'ordinal' | 'band' | 'point';

496

497

type Domain = any[] | DomainRef;

498

type Range = any[] | RangeRef | string;

499

500

interface DomainRef {

501

/** Data source reference */

502

data?: string;

503

504

/** Field reference */

505

field?: string;

506

507

/** Sort configuration */

508

sort?: boolean | SortOrder;

509

510

/** Union multiple data sources */

511

fields?: FieldRef[];

512

}

513

514

interface RangeRef {

515

/** Range scheme name */

516

scheme?: string;

517

518

/** Range extent */

519

extent?: number[];

520

521

/** Range count */

522

count?: number;

523

}

524

525

interface FieldRef {

526

/** Data source name */

527

data: string;

528

529

/** Field name */

530

field: string;

531

}

532

533

interface SortOrder {

534

/** Sort field */

535

field?: string;

536

537

/** Sort order direction */

538

order?: 'ascending' | 'descending';

539

}

540

541

interface Interpolate {

542

/** Interpolation type */

543

type?: string;

544

545

/** Interpolation gamma */

546

gamma?: number;

547

}

548

```

549

550

### Mark Definitions

551

552

Visual mark specification structures.

553

554

```typescript { .api }

555

interface Mark {

556

/** Mark type */

557

type: MarkType;

558

559

/** Mark name */

560

name?: string;

561

562

/** Mark description */

563

description?: string;

564

565

/** Mark role */

566

role?: string;

567

568

/** Mark style */

569

style?: string | string[];

570

571

/** Mark group/parent */

572

from?: MarkFrom;

573

574

/** Mark encoding */

575

encode?: MarkEncode;

576

577

/** Mark transforms */

578

transform?: Transform[];

579

580

/** Mark sort configuration */

581

sort?: SortOrder;

582

583

/** Clip mark to group bounds */

584

clip?: boolean;

585

586

/** Mark interactive flag */

587

interactive?: boolean;

588

589

/** Mark key field */

590

key?: string;

591

592

/** Nested marks (group marks) */

593

marks?: Mark[];

594

595

/** Group scales */

596

scales?: Scale[];

597

598

/** Group axes */

599

axes?: Axis[];

600

601

/** Group legends */

602

legends?: Legend[];

603

}

604

605

type MarkType = 'arc' | 'area' | 'image' | 'group' | 'line' | 'path' | 'rect' | 'rule' | 'shape' | 'symbol' | 'text' | 'trail';

606

607

interface MarkFrom {

608

/** Data source name */

609

data?: string;

610

611

/** Facet configuration */

612

facet?: FacetMapping;

613

}

614

615

interface FacetMapping {

616

/** Facet data source */

617

data: string;

618

619

/** Facet field */

620

field?: string;

621

622

/** Facet groupby */

623

groupby?: string | string[];

624

625

/** Facet aggregate */

626

aggregate?: AggregateOp;

627

}

628

629

interface MarkEncode {

630

/** Enter encoding set */

631

enter?: EncodeEntry;

632

633

/** Update encoding set */

634

update?: EncodeEntry;

635

636

/** Exit encoding set */

637

exit?: EncodeEntry;

638

639

/** Hover encoding set */

640

hover?: EncodeEntry;

641

642

/** Select encoding set */

643

select?: EncodeEntry;

644

}

645

646

interface EncodeEntry {

647

/** Visual property encodings */

648

[property: string]: ValueRef | ProductionRule[];

649

}

650

651

interface ValueRef {

652

/** Literal value */

653

value?: any;

654

655

/** Field reference */

656

field?: string;

657

658

/** Scale reference */

659

scale?: string;

660

661

/** Band reference */

662

band?: boolean | number;

663

664

/** Offset value */

665

offset?: number | ValueRef;

666

667

/** Multiplication factor */

668

mult?: number | ValueRef;

669

670

/** Signal reference */

671

signal?: string;

672

673

/** Color value reference */

674

color?: ColorRef;

675

676

/** Gradient reference */

677

gradient?: string;

678

679

/** Test condition */

680

test?: string;

681

}

682

683

interface ProductionRule {

684

/** Test condition */

685

test: string;

686

687

/** Value if test passes */

688

value?: any;

689

690

/** Field if test passes */

691

field?: string;

692

693

/** Scale if test passes */

694

scale?: string;

695

696

/** Band if test passes */

697

band?: boolean | number;

698

699

/** Signal if test passes */

700

signal?: string;

701

}

702

703

interface ColorRef {

704

/** Color value */

705

value?: Color;

706

707

/** Gradient definition */

708

gradient?: GradientRef;

709

710

/** Color field */

711

field?: string;

712

713

/** Color scale */

714

scale?: string;

715

}

716

717

interface GradientRef {

718

/** Gradient type */

719

gradient: 'linear' | 'radial';

720

721

/** Color stops */

722

stops: GradientStop[];

723

724

/** Gradient coordinates */

725

x1?: number;

726

y1?: number;

727

x2?: number;

728

y2?: number;

729

r1?: number;

730

r2?: number;

731

}

732

733

interface GradientStop {

734

/** Stop offset (0-1) */

735

offset: number;

736

737

/** Stop color */

738

color: string;

739

}

740

741

type AggregateOp = 'count' | 'mean' | 'average' | 'sum' | 'min' | 'max' | 'median' | 'q1' | 'q3' | 'variance' | 'stdev' | 'stderr' | 'distinct' | 'ci0' | 'ci1' | 'missing' | 'valid';

742

```

743

744

### Runtime Context

745

746

Runtime context creation for expression evaluation.

747

748

```typescript { .api }

749

/**

750

* Create runtime context for expression evaluation

751

* @param dataflow - Dataflow instance

752

* @param signals - Signal registry

753

* @param data - Data registry

754

* @param mutates - Mutation tracking function

755

* @returns Runtime context object

756

*/

757

function runtimeContext(

758

dataflow: Dataflow,

759

signals: { [name: string]: any },

760

data: { [name: string]: any },

761

mutates?: (name: string) => boolean

762

): RuntimeContext;

763

764

interface RuntimeContext {

765

/** Dataflow instance */

766

dataflow: Dataflow;

767

768

/** Signal accessor */

769

signals: { [name: string]: any };

770

771

/** Data accessor */

772

data: { [name: string]: any };

773

774

/** Mutation tracker */

775

mutates?: (name: string) => boolean;

776

777

/** Context functions */

778

functions: { [name: string]: Function };

779

}

780

```

781

782

## Usage Examples

783

784

### Basic Specification Parsing

785

786

```typescript

787

import { parse } from "vega";

788

789

const spec = {

790

"$schema": "https://vega.github.io/schema/vega/v5.json",

791

"width": 400,

792

"height": 200,

793

"data": [

794

{

795

"name": "table",

796

"values": [

797

{"category": "A", "amount": 28},

798

{"category": "B", "amount": 55},

799

{"category": "C", "amount": 43}

800

]

801

}

802

],

803

"scales": [

804

{

805

"name": "xscale",

806

"type": "band",

807

"domain": {"data": "table", "field": "category"},

808

"range": "width",

809

"padding": 0.1

810

},

811

{

812

"name": "yscale",

813

"type": "linear",

814

"domain": {"data": "table", "field": "amount"},

815

"range": "height"

816

}

817

],

818

"marks": [

819

{

820

"type": "rect",

821

"from": {"data": "table"},

822

"encode": {

823

"enter": {

824

"x": {"scale": "xscale", "field": "category"},

825

"width": {"scale": "xscale", "band": 1},

826

"y": {"scale": "yscale", "field": "amount"},

827

"y2": {"scale": "yscale", "value": 0},

828

"fill": {"value": "steelblue"}

829

}

830

}

831

}

832

]

833

};

834

835

const runtime = parse(spec);

836

console.log(runtime.operators.length); // Number of created operators

837

```

838

839

### Configuration Merging

840

841

```typescript

842

import { parse } from "vega";

843

844

const spec = {

845

// ... specification

846

};

847

848

const config = {

849

view: {

850

width: 600,

851

height: 400,

852

background: "#f5f5f5"

853

},

854

mark: {

855

fill: "steelblue",

856

stroke: "white",

857

strokeWidth: 2

858

},

859

axis: {

860

labelFont: "Arial",

861

labelFontSize: 12,

862

titleFont: "Arial",

863

titleFontSize: 14

864

}

865

};

866

867

const runtime = parse(spec, config);

868

```

869

870

### Custom Functions

871

872

```typescript

873

import { parse } from "vega";

874

875

const customFunctions = {

876

myCustomFunction: (value) => {

877

return value * 2 + 10;

878

},

879

formatCurrency: (value) => {

880

return new Intl.NumberFormat('en-US', {

881

style: 'currency',

882

currency: 'USD'

883

}).format(value);

884

}

885

};

886

887

const runtime = parse(spec, null, {

888

functions: customFunctions

889

});

890

```

891

892

### AST Mode

893

894

```typescript

895

import { parse } from "vega";

896

897

// Parse to AST instead of executable runtime

898

const ast = parse(spec, null, { ast: true });

899

console.log(ast); // Abstract syntax tree representation

900

```

901

902

### Complex Data Specification

903

904

```typescript

905

const spec = {

906

"data": [

907

{

908

"name": "source",

909

"url": "data/cars.json"

910

},

911

{

912

"name": "filtered",

913

"source": "source",

914

"transform": [

915

{"type": "filter", "expr": "datum.year > 1970"},

916

{"type": "aggregate", "groupby": ["origin"], "ops": ["mean"], "fields": ["mpg"], "as": ["avg_mpg"]}

917

]

918

}

919

],

920

"scales": [

921

{

922

"name": "x",

923

"type": "linear",

924

"domain": {"data": "filtered", "field": "avg_mpg"},

925

"range": "width"

926

},

927

{

928

"name": "y",

929

"type": "band",

930

"domain": {"data": "filtered", "field": "origin", "sort": {"field": "avg_mpg", "order": "descending"}},

931

"range": "height",

932

"padding": 0.1

933

}

934

]

935

// ... marks

936

};

937

938

const runtime = parse(spec);

939

```

940

941

### Signal-Driven Interactivity

942

943

```typescript

944

const interactiveSpec = {

945

"signals": [

946

{

947

"name": "selectedCategory",

948

"value": null,

949

"on": [

950

{"events": "rect:click", "update": "datum.category"}

951

]

952

},

953

{

954

"name": "highlightOpacity",

955

"value": 0.8,

956

"on": [

957

{"events": "rect:mouseover", "update": "1.0"},

958

{"events": "rect:mouseout", "update": "0.8"}

959

]

960

}

961

],

962

"marks": [

963

{

964

"type": "rect",

965

"encode": {

966

"enter": {

967

"fill": {"value": "steelblue"}

968

},

969

"update": {

970

"fillOpacity": [

971

{"test": "datum.category === selectedCategory", "value": 1.0},

972

{"signal": "highlightOpacity"}

973

]

974

}

975

}

976

}

977

]

978

};

979

980

const runtime = parse(interactiveSpec);

981

```

982

983

### Custom Mark Configuration

984

985

```typescript

986

const configuredSpec = {

987

"config": {

988

"mark": {

989

"tooltip": true

990

},

991

"rect": {

992

"fill": "lightblue",

993

"stroke": "navy",

994

"strokeWidth": 1,

995

"cornerRadius": 3

996

},

997

"text": {

998

"font": "Helvetica",

999

"fontSize": 12,

1000

"fill": "black"

1001

}

1002

},

1003

// ... rest of specification

1004

};

1005

1006

const runtime = parse(configuredSpec);

1007

```

1008

1009

### Runtime Context Usage

1010

1011

```typescript

1012

import { runtimeContext } from "vega";

1013

1014

// Create custom runtime context

1015

const context = runtimeContext(

1016

dataflow,

1017

signalRegistry,

1018

dataRegistry,

1019

(name) => mutatingOperators.has(name)

1020

);

1021

1022

// Use context for expression evaluation

1023

const expressionResult = evaluateExpression("datum.value * signal('multiplier')", context);

1024

```