A Nightingale Rose Diagram visualization plugin for Apache Superset that creates polar coordinate charts with equal-angle wedges where values are represented by area rather than radius.
npx @tessl/cli install tessl/npm-superset-ui--legacy-plugin-chart-rose@0.18.0A Nightingale Rose Diagram visualization plugin for Apache Superset that creates polar coordinate charts where data values are represented as sectors with varying radii. The chart displays data in a circular format with equal-angle wedges, making it ideal for showing categorical data with quantitative dimensions and temporal patterns.
npm install @superset-ui/legacy-plugin-chart-roseimport RoseChartPlugin from '@superset-ui/legacy-plugin-chart-rose';For CommonJS:
const RoseChartPlugin = require('@superset-ui/legacy-plugin-chart-rose').default;import { SuperChart } from '@superset-ui/core';
import RoseChartPlugin from '@superset-ui/legacy-plugin-chart-rose';
// Register the plugin with Superset
new RoseChartPlugin().configure({ key: 'rose' }).register();
// Use within Superset or with SuperChart
const roseChart = (
<SuperChart
chartType="rose"
width={600}
height={400}
formData={{
colorScheme: 'd3Category10',
numberFormat: 'SMART_NUMBER',
dateTimeFormat: 'smart_date',
richTooltip: true,
roseAreaProportion: false,
sliceId: 1
}}
queriesData={[{
data: {
"1609459200000": [
{ key: ["Product A"], name: ["Product A"], time: 1609459200000, value: 100 },
{ key: ["Product B"], name: ["Product B"], time: 1609459200000, value: 75 }
],
"1609545600000": [
{ key: ["Product A"], name: ["Product A"], time: 1609545600000, value: 120 },
{ key: ["Product B"], name: ["Product B"], time: 1609545600000, value: 90 }
]
}
}]}
/>
);In Superset, the plugin is automatically registered and available as a "Nightingale Rose Chart" visualization type when creating new charts.
The rose chart plugin is built around several key components:
Main plugin class for registering the rose chart with Superset.
export default class RoseChartPlugin extends ChartPlugin {
constructor() {
super({
loadChart: () => import('./ReactRose'),
metadata: ChartMetadata,
transformProps: transformProps,
controlPanel: controlPanel,
});
}
}
class ChartPlugin {
configure(config) { /* inherited method */ }
register() { /* inherited method */ }
}The plugin automatically configures chart metadata:
Core visualization component that renders the rose diagram using D3.js.
function Rose(element, props) {
// D3.js-based chart rendering function
}
// PropTypes validation
Rose.propTypes = {
data: PropTypes.objectOf(
PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.arrayOf(PropTypes.string),
name: PropTypes.arrayOf(PropTypes.string),
time: PropTypes.number,
value: PropTypes.number,
}),
),
),
width: PropTypes.number,
height: PropTypes.number,
colorScheme: PropTypes.string,
dateTimeFormat: PropTypes.string,
numberFormat: PropTypes.string,
useRichTooltip: PropTypes.bool,
useAreaProportions: PropTypes.bool,
sliceId: PropTypes.number,
};
// Data structure
const RoseData = {
"1609459200000": [
{
key: ["Category A"],
name: ["Category A"],
time: 1609459200000,
value: 100
}
]
};The Rose component creates an interactive polar coordinate chart with the following features:
React wrapper component with styling and theming support.
const ReactRose = ({ className, ...otherProps }) => (
<div className={className}>
<Global styles={theme => css`/* tooltip styles */`} />
<ReactComponent {...otherProps} />
</div>
);
export default styled(ReactRose)`/* chart styles */`;
// Component props (passed to ReactComponent)
const reactRoseProps = {
className: String, // optional
width: Number,
height: Number,
data: Object, // RoseData format
colorScheme: String,
dateTimeFormat: String,
numberFormat: String,
useRichTooltip: Boolean,
useAreaProportions: Boolean,
sliceId: Number,
};The ReactRose component provides:
Transforms chart properties from Superset format to component props.
export default function transformProps(chartProps) {
const { width, height, formData, queriesData } = chartProps;
const {
colorScheme,
dateTimeFormat,
numberFormat,
richTooltip,
roseAreaProportion,
sliceId,
} = formData;
return {
width,
height,
data: queriesData[0].data,
colorScheme,
dateTimeFormat,
numberFormat,
useAreaProportions: roseAreaProportion,
useRichTooltip: richTooltip,
sliceId,
};
}
// Input structure
const SupersetChartProps = {
width: Number,
height: Number,
formData: {
colorScheme: String,
dateTimeFormat: String,
numberFormat: String,
richTooltip: Boolean,
roseAreaProportion: Boolean,
sliceId: Number,
},
queriesData: [{
data: Object // RoseData format
}]
};Configuration object defining available chart options and controls.
const config = {
controlPanelSections: [
sections.legacyTimeseriesTime,
{
label: 'Query',
expanded: true,
controlSetRows: [
['metrics'],
['adhoc_filters'],
['groupby'],
['limit', 'timeseries_limit_metric'],
['order_desc'],
[{
name: 'contribution',
config: {
type: 'CheckboxControl',
label: 'Contribution',
default: false,
description: 'Compute the contribution to the total',
},
}],
['row_limit', null],
],
},
{
label: 'Chart Options',
expanded: true,
controlSetRows: [
['color_scheme'],
[
{
name: 'number_format',
config: {
type: 'SelectControl',
freeForm: true,
label: 'Number format',
renderTrigger: true,
default: 'SMART_NUMBER',
choices: D3_FORMAT_OPTIONS,
description: D3_FORMAT_DOCS,
},
},
{
name: 'date_time_format',
config: {
type: 'SelectControl',
freeForm: true,
label: 'Date Time Format',
renderTrigger: true,
default: 'smart_date',
choices: D3_TIME_FORMAT_OPTIONS,
description: D3_FORMAT_DOCS,
},
},
],
[
{
name: 'rich_tooltip',
config: {
type: 'CheckboxControl',
label: 'Rich Tooltip',
renderTrigger: true,
default: true,
description: 'The rich tooltip shows a list of all series for that point in time',
},
},
{
name: 'rose_area_proportion',
config: {
type: 'CheckboxControl',
label: 'Use Area Proportions',
description: 'Check if the Rose Chart should use segment area instead of segment radius for proportioning',
default: false,
renderTrigger: true,
},
},
],
],
},
// Advanced Analytics section with rolling window, time comparison, resample options
],
formDataOverrides: formData => ({
...formData,
groupby: getStandardizedControls().popAllColumns(),
metrics: getStandardizedControls().popAllMetrics(),
}),
};The control panel provides:
// Required peer dependencies that must be installed separately
"@emotion/react": "^11.4.1"
"@superset-ui/chart-controls": "*"
"@superset-ui/core": "*"
"react": "^16.13.1"// Automatically installed dependencies
"d3": "^3.5.17" // D3.js visualization library (legacy version)
"nvd3-fork": "^2.0.5" // NVD3 charting components fork
"prop-types": "^15.6.2" // React prop validationThe component handles various error conditions: