How to Create Custom Visualization Plugins (Chart Types) for Apache Superset
To create a custom visualization plugin for Apache Superset, extend the ChartPlugin class from @superset-ui/core to define metadata, loadChart, transformProps, and controlPanel, then register it in MainPreset with a unique key.
Apache Superset’s visualization layer is built on a modular plugin architecture centered around the ChartPlugin class. Whether you need a proprietary chart type for internal metrics or a complex D3 visualization, the apache/superset repository provides a robust framework for extending the default chart library using patterns established by production plugins like Word Cloud.
Understanding the ChartPlugin Architecture
Every custom chart in Superset is an instance of ChartPlugin that orchestrates five core responsibilities. In superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/index.ts, the WordCloudChartPlugin demonstrates this structure by wiring together metadata, data transformation, and UI controls.
The essential components include:
- ChartMetadata: Defines the display name, description, thumbnail, and tags visible in the chart picker.
- loadChart: A lazy-loading function that imports the React component responsible for rendering.
- transformProps: Converts the raw query results (
formDataandqueriesData) into props consumed by your React component. - buildQuery: (Optional) Customizes the SQL or JSON payload sent to the backend before execution.
- Control Panel Definition: Declares the form fields and UI controls available in the Explore view.
Step-by-Step Implementation Guide
1. Scaffold the Plugin Structure
Superset includes a Yeoman-style generator located at superset-frontend/packages/generator-superset. Run the generator from the superset-frontend directory to create the boilerplate:
cd superset-frontend
npm run generate-plugin
This creates a new package under superset-frontend/plugins/plugin-chart-<your-name> containing package.json, TypeScript configuration, and stub files. The template reference is available at superset-frontend/packages/generator-superset/generators/plugin-chart/templates/README.erb.
2. Implement the ChartPlugin Class
Create a class extending ChartPlugin<TFormData> in src/plugin/index.ts. This class constructor must pass an object containing metadata, the lazy loader, transformation logic, and the control panel configuration.
import { ChartMetadata, ChartPlugin } from '@superset-ui/core';
import transformProps from './transformProps';
import buildQuery from './buildQuery';
import controlPanel from './controlPanel';
import thumbnail from '../images/thumbnail.png';
const metadata = new ChartMetadata({
name: t('My Fancy Chart'),
description: t('A custom visualization for specialized analytics.'),
thumbnail,
});
export default class MyFancyChartPlugin extends ChartPlugin<MyFormData> {
constructor() {
super({
metadata,
loadChart: () => import('../chart/MyFancyChart'),
transformProps,
buildQuery,
controlPanel,
});
}
}
The Word Cloud plugin implementation at superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/index.ts provides a concrete reference for this pattern.
3. Define the Control Panel
The control panel configuration determines which UI controls appear in the Explore view. Export a ControlPanelConfig from src/plugin/controlPanel.tsx using components from @superset-ui/chart-controls.
import { ControlPanelConfig } from '@superset-ui/chart-controls';
import { t } from '@apache-superset/core';
export default {
controlPanelSections: [
{
label: t('Query'),
controlSetRows: [['metrics'], ['groupby']],
},
{
label: t('Display'),
controlSetRows: [
['color_scheme', 'label_type'],
],
},
],
} as ControlPanelConfig;
See superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/controlPanel.tsx for a complete example including custom controls.
4. Write the transformProps Function
The transformProps function bridges Superset's query response and your React component's prop interface. It receives chartProps containing width, height, formData, and queriesData.
export default function transformProps(chartProps) {
const { width, height, formData, queriesData } = chartProps;
const { metric, colorScheme } = formData;
const data = queriesData[0].data;
return {
width,
height,
data,
metric,
colorScheme,
};
}
Reference the Word Cloud implementation at superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/transformProps.ts for data mapping logic.
5. (Optional) Implement Custom buildQuery
When the default query generation is insufficient, implement buildQuery to customize the payload sent to the backend. Use buildQueryContext and PostProcessingOperator from @superset-ui/core.
import { buildQueryContext, PostProcessingOperator } from '@superset-ui/core';
export default function buildQuery(formData) {
return buildQueryContext(formData, baseQueryObject => [
{
...baseQueryObject,
post_processing: [
{
operation: PostProcessingOperator.PIVOT,
options: {
index: ['category'],
columns: ['metric'],
aggregates: { value: { operator: 'sum' } },
},
},
],
},
]);
}
The Word Cloud plugin includes a minimal example at superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts.
6. Create the React Chart Component
The actual rendering logic lives in a React component, typically using libraries like D3 or ECharts. This component receives the props returned by transformProps.
import React from 'react';
export default function MyFancyChart({ data, width, height, metric }) {
return (
<svg width={width} height={height}>
{data.map((d, i) => (
<circle
key={i}
cx={(i * 50) + 25}
cy={height / 2}
r={d[metric] / 10}
fill="steelblue"
/>
))}
</svg>
);
}
Study superset-frontend/plugins/plugin-chart-word-cloud/src/chart/WordCloud.tsx for a production-grade D3 implementation.
7. Register the Plugin in MainPreset
To make the chart available in the UI, register it in superset-frontend/src/visualizations/presets/MainPreset.ts. Import your plugin and add it to the preset with a unique VizType key.
import { MyFancyChartPlugin } from '@superset-ui/plugin-chart-my-fancy';
new MyFancyChartPlugin().configure({ key: VizType.MyFancy }),
The Word Cloud registration appears at lines 144-147 in superset-frontend/src/visualizations/presets/MainPreset.ts.
Complete Minimal Example: Hello World Chart
Below is a fully functional skeleton for a "Hello World" chart plugin that renders static text in an SVG.
src/plugin/index.ts:
import { ChartMetadata, ChartPlugin } from '@superset-ui/core';
import transformProps from './transformProps';
import controlPanel from './controlPanel';
import thumbnail from '../images/thumbnail.png';
const metadata = new ChartMetadata({
name: t('Hello World'),
description: t('A minimal example chart.'),
thumbnail,
});
export default class HelloWorldChartPlugin extends ChartPlugin<any> {
constructor() {
super({
metadata,
loadChart: () => import('../chart/HelloWorld'),
transformProps,
controlPanel,
});
}
}
src/plugin/controlPanel.tsx:
import { ControlPanelConfig } from '@superset-ui/chart-controls';
import { t } from '@apache-superset/core';
export default {
controlPanelSections: [
{
label: t('Query'),
controlSetRows: [['metrics']],
},
],
} as ControlPanelConfig;
src/plugin/transformProps.ts:
export default function transformProps({ width, height }) {
return { width, height };
}
src/chart/HelloWorld.tsx:
import React from 'react';
export default function HelloWorld({ width, height }) {
return (
<svg width={width} height={height}>
<text x={width / 2} y={height / 2} textAnchor="middle" fontSize="24">
Hello, Superset!
</text>
</svg>
);
}
Finally, register the plugin in MainPreset.ts:
import { HelloWorldChartPlugin } from '@superset-ui/plugin-chart-hello-world';
new HelloWorldChartPlugin().configure({ key: VizType.HelloWorld }),
Run npm run dev from superset-frontend, and "Hello World" will appear in the Viz Type dropdown.
Summary
- ChartPlugin Architecture: Every custom visualization extends
ChartPluginand supplies metadata,loadChart,transformProps, an optionalbuildQuery, and a control panel definition. - File Locations: Plugin code belongs in
superset-frontend/plugins/, while registration occurs insuperset-frontend/src/visualizations/presets/MainPreset.ts. - Generator Tool: Use
npm run generate-pluginto scaffold the directory structure and boilerplate. - Data Flow:
transformPropsmapsformDataandqueriesDatato React props, whilebuildQueryoptionally customizes the backend request. - Registration: Each plugin requires a unique
VizTypekey inMainPresetto appear in the chart creation UI.
Frequently Asked Questions
What is the ChartPlugin class in Superset?
The ChartPlugin class is the foundational abstraction in @superset-ui/core that encapsulates a visualization's metadata, configuration UI, data transformation logic, and rendering component. It acts as the bridge between Superset's backend data engine and the frontend React chart implementation.
Where do I register a custom chart plugin?
Register custom plugins in superset-frontend/src/visualizations/presets/MainPreset.ts. Import your plugin class and instantiate it with .configure({ key: VizType.YourUniqueKey }), adding the result to the preset's plugin array. This registration makes the chart available in the Explore view's visualization type selector.
How do I customize the query sent to the backend?
Implement a buildQuery function that receives formData and returns a query context object. Use buildQueryContext from @superset-ui/core to generate the base query, then modify it with custom post_processing steps or altered parameters. The Word Cloud plugin at superset-frontend/plugins/plugin-chart-word-cloud/src/plugin/buildQuery.ts demonstrates the basic structure.
Can I use third-party libraries like D3 or ECharts?
Yes. The React component loaded by loadChart can import any visualization library. The Word Cloud plugin uses d3-cloud, while other core plugins use ECharts. Ensure you declare these dependencies in your plugin's package.json, and import them in your chart component file (e.g., src/chart/YourChart.tsx).
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →