Chart
Allow users to view and interact with graphical representations of data.
Intro
The Chart component is a tailored wrapper built for the Highcharts library within a React environment. It's designed to offer a seamless integration of Highcharts while incorporating customized features, improved accessibility, and enhanced usability.
Key Features
- Customizations: The
Chartcomponent provides predefined customizations regarding colors, sizes, and themes to maintain consistency and visual appeal across charts. - Accessibility Improvements: Accessibility is a prime focus. The component ensures that charts are optimized for screen readers and other assistive technologies, making data visualization more inclusive.
- Enhanced Usability: With improved interaction elements and intuitive functionalities, the
Chartcomponent aims to enhance user experience and ease of navigation within the charts. - Highcharts Features: Developers have full access to all Highcharts features, allowing them to leverage the extensive capabilities of Highcharts to create sophisticated and detailed charts.
Support and Troubleshooting
The Chart component strives to ensure a seamless experience with Highcharts integrations. If you encounter any issues or discrepancies specific to the Chart component that differ from the standard Highcharts behavior, please reach out to us for support. If the issue works as expected with Highcharts in its raw form, kindly let us know to address the compatibility concern.
Examples
The examples below showcase the various kinds of charts suported by Highcharts, such as line charts, column charts, and more (coming soon). Click on the tabs to view the examples.
For general features and functionalities, please refer to the Miscellaneous section.
Basic usage
<Chart
options={{
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
/>Usage with categories
<Chart
options={{
xAxis: {
categories: ["Apples", "Bananas", "Oranges", "Strawberries"],
tickInterval: 1,
},
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52],
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44],
},
],
}}
/>Usage with X axis showing time
<Chart
options={{
xAxis: {
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
series: [
{
type: "line",
name: "Series 1",
dashStyle: "ShortDot",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 10,
},
{
x: Date.UTC(2010, 1, 2),
y: 20,
},
{
x: Date.UTC(2010, 2, 3),
y: 30,
},
{
x: Date.UTC(2010, 3, 4),
y: 40,
},
{
x: Date.UTC(2010, 4, 5),
y: 50,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 20,
},
{
x: Date.UTC(2010, 1, 2),
y: 30,
},
{
x: Date.UTC(2010, 2, 3),
y: 40,
},
{
x: Date.UTC(2010, 3, 4),
y: 50,
},
{
x: Date.UTC(2010, 5, 5),
y: 60,
},
],
},
],
}}
/>Usage with multiple Y axes
<Chart
options={{
xAxis: [
{
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
],
yAxis: [{}, { opposite: true }],
series: [
{
type: "line",
name: "Series 1",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 10,
},
{
x: Date.UTC(2010, 1, 1),
y: 20,
},
{
x: Date.UTC(2010, 2, 1),
y: 30,
},
{
x: Date.UTC(2010, 3, 1),
y: 40,
},
{
x: Date.UTC(2010, 4, 1),
y: 50,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 20,
},
{
x: Date.UTC(2010, 1, 1),
y: 30,
},
{
x: Date.UTC(2010, 2, 1),
y: 40,
},
{
x: Date.UTC(2010, 3, 1),
y: 50,
},
{
x: Date.UTC(2010, 5, 1),
y: 60,
},
],
},
{
type: "line",
name: "Series 3",
data: [
{
x: Date.UTC(2010, 0, 1),
y: 25,
},
{
x: Date.UTC(2010, 1, 1),
y: 50,
},
{
x: Date.UTC(2010, 2, 1),
y: 75,
},
{
x: Date.UTC(2010, 3, 1),
y: 90,
},
{
x: Date.UTC(2010, 5, 1),
y: 105,
},
],
yAxis: 1,
},
],
}}
/>Usage with several series
<Chart
options={{
series: [
{
type: "line",
name: "Series 1",
data: [1.12, 1.14, 1.13, 1.16, 1.18, 1.17, 1.15, 1.19, 1.2, 1.22].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [1.01, 1.05, 1.1, 1.09, 1.05, 1.02, 1.0, 1.01, 1.01, 1.02].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 3",
data: [0.9, 1.01, 1.02, 1.03, 1.02, 1.0, 0.98, 0.96, 0.95, 0.99].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 4",
data: [1.5, 1.6, 1.65, 1.7, 1.75, 1.78, 1.78, 1.79, 1.8, 1.8].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 5",
data: [1.4, 1.38, 1.35, 1.31, 1.3, 1.3, 1.29, 1.28, 1.3, 1.32].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 6",
data: [1.0, 1.1, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
/>Usage with Annotations
Annotations are designed to be easily adaptable to any backend. For that, you can map your own data structure to our Annotations interface which has the following definition:
type AnnotationItem = {
id: string | number;
date: Date;
category?: string;
comment: string;
createdBy: string;
visibility: string;
isFavorite: boolean;
visibleIn: string[];
username: string;
isEditable?: boolean;
}Annotations are editable by default. Set isEditable to false on the annotations the current user is not allowed to change – for instance based on their permissions – and the edit button is hidden for those rows. When no annotation in the list is editable, the whole edit column is left out.
In addition, the Chart component also provides properties for handling all basic annotation operations, such as creation (onCreateAnnotation), update (onUpdateAnnotation), and deletion (onDeleteAnnotation).
In the example below, the API object simulates the implementation of these methods and also provides a list of annotations according to the AnnotationItem interface.
const chartDateOptions: DateOptions = {
locale: "en-us",
skipTimezoneReset: false,
};
const [annotationsData, setAnnotationsData] = useState<AnnotationItem[]>([]);
const [annotationsAreasVisibleIn, setAnnotationsAreasVisibleIn] = useState<
AnnotationAreasVisibleIn[]
>([]);
useEffect(() => {
let isDataFetchDone = true;
API.fetch().then((data) => isDataFetchDone && setAnnotationsData(data));
API.fetchAreasVisibleIn().then(
(areas) => isDataFetchDone && setAnnotationsAreasVisibleIn(areas)
);
return () => {
isDataFetchDone = false;
};
}, []);
return (
<Chart
options={{
xAxis: {
type: "datetime",
// Set interval of tick marks to one month. For datetime axes this is based on milliseconds.
tickInterval: 24 * 3600 * 1000 * 30,
},
series: [
{
type: "line",
name: "Series 1",
data: [
{
x: Date.UTC(2022, 1, 1),
y: 20,
},
{
x: Date.UTC(2022, 2, 1),
y: 30,
},
{
x: Date.UTC(2022, 3, 1),
y: 40,
},
{
x: Date.UTC(2022, 4, 1),
y: 50,
},
{
x: Date.UTC(2022, 5, 1),
y: 30,
},
],
},
{
type: "line",
name: "Series 2",
data: [
{
x: Date.UTC(2022, 0, 1),
y: 20,
},
{
x: Date.UTC(2022, 1, 1),
y: 30,
},
{
x: Date.UTC(2022, 2, 1),
y: 40,
},
{
x: Date.UTC(2022, 3, 1),
y: 50,
},
{
x: Date.UTC(2022, 5, 1),
y: 60,
},
],
},
],
}}
showAnnotationButton
annotations={annotationsData}
chartPeriod={[new Date(2022, 0, 1), new Date(2022, 3, 1)]}
onUpdateAnnotation={async (data: Omit<Partial<AnnotationItem>, "createdBy">) => {
await API.update(data);
setAnnotationsData(await API.fetch());
}}
onCreateAnnotation={async (data: Omit<AnnotationItem, "id" | "createdBy">) => {
await API.create(data);
setAnnotationsData(await API.fetch());
}}
onDeleteAnnotation={async (id: string | number) => {
await API.delete(id);
setAnnotationsData(await API.fetch());
}}
chartDateOptions={chartDateOptions}
annotationAreasVisibleIn={annotationsAreasVisibleIn}
annotationAreasVisibleInDefaultSelect={["accessibility", "ads"]}
/>
);Miscellaneous
These examples showcase the various features and functionalities of the Chart component that are not specific to any particular chart type. It includes features such as legends, tooltips, sizes, and more.
Usage with reference lines
const { ColorRed, ColorTextStaticBody } = useDesignToken();
return (
<Chart
options={{
yAxis: {
plotLines: [
{
value: 70,
color: ColorRed,
width: 3,
dashStyle: "ShortDot",
label: {
text: "Limit (70)",
align: "right",
x: -5,
style: {
color: ColorTextStaticBody,
},
},
},
],
},
series: [
{
type: "line",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [15, 13, 38, 42, 42, 47, 46, 51, 56].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
/>
);Usage with no legend
<Chart
options={{
plotOptions: {
series: {
showInLegend: false,
},
},
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue1",
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
customValue: "customValue2",
};
}),
},
],
}}
/>Usage with native Highcharts legend
By default, the Chart component uses a custom legend implementation. You can use the native Highcharts legend by setting the useHighchartsLegend property to true. This works for all chart types.
<Chart
useHighchartsLegend={true}
options={{
plotOptions: {
pie: {
allowPointSelect: true,
cursor: "pointer",
dataLabels: {
enabled: false,
},
showInLegend: true,
},
},
series: [
{
type: "pie",
name: "Fruits",
data: [
{
name: "Apples",
y: 74.77,
sliced: true,
selected: true,
},
{
name: "Bananas",
y: 12.82,
},
{
name: "Oranges",
y: 4.63,
},
{
name: "Strawberries",
y: 2.44,
},
{
name: "Other",
y: 3.28,
},
],
},
],
}}
/>Usage with series hidden on load
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
selected: false,
},
],
}}
/>Usage with series not visible in the legends
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, 52, 57, 56, 61, 66].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
{
showInLegend: false,
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, 49, 59, 65, 71, 82].map((val, i) => {
return {
x: i,
y: val,
name: i.toString(),
};
}),
},
],
}}
/>Usage with missing data
If all series contain empty data (undefined, null or NaN) in a determined position, the row will not be displayed on the table visualization.
<Chart
options={{
series: [
{
type: "column",
name: "Series 1",
data: [25, 23, 48, 52, undefined, 52, 57, 56, 61].map((val, i) => {
return {
x: i,
y: val,
};
}),
},
{
type: "line",
name: "Series 2",
data: [18, 26, 36, 44, undefined, 49, 59, 65, 71].map((val, i) => {
return {
x: i,
y: val,
};
}),
},
],
}}
/>Usage with tooltip formatters
The header of the chart tooltip can be formatted using the optional property tooltipHeaderFormatter with the values default, named, and keyed.
The individual points of the chart tooltip can be formatted using the optional property tooltipPointFormatter with the values default, named, and customValue.