diff --git a/packages/charts/src/components/DonutChart/DonutChart.mdx b/packages/charts/src/components/DonutChart/DonutChart.mdx
index 263efa8218d..a2db4b3c14b 100644
--- a/packages/charts/src/components/DonutChart/DonutChart.mdx
+++ b/packages/charts/src/components/DonutChart/DonutChart.mdx
@@ -43,7 +43,7 @@ import LegendStory from '../../resources/LegendConfig.mdx';
### With highlighted active segment
-
+
### Hide labels
diff --git a/packages/charts/src/components/DonutChart/DonutChart.stories.tsx b/packages/charts/src/components/DonutChart/DonutChart.stories.tsx
index 8fb755775a9..57fb982de9c 100644
--- a/packages/charts/src/components/DonutChart/DonutChart.stories.tsx
+++ b/packages/charts/src/components/DonutChart/DonutChart.stories.tsx
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
+import { useEffect, useState } from 'react';
import { legendConfig, simpleDataSet, simpleDataSetWithSmallValues, tooltipConfig } from '../../resources/DemoProps.js';
import { DonutChart } from './DonutChart.js';
@@ -73,15 +74,6 @@ export const WithFormatter: Story = {
}
};
-export const WithHighlightedActiveSegment: Story = {
- args: {
- chartConfig: {
- activeSegment: 9,
- showActiveSegmentDataLabel: true
- }
- }
-};
-
export const HideLabels: Story = {
args: {
measure: {
@@ -103,3 +95,27 @@ export const WithCustomTooltipConfig: Story = {
export const WithCustomLegendConfig: Story = {
args: legendConfig
};
+
+export const WithActiveShape: Story = {
+ args: {
+ chartConfig: {
+ activeSegment: 1,
+ showActiveSegmentDataLabel: true
+ }
+ },
+ render(args) {
+ const [activeSegment, setActiveSegment] = useState(args.chartConfig.activeSegment);
+ const handleChartClick = (e) => {
+ const { dataIndex } = e.detail;
+ if (dataIndex != null) {
+ setActiveSegment(dataIndex);
+ }
+ };
+
+ useEffect(() => {
+ setActiveSegment(args.chartConfig.activeSegment);
+ }, [args.chartConfig.activeSegment]);
+
+ return ;
+ }
+};
diff --git a/packages/charts/src/components/DonutChart/DonutChart.tsx b/packages/charts/src/components/DonutChart/DonutChart.tsx
index a68d13bd8b7..f57b0e4f7bc 100644
--- a/packages/charts/src/components/DonutChart/DonutChart.tsx
+++ b/packages/charts/src/components/DonutChart/DonutChart.tsx
@@ -17,7 +17,7 @@ const DonutChart = forwardRef((props, ref) => {
...props.chartConfig
};
- return ;
+ return ;
});
DonutChart.displayName = 'DonutChart';
diff --git a/packages/charts/src/components/PieChart/PieChart.module.css b/packages/charts/src/components/PieChart/PieChart.module.css
index 0cdf5dffd31..1c18aa43261 100644
--- a/packages/charts/src/components/PieChart/PieChart.module.css
+++ b/packages/charts/src/components/PieChart/PieChart.module.css
@@ -3,4 +3,11 @@
path:focus {
outline: none;
}
+
+ [data-active-legend] {
+ background: color-mix(in srgb, var(--sapSelectedColor), transparent 87%);
+ :global(.recharts-legend-item-text) {
+ color: var(--sapTextColor) !important;
+ }
+ }
}
diff --git a/packages/charts/src/components/PieChart/PieChart.stories.tsx b/packages/charts/src/components/PieChart/PieChart.stories.tsx
index 8080b15a32a..f01e01b0242 100644
--- a/packages/charts/src/components/PieChart/PieChart.stories.tsx
+++ b/packages/charts/src/components/PieChart/PieChart.stories.tsx
@@ -1,4 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
+import { useEffect, useState } from 'react';
import { legendConfig, simpleDataSet, simpleDataSetWithSmallValues, tooltipConfig } from '../../resources/DemoProps.js';
import { PieChart } from './PieChart.js';
@@ -51,6 +52,41 @@ export const WithFormatter: Story = {
activeSegment: 1,
showActiveSegmentDataLabel: true
}
+ },
+ render(args) {
+ const [activeSegment, setActiveSegment] = useState(1);
+ const handleChartClick = (e) => {
+ const { dataIndex } = e.detail;
+ if (dataIndex != null) {
+ setActiveSegment(dataIndex);
+ }
+ };
+
+ return ;
+ }
+};
+
+export const WithActiveShape: Story = {
+ args: {
+ chartConfig: {
+ activeSegment: 1,
+ showActiveSegmentDataLabel: true
+ }
+ },
+ render(args) {
+ const [activeSegment, setActiveSegment] = useState(args.chartConfig.activeSegment);
+ const handleChartClick = (e) => {
+ const { dataIndex } = e.detail;
+ if (dataIndex != null) {
+ setActiveSegment(dataIndex);
+ }
+ };
+
+ useEffect(() => {
+ setActiveSegment(args.chartConfig.activeSegment);
+ }, [args.chartConfig.activeSegment]);
+
+ return ;
}
};
diff --git a/packages/charts/src/components/PieChart/PieChart.tsx b/packages/charts/src/components/PieChart/PieChart.tsx
index 7ad052a0a0c..4ad11114100 100644
--- a/packages/charts/src/components/PieChart/PieChart.tsx
+++ b/packages/charts/src/components/PieChart/PieChart.tsx
@@ -1,6 +1,6 @@
'use client';
-import { enrichEventWithDetails, useStylesheet } from '@ui5/webcomponents-react-base';
+import { enrichEventWithDetails, useStylesheet, useSyncRef } from '@ui5/webcomponents-react-base';
import { clsx } from 'clsx';
import type { CSSProperties } from 'react';
import { cloneElement, forwardRef, isValidElement, useCallback, useMemo } from 'react';
@@ -109,6 +109,8 @@ const PieChart = forwardRef((props, ref) => {
} = props;
useStylesheet(styleData, PieChart.displayName);
+ const [componentRef, chartRef] = useSyncRef(ref);
+ const isDonutChart = props['data-component-name'] === 'DonutChart';
const chartConfig: PieChartProps['chartConfig'] = {
margin: { right: 30, left: 30, bottom: 30, top: 30, ...(props.chartConfig?.margin ?? {}) },
@@ -193,12 +195,23 @@ const PieChart = forwardRef((props, ref) => {
const ex = mx + (cos >= 0 ? 1 : -1) * 22;
const ey = my;
const textAnchor = cos >= 0 ? 'start' : 'end';
+ const activeLegendItem = chartRef.current?.querySelector(
+ `.legend-item-${chartConfig.activeSegment}`
+ );
+ if (!activeLegendItem?.dataset.activeLegend) {
+ const allLegendItems = chartRef.current?.querySelectorAll('.recharts-legend-item');
+
+ allLegendItems.forEach((item) => item.removeAttribute('data-active-legend'));
+ activeLegendItem.setAttribute('data-active-legend', 'true');
+ }
return (
-
- {payload.name}
-
+ {isDonutChart && (
+
+ {payload.name}
+
+ )}
((props, ref) => {
);
},
- [showActiveSegmentDataLabel]
+ [showActiveSegmentDataLabel, chartConfig.activeSegment, isDonutChart]
);
const renderLabelLine = useCallback(
@@ -249,11 +262,11 @@ const PieChart = forwardRef((props, ref) => {
if (chartConfig.activeSegment != null && showActiveSegmentDataLabel) {
if (chartConfig.legendPosition === 'bottom') {
return {
- paddingTop: '30px'
+ paddingBlockStart: '30px'
};
} else if (chartConfig.legendPosition === 'top') {
return {
- paddingBottom: '30px'
+ paddingBlockEnd: '30px'
};
}
}
@@ -266,7 +279,7 @@ const PieChart = forwardRef((props, ref) => {
return (
((props, ref) => {
label={dataLabel}
activeIndex={chartConfig.activeSegment}
activeShape={chartConfig.activeSegment != null && renderActiveShape}
+ rootTabIndex={-1}
>
{centerLabel && {centerLabel}}
{dataset &&