Superset series 4/6 — Modifying plugins
Teclead Ventures
We enable our enterprise clients to reach the mass market and digitalize internal and external businees processes. https://teclead-ventures.de/en
We are hiring!
Introduction
Modifying an existing plugin can be a great way to add new functionality to Superset, tweak the behavior of an existing feature, or fix a bug. Instead of creating a plugin from scratch it can often be more suitable to build upon already implemented plugins.
Open up an Editor of your choice and start editing the cloned repository. You can find all plugins in the directory: /superset-frontend/plugins
We will start by choosing a Plugin which we want to modify. In this guide we are choosing the heatmap Plugin which you can find in the /superset-frontend/plugins/legacy-plugin-chart-heatmap
directory. Feel free to choose any other Plugin or any other dataset.
If you want to modify a plugin but keep the original one, then it might be useful to copy the desired plugin first. In the third guide of our superset documentation we discuss how to copy plugins.
Version
In this Guide we are using Superset version 2.1.0
You can use the same version by checking out in the corresponding branch
git checkout 2.1.0
Preparation
- Make sure to stop any other superset non-related PostgreSQL instances
- Node 16.9.1
- Python 3.6 or newer
Then run the following commands in /superset-frontend
directory:
cd superset-frontend
npm i
npm run build
cd ..
superset load examples
superset db upgrade
superset init
superset run -p 8088 --with-threads --reload --debugger
Result Repository
This Superset documentation series will guide you through each step of customizing Superset. If you’d like to use the results directly, you can clone our Git repository, which includes all changes made during the course of this guide:
(OPTIONAL)
git clone https://github.com/Teclead-Ventures/superset
Default Plugin Preview
💡It can take a bit for the datasets to fetch , if you can not see them try closing the page and reopen it
To preview our heatmap Plugin we can create a new chart by clicking the plus button in the top right corner and selecting ‘Chart’.
Then a dataset has to be chosen, in our example we choose the video_game_sales
, as well as the heatmap Chart type:
Now we can set our query in the control panel on the left hand side to create a default heatmap chart.
For this demonstration we will implement a feature which allows us to set our own Color Scheme by picking a color. We will edit the Controlpanel.tsx
and change the data flow. In part 2 of our superset series we explain those two topics.
The result will look like this :
As you can see instead of choosing a linear color scheme, we are able to choose a color from an added color picker.
- In
/legacy-plugin-chart-heatmapcopy/src/controlPanel.tsx
we are adding the following color picker option:
controlSetRows: [
['linear_color_scheme'],
// Copy and Paste the following Array
[
{
name: 'primary_color_picker',
config: {
type: 'ColorPickerControl',
label: t('Primary Color'),
description: t(
'Use this to define a static color for all circles',
),
default: { r: 70, g: 80, b: 120, a: 1 },
renderTrigger: true,
},
},
],
//
...
]
When rebuilding superset the new option should appear in the controlpanel :
2. Now we adjust the /legacy-plugin-chart-heatmapcopy/src/transformProps.js
props so that our color value is passed to the plugin correctly. Add primaryColorPicker
:
Note that you should use the same name as the one you defined in the
controlPanel.tsx
file, but in camelCase instead of snake_case. So in our example we used primary_color_picker in controlpanel and primaryColorPicker in transformprops
export default function transformProps(chartProps) {
const { width, height, formData, queriesData } = chartProps;
const {
bottomMargin,
canvasImageRendering,
allColumnsX,
allColumnsY,
linearColorScheme,
primaryColorPicker, // ADDED
leftMargin,
metric,
normalized,
showLegend,
showPerc,
showValues,
sortXAxis,
sortYAxis,
xscaleInterval,
yscaleInterval,
yAxisBounds,
yAxisFormat,
} = formData;
return {
width,
height,
data: queriesData[0].data,
bottomMargin,
canvasImageRendering,
colorScheme: linearColorScheme,
primaryColorPicker, // ADDED
columnX: allColumnsX,
columnY: allColumnsY,
leftMargin,
metric,
normalized,
numberFormat: yAxisFormat,
showLegend,
showPercentage: showPerc,
showValues,
sortXAxis,
sortYAxis,
xScaleInterval: parseInt(xscaleInterval, 10),
yScaleInterval: parseInt(yscaleInterval, 10),
yAxisBounds,
};
}
3. Next in the /legacy-plugin-chart-heatmapcopy/src/Heatmap.js
add primaryColorPicker :
const propTypes = {
data: PropTypes.shape({
records: PropTypes.arrayOf(
PropTypes.shape({
x: PropTypes.string,
y: PropTypes.string,
v: PropTypes.number,
perc: PropTypes.number,
rank: PropTypes.number,
}),
),
extents: PropTypes.arrayOf(PropTypes.number),
}),
width: PropTypes.number,
height: PropTypes.number,
bottomMargin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
primaryColorPicker: PropTypes.object, // Added
columnX: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
columnY: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
leftMargin: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
metric: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
normalized: PropTypes.bool,
numberFormat: PropTypes.string,
showLegend: PropTypes.bool,
showPercentage: PropTypes.bool,
showValues: PropTypes.bool,
sortXAxis: PropTypes.string,
sortYAxis: PropTypes.string,
xScaleInterval: PropTypes.number,
yScaleInterval: PropTypes.number,
yAxisBounds: PropTypes.arrayOf(PropTypes.number),
};
4. Do the same for props
:
function Heatmap(element, props) {
const {
data,
width,
height,
bottomMargin,
canvasImageRendering,
primaryColorPicker, // added
columnX,
columnY,
leftMargin,
metric,
normalized,
numberFormat,
showLegend,
showPercentage,
showValues,
sortXAxis,
sortYAxis,
xScaleInterval,
yScaleInterval,
yAxisBounds,
} = props
5. Now we adjust the colorScale
Variable inside the Heatmap.js
// Find this Variable
const colorScale = getSequentialSchemeRegistry()
.get(colorScheme)
.createLinearScale([minBound, maxBound]);
For this step create a function which takes the RGB Object from the primaryColorPicker and returns a colorScale array. This can be implemented like this :
function rgbToHex(r, g, b) {
return `#${[r, g, b].map(x => x.toString(16).padStart(2, '0')).join('')}`;
}
function generateColorScale(primaryColorPicker) {
const { r, g, b } = primaryColorPicker;
const stepSize = (255 - Math.max(r, g, b)) / 10;
const tempcolorScale = [];
for (let i = 0; i < 10; i += 1) {
const newR = Math.min(255, r + i * stepSize);
const newG = Math.min(255, g + i * stepSize);
const newB = Math.min(255, b + i * stepSize);
tempcolorScale.push(
rgbToHex(Math.round(newR), Math.round(newG), Math.round(newB)),
);
}
return tempcolorScale.reverse();
}
Using those methods we can modify the colorScale variable :
// Add this
const beforeScaleAdded = getSequentialSchemeRegistry().get(colorScheme);
beforeScaleAdded.colors = generateColorScale(primaryColorPicker);
// Adjust colorScale to this :
const colorScale = beforeScaleAdded .createLinearScale([minBound, maxBound]);
Rebuild Superset by running :
cd superset-frontend
npm i
npm run build
cd ..
superset db upgrade
superset init
superset run -p 8088 --with-threads --reload --debugger
And that is it! Sometimes checking the NORMALIZED Checkbox gives better resuts. The heatmap plugin should then look like this :
Wrapping up this guide shows you how props are passed inside superset plugins and how to set different settings which affect the data visualization. In your very own use case this knowledge will help you to customize and add features to default plugins.
In the next part of our superset series we will show you how to add plugins from scratch which we will then use in the guide after to visualize maps using the Openlayers library.
Superset Setup Part 1 : https://medium.com/@teclead-ventures/superset-series-1-6-setting-up-superset-a750481c228e
Superset Controlpanel Part 2 : https://medium.com/@teclead-ventures/superset-series-2-6-control-panel-31a84afae465
Cloning Superset Plugins Part 3: https://medium.com/@teclead-ventures/superset-series-3-6-cloning-plugins-3336a8a979a0
Adding Superset Plugins Part 5 : https://medium.com/@teclead-ventures/superset-series-5-6-adding-plugins-4677c6a1ff5b
Visualizing Maps using Openlayers in Superset Part 6 : https://teclead-ventures.medium.com/superset-series-6-6-openlayers-map-visualization-e72e2976cfa0
Author : Daniel Jin Wodke
Editors: Ruben Karlsson, Matthias Daiber, Cherif Khlass, Lukas Zöllner, John Einicke