Skip to main content

The Polar Sunburst Chart Type

The Polar Sunburst Chart is a powerful way to visualize hierarchical data in a circular format. This chart type is not a single series, but rather a dynamic composition of multiple PolarColumnRenderableSeriesšŸ“˜, arranged by angular position and radial depth.

Each layer in the hierarchy becomes a new radial level, with children elements subdividing the angular range of their parents. Selection and drill-down functionality are built in, allowing users to click to zoom in or back out of the tree.

Above: The JavaScript Polar Sunburst Chart example from the SciChart.js Demo

How It Works​

Unlike typical charts where one renderable series maps to one data set, the Sunburst chart is generated by iterating over hierarchical data and creating a new PolarColumnRenderableSeries for each level of the tree.

  • Each column segment represents a node in the tree.
  • Angular size corresponds to value, while radial distance encodes depth.
  • A custom SunburstMetadata object is attached to each data point for drill-down interaction.
  • The chart uses animation to smoothly zoom between levels.
note

This is not a SunburstSeries. Instead, it is a recursive aggregation of multiple polar column series.

The chart listens for selection events on the segments and redraws itself with a smooth animation when drilling into or out of the hierarchy.

Building a Polar Sunburst Chart​

Once configured, only the data guides how complex / primitive the chart is. The chart can handle any depth of hierarchy, and the segments will automatically adjust their angular and radial sizes based on the data.

Here is another preview:

Behind the scenes:

  • getDataById() processes hierarchical JSON into level-wise flat arrays.
  • SunburstPaletteProvider adjusts fill colors per selection state.
  • custom function drawSeriesFn() adds and animates layers of PolarColumnRenderableSeries.

Hierarchical Data Input Format​

The data must be provided in a tree structure like this:

type TElement = {
name: string;
value: number;
backgroundColor: string;
children?: TElement[];
};

// example:
export const sunburstData: TElement = {
name: "TechCorp",
value: 457,
backgroundColor: "#ffffff",
children: [ ... ] // children elements (which are also <TElement>)
};

The code is a bit complex, here is the whole bit in case you want to try this yourself:

const drawExample = async (rootElement: string | HTMLDivElement) => {
const { sciChartSurface, wasmContext } = await SciChartPolarSurface.create(rootElement, {
theme: new SciChartJsNavyTheme()
});

const startAngle = -Math.PI / 2;
const totalAngle = 2 * Math.PI;

const xAxis = new PolarNumericAxis(wasmContext, {
isVisible: false,
polarAxisMode: EPolarAxisMode.Angular,
axisAlignment: EAxisAlignment.Top,
visibleRange: new NumberRange(0, 65),
startAngle,
totalAngle
});
xAxis.polarLabelMode = EPolarLabelMode.Parallel;
sciChartSurface.xAxes.add(xAxis);

const yAxis = new PolarNumericAxis(wasmContext, {
isVisible: false,
polarAxisMode: EPolarAxisMode.Radial,
axisAlignment: EAxisAlignment.Right,
visibleRange: new NumberRange(0, 6),
flippedCoordinates: false,
startAngle,
totalAngle
});
sciChartSurface.yAxes.add(yAxis);

const dataPointSelectionModifier = new PolarDataPointSelectionModifier({
allowClickSelect: true,
allowDragSelect: true,
selectionStroke: "red",
selectionFill: "#ff879f33"
});

drawSeriesFn(
wasmContext,
xAxis,
yAxis,
sciChartSurface,
EPolarLabelMode.Parallel,
dataPointSelectionModifier,
[0],
0,
[0]
);

sciChartSurface.chartModifiers.add(dataPointSelectionModifier);

return { sciChartSurface, wasmContext };
};