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

scales.mddocs/

0

# Scales & Projections

1

2

Vega's scale and projection system provides data encoding through scales that map data values to visual properties, color schemes for categorical and continuous data, and geographic projections for cartographic visualizations.

3

4

## Capabilities

5

6

### Scale System

7

8

Core scale creation and management for data encoding.

9

10

```typescript { .api }

11

/**

12

* Create or access a scale function

13

* @param type - Scale type identifier

14

* @param scale - Optional scale configuration object

15

* @returns Scale function or scale registry entry

16

*/

17

function scale(type: string, scale?: ScaleConfig): ScaleFunction | any;

18

19

/**

20

* Access color scheme by name

21

* @param name - Color scheme name

22

* @param scheme - Optional scheme definition to register

23

* @returns Color scheme array or registration result

24

*/

25

function scheme(name: string, scheme?: ColorScheme): string[] | any;

26

27

interface ScaleConfig {

28

/** Scale domain (input range) */

29

domain?: any[];

30

31

/** Scale range (output range) */

32

range?: any[];

33

34

/** Scale type-specific parameters */

35

[key: string]: any;

36

}

37

38

interface ScaleFunction {

39

/** Map domain value to range value */

40

(value: any): any;

41

42

/** Get or set the scale domain */

43

domain(): any[];

44

domain(domain: any[]): ScaleFunction;

45

46

/** Get or set the scale range */

47

range(): any[];

48

range(range: any[]): ScaleFunction;

49

50

/** Create inverted scale function */

51

invert?(value: any): any;

52

53

/** Get scale bandwidth (for band scales) */

54

bandwidth?(): number;

55

56

/** Get scale step (for band scales) */

57

step?(): number;

58

59

/** Copy the scale */

60

copy(): ScaleFunction;

61

}

62

63

type ColorScheme = string[] | { [key: string]: string[] };

64

```

65

66

### Scale Types

67

68

Built-in scale types for different data mappings.

69

70

```typescript { .api }

71

/** Linear scale for continuous numeric data */

72

type LinearScale = ScaleFunction & {

73

/** Get scale ticks */

74

ticks(count?: number): number[];

75

76

/** Get tick format function */

77

tickFormat(count?: number, specifier?: string): (value: number) => string;

78

79

/** Set interpolator function */

80

interpolate(interpolator: (a: any, b: any) => (t: number) => any): LinearScale;

81

82

/** Set clamping behavior */

83

clamp(clamp: boolean): LinearScale;

84

clamp(): boolean;

85

86

/** Set nice domain boundaries */

87

nice(count?: number): LinearScale;

88

};

89

90

/** Log scale for exponential data */

91

type LogScale = ScaleFunction & {

92

/** Set logarithm base */

93

base(base: number): LogScale;

94

base(): number;

95

96

/** Get scale ticks */

97

ticks(count?: number): number[];

98

99

/** Get tick format function */

100

tickFormat(count?: number, specifier?: string): (value: number) => string;

101

102

/** Set clamping behavior */

103

clamp(clamp: boolean): LogScale;

104

clamp(): boolean;

105

106

/** Set nice domain boundaries */

107

nice(): LogScale;

108

};

109

110

/** Power scale with configurable exponent */

111

type PowScale = ScaleFunction & {

112

/** Set power exponent */

113

exponent(exponent: number): PowScale;

114

exponent(): number;

115

116

/** Get scale ticks */

117

ticks(count?: number): number[];

118

119

/** Get tick format function */

120

tickFormat(count?: number, specifier?: string): (value: number) => string;

121

122

/** Set clamping behavior */

123

clamp(clamp: boolean): PowScale;

124

clamp(): boolean;

125

126

/** Set nice domain boundaries */

127

nice(count?: number): PowScale;

128

};

129

130

/** Square root scale (power scale with exponent 0.5) */

131

type SqrtScale = PowScale;

132

133

/** Symmetric log scale for data including zero */

134

type SymlogScale = ScaleFunction & {

135

/** Set linear threshold around zero */

136

constant(constant: number): SymlogScale;

137

constant(): number;

138

139

/** Get scale ticks */

140

ticks(count?: number): number[];

141

142

/** Get tick format function */

143

tickFormat(count?: number, specifier?: string): (value: number) => string;

144

145

/** Set clamping behavior */

146

clamp(clamp: boolean): SymlogScale;

147

clamp(): boolean;

148

149

/** Set nice domain boundaries */

150

nice(): SymlogScale;

151

};

152

153

/** Identity scale (passthrough) */

154

type IdentityScale = ScaleFunction;

155

156

/** Time scale for temporal data */

157

type TimeScale = ScaleFunction & {

158

/** Get scale ticks */

159

ticks(interval?: any): Date[];

160

161

/** Get tick format function */

162

tickFormat(count?: number, specifier?: string): (value: Date) => string;

163

164

/** Set clamping behavior */

165

clamp(clamp: boolean): TimeScale;

166

clamp(): boolean;

167

168

/** Set nice domain boundaries */

169

nice(interval?: any): TimeScale;

170

};

171

172

/** UTC time scale */

173

type UTCScale = TimeScale;

174

175

/** Sequential scale for continuous color mapping */

176

type SequentialScale = ScaleFunction & {

177

/** Set interpolator function */

178

interpolator(interpolator: (t: number) => any): SequentialScale;

179

interpolator(): (t: number) => any;

180

181

/** Set clamping behavior */

182

clamp(clamp: boolean): SequentialScale;

183

clamp(): boolean;

184

};

185

186

/** Diverging scale for data with meaningful center */

187

type DivergingScale = ScaleFunction & {

188

/** Set interpolator function */

189

interpolator(interpolator: (t: number) => any): DivergingScale;

190

interpolator(): (t: number) => any;

191

192

/** Set clamping behavior */

193

clamp(clamp: boolean): DivergingScale;

194

clamp(): boolean;

195

};

196

197

/** Quantile scale for statistical distributions */

198

type QuantileScale = ScaleFunction & {

199

/** Get quantiles array */

200

quantiles(): number[];

201

};

202

203

/** Quantize scale for uniform binning */

204

type QuantizeScale = ScaleFunction & {

205

/** Get thresholds array */

206

thresholds(): number[];

207

208

/** Set nice domain boundaries */

209

nice(count?: number): QuantizeScale;

210

};

211

212

/** Threshold scale for custom breakpoints */

213

type ThresholdScale = ScaleFunction & {

214

/** Set threshold values */

215

thresholds(thresholds: number[]): ThresholdScale;

216

thresholds(): number[];

217

};

218

219

/** Ordinal scale for categorical data */

220

type OrdinalScale = ScaleFunction & {

221

/** Get unknown value handler */

222

unknown(): any;

223

unknown(value: any): OrdinalScale;

224

};

225

226

/** Band scale for bar charts and similar */

227

type BandScale = ScaleFunction & {

228

/** Get bandwidth of each band */

229

bandwidth(): number;

230

231

/** Get step between band starts */

232

step(): number;

233

234

/** Set padding between bands */

235

padding(padding: number): BandScale;

236

padding(): number;

237

238

/** Set inner padding between bands */

239

paddingInner(padding: number): BandScale;

240

paddingInner(): number;

241

242

/** Set outer padding at scale edges */

243

paddingOuter(padding: number): BandScale;

244

paddingOuter(): number;

245

246

/** Set alignment of bands within range */

247

align(align: number): BandScale;

248

align(): number;

249

250

/** Round band positions to integers */

251

round(round: boolean): BandScale;

252

round(): boolean;

253

};

254

255

/** Point scale for scatterplots */

256

type PointScale = ScaleFunction & {

257

/** Get step between points */

258

step(): number;

259

260

/** Set padding at scale edges */

261

padding(padding: number): PointScale;

262

padding(): number;

263

264

/** Set alignment of points within range */

265

align(align: number): PointScale;

266

align(): number;

267

268

/** Round point positions to integers */

269

round(round: boolean): PointScale;

270

round(): boolean;

271

};

272

```

273

274

### Interpolation Functions

275

276

Value interpolation for continuous scales.

277

278

```typescript { .api }

279

/**

280

* Create interpolation function for continuous scales

281

* @param type - Interpolation type

282

* @param options - Interpolation options

283

* @returns Interpolation function

284

*/

285

function interpolate(type: string, options?: InterpolationOptions): (a: any, b: any) => (t: number) => any;

286

287

/**

288

* Color interpolation for color scales

289

* @param colors - Array of color values

290

* @param type - Interpolation type ('rgb', 'hsl', 'lab', etc.)

291

* @param options - Interpolation options

292

* @returns Color interpolation function

293

*/

294

function interpolateColors(colors: any[], type?: string, options?: InterpolationOptions): (t: number) => string;

295

296

/**

297

* Range interpolation for scale ranges

298

* @param range - Range values to interpolate

299

* @returns Range interpolation function

300

*/

301

function interpolateRange(range: any[]): (t: number) => any;

302

303

/**

304

* Create quantized interpolator

305

* @param interpolator - Base interpolation function

306

* @param count - Number of discrete steps

307

* @returns Quantized interpolation function

308

*/

309

function quantizeInterpolator(interpolator: (t: number) => any, count: number): (t: number) => any;

310

311

interface InterpolationOptions {

312

/** Color space for color interpolation */

313

colorSpace?: 'rgb' | 'hsl' | 'hcl' | 'lab' | 'cubehelix';

314

315

/** Gamma correction for color interpolation */

316

gamma?: number;

317

318

/** Use shorter hue path for hue interpolation */

319

hue?: 'shorter' | 'longer' | 'increasing' | 'decreasing';

320

}

321

```

322

323

### Scale Transformations

324

325

Scale manipulation utilities for panning and zooming.

326

327

```typescript { .api }

328

/**

329

* Pan linear scale by specified offset

330

* @param scale - Linear scale to pan

331

* @param offset - Pan offset amount

332

* @returns New panned scale

333

*/

334

function panLinear(scale: LinearScale, offset: number): LinearScale;

335

336

/**

337

* Pan logarithmic scale by specified offset

338

* @param scale - Log scale to pan

339

* @param offset - Pan offset amount

340

* @returns New panned scale

341

*/

342

function panLog(scale: LogScale, offset: number): LogScale;

343

344

/**

345

* Pan power scale by specified offset

346

* @param scale - Power scale to pan

347

* @param offset - Pan offset amount

348

* @returns New panned scale

349

*/

350

function panPow(scale: PowScale, offset: number): PowScale;

351

352

/**

353

* Pan symmetric log scale by specified offset

354

* @param scale - Symlog scale to pan

355

* @param offset - Pan offset amount

356

* @returns New panned scale

357

*/

358

function panSymlog(scale: SymlogScale, offset: number): SymlogScale;

359

360

/**

361

* Zoom linear scale by specified factor

362

* @param scale - Linear scale to zoom

363

* @param anchor - Zoom anchor point

364

* @param factor - Zoom factor (>1 zooms in, <1 zooms out)

365

* @returns New zoomed scale

366

*/

367

function zoomLinear(scale: LinearScale, anchor: number, factor: number): LinearScale;

368

369

/**

370

* Zoom logarithmic scale by specified factor

371

* @param scale - Log scale to zoom

372

* @param anchor - Zoom anchor point

373

* @param factor - Zoom factor

374

* @returns New zoomed scale

375

*/

376

function zoomLog(scale: LogScale, anchor: number, factor: number): LogScale;

377

378

/**

379

* Zoom power scale by specified factor

380

* @param scale - Power scale to zoom

381

* @param anchor - Zoom anchor point

382

* @param factor - Zoom factor

383

* @returns New zoomed scale

384

*/

385

function zoomPow(scale: PowScale, anchor: number, factor: number): PowScale;

386

387

/**

388

* Zoom symmetric log scale by specified factor

389

* @param scale - Symlog scale to zoom

390

* @param anchor - Zoom anchor point

391

* @param factor - Zoom factor

392

* @returns New zoomed scale

393

*/

394

function zoomSymlog(scale: SymlogScale, anchor: number, factor: number): SymlogScale;

395

```

396

397

### Geographic Projections

398

399

Geographic coordinate system transformations.

400

401

```typescript { .api }

402

/**

403

* Create or access a geographic projection

404

* @param type - Projection type identifier

405

* @param projection - Optional projection configuration

406

* @returns Projection function or projection registry entry

407

*/

408

function projection(type: string, projection?: ProjectionConfig): ProjectionFunction | any;

409

410

interface ProjectionConfig {

411

/** Projection center coordinates [longitude, latitude] */

412

center?: [number, number];

413

414

/** Projection rotation [yaw, pitch, roll] */

415

rotate?: [number, number, number?];

416

417

/** Projection scale factor */

418

scale?: number;

419

420

/** Projection translation offset [x, y] */

421

translate?: [number, number];

422

423

/** Clipping extent [[x0, y0], [x1, y1]] */

424

clipExtent?: [[number, number], [number, number]];

425

426

/** Clipping angle in degrees */

427

clipAngle?: number;

428

429

/** Precision for adaptive resampling */

430

precision?: number;

431

432

/** Projection-specific parameters */

433

[key: string]: any;

434

}

435

436

interface ProjectionFunction {

437

/** Project geographic coordinates to screen coordinates */

438

(coordinates: [number, number]): [number, number] | null;

439

440

/** Inverse projection from screen to geographic coordinates */

441

invert?(coordinates: [number, number]): [number, number] | null;

442

443

/** Get or set projection center */

444

center(): [number, number];

445

center(center: [number, number]): ProjectionFunction;

446

447

/** Get or set projection rotation */

448

rotate(): [number, number, number?];

449

rotate(angles: [number, number, number?]): ProjectionFunction;

450

451

/** Get or set projection scale */

452

scale(): number;

453

scale(scale: number): ProjectionFunction;

454

455

/** Get or set projection translation */

456

translate(): [number, number];

457

translate(translate: [number, number]): ProjectionFunction;

458

459

/** Get or set clipping extent */

460

clipExtent(): [[number, number], [number, number]] | null;

461

clipExtent(extent: [[number, number], [number, number]] | null): ProjectionFunction;

462

463

/** Get or set clipping angle */

464

clipAngle(): number | null;

465

clipAngle(angle: number | null): ProjectionFunction;

466

467

/** Get or set precision */

468

precision(): number;

469

precision(precision: number): ProjectionFunction;

470

471

/** Fit projection to geographic bounds */

472

fitExtent?(extent: [[number, number], [number, number]], object: any): ProjectionFunction;

473

474

/** Fit projection to geographic size */

475

fitSize?(size: [number, number], object: any): ProjectionFunction;

476

477

/** Copy the projection */

478

copy(): ProjectionFunction;

479

}

480

```

481

482

### Built-in Color Schemes

483

484

Predefined color schemes for data visualization.

485

486

```typescript { .api }

487

/** Categorical color schemes */

488

interface CategoricalSchemes {

489

/** 10-color categorical palette */

490

category10: string[];

491

492

/** 20-color categorical palette */

493

category20: string[];

494

495

/** 20b-color categorical palette */

496

category20b: string[];

497

498

/** 20c-color categorical palette */

499

category20c: string[];

500

501

/** Accent color scheme */

502

accent: string[];

503

504

/** Dark2 color scheme */

505

dark2: string[];

506

507

/** Paired color scheme */

508

paired: string[];

509

510

/** Pastel1 color scheme */

511

pastel1: string[];

512

513

/** Pastel2 color scheme */

514

pastel2: string[];

515

516

/** Set1 color scheme */

517

set1: string[];

518

519

/** Set2 color scheme */

520

set2: string[];

521

522

/** Set3 color scheme */

523

set3: string[];

524

525

/** Tableau10 color scheme */

526

tableau10: string[];

527

528

/** Tableau20 color scheme */

529

tableau20: string[];

530

}

531

532

/** Sequential color schemes */

533

interface SequentialSchemes {

534

/** Blues sequential scheme */

535

blues: string[];

536

537

/** Greens sequential scheme */

538

greens: string[];

539

540

/** Oranges sequential scheme */

541

oranges: string[];

542

543

/** Purples sequential scheme */

544

purples: string[];

545

546

/** Reds sequential scheme */

547

reds: string[];

548

549

/** Greys sequential scheme */

550

greys: string[];

551

552

/** Turbo perceptually uniform scheme */

553

turbo: string[];

554

555

/** Viridis perceptually uniform scheme */

556

viridis: string[];

557

558

/** Plasma perceptually uniform scheme */

559

plasma: string[];

560

561

/** Inferno perceptually uniform scheme */

562

inferno: string[];

563

564

/** Magma perceptually uniform scheme */

565

magma: string[];

566

567

/** Cividis colorblind-friendly scheme */

568

cividis: string[];

569

}

570

571

/** Diverging color schemes */

572

interface DivergingSchemes {

573

/** Blue-Red diverging scheme */

574

blueorange: string[];

575

576

/** Blue-White-Red diverging scheme */

577

bluewhitered: string[];

578

579

/** Brown-Blue-Green diverging scheme */

580

brownbluegreen: string[];

581

582

/** Purple-Green diverging scheme */

583

purplegreen: string[];

584

585

/** Purple-Orange diverging scheme */

586

purpleorange: string[];

587

588

/** Red-Blue diverging scheme */

589

redblue: string[];

590

591

/** Red-Grey diverging scheme */

592

redgrey: string[];

593

594

/** Red-Yellow-Blue diverging scheme */

595

redyellowblue: string[];

596

597

/** Red-Yellow-Green diverging scheme */

598

redyellowgreen: string[];

599

600

/** Spectral diverging scheme */

601

spectral: string[];

602

}

603

```

604

605

## Usage Examples

606

607

### Basic Scale Usage

608

609

```typescript

610

import { scale } from "vega";

611

612

// Create linear scale

613

const xScale = scale('linear')

614

.domain([0, 100])

615

.range([0, 400]);

616

617

console.log(xScale(50)); // 200

618

619

// Create ordinal scale

620

const colorScale = scale('ordinal')

621

.domain(['A', 'B', 'C'])

622

.range(['red', 'green', 'blue']);

623

624

console.log(colorScale('B')); // 'green'

625

```

626

627

### Time Scale

628

629

```typescript

630

import { scale } from "vega";

631

632

const timeScale = scale('time')

633

.domain([new Date('2023-01-01'), new Date('2023-12-31')])

634

.range([0, 500]);

635

636

// Map date to pixel position

637

const position = timeScale(new Date('2023-06-15'));

638

639

// Get nice tick values

640

const ticks = timeScale.ticks(5);

641

const tickFormat = timeScale.tickFormat(5, '%b');

642

```

643

644

### Band Scale for Bar Charts

645

646

```typescript

647

import { scale } from "vega";

648

649

const xScale = scale('band')

650

.domain(['Q1', 'Q2', 'Q3', 'Q4'])

651

.range([0, 400])

652

.padding(0.1);

653

654

// Get bar positions and widths

655

const barWidth = xScale.bandwidth();

656

const q2Position = xScale('Q2');

657

658

console.log(`Q2 bar at ${q2Position}, width ${barWidth}`);

659

```

660

661

### Color Schemes

662

663

```typescript

664

import { scheme, scale } from "vega";

665

666

// Use built-in color scheme

667

const colors = scheme('category10');

668

const colorScale = scale('ordinal')

669

.domain(['A', 'B', 'C'])

670

.range(colors);

671

672

// Sequential color scale

673

const seqColors = scheme('blues');

674

const heatmapScale = scale('sequential')

675

.domain([0, 100])

676

.range(seqColors);

677

```

678

679

### Custom Interpolation

680

681

```typescript

682

import { scale, interpolate, interpolateColors } from "vega";

683

684

// Custom color interpolation

685

const customColors = interpolateColors(['#ff0000', '#00ff00', '#0000ff'], 'lab');

686

687

const colorScale = scale('linear')

688

.domain([0, 100])

689

.range([0, 1])

690

.interpolate(() => customColors);

691

692

console.log(colorScale(50)); // Interpolated color

693

```

694

695

### Geographic Projections

696

697

```typescript

698

import { projection } from "vega";

699

700

// Create Mercator projection

701

const proj = projection('mercator')

702

.scale(1000)

703

.center([0, 0])

704

.translate([400, 300]);

705

706

// Project coordinates

707

const [x, y] = proj([-74, 40.7]); // NYC coordinates

708

console.log(`NYC at screen coordinates: ${x}, ${y}`);

709

710

// Inverse projection

711

const [lng, lat] = proj.invert([x, y]);

712

console.log(`Back to geo coordinates: ${lng}, ${lat}`);

713

```

714

715

### Scale Transformations

716

717

```typescript

718

import { scale, panLinear, zoomLinear } from "vega";

719

720

const baseScale = scale('linear')

721

.domain([0, 100])

722

.range([0, 500]);

723

724

// Pan the scale

725

const pannedScale = panLinear(baseScale, 50);

726

console.log(pannedScale.domain()); // [50, 150]

727

728

// Zoom the scale

729

const zoomedScale = zoomLinear(baseScale, 50, 2);

730

console.log(zoomedScale.domain()); // [25, 75]

731

```

732

733

### Quantile Scale

734

735

```typescript

736

import { scale } from "vega";

737

738

const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

739

740

const quantileScale = scale('quantile')

741

.domain(data)

742

.range(['low', 'medium', 'high']);

743

744

console.log(quantileScale(3)); // 'low'

745

console.log(quantileScale(7)); // 'medium'

746

console.log(quantileScale(9)); // 'high'

747

748

// Get quantile boundaries

749

const quantiles = quantileScale.quantiles();

750

console.log(quantiles); // [3.25, 6.75]

751

```

752

753

### Threshold Scale

754

755

```typescript

756

import { scale } from "vega";

757

758

const thresholdScale = scale('threshold')

759

.domain([0, 50, 100])

760

.range(['low', 'medium', 'high', 'very high']);

761

762

console.log(thresholdScale(-10)); // 'low'

763

console.log(thresholdScale(25)); // 'low'

764

console.log(thresholdScale(75)); // 'medium'

765

console.log(thresholdScale(150)); // 'very high'

766

```

767

768

### Complex Projection Setup

769

770

```typescript

771

import { projection } from "vega";

772

773

// Albers projection for US maps

774

const usProjection = projection('albers')

775

.rotate([96, 0])

776

.center([-0.6, 38.7])

777

.parallels([29.5, 45.5])

778

.scale(1000)

779

.translate([400, 250]);

780

781

// Fit projection to bounding box

782

const bounds = {

783

type: "FeatureCollection",

784

features: [/* GeoJSON features */]

785

};

786

787

usProjection.fitSize([800, 500], bounds);

788

```