0
# Plugin System
1
2
This module provides the comprehensive chart plugin system and dynamic loading infrastructure for Superset's extensible visualization framework. It includes chart plugins, component registries, the SuperChart rendering system, and support for both static and dynamically loaded chart components.
3
4
## Overview
5
6
The plugin system is built around the ChartPlugin class that extends the base Plugin class, providing specialized functionality for chart visualization components. It supports lazy loading of chart components, build query functions, transform props, and control panels, enabling efficient code splitting and dynamic plugin registration.
7
8
## Chart Plugin Architecture
9
10
### ChartPlugin Class { .api }
11
12
Core plugin class for chart visualizations with support for lazy loading:
13
14
```typescript
15
import { ChartPlugin, ChartMetadata } from '@superset-ui/core';
16
17
interface ChartPluginConfig<
18
FormData extends QueryFormData = QueryFormData,
19
Props extends ChartProps = ChartProps
20
> {
21
metadata: ChartMetadata;
22
23
// Build Query (choose one approach)
24
buildQuery?: BuildQueryFunction<FormData>;
25
loadBuildQuery?: PromiseOrValueLoader<ValueOrModuleWithValue<BuildQueryFunction<FormData>>>;
26
27
// Transform Props (choose one approach)
28
transformProps?: TransformProps<Props>;
29
loadTransformProps?: PromiseOrValueLoader<ValueOrModuleWithValue<TransformProps<Props>>>;
30
31
// Chart Component (choose one approach)
32
Chart?: ChartType;
33
loadChart?: PromiseOrValueLoader<ValueOrModuleWithValue<ChartType>>;
34
35
// Control Panel (choose one approach)
36
controlPanel?: ChartControlPanel;
37
loadControlPanel?: PromiseOrValueLoader<ValueOrModuleWithValue<ChartControlPanel>>;
38
}
39
40
class ChartPlugin<
41
FormData extends QueryFormData = QueryFormData,
42
Props extends ChartProps = ChartProps
43
> extends Plugin {
44
constructor(config: ChartPluginConfig<FormData, Props>);
45
46
// Override base Plugin methods
47
register(): this;
48
unregister(): this;
49
50
// Plugin configuration
51
configure(config: Partial<ChartPluginConfig<FormData, Props>>, replace?: boolean): this;
52
}
53
54
// Utility types for lazy loading
55
type PromiseOrValue<T> = Promise<T> | T;
56
type PromiseOrValueLoader<T> = () => PromiseOrValue<T>;
57
type ChartType = React.ComponentType<any>;
58
type ValueOrModuleWithValue<T> = T | { default: T };
59
```
60
61
### ChartMetadata Class { .api }
62
63
Metadata container that describes chart plugin capabilities and configuration:
64
65
```typescript
66
import { ChartMetadata, Behavior } from '@superset-ui/core';
67
68
interface ChartMetadataConfig {
69
name: string; // Display name for the chart
70
description?: string; // Human-readable description
71
canBeAnnotationTypes?: string[]; // Supported annotation types
72
category?: string; // Chart category for grouping
73
credits?: string[]; // Attribution/credits
74
datasourceCount?: number; // Number of required data sources
75
deprecated?: boolean; // Whether chart is deprecated
76
exampleGallery?: ExampleImage[]; // Example gallery images
77
show?: boolean; // Whether to show in chart picker
78
supportedAnnotationTypes?: string[]; // Annotation types this chart supports
79
thumbnail?: string; // Thumbnail image URL
80
useLegacyApi?: boolean; // Whether to use legacy API format
81
behaviors?: Behavior[]; // Chart behavior capabilities
82
tags?: string[]; // Tags for categorization and search
83
}
84
85
class ChartMetadata {
86
constructor(config: ChartMetadataConfig);
87
88
// Metadata properties (all readonly)
89
readonly name: string;
90
readonly description?: string;
91
readonly canBeAnnotationTypes?: string[];
92
readonly category?: string;
93
readonly credits?: string[];
94
readonly datasourceCount?: number;
95
readonly deprecated?: boolean;
96
readonly exampleGallery?: ExampleImage[];
97
readonly show?: boolean;
98
readonly supportedAnnotationTypes?: string[];
99
readonly thumbnail?: string;
100
readonly useLegacyApi?: boolean;
101
readonly behaviors?: Behavior[];
102
readonly tags?: string[];
103
104
// Utility methods
105
clone(overrides?: Partial<ChartMetadataConfig>): ChartMetadata;
106
}
107
108
// Chart behavior enumeration
109
enum Behavior {
110
INTERACTIVE_CHART = 'INTERACTIVE_CHART',
111
NATIVE_FILTER = 'NATIVE_FILTER',
112
DRILL_TO_DETAIL = 'DRILL_TO_DETAIL',
113
DRILL_BY = 'DRILL_BY'
114
}
115
116
interface ExampleImage {
117
url: string;
118
caption?: string;
119
}
120
```
121
122
## Chart Component System
123
124
### SuperChart Component { .api }
125
126
Main chart rendering component that handles plugin loading and error boundaries:
127
128
```typescript
129
import { SuperChart } from '@superset-ui/core';
130
131
interface SuperChartProps extends Omit<ChartPropsConfig, 'width' | 'height'> {
132
// Chart identification
133
chartType: string; // Registered chart type key
134
135
// Dimensions (auto-sizing if not specified)
136
width?: number | string;
137
height?: number | string;
138
139
// Error handling
140
disableErrorBoundary?: boolean; // Disable built-in error boundary
141
FallbackComponent?: React.ComponentType<FallbackPropsWithDimension>;
142
onErrorBoundary?: (error: Error, errorInfo: React.ErrorInfo) => void;
143
144
// Behavior configuration
145
debounceTime?: number; // Resize debounce time in ms
146
enableNoResults?: boolean; // Show "No Results" message
147
showOverflow?: boolean; // Show overflow content
148
149
// Refs for integration
150
parentRef?: React.RefObject<any>;
151
inputRef?: React.RefObject<any>;
152
153
// Layout wrapper
154
Wrapper?: React.ComponentType<WrapperProps>;
155
}
156
157
// SuperChart component
158
const SuperChart: React.ComponentType<SuperChartProps>;
159
160
// Dimension and wrapper types
161
interface WrapperProps extends Dimension {
162
children: React.ReactNode;
163
}
164
165
type FallbackPropsWithDimension = {
166
error: Error;
167
resetErrorBoundary: () => void;
168
width?: number;
169
height?: number;
170
};
171
```
172
173
### ChartProps Class { .api }
174
175
Props container that manages chart data and configuration:
176
177
```typescript
178
import { ChartProps } from '@superset-ui/core';
179
180
interface ChartPropsConfig {
181
annotationData?: AnnotationData;
182
datasource?: Datasource;
183
initialValues?: any;
184
formData?: QueryFormData;
185
height?: number;
186
hooks?: ChartHooks;
187
ownCurrentState?: any;
188
ownState?: any;
189
queriesData?: ChartDataResponseResult[];
190
rawDatasource?: Datasource;
191
rawFormData?: QueryFormData;
192
width?: number;
193
}
194
195
class ChartProps {
196
constructor(config?: ChartPropsConfig & { [key: string]: any });
197
198
// Core properties
199
readonly annotationData: AnnotationData;
200
readonly datasource: Datasource;
201
readonly formData: QueryFormData;
202
readonly height: number;
203
readonly hooks: ChartHooks;
204
readonly initialValues: any;
205
readonly ownCurrentState: any;
206
readonly ownState: any;
207
readonly queriesData: ChartDataResponseResult[];
208
readonly rawDatasource: Datasource;
209
readonly rawFormData: QueryFormData;
210
readonly width: number;
211
}
212
```
213
214
## Registry System
215
216
### Chart Registries { .api }
217
218
Specialized registries for managing different aspects of chart plugins:
219
220
```typescript
221
import {
222
getChartComponentRegistry,
223
getChartMetadataRegistry,
224
getChartBuildQueryRegistry,
225
getChartTransformPropsRegistry,
226
getChartControlPanelRegistry
227
} from '@superset-ui/core';
228
229
// Chart component registry
230
function getChartComponentRegistry(): RegistryWithDefaultKey<ChartType>;
231
232
// Chart metadata registry
233
function getChartMetadataRegistry(): RegistryWithDefaultKey<ChartMetadata>;
234
235
// Build query function registry
236
function getChartBuildQueryRegistry(): RegistryWithDefaultKey<BuildQueryFunction>;
237
238
// Transform props function registry
239
function getChartTransformPropsRegistry(): RegistryWithDefaultKey<TransformProps>;
240
241
// Control panel configuration registry
242
function getChartControlPanelRegistry(): RegistryWithDefaultKey<ChartControlPanel>;
243
```
244
245
## Transform Functions
246
247
### BuildQuery Function { .api }
248
249
Function type for building queries from form data:
250
251
```typescript
252
type BuildQueryFunction<FormData extends QueryFormData = QueryFormData> = (
253
formData: FormData
254
) => QueryContext;
255
256
// Query context structure
257
interface QueryContext {
258
datasource: DatasourceInfo;
259
queries: Query[];
260
force?: boolean;
261
result_format?: QueryResultFormat;
262
result_type?: QueryResultType;
263
}
264
265
interface Query {
266
annotation_layers?: AnnotationLayer[];
267
applied_time_extras?: AppliedTimeExtra;
268
columns?: QueryColumn[];
269
extras?: QueryExtra;
270
filters?: QueryFilter[];
271
granularity?: string;
272
groupby?: QueryColumn[];
273
having?: string;
274
is_timeseries?: boolean;
275
limit?: number;
276
metrics?: QueryMetric[];
277
order_desc?: boolean;
278
orderby?: QueryOrderBy[];
279
post_processing?: PostProcessingRule[];
280
row_limit?: number;
281
series_columns?: QueryColumn[];
282
series_limit?: number;
283
series_limit_metric?: QueryMetric;
284
time_grain?: string;
285
time_range?: string;
286
timeseries_limit?: number;
287
timeseries_limit_metric?: QueryMetric;
288
url_params?: UrlParams;
289
where?: string;
290
}
291
```
292
293
### TransformProps Function { .api }
294
295
Function type for transforming query results into chart props:
296
297
```typescript
298
type TransformProps<Props extends ChartProps = ChartProps> = (
299
chartProps: ChartProps
300
) => Props;
301
302
// Common transform props patterns
303
type TimeseriesTransformProps = TransformProps<{
304
data: TimeseriesDataRecord[];
305
width: number;
306
height: number;
307
// ... chart-specific props
308
}>;
309
310
type TableTransformProps = TransformProps<{
311
data: TableDataRecord[];
312
columns: TableColumnConfig[];
313
// ... table-specific props
314
}>;
315
```
316
317
## Dynamic Loading Utilities
318
319
### Loadable Renderer { .api }
320
321
Utilities for creating lazy-loaded chart components:
322
323
```typescript
324
import { createLoadableRenderer } from '@superset-ui/core';
325
326
function createLoadableRenderer<Props, FormData extends QueryFormData = QueryFormData>(config: {
327
loader: () => Promise<{ default: React.ComponentType<Props> }>;
328
loading?: React.ComponentType<any>;
329
fallback?: React.ComponentType<{ error: Error }>;
330
}): React.ComponentType<Props>;
331
332
// React component converter
333
function reactify(component: any): React.ComponentType<any>;
334
```
335
336
## Usage Examples
337
338
### Creating a Basic Chart Plugin
339
340
```typescript
341
import {
342
ChartPlugin,
343
ChartMetadata,
344
Behavior,
345
buildQueryContext,
346
QueryFormData
347
} from '@superset-ui/core';
348
349
// Define form data interface
350
interface BarChartFormData extends QueryFormData {
351
groupby: string[];
352
metrics: string[];
353
color_scheme?: string;
354
x_axis_label?: string;
355
y_axis_label?: string;
356
}
357
358
// Create chart metadata
359
const metadata = new ChartMetadata({
360
name: 'Bar Chart',
361
description: 'Simple bar chart visualization',
362
category: 'Evolution',
363
behaviors: [Behavior.INTERACTIVE_CHART, Behavior.DRILL_TO_DETAIL],
364
thumbnail: '/static/assets/images/viz_types/bar.png',
365
tags: ['Basic', 'Popular', 'Business']
366
});
367
368
// Build query function
369
const buildQuery = (formData: BarChartFormData) => {
370
return buildQueryContext(formData, {
371
queryFields: {
372
groupby: 'groupby',
373
metrics: 'metrics'
374
}
375
});
376
};
377
378
// Transform props function
379
const transformProps = (chartProps: ChartProps) => {
380
const { width, height, formData, queriesData } = chartProps;
381
const data = queriesData[0]?.data || [];
382
383
return {
384
width,
385
height,
386
data,
387
colorScheme: formData.color_scheme,
388
xAxisLabel: formData.x_axis_label,
389
yAxisLabel: formData.y_axis_label
390
};
391
};
392
393
// Chart component (simplified)
394
const BarChart: React.FC<any> = ({ width, height, data }) => (
395
<div style={{ width, height }}>
396
{/* Chart implementation */}
397
</div>
398
);
399
400
// Create and register plugin
401
const BarChartPlugin = new ChartPlugin({
402
metadata,
403
buildQuery,
404
transformProps,
405
Chart: BarChart
406
});
407
408
BarChartPlugin.register();
409
```
410
411
### Lazy-Loaded Chart Plugin
412
413
```typescript
414
import { ChartPlugin, ChartMetadata } from '@superset-ui/core';
415
416
// Create plugin with lazy loading
417
const LazyBarChartPlugin = new ChartPlugin({
418
metadata: new ChartMetadata({
419
name: 'Lazy Bar Chart',
420
description: 'Dynamically loaded bar chart',
421
category: 'Evolution'
422
}),
423
424
// Lazy load chart component
425
loadChart: () => import('./charts/BarChart').then(module => module.default),
426
427
// Lazy load build query function
428
loadBuildQuery: () => import('./queries/barChartQuery').then(module => module.buildQuery),
429
430
// Lazy load transform props
431
loadTransformProps: () => import('./transforms/barChartTransform').then(module => module.transformProps),
432
433
// Lazy load control panel
434
loadControlPanel: () => import('./controls/barChartControls').then(module => module.default)
435
});
436
```
437
438
### Using SuperChart Component
439
440
```typescript
441
import React from 'react';
442
import { SuperChart, ChartDataResponseResult } from '@superset-ui/core';
443
444
interface DashboardChartProps {
445
chartId: number;
446
formData: QueryFormData;
447
queriesData: ChartDataResponseResult[];
448
width?: number;
449
height?: number;
450
}
451
452
const DashboardChart: React.FC<DashboardChartProps> = ({
453
chartId,
454
formData,
455
queriesData,
456
width = 400,
457
height = 300
458
}) => {
459
const handleChartError = (error: Error) => {
460
console.error(`Chart ${chartId} error:`, error);
461
};
462
463
return (
464
<SuperChart
465
chartType={formData.viz_type}
466
width={width}
467
height={height}
468
formData={formData}
469
queriesData={queriesData}
470
onErrorBoundary={handleChartError}
471
enableNoResults={true}
472
/>
473
);
474
};
475
```
476
477
### Advanced Plugin with Control Panel
478
479
```typescript
480
import {
481
ChartPlugin,
482
ChartMetadata,
483
ControlPanelConfig
484
} from '@superset-ui/core';
485
486
// Control panel configuration
487
const controlPanel: ControlPanelConfig = {
488
controlPanelSections: [
489
{
490
label: 'Query',
491
expanded: true,
492
controlSetRows: [
493
['metrics'],
494
['groupby'],
495
['limit', 'timeseries_limit_metric'],
496
['order_desc', 'contribution'],
497
['row_limit', null]
498
]
499
},
500
{
501
label: 'Chart Options',
502
expanded: true,
503
controlSetRows: [
504
['color_scheme'],
505
['show_legend', 'legend_position'],
506
['x_axis_label', 'y_axis_label']
507
]
508
}
509
],
510
controlOverrides: {
511
color_scheme: {
512
renderTrigger: true,
513
default: 'supersetColors'
514
}
515
}
516
};
517
518
// Advanced chart plugin
519
const AdvancedBarChartPlugin = new ChartPlugin({
520
metadata: new ChartMetadata({
521
name: 'Advanced Bar Chart',
522
description: 'Bar chart with extensive configuration options',
523
category: 'Evolution',
524
behaviors: [
525
Behavior.INTERACTIVE_CHART,
526
Behavior.DRILL_TO_DETAIL,
527
Behavior.DRILL_BY
528
]
529
}),
530
Chart: AdvancedBarChart,
531
buildQuery: buildAdvancedBarQuery,
532
transformProps: transformAdvancedBarProps,
533
controlPanel
534
});
535
```
536
537
### Plugin Registry Management
538
539
```typescript
540
import {
541
getChartComponentRegistry,
542
getChartMetadataRegistry,
543
ChartPlugin
544
} from '@superset-ui/core';
545
546
// Register multiple plugins
547
const plugins = [BarChartPlugin, LineChartPlugin, PieChartPlugin];
548
549
plugins.forEach(plugin => plugin.register());
550
551
// Get registered chart types
552
const componentRegistry = getChartComponentRegistry();
553
const availableChartTypes = componentRegistry.keys();
554
555
// Get chart metadata
556
const metadataRegistry = getChartMetadataRegistry();
557
const barChartMetadata = metadataRegistry.get('bar');
558
559
// Unregister plugin
560
const unregisterPlugin = (chartType: string) => {
561
const componentRegistry = getChartComponentRegistry();
562
const metadataRegistry = getChartMetadataRegistry();
563
564
componentRegistry.remove(chartType);
565
metadataRegistry.remove(chartType);
566
};
567
```
568
569
### Error Handling and Fallbacks
570
571
```typescript
572
import React from 'react';
573
import { SuperChart, FallbackPropsWithDimension } from '@superset-ui/core';
574
575
// Custom fallback component
576
const ChartErrorFallback: React.FC<FallbackPropsWithDimension> = ({
577
error,
578
resetErrorBoundary,
579
width,
580
height
581
}) => (
582
<div
583
style={{
584
width,
585
height,
586
display: 'flex',
587
flexDirection: 'column',
588
alignItems: 'center',
589
justifyContent: 'center',
590
border: '2px dashed #ccc'
591
}}
592
>
593
<h3>Chart Error</h3>
594
<p>{error.message}</p>
595
<button onClick={resetErrorBoundary}>
596
Try Again
597
</button>
598
</div>
599
);
600
601
// Use with SuperChart
602
<SuperChart
603
chartType="advanced_bar"
604
formData={formData}
605
queriesData={queriesData}
606
FallbackComponent={ChartErrorFallback}
607
onErrorBoundary={(error, errorInfo) => {
608
// Log error to monitoring service
609
console.error('Chart render error:', error, errorInfo);
610
}}
611
/>
612
```
613
614
## Related Documentation
615
616
- [Core Models & Utilities](./core-models.md) - Base Plugin class and Registry system
617
- [Dashboard Components](./dashboard.md) - Dashboard integration with chart plugins
618
- [Data Connection](./data-connection.md) - API integration for chart data
619
- [Data Formatting](./data-formatting.md) - Formatting utilities for chart display