0
# Export and Utilities
1
2
Functions for exporting plots as images, validating data, and managing plot lifecycle. These utilities provide essential functionality for plot management and data export.
3
4
## Image Export
5
6
### toImage
7
8
Exports a plot as an image in various formats with customizable options.
9
10
```javascript { .api }
11
/**
12
* Exports plot as image data
13
* @param figure - Graph div element or figure object
14
* @param options - Export configuration options
15
* @returns Promise resolving to image data URL or binary data
16
*/
17
function toImage(
18
figure: HTMLElement | FigureConfig,
19
options?: ImageExportOptions
20
): Promise<string>;
21
22
interface ImageExportOptions {
23
format?: 'png' | 'jpeg' | 'webp' | 'svg' | 'pdf' | 'eps' | 'html';
24
width?: number;
25
height?: number;
26
scale?: number; // DPI multiplier (1 = 72 DPI, 2 = 144 DPI, etc.)
27
engine?: 'auto' | 'kaleido' | 'orca';
28
imageDataOnly?: boolean; // Return raw image data instead of data URL
29
}
30
31
interface FigureConfig {
32
data: PlotData;
33
layout?: Partial<Layout>;
34
config?: Partial<Config>;
35
}
36
```
37
38
**Usage Examples:**
39
40
```javascript
41
import Plotly from 'plotly.js-dist';
42
43
// Basic image export as PNG
44
const imageData = await Plotly.toImage('my-chart', {
45
format: 'png',
46
width: 800,
47
height: 600,
48
scale: 2 // High DPI for crisp images
49
});
50
51
// Use the data URL (can be set as img src)
52
const img = document.createElement('img');
53
img.src = imageData;
54
document.body.appendChild(img);
55
56
// Export as JPEG with compression
57
const jpegData = await Plotly.toImage('my-chart', {
58
format: 'jpeg',
59
width: 1200,
60
height: 800,
61
scale: 1
62
});
63
64
// Export as SVG (vector format)
65
const svgData = await Plotly.toImage('my-chart', {
66
format: 'svg',
67
width: 800,
68
height: 600
69
});
70
71
// Export from figure object (without DOM element)
72
const figure = {
73
data: [{
74
x: [1, 2, 3, 4],
75
y: [10, 11, 12, 13],
76
type: 'scatter'
77
}],
78
layout: {
79
title: 'Sample Plot',
80
width: 600,
81
height: 400
82
}
83
};
84
85
const figureImage = await Plotly.toImage(figure, {
86
format: 'png',
87
scale: 2
88
});
89
90
// Export for print (high resolution)
91
const printImage = await Plotly.toImage('my-chart', {
92
format: 'png',
93
width: 3200, // 300 DPI at ~10.7 inches wide
94
height: 2400, // 300 DPI at 8 inches tall
95
scale: 1
96
});
97
```
98
99
### downloadImage
100
101
Downloads a plot as an image file directly to the user's device.
102
103
```javascript { .api }
104
/**
105
* Downloads plot as image file
106
* @param graphDiv - Graph div element
107
* @param options - Download configuration options
108
* @returns Promise resolving when download completes
109
*/
110
function downloadImage(
111
graphDiv: HTMLElement,
112
options?: DownloadImageOptions
113
): Promise<void>;
114
115
interface DownloadImageOptions extends ImageExportOptions {
116
filename?: string; // Default: 'newplot'
117
}
118
```
119
120
**Usage Examples:**
121
122
```javascript
123
// Basic download as PNG
124
await Plotly.downloadImage('my-chart', {
125
filename: 'my-analysis',
126
format: 'png',
127
width: 1200,
128
height: 800,
129
scale: 2
130
});
131
132
// Download high-resolution PDF
133
await Plotly.downloadImage('my-chart', {
134
filename: 'report-chart',
135
format: 'pdf',
136
width: 800,
137
height: 600
138
});
139
140
// Download for web use
141
await Plotly.downloadImage('my-chart', {
142
filename: 'web-chart',
143
format: 'webp',
144
width: 800,
145
height: 600,
146
scale: 1
147
});
148
149
// Download SVG for editing
150
await Plotly.downloadImage('my-chart', {
151
filename: 'editable-chart',
152
format: 'svg'
153
});
154
```
155
156
## Data Validation
157
158
### validate
159
160
Validates plot data and layout against the Plotly.js schema to catch errors before plotting.
161
162
```javascript { .api }
163
/**
164
* Validates plot data and layout against schema
165
* @param data - Array of trace objects to validate
166
* @param layout - Layout object to validate
167
* @returns Array of validation error objects
168
*/
169
function validate(
170
data: PlotData,
171
layout?: Partial<Layout>
172
): ValidationError[];
173
174
interface ValidationError {
175
code: string;
176
message: string;
177
path: string; // JSON path to invalid attribute
178
value: any; // The invalid value
179
trace?: number; // Trace index if error is in trace data
180
}
181
```
182
183
**Usage Examples:**
184
185
```javascript
186
// Validate trace data
187
const data = [{
188
x: [1, 2, 3],
189
y: [4, 5, 6],
190
type: 'scatter',
191
mode: 'invalid-mode' // This will cause validation error
192
}];
193
194
const layout = {
195
title: 'Test Chart',
196
xaxis: {
197
range: [0, 'invalid'] // This will cause validation error
198
}
199
};
200
201
const errors = Plotly.validate(data, layout);
202
203
if (errors.length > 0) {
204
console.error('Validation errors found:');
205
errors.forEach(error => {
206
console.error(`${error.code}: ${error.message}`);
207
console.error(`Path: ${error.path}`);
208
console.error(`Value: ${error.value}`);
209
});
210
} else {
211
console.log('Data is valid!');
212
await Plotly.newPlot('chart', data, layout);
213
}
214
215
// Common validation patterns
216
function validateBeforePlot(data, layout) {
217
const errors = Plotly.validate(data, layout);
218
219
if (errors.length > 0) {
220
const errorMessages = errors.map(e => `${e.path}: ${e.message}`);
221
throw new Error(`Validation failed:\n${errorMessages.join('\n')}`);
222
}
223
224
return true;
225
}
226
227
// Validate individual traces
228
function validateTrace(trace, traceIndex) {
229
const errors = Plotly.validate([trace]);
230
return errors.filter(error => error.trace === 0);
231
}
232
233
// Validate layout only
234
function validateLayout(layout) {
235
return Plotly.validate([], layout);
236
}
237
```
238
239
## Plot Lifecycle Management
240
241
### purge
242
243
Completely removes a plot and cleans up all associated resources to prevent memory leaks.
244
245
```javascript { .api }
246
/**
247
* Completely removes plot and cleans up resources
248
* @param graphDiv - Graph div element to purge
249
* @returns The graph div element
250
*/
251
function purge(graphDiv: HTMLElement): HTMLElement;
252
```
253
254
**Usage Examples:**
255
256
```javascript
257
// Clean up single plot
258
const chartDiv = document.getElementById('my-chart');
259
Plotly.purge(chartDiv);
260
261
// Clean up before removing from DOM
262
function removeChart(chartId) {
263
const chartDiv = document.getElementById(chartId);
264
if (chartDiv && chartDiv.data) {
265
Plotly.purge(chartDiv);
266
}
267
chartDiv.remove();
268
}
269
270
// Clean up in React component
271
class PlotComponent extends React.Component {
272
componentWillUnmount() {
273
if (this.chartRef.current) {
274
Plotly.purge(this.chartRef.current);
275
}
276
}
277
278
render() {
279
return <div ref={this.chartRef} />;
280
}
281
}
282
283
// Clean up multiple charts
284
function purgeAllCharts() {
285
const charts = document.querySelectorAll('[data-plotly]');
286
charts.forEach(chart => {
287
Plotly.purge(chart);
288
});
289
}
290
291
// Memory leak prevention pattern
292
async function createTemporaryChart(data, layout) {
293
const tempDiv = document.createElement('div');
294
document.body.appendChild(tempDiv);
295
296
try {
297
await Plotly.newPlot(tempDiv, data, layout);
298
299
// Do something with the chart
300
const imageData = await Plotly.toImage(tempDiv);
301
return imageData;
302
303
} finally {
304
// Always clean up
305
Plotly.purge(tempDiv);
306
tempDiv.remove();
307
}
308
}
309
```
310
311
## Schema and Configuration
312
313
### PlotSchema
314
315
Access to the complete Plotly.js schema for programmatic inspection of available attributes.
316
317
```javascript { .api }
318
/**
319
* Complete Plotly.js schema with all trace types and attributes
320
*/
321
interface PlotSchema {
322
traces: {
323
[traceType: string]: TraceSchema;
324
};
325
layout: LayoutSchema;
326
transforms: {
327
[transformType: string]: TransformSchema;
328
};
329
frames: FrameSchema;
330
animation: AnimationSchema;
331
}
332
333
interface TraceSchema {
334
attributes: AttributeSchema;
335
meta: {
336
description: string;
337
hrName: string;
338
};
339
}
340
```
341
342
**Usage Examples:**
343
344
```javascript
345
// Access schema information
346
const schema = Plotly.PlotSchema.get();
347
348
// Get available trace types
349
const traceTypes = Object.keys(schema.traces);
350
console.log('Available trace types:', traceTypes);
351
352
// Get attributes for a specific trace type
353
const scatterAttributes = schema.traces.scatter.attributes;
354
console.log('Scatter trace attributes:', Object.keys(scatterAttributes));
355
356
// Get layout attributes
357
const layoutAttributes = schema.layout;
358
console.log('Layout attributes:', Object.keys(layoutAttributes));
359
360
// Check if attribute exists
361
function hasAttribute(traceType, attributePath) {
362
const trace = schema.traces[traceType];
363
if (!trace) return false;
364
365
// Navigate nested attributes
366
const pathParts = attributePath.split('.');
367
let current = trace.attributes;
368
369
for (const part of pathParts) {
370
if (!current[part]) return false;
371
current = current[part];
372
}
373
374
return true;
375
}
376
377
// Example usage
378
console.log(hasAttribute('scatter', 'marker.color')); // true
379
console.log(hasAttribute('scatter', 'invalid.attribute')); // false
380
381
// Get attribute metadata
382
function getAttributeInfo(traceType, attributePath) {
383
const trace = schema.traces[traceType];
384
if (!trace) return null;
385
386
const pathParts = attributePath.split('.');
387
let current = trace.attributes;
388
389
for (const part of pathParts) {
390
if (!current[part]) return null;
391
current = current[part];
392
}
393
394
return {
395
valType: current.valType,
396
dflt: current.dflt,
397
description: current.description,
398
values: current.values,
399
min: current.min,
400
max: current.max
401
};
402
}
403
```
404
405
### setPlotConfig
406
407
Sets global configuration defaults that apply to all plots.
408
409
```javascript { .api }
410
/**
411
* Sets global plot configuration defaults
412
* @param config - Configuration object to merge with defaults
413
* @returns Extended configuration object
414
*/
415
function setPlotConfig(config: Partial<Config>): Config;
416
```
417
418
**Usage Examples:**
419
420
```javascript
421
// Set global defaults
422
Plotly.setPlotConfig({
423
displayModeBar: false,
424
responsive: true,
425
displaylogo: false
426
});
427
428
// All subsequent plots will use these defaults
429
await Plotly.newPlot('chart1', data1, layout1);
430
await Plotly.newPlot('chart2', data2, layout2);
431
432
// Override global config for specific plot
433
await Plotly.newPlot('chart3', data3, layout3, {
434
displayModeBar: true // Override global setting
435
});
436
437
// Set organization branding defaults
438
Plotly.setPlotConfig({
439
displaylogo: false,
440
modeBarButtonsToRemove: ['sendDataToCloud'],
441
toImageButtonOptions: {
442
filename: 'company-chart',
443
format: 'png',
444
width: 1200,
445
height: 800,
446
scale: 2
447
}
448
});
449
450
// Set accessibility defaults
451
Plotly.setPlotConfig({
452
displayModeBar: true,
453
modeBarButtonsToAdd: [{
454
name: 'textDescription',
455
title: 'Get text description',
456
icon: '๐',
457
click: function(gd) {
458
alert(generateTextDescription(gd));
459
}
460
}]
461
});
462
```
463
464
## Utility Functions
465
466
### Version Information
467
468
```javascript { .api }
469
/**
470
* Get Plotly.js version information
471
*/
472
const version: string;
473
```
474
475
### Error Handling Utilities
476
477
```javascript
478
// Safe plotting with error handling
479
async function safePlot(elementId, data, layout, config) {
480
try {
481
// Validate first
482
const errors = Plotly.validate(data, layout);
483
if (errors.length > 0) {
484
throw new Error(`Validation failed: ${errors.map(e => e.message).join(', ')}`);
485
}
486
487
// Create plot
488
await Plotly.newPlot(elementId, data, layout, config);
489
490
} catch (error) {
491
console.error('Plot creation failed:', error);
492
493
// Show error to user
494
const errorDiv = document.getElementById(elementId);
495
errorDiv.innerHTML = `
496
<div style="padding: 20px; text-align: center; color: red;">
497
<h3>Plot Error</h3>
498
<p>${error.message}</p>
499
</div>
500
`;
501
}
502
}
503
504
// Batch export with error handling
505
async function exportMultiplePlots(plotIds, options) {
506
const results = [];
507
508
for (const plotId of plotIds) {
509
try {
510
const imageData = await Plotly.toImage(plotId, options);
511
results.push({ plotId, success: true, data: imageData });
512
} catch (error) {
513
results.push({ plotId, success: false, error: error.message });
514
}
515
}
516
517
return results;
518
}
519
```
520
521
### Performance Monitoring
522
523
```javascript
524
// Performance monitoring utilities
525
function measurePlotTime(elementId, data, layout, config) {
526
const startTime = performance.now();
527
528
return Plotly.newPlot(elementId, data, layout, config).then(() => {
529
const endTime = performance.now();
530
const duration = endTime - startTime;
531
532
console.log(`Plot ${elementId} created in ${duration.toFixed(2)}ms`);
533
return duration;
534
});
535
}
536
537
// Memory usage monitoring
538
function getPlotMemoryUsage(elementId) {
539
const element = document.getElementById(elementId);
540
if (!element || !element.data) {
541
return null;
542
}
543
544
const dataSize = JSON.stringify(element.data).length;
545
const layoutSize = JSON.stringify(element.layout).length;
546
547
return {
548
dataSize,
549
layoutSize,
550
totalSize: dataSize + layoutSize,
551
traceCount: element.data.length
552
};
553
}
554
```
555
556
## Advanced Export Patterns
557
558
### Batch Export
559
560
```javascript
561
// Export multiple charts as a single document
562
async function exportDashboard(chartIds, options = {}) {
563
const images = await Promise.all(
564
chartIds.map(id => Plotly.toImage(id, {
565
format: 'png',
566
width: 800,
567
height: 600,
568
scale: 2,
569
...options
570
}))
571
);
572
573
// Create a combined image or document
574
return combinImages(images);
575
}
576
577
// Export with custom watermark
578
async function exportWithWatermark(chartId, watermarkText) {
579
// Add watermark annotation
580
await Plotly.relayout(chartId, {
581
'annotations[0]': {
582
text: watermarkText,
583
x: 0.95,
584
y: 0.05,
585
xref: 'paper',
586
yref: 'paper',
587
xanchor: 'right',
588
yanchor: 'bottom',
589
showarrow: false,
590
font: { size: 10, color: 'rgba(0,0,0,0.3)' }
591
}
592
});
593
594
// Export with watermark
595
const imageData = await Plotly.toImage(chartId);
596
597
// Remove watermark
598
await Plotly.relayout(chartId, {
599
'annotations[0]': null
600
});
601
602
return imageData;
603
}
604
```
605
606
### Export Quality Optimization
607
608
```javascript
609
// Optimize export settings based on use case
610
const exportPresets = {
611
web: {
612
format: 'webp',
613
scale: 1,
614
width: 800,
615
height: 600
616
},
617
print: {
618
format: 'pdf',
619
scale: 1,
620
width: 3200, // 300 DPI
621
height: 2400
622
},
623
presentation: {
624
format: 'png',
625
scale: 2,
626
width: 1920,
627
height: 1080
628
},
629
thumbnail: {
630
format: 'jpeg',
631
scale: 1,
632
width: 300,
633
height: 200
634
}
635
};
636
637
async function exportForUseCase(chartId, useCase) {
638
const options = exportPresets[useCase];
639
if (!options) {
640
throw new Error(`Unknown use case: ${useCase}`);
641
}
642
643
return await Plotly.toImage(chartId, options);
644
}
645
```