or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

3d-charts.mdbasic-charts.mdcore-plotting.mdevents.mdexport-utilities.mdindex.mdlayout.mdstatistical-charts.md

events.mddocs/

0

# Events and Interactions

1

2

Complete event system for handling user interactions, plot updates, and custom behaviors.

3

4

## Capabilities

5

6

### Event Management

7

8

Methods for adding, removing, and managing event listeners on plots.

9

10

```javascript { .api }

11

/**

12

* Event listener management methods

13

*/

14

interface EventMethods {

15

/**

16

* Add event listener to plot

17

* @param event - Event name

18

* @param handler - Event handler function

19

*/

20

on(event: string, handler: Function): void;

21

22

/**

23

* Add one-time event listener

24

* @param event - Event name

25

* @param handler - Event handler function that will be called only once

26

*/

27

once(event: string, handler: Function): void;

28

29

/**

30

* Remove specific event listener

31

* @param event - Event name

32

* @param handler - Specific handler function to remove

33

*/

34

removeListener(event: string, handler: Function): void;

35

36

/**

37

* Remove all listeners for a specific event

38

* @param event - Event name

39

*/

40

removeAllListeners(event: string): void;

41

42

/**

43

* Emit/trigger an event

44

* @param event - Event name

45

* @param data - Event data to pass to handlers

46

*/

47

emit(event: string, data?: any): void;

48

}

49

```

50

51

**Usage Examples:**

52

53

```javascript

54

// Add event listener

55

const myDiv = document.getElementById('myDiv');

56

57

myDiv.on('plotly_click', function(data) {

58

console.log('Plot clicked:', data);

59

});

60

61

// One-time listener

62

myDiv.once('plotly_afterplot', function() {

63

console.log('Plot created for the first time');

64

});

65

66

// Remove specific listener

67

function clickHandler(data) {

68

console.log('Clicked:', data);

69

}

70

myDiv.on('plotly_click', clickHandler);

71

myDiv.removeListener('plotly_click', clickHandler);

72

73

// Remove all listeners for an event

74

myDiv.removeAllListeners('plotly_hover');

75

```

76

77

### Plot Lifecycle Events

78

79

Events that fire during plot creation, updates, and destruction.

80

81

```javascript { .api }

82

/**

83

* Plot lifecycle event names and their data structures

84

*/

85

interface PlotLifecycleEvents {

86

'plotly_beforeplot': {};

87

'plotly_afterplot': {};

88

'plotly_redraw': {};

89

'plotly_restyle': {

90

data: any[];

91

traces: number[];

92

};

93

'plotly_relayout': {

94

layout: Partial<Layout>;

95

};

96

'plotly_update': {

97

data: any[];

98

layout: Partial<Layout>;

99

traces: number[];

100

};

101

'plotly_react': {

102

data: any[];

103

layout: Partial<Layout>;

104

};

105

'plotly_framework': any;

106

'plotly_purge': {};

107

}

108

```

109

110

**Usage Examples:**

111

112

```javascript

113

// Listen for plot creation

114

myDiv.on('plotly_afterplot', function() {

115

console.log('Plot has been created');

116

// Initialize any custom behaviors

117

});

118

119

// Listen for restyle events

120

myDiv.on('plotly_restyle', function(eventData) {

121

console.log('Traces restyled:', eventData.traces);

122

console.log('Update data:', eventData.data);

123

});

124

125

// Listen for layout changes

126

myDiv.on('plotly_relayout', function(eventData) {

127

console.log('Layout updated:', eventData.layout);

128

if (eventData.layout['xaxis.range']) {

129

console.log('X-axis range changed');

130

}

131

});

132

133

// Listen for combined updates

134

myDiv.on('plotly_update', function(eventData) {

135

console.log('Plot updated');

136

console.log('Data changes:', eventData.data);

137

console.log('Layout changes:', eventData.layout);

138

});

139

```

140

141

### User Interaction Events

142

143

Events triggered by user interactions with the plot.

144

145

```javascript { .api }

146

/**

147

* User interaction event data structures

148

*/

149

interface InteractionEvents {

150

'plotly_click': {

151

points: PlotlyClickPoint[];

152

event: MouseEvent;

153

};

154

'plotly_hover': {

155

points: PlotlyHoverPoint[];

156

event: MouseEvent;

157

xpx: number;

158

ypx: number;

159

};

160

'plotly_unhover': {

161

points: PlotlyHoverPoint[];

162

event: MouseEvent;

163

};

164

'plotly_selected': {

165

points: PlotlySelectedPoint[];

166

selection?: SelectionRange;

167

};

168

'plotly_deselect': {};

169

'plotly_brushing': {

170

range: BrushRange;

171

};

172

'plotly_brushed': {

173

range: BrushRange;

174

};

175

'plotly_doubleclick': {};

176

'plotly_zoom': {};

177

'plotly_pan': {};

178

}

179

180

interface PlotlyClickPoint {

181

curveNumber: number;

182

pointNumber: number | number[];

183

pointIndex: number;

184

x: any;

185

y: any;

186

z?: any;

187

data: any;

188

fullData: any;

189

xaxis: any;

190

yaxis: any;

191

}

192

193

interface PlotlyHoverPoint extends PlotlyClickPoint {

194

bbox: {

195

x0: number;

196

x1: number;

197

y0: number;

198

y1: number;

199

};

200

distance: number;

201

}

202

203

interface PlotlySelectedPoint extends PlotlyClickPoint {

204

selected?: boolean;

205

}

206

207

interface SelectionRange {

208

x: [number, number];

209

y: [number, number];

210

}

211

212

interface BrushRange {

213

x: [number, number];

214

y: [number, number];

215

}

216

```

217

218

**Usage Examples:**

219

220

```javascript

221

// Handle click events

222

myDiv.on('plotly_click', function(data) {

223

const point = data.points[0];

224

console.log('Clicked point:', {

225

trace: point.curveNumber,

226

index: point.pointNumber,

227

x: point.x,

228

y: point.y

229

});

230

231

// Highlight clicked point

232

Plotly.restyle(myDiv, {

233

'marker.color': 'red'

234

}, [point.curveNumber]);

235

});

236

237

// Handle hover events

238

myDiv.on('plotly_hover', function(data) {

239

const point = data.points[0];

240

console.log('Hovering over:', point.x, point.y);

241

242

// Update external display

243

document.getElementById('info').innerHTML =

244

`Value: ${point.y} at ${point.x}`;

245

});

246

247

myDiv.on('plotly_unhover', function() {

248

document.getElementById('info').innerHTML = '';

249

});

250

251

// Handle selection events

252

myDiv.on('plotly_selected', function(data) {

253

console.log('Selected points:', data.points.length);

254

255

if (data.points.length > 0) {

256

const selectedData = data.points.map(pt => ({

257

x: pt.x,

258

y: pt.y,

259

trace: pt.curveNumber

260

}));

261

console.log('Selected data:', selectedData);

262

}

263

});

264

265

// Handle brush selection

266

myDiv.on('plotly_brushed', function(data) {

267

console.log('Brushed area:', data.range);

268

269

// Filter data in another chart based on selection

270

const xRange = data.range.x;

271

const yRange = data.range.y;

272

273

// Update related visualization

274

updateSecondaryChart(xRange, yRange);

275

});

276

```

277

278

### Animation Events

279

280

Events related to plot animations and frame transitions.

281

282

```javascript { .api }

283

/**

284

* Animation event data structures

285

*/

286

interface AnimationEvents {

287

'plotly_animating': {};

288

'plotly_animatingframe': {

289

frame: any;

290

animation: any;

291

};

292

'plotly_animated': {};

293

'plotly_animationinterrupted': {};

294

}

295

```

296

297

**Usage Examples:**

298

299

```javascript

300

// Track animation progress

301

myDiv.on('plotly_animating', function() {

302

console.log('Animation started');

303

document.getElementById('status').innerHTML = 'Animating...';

304

});

305

306

myDiv.on('plotly_animatingframe', function(data) {

307

console.log('Frame:', data.frame.name);

308

});

309

310

myDiv.on('plotly_animated', function() {

311

console.log('Animation completed');

312

document.getElementById('status').innerHTML = 'Complete';

313

});

314

315

// Handle interrupted animations

316

myDiv.on('plotly_animationinterrupted', function() {

317

console.log('Animation was interrupted');

318

document.getElementById('status').innerHTML = 'Interrupted';

319

});

320

```

321

322

### Programmatic Hover and Interaction

323

324

Methods for triggering hover effects and interactions programmatically.

325

326

```javascript { .api }

327

/**

328

* Programmatic interaction methods

329

*/

330

interface ProgrammaticInteractions {

331

/**

332

* Trigger hover effect on specific points

333

* @param gd - Graph div element

334

* @param hoverData - Array of points to hover over

335

* @param hoverOpts - Hover options and styling

336

*/

337

hover(gd: any, hoverData: HoverData[], hoverOpts?: HoverOptions): void;

338

339

/**

340

* Clear all hover effects

341

* @param gd - Graph div element

342

*/

343

unhover(gd: any): void;

344

345

/**

346

* Create standalone hover box (not attached to plot)

347

* @param hoverData - Hover data for the box

348

* @param opts - Positioning and styling options

349

*/

350

loneHover(hoverData: HoverData, opts: LoneHoverOptions): HTMLElement;

351

352

/**

353

* Remove standalone hover box

354

* @param container - Container element with hover box

355

*/

356

loneUnhover(container: HTMLElement): void;

357

}

358

359

interface HoverData {

360

curveNumber: number;

361

pointNumber: number;

362

x?: any;

363

y?: any;

364

z?: any;

365

}

366

367

interface HoverOptions {

368

xpx?: number;

369

ypx?: number;

370

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

371

}

372

373

interface LoneHoverOptions {

374

container: HTMLElement;

375

x0: number;

376

x1: number;

377

y0: number;

378

y1: number;

379

anchorX?: number;

380

anchorY?: number;

381

colorIndex?: number;

382

}

383

```

384

385

**Usage Examples:**

386

387

```javascript

388

// Programmatically trigger hover

389

function highlightPoint(traceIndex, pointIndex) {

390

Plotly.Fx.hover(myDiv, [{

391

curveNumber: traceIndex,

392

pointNumber: pointIndex

393

}]);

394

}

395

396

// Clear hover

397

function clearHighlight() {

398

Plotly.Fx.unhover(myDiv);

399

}

400

401

// Create standalone hover box

402

function showCustomTooltip(x, y, text) {

403

const container = document.getElementById('tooltip-container');

404

405

Plotly.Fx.loneHover({

406

x: x,

407

y: y,

408

text: text,

409

color: 'blue'

410

}, {

411

container: container,

412

x0: 100,

413

x1: 200,

414

y0: 50,

415

y1: 100

416

});

417

}

418

419

// Remove standalone hover

420

function hideCustomTooltip() {

421

const container = document.getElementById('tooltip-container');

422

Plotly.Fx.loneUnhover(container);

423

}

424

```

425

426

### Custom Event Handlers

427

428

Examples of common event handling patterns and custom behaviors.

429

430

**Usage Examples:**

431

432

```javascript

433

// Cross-filter pattern - link multiple charts

434

function linkCharts(chart1, chart2) {

435

chart1.on('plotly_selected', function(data) {

436

if (data.points.length > 0) {

437

const selectedIds = data.points.map(pt => pt.customdata);

438

439

// Filter second chart based on selection

440

const filteredTrace = filterTraceByIds(chart2Data, selectedIds);

441

Plotly.react(chart2, [filteredTrace], chart2Layout);

442

}

443

});

444

445

chart1.on('plotly_deselect', function() {

446

// Reset second chart

447

Plotly.react(chart2, chart2Data, chart2Layout);

448

});

449

}

450

451

// Zoom synchronization between charts

452

function synchronizeZoom(chart1, chart2) {

453

chart1.on('plotly_relayout', function(eventData) {

454

if (eventData['xaxis.range[0]'] !== undefined) {

455

Plotly.relayout(chart2, {

456

'xaxis.range': eventData['xaxis.range']

457

});

458

}

459

});

460

461

chart2.on('plotly_relayout', function(eventData) {

462

if (eventData['xaxis.range[0]'] !== undefined) {

463

Plotly.relayout(chart1, {

464

'xaxis.range': eventData['xaxis.range']

465

});

466

}

467

});

468

}

469

470

// Custom click behavior - drill down

471

myDiv.on('plotly_click', function(data) {

472

const point = data.points[0];

473

474

if (point.customdata && point.customdata.drillDown) {

475

// Load drill-down data

476

loadDrillDownData(point.customdata.category)

477

.then(newData => {

478

Plotly.react(myDiv, newData, newLayout);

479

});

480

}

481

});

482

483

// Responsive behavior on window resize

484

window.addEventListener('resize', function() {

485

Plotly.Plots.resize(myDiv);

486

});

487

488

// Custom selection behavior

489

myDiv.on('plotly_selected', function(data) {

490

if (data.points.length > 0) {

491

// Calculate statistics for selected points

492

const values = data.points.map(pt => pt.y);

493

const stats = {

494

count: values.length,

495

sum: values.reduce((a, b) => a + b, 0),

496

mean: values.reduce((a, b) => a + b, 0) / values.length,

497

min: Math.min(...values),

498

max: Math.max(...values)

499

};

500

501

// Update statistics display

502

updateStatsDisplay(stats);

503

}

504

});

505

```

506

507

## Event Data Reference

508

509

### Common Event Properties

510

511

```javascript { .api }

512

/**

513

* Common properties available in most event data objects

514

*/

515

interface BaseEventData {

516

event?: MouseEvent | TouchEvent;

517

points?: PlotlyPoint[];

518

range?: any;

519

lassoPoints?: any;

520

}

521

522

interface PlotlyPoint {

523

curveNumber: number;

524

pointNumber: number | number[];

525

pointIndex: number;

526

x: any;

527

y: any;

528

z?: any;

529

data: any;

530

fullData: any;

531

xaxis: any;

532

yaxis: any;

533

bbox?: {

534

x0: number;

535

x1: number;

536

y0: number;

537

y1: number;

538

};

539

distance?: number;

540

customdata?: any;

541

text?: string;

542

hovertext?: string;

543

}

544

```

545

546

### Event Timing and Performance

547

548

```javascript { .api }

549

/**

550

* Event timing considerations and performance options

551

*/

552

interface EventTiming {

553

// Debounce hover events for performance

554

hoverDebounce?: number;

555

556

// Throttle selection events

557

selectionThrottle?: number;

558

559

// Disable events for performance

560

staticPlot?: boolean;

561

}

562

```

563

564

**Usage Examples:**

565

566

```javascript

567

// Debounced hover handler for performance

568

let hoverTimeout;

569

myDiv.on('plotly_hover', function(data) {

570

clearTimeout(hoverTimeout);

571

hoverTimeout = setTimeout(() => {

572

// Process hover data

573

processHoverData(data);

574

}, 100);

575

});

576

577

// Throttled selection handler

578

let lastSelectionTime = 0;

579

myDiv.on('plotly_selected', function(data) {

580

const now = Date.now();

581

if (now - lastSelectionTime > 200) {

582

processSelection(data);

583

lastSelectionTime = now;

584

}

585

});

586

```