or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdchart-types.mdcore-plotting.mddata-streaming.mddata-updates.mdexport-utilities.mdindex.mdinteractive-components.mdlayout-system.mdtrace-management.md

layout-system.mddocs/

0

# Layout System

1

2

Comprehensive layout controls for plot appearance, axes, legends, annotations, and interactive elements. The layout system controls everything outside of the actual data traces.

3

4

## Core Layout Structure

5

6

```javascript { .api }

7

interface Layout {

8

// Plot dimensions and positioning

9

width?: number;

10

height?: number;

11

margin?: MarginConfig;

12

autosize?: boolean;

13

14

// Plot styling

15

title?: string | TitleConfig;

16

font?: FontConfig;

17

paper_bgcolor?: string;

18

plot_bgcolor?: string;

19

colorway?: string[];

20

template?: string | TemplateConfig;

21

22

// Axes configuration

23

xaxis?: AxisConfig;

24

yaxis?: AxisConfig;

25

scene?: Scene3DConfig; // For 3D plots

26

27

// Interactive elements

28

legend?: LegendConfig;

29

annotations?: AnnotationConfig[];

30

shapes?: ShapeConfig[];

31

images?: ImageConfig[];

32

33

// Controls

34

updatemenus?: UpdateMenuConfig[];

35

sliders?: SliderConfig[];

36

37

// Layout modes

38

barmode?: 'stack' | 'group' | 'overlay' | 'relative';

39

boxmode?: 'group' | 'overlay';

40

dragmode?: 'zoom' | 'pan' | 'select' | 'lasso' | 'orbit' | 'turntable' | false;

41

hovermode?: 'x' | 'y' | 'closest' | 'x unified' | 'y unified' | false;

42

43

// Grid and subplots

44

grid?: GridConfig;

45

46

// Geographic

47

geo?: GeoConfig;

48

mapbox?: MapboxConfig;

49

50

// Calendars and localization

51

calendar?: string;

52

53

// Animation

54

transition?: TransitionConfig;

55

}

56

```

57

58

## Plot Dimensions and Margins

59

60

### Size Configuration

61

62

```javascript { .api }

63

interface MarginConfig {

64

l?: number; // Left margin

65

r?: number; // Right margin

66

t?: number; // Top margin

67

b?: number; // Bottom margin

68

pad?: number; // Padding between plotting area and margins

69

autoexpand?: boolean; // Auto-expand margins for labels

70

}

71

```

72

73

**Usage Examples:**

74

75

```javascript

76

// Fixed size plot

77

const layout = {

78

width: 800,

79

height: 600,

80

margin: {

81

l: 50,

82

r: 50,

83

t: 100,

84

b: 50

85

}

86

};

87

88

// Responsive plot that fills container

89

const responsiveLayout = {

90

autosize: true,

91

margin: { l: 40, r: 40, t: 40, b: 40 }

92

};

93

94

// Auto-expanding margins for long labels

95

const autoMarginLayout = {

96

margin: {

97

l: 80,

98

r: 20,

99

t: 60,

100

b: 60,

101

autoexpand: true

102

}

103

};

104

```

105

106

## Titles and Text

107

108

### Title Configuration

109

110

```javascript { .api }

111

interface TitleConfig {

112

text?: string;

113

font?: FontConfig;

114

x?: number; // 0-1, horizontal position

115

y?: number; // 0-1, vertical position

116

xanchor?: 'auto' | 'left' | 'center' | 'right';

117

yanchor?: 'auto' | 'top' | 'middle' | 'bottom';

118

xref?: 'container' | 'paper';

119

yref?: 'container' | 'paper';

120

pad?: PaddingConfig;

121

}

122

123

interface FontConfig {

124

family?: string;

125

size?: number;

126

color?: string;

127

}

128

129

interface PaddingConfig {

130

t?: number;

131

b?: number;

132

l?: number;

133

r?: number;

134

}

135

```

136

137

**Usage Examples:**

138

139

```javascript

140

// Simple title

141

const layout = {

142

title: 'My Chart Title'

143

};

144

145

// Advanced title configuration

146

const advancedTitle = {

147

title: {

148

text: 'Advanced Chart Title',

149

font: {

150

family: 'Arial, sans-serif',

151

size: 24,

152

color: '#333'

153

},

154

x: 0.5, // Center horizontally

155

y: 0.95, // Near top

156

xanchor: 'center',

157

yanchor: 'top'

158

}

159

};

160

161

// Multi-line title with HTML

162

const htmlTitle = {

163

title: {

164

text: 'Main Title<br><sub>Subtitle with smaller text</sub>',

165

font: { size: 18 }

166

}

167

};

168

```

169

170

## Axes Configuration

171

172

### Axis Properties

173

174

```javascript { .api }

175

interface AxisConfig {

176

// Axis title

177

title?: string | AxisTitleConfig;

178

179

// Range and scaling

180

range?: [number, number] | [string, string];

181

autorange?: boolean | 'reversed';

182

type?: 'linear' | 'log' | 'date' | 'category' | 'multicategory';

183

184

// Ticks

185

tickmode?: 'auto' | 'linear' | 'array';

186

tick0?: number;

187

dtick?: number | string;

188

tickvals?: number[] | string[];

189

ticktext?: string[];

190

tickangle?: number;

191

tickfont?: FontConfig;

192

tickformat?: string;

193

tickprefix?: string;

194

ticksuffix?: string;

195

196

// Grid and lines

197

showgrid?: boolean;

198

gridcolor?: string;

199

gridwidth?: number;

200

showline?: boolean;

201

linecolor?: string;

202

linewidth?: number;

203

mirror?: boolean | 'ticks' | 'all' | 'allticks';

204

205

// Axis line and zero line

206

zeroline?: boolean;

207

zerolinecolor?: string;

208

zerolinewidth?: number;

209

210

// Positioning

211

side?: 'top' | 'bottom' | 'left' | 'right';

212

position?: number; // 0-1

213

anchor?: string; // Other axis id

214

overlaying?: string; // Other axis id

215

216

// Spikes (crosshair lines)

217

showspikes?: boolean;

218

spikecolor?: string;

219

spikethickness?: number;

220

spikedash?: string;

221

spikemode?: 'toaxis' | 'across' | 'marker';

222

spikesnap?: 'data' | 'cursor' | 'hovered data';

223

224

// Visibility

225

visible?: boolean;

226

showticklabels?: boolean;

227

228

// Categorical axes

229

categoryorder?: 'trace' | 'category ascending' | 'category descending' | 'array' | 'total ascending' | 'total descending' | 'min ascending' | 'min descending' | 'max ascending' | 'max descending' | 'sum ascending' | 'sum descending' | 'mean ascending' | 'mean descending' | 'median ascending' | 'median descending';

230

categoryarray?: string[];

231

232

// Constraints

233

constrain?: 'range' | 'domain';

234

constraintoward?: 'left' | 'center' | 'right' | 'top' | 'middle' | 'bottom';

235

236

// Calendar

237

calendar?: string;

238

}

239

240

interface AxisTitleConfig {

241

text?: string;

242

font?: FontConfig;

243

standoff?: number;

244

}

245

```

246

247

**Usage Examples:**

248

249

```javascript

250

// Basic axis configuration

251

const layout = {

252

xaxis: {

253

title: 'Time (seconds)',

254

range: [0, 10],

255

showgrid: true,

256

gridcolor: 'lightgray'

257

},

258

yaxis: {

259

title: 'Temperature (°C)',

260

range: [-10, 40],

261

zeroline: true,

262

zerolinecolor: 'red',

263

zerolinewidth: 2

264

}

265

};

266

267

// Logarithmic axis

268

const logLayout = {

269

yaxis: {

270

type: 'log',

271

title: 'Log Scale',

272

range: [0, 2], // 10^0 to 10^2

273

dtick: 1 // Major tick every power of 10

274

}

275

};

276

277

// Date axis

278

const dateLayout = {

279

xaxis: {

280

type: 'date',

281

title: 'Date',

282

tickformat: '%Y-%m-%d',

283

range: ['2023-01-01', '2023-12-31']

284

}

285

};

286

287

// Categorical axis with custom order

288

const catLayout = {

289

xaxis: {

290

type: 'category',

291

categoryorder: 'array',

292

categoryarray: ['Small', 'Medium', 'Large', 'X-Large']

293

}

294

};

295

296

// Dual y-axes

297

const dualAxisLayout = {

298

yaxis: {

299

title: 'Primary Y-axis',

300

side: 'left'

301

},

302

yaxis2: {

303

title: 'Secondary Y-axis',

304

side: 'right',

305

overlaying: 'y',

306

range: [0, 100]

307

}

308

};

309

```

310

311

## Visual Styling

312

313

### Color and Appearance

314

315

```javascript { .api }

316

interface TemplateConfig {

317

data?: {

318

scatter?: Partial<ScatterTrace>[];

319

bar?: Partial<BarTrace>[];

320

[traceType: string]: Partial<any>[];

321

};

322

layout?: Partial<Layout>;

323

}

324

```

325

326

**Usage Examples:**

327

328

```javascript

329

// Basic styling

330

const styledLayout = {

331

paper_bgcolor: 'white',

332

plot_bgcolor: 'rgba(240, 240, 240, 0.5)',

333

font: {

334

family: 'Arial, sans-serif',

335

size: 14,

336

color: '#333'

337

},

338

colorway: ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd']

339

};

340

341

// Dark theme

342

const darkLayout = {

343

paper_bgcolor: '#1e1e1e',

344

plot_bgcolor: '#2d2d2d',

345

font: { color: 'white' },

346

xaxis: {

347

gridcolor: '#404040',

348

linecolor: '#666',

349

tickcolor: 'white'

350

},

351

yaxis: {

352

gridcolor: '#404040',

353

linecolor: '#666',

354

tickcolor: 'white'

355

}

356

};

357

358

// Custom template

359

const customTemplate = {

360

layout: {

361

colorway: ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FECA57'],

362

font: { family: 'Roboto, sans-serif' },

363

paper_bgcolor: '#F8F9FA',

364

plot_bgcolor: 'white'

365

},

366

data: {

367

scatter: [{

368

marker: { line: { width: 0.5 } }

369

}],

370

bar: [{

371

marker: { line: { width: 1.5, color: 'white' } }

372

}]

373

}

374

};

375

```

376

377

## Interactive Elements

378

379

### Hover Configuration

380

381

```javascript

382

// Hover behavior

383

const hoverLayout = {

384

hovermode: 'x unified', // Show all y-values for same x

385

hoverlabel: {

386

bgcolor: 'white',

387

bordercolor: 'black',

388

font: { size: 16, family: 'Arial' }

389

}

390

};

391

392

// Disable hover

393

const noHoverLayout = {

394

hovermode: false

395

};

396

397

// Closest point hover

398

const closestLayout = {

399

hovermode: 'closest'

400

};

401

```

402

403

### Drag and Selection Modes

404

405

```javascript

406

// Zoom and pan controls

407

const interactiveLayout = {

408

dragmode: 'zoom', // or 'pan', 'select', 'lasso'

409

selectdirection: 'diagonal' // or 'horizontal', 'vertical'

410

};

411

412

// Disable interactions

413

const staticLayout = {

414

dragmode: false,

415

scrollZoom: false,

416

doubleClick: false

417

};

418

```

419

420

## Subplot Configuration

421

422

### Grid Layouts

423

424

```javascript { .api }

425

interface GridConfig {

426

rows?: number;

427

columns?: number;

428

pattern?: 'independent' | 'coupled';

429

xaxes?: string[];

430

yaxes?: string[];

431

subplots?: string[][];

432

xgap?: number; // 0-1

433

ygap?: number; // 0-1

434

domain?: {

435

x?: [number, number];

436

y?: [number, number];

437

};

438

}

439

```

440

441

**Usage Examples:**

442

443

```javascript

444

// 2x2 subplot grid

445

const subplotLayout = {

446

grid: {

447

rows: 2,

448

columns: 2,

449

pattern: 'independent',

450

subplots: [

451

['xy', 'x2y'],

452

['xy2', 'x2y2']

453

]

454

},

455

xaxis: { domain: [0, 0.48] },

456

xaxis2: { domain: [0.52, 1] },

457

yaxis: { domain: [0.52, 1] },

458

yaxis2: { domain: [0, 0.48] }

459

};

460

461

// Shared x-axis subplots

462

const sharedXLayout = {

463

xaxis: { domain: [0, 1] },

464

yaxis: { domain: [0.55, 1] },

465

yaxis2: { domain: [0, 0.45] },

466

// Both traces use same xaxis, different yaxis

467

};

468

```

469

470

## 3D Scene Configuration

471

472

```javascript { .api }

473

interface Scene3DConfig {

474

camera?: {

475

eye?: { x?: number; y?: number; z?: number; };

476

center?: { x?: number; y?: number; z?: number; };

477

up?: { x?: number; y?: number; z?: number; };

478

projection?: { type?: 'perspective' | 'orthographic'; };

479

};

480

xaxis?: Axis3DConfig;

481

yaxis?: Axis3DConfig;

482

zaxis?: Axis3DConfig;

483

aspectmode?: 'auto' | 'cube' | 'data' | 'manual';

484

aspectratio?: { x?: number; y?: number; z?: number; };

485

bgcolor?: string;

486

dragmode?: 'orbit' | 'turntable' | 'zoom' | 'pan' | false;

487

hovermode?: 'closest' | false;

488

}

489

490

interface Axis3DConfig extends AxisConfig {

491

backgroundcolor?: string;

492

showbackground?: boolean;

493

showaxeslabels?: boolean;

494

}

495

```

496

497

**Usage Examples:**

498

499

```javascript

500

// 3D scene configuration

501

const scene3DLayout = {

502

scene: {

503

camera: {

504

eye: { x: 1.2, y: 1.2, z: 1.2 },

505

center: { x: 0, y: 0, z: 0 }

506

},

507

xaxis: {

508

title: 'X Axis',

509

showbackground: true,

510

backgroundcolor: 'rgba(230, 230, 230, 0.5)'

511

},

512

yaxis: {

513

title: 'Y Axis',

514

showbackground: true,

515

backgroundcolor: 'rgba(230, 230, 230, 0.5)'

516

},

517

zaxis: {

518

title: 'Z Axis',

519

showbackground: true,

520

backgroundcolor: 'rgba(230, 230, 230, 0.5)'

521

},

522

aspectmode: 'cube',

523

dragmode: 'orbit'

524

}

525

};

526

```

527

528

## Geographic Configuration

529

530

```javascript { .api }

531

interface GeoConfig {

532

resolution?: 110 | 50;

533

scope?: 'world' | 'usa' | 'europe' | 'asia' | 'africa' | 'north america' | 'south america';

534

projection?: {

535

type?: 'equirectangular' | 'mercator' | 'orthographic' | 'natural earth' | 'kavrayskiy7' | 'miller' | 'robinson' | 'eckert4' | 'azimuthal equal area' | 'azimuthal equidistant' | 'conic equal area' | 'conic conformal' | 'conic equidistant' | 'gnomonic' | 'stereographic' | 'mollweide' | 'hammer' | 'transverse mercator' | 'albers usa' | 'winkel tripel' | 'aitoff' | 'sinusoidal';

536

rotation?: { lon?: number; lat?: number; roll?: number; };

537

scale?: number;

538

};

539

center?: { lon?: number; lat?: number; };

540

showland?: boolean;

541

landcolor?: string;

542

showocean?: boolean;

543

oceancolor?: string;

544

showlakes?: boolean;

545

lakecolor?: string;

546

showcountries?: boolean;

547

countrycolor?: string;

548

countrywidth?: number;

549

showrivers?: boolean;

550

rivercolor?: string;

551

riverwidth?: number;

552

showcoastlines?: boolean;

553

coastlinecolor?: string;

554

coastlinewidth?: number;

555

bgcolor?: string;

556

}

557

```

558

559

## Advanced Layout Patterns

560

561

### Responsive Design

562

563

```javascript

564

// Responsive layout that adapts to container

565

const responsiveLayout = {

566

autosize: true,

567

margin: { l: 50, r: 50, t: 50, b: 50, autoexpand: true },

568

font: { size: 12 },

569

legend: {

570

orientation: 'h',

571

y: -0.2,

572

x: 0.5,

573

xanchor: 'center'

574

}

575

};

576

577

// Mobile-friendly configuration

578

const mobileLayout = {

579

width: 350,

580

height: 250,

581

margin: { l: 40, r: 20, t: 40, b: 40 },

582

font: { size: 10 },

583

showlegend: false,

584

dragmode: false

585

};

586

```

587

588

### Multi-Chart Dashboards

589

590

```javascript

591

// Dashboard with multiple chart areas

592

const dashboardLayout = {

593

grid: {

594

rows: 2,

595

columns: 2,

596

pattern: 'independent'

597

},

598

annotations: [

599

{

600

text: 'Chart 1',

601

x: 0.25,

602

y: 0.95,

603

xref: 'paper',

604

yref: 'paper',

605

showarrow: false,

606

font: { size: 16, color: 'blue' }

607

},

608

{

609

text: 'Chart 2',

610

x: 0.75,

611

y: 0.95,

612

xref: 'paper',

613

yref: 'paper',

614

showarrow: false,

615

font: { size: 16, color: 'red' }

616

}

617

]

618

};

619

```

620

621

## Performance Considerations

622

623

- Use `autosize: true` with CSS for responsive designs

624

- Minimize the number of annotations and shapes for better performance

625

- Consider disabling unnecessary features (grid, zeroline) for cleaner, faster rendering

626

- Use appropriate axis ranges to avoid auto-ranging calculations

627

- For animations, pre-define layout configurations in frames