or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-models.mddashboard.mddata-connection.mddata-formatting.mdindex.mdplugin-system.mdtranslation.mdui-styling.mdvalidation-math.md

plugin-system.mddocs/

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