A Nightingale Series, also called Rose or Wind Series, represents data as radial segments, with one segment per category value. It can simplify the comparison of datasets across multiple categories, providing a concise depiction of data trends.
Simple Nightingale Copy Link
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
AngleCategoryAxisModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: "Revenue by Product Category",
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
},
],
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
To create a Nightingale Series, use the nightingale series type.
{
series: [
{ type: 'nightingale', angleKey: 'quarter', radiusKey: 'software', radiusName: 'Software' },
{ type: 'nightingale', angleKey: 'quarter', radiusKey: 'hardware', radiusName: 'Hardware' },
{ type: 'nightingale', angleKey: 'quarter', radiusKey: 'services', radiusName: 'Services' },
],
}In this configuration:
angleKeyis set to 'quarter', which is the shared category for the Angle Axis.radiusKeyspecifies the numerical datasets, 'software', 'hardware', and 'services', for the Radius Axis.radiusNamelabels each series, such as 'Software', 'Hardware', and 'Services'.
Grouped Nightingale Copy Link
Grouping sectors is used when you want to compare multiple data series side by side within the same category.
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
AngleCategoryAxisModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: `Revenue by product category`,
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
grouped: true,
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
grouped: true,
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
grouped: true,
},
],
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
To group sectors in a Nightingale Series, enable the grouped series property.
{
series: [
{
type: 'nightingale',
angleKey: 'quarter',
radiusKey: 'software',
radiusName: 'Software',
grouped: true,
},
{
type: 'nightingale',
angleKey: 'quarter',
radiusKey: 'hardware',
radiusName: 'Hardware',
grouped: true,
},
{
type: 'nightingale',
angleKey: 'quarter',
radiusKey: 'services',
radiusName: 'Services',
grouped: true,
},
],
} Customisation Copy Link
Inner Radius Copy Link
The inner radius can be used to create a 'donut' effect.
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AngleCategoryAxisModule,
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: `Revenue by product category`,
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
},
],
axes: {
angle: {
type: "angle-category",
},
radius: {
type: "radius-number",
innerRadiusRatio: 0.2,
},
},
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
To create this 'donut' effect, use the innerRadiusRatio option on the Radius Number Axis.
{
axes: {
angle: { type: 'angle-category' },
radius: { type: 'radius-number', innerRadiusRatio: 0.2 },
},
}Any value between 0 and 1 will set the inner radius as a proportion of the overall radius.
Category Padding Copy Link
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AngleCategoryAxisModule,
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: `Revenue by product category`,
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
grouped: true,
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
grouped: true,
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
grouped: true,
},
],
axes: {
angle: {
type: "angle-category",
groupPaddingInner: 0.2,
paddingInner: 0.3,
},
radius: {
type: "radius-number",
},
},
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
The following options are used to control the padding between different elements on the Angle Axis:
paddingInner: Gap between column groups, ranges from0(no gap) to1(maximum spacing).groupPaddingInner: Spacing within a group, ranges from0(columns touching) to1(widest gap).
{
axes: {
angle: { type: 'angle-category', groupPaddingInner: 0.2, paddingInner: 0.3 },
radius: { type: 'radius-number' },
},
} Axis Label Orientation Copy Link
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AngleCategoryAxisModule,
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: `Revenue by product category`,
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
},
],
axes: {
angle: {
type: "angle-category",
label: {
orientation: "parallel",
},
},
radius: {
type: "radius-number",
},
},
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
To change Angle Axis Label orientation, use the label.orientation property with these options:
fixed: Labels have fixed orientation (default).parallel: Labels align parallel to the axis.perpendicular: Labels align perpendicular to the axis.
The following configuration changes the orientation of the Axis Labels to parallel :
{
axes: {
angle: {
type: 'angle-category',
label: {
orientation: 'parallel',
},
},
radius: { type: 'radius-number' },
},
} Radius Axis Position Copy Link
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import { AgCharts } from "ag-charts-react";
import {
AgChartOptions,
AngleCategoryAxisModule,
AnimationModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NightingaleSeriesModule,
RadiusNumberAxisModule,
} from "ag-charts-enterprise";
import { getData } from "./data";
ModuleRegistry.registerModules([
AngleCategoryAxisModule,
AnimationModule,
CrosshairModule,
LegendModule,
NightingaleSeriesModule,
RadiusNumberAxisModule,
ContextMenuModule,
]);
const ChartExample = () => {
const [options, setOptions] = useState<AgChartOptions>({
data: getData(),
title: {
text: `Revenue by product category`,
},
subtitle: {
text: "Millions USD",
},
series: [
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "software",
radiusName: "Software",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "hardware",
radiusName: "Hardware",
},
{
type: "nightingale",
angleKey: "quarter",
radiusKey: "services",
radiusName: "Services",
},
],
axes: {
angle: {
type: "angle-category",
},
radius: {
type: "radius-number",
positionAngle: 90,
label: {
rotation: -90,
},
},
},
});
return <AgCharts options={options} />;
};
const root = createRoot(document.getElementById("root")!);
root.render(<ChartExample />);
export function getData() {
return [
{
quarter: `Q1'22`,
software: 4.35,
hardware: 2.14,
services: 3.91,
},
{
quarter: `Q2'22`,
software: 4.28,
hardware: 3.13,
services: 3.04,
},
{
quarter: `Q3'22`,
software: 4.14,
hardware: 3.34,
services: 3.18,
},
{
quarter: `Q4'22`,
software: 3.48,
hardware: 3.56,
services: 3.61,
},
{
quarter: `Q1'23`,
software: 3.35,
hardware: 3.14,
services: 3.91,
},
{
quarter: `Q2'23`,
software: 3.28,
hardware: 3.13,
services: 3.54,
},
{
quarter: `Q3'23`,
software: 3.14,
hardware: 2.84,
services: 3.18,
},
{
quarter: `Q4'23`,
software: 2.48,
hardware: 2.46,
services: 3.21,
},
];
}
Customise the Radius Axis Line position via positionAngle and Axis Label rotation using label.rotation:
{
axes: {
angle: { type: 'angle-category' },
radius: {
type: 'radius-number',
positionAngle: 90,
label: {
rotation: -90,
},
},
},
}