From 0faa9c52397269a48280959ba049f611ddb03868 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:51:34 +0200 Subject: [PATCH] [charts] Add `arcLabelRadius` property (@alexfauquette) (#11563) Co-authored-by: Alexandre Fauquette <45398769+alexfauquette@users.noreply.github.com> --- docs/data/charts/pie/pie.md | 6 +++++ .../x/api/charts/pie-arc-label-plot.json | 8 ++++-- docs/pages/x/api/charts/pie-arc-plot.json | 8 ++++-- .../api-docs/charts/pie-arc-label-plot.json | 5 ++++ .../api-docs/charts/pie-arc-plot.json | 5 ++++ .../x-charts/src/PieChart/PieArcLabel.tsx | 15 +++++------ .../x-charts/src/PieChart/PieArcLabelPlot.tsx | 13 +++++++++- packages/x-charts/src/PieChart/PieArcPlot.tsx | 8 ++++++ packages/x-charts/src/PieChart/PieChart.tsx | 3 +++ packages/x-charts/src/PieChart/PiePlot.tsx | 8 ++++++ .../src/PieChart/dataTransform/transition.ts | 26 ++++++++++++++++--- .../dataTransform/useTransformData.ts | 21 ++++++++++----- .../x-charts/src/models/seriesType/pie.ts | 14 ++++++++++ 13 files changed, 118 insertions(+), 22 deletions(-) diff --git a/docs/data/charts/pie/pie.md b/docs/data/charts/pie/pie.md index 82a75544cf58..0d6a0b7cb43b 100644 --- a/docs/data/charts/pie/pie.md +++ b/docs/data/charts/pie/pie.md @@ -45,6 +45,7 @@ Pie series shape is described by multiple properties: - `innerRadius` The radius between the center and the beginning of the arc. The default is set to 0. - `outerRadius` The radius between the center and the end of the arc. The default is the largest value available in the drawing area. +- `arcLabelRadius` The radius between the center and the arc label. - `paddingAngle` The angle (in degrees) between two arcs. - `cornerRadius` Similar to the CSS `border-radius`. - `startAngle`/`endAngle` The angle range of the pie chart. Values are given in degrees. @@ -52,6 +53,11 @@ Pie series shape is described by multiple properties: {{"demo": "PieShapeNoSnap.js", "hideToolbar": true, "bg": "playground"}} +The following properties accept percentage string (for example `'50%'`). + +- `innerRadius`/`outerRadius`/`arcLabelRadius` with `'100%'` equivalent to maximal radius fitting in the drawing area. +- `cx`, `cy` with `'100%'` equivalent to the drawing area width/height. + ## Labels You can display labels on the arcs. diff --git a/docs/pages/x/api/charts/pie-arc-label-plot.json b/docs/pages/x/api/charts/pie-arc-label-plot.json index 7a0de52bb3fc..554da1463ff0 100644 --- a/docs/pages/x/api/charts/pie-arc-label-plot.json +++ b/docs/pages/x/api/charts/pie-arc-label-plot.json @@ -8,17 +8,21 @@ } }, "arcLabelMinAngle": { "type": { "name": "number" } }, + "arcLabelRadius": { + "type": { "name": "number" }, + "default": "(innerRadius - outerRadius) / 2" + }, "cornerRadius": { "type": { "name": "number" }, "default": "0" }, "faded": { "type": { "name": "shape", - "description": "{ additionalRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" + "description": "{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" } }, "highlighted": { "type": { "name": "shape", - "description": "{ additionalRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" + "description": "{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" } }, "innerRadius": { "type": { "name": "number" }, "default": "0" }, diff --git a/docs/pages/x/api/charts/pie-arc-plot.json b/docs/pages/x/api/charts/pie-arc-plot.json index f46edaaf4c71..cdcf9fb0e0ad 100644 --- a/docs/pages/x/api/charts/pie-arc-plot.json +++ b/docs/pages/x/api/charts/pie-arc-plot.json @@ -1,17 +1,21 @@ { "props": { "outerRadius": { "type": { "name": "number" }, "required": true }, + "arcLabelRadius": { + "type": { "name": "number" }, + "default": "(innerRadius - outerRadius) / 2" + }, "cornerRadius": { "type": { "name": "number" }, "default": "0" }, "faded": { "type": { "name": "shape", - "description": "{ additionalRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" + "description": "{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" } }, "highlighted": { "type": { "name": "shape", - "description": "{ additionalRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" + "description": "{ additionalRadius?: number, arcLabelRadius?: number, color?: string, cornerRadius?: number, innerRadius?: number, outerRadius?: number, paddingAngle?: number }" } }, "innerRadius": { "type": { "name": "number" }, "default": "0" }, diff --git a/docs/translations/api-docs/charts/pie-arc-label-plot.json b/docs/translations/api-docs/charts/pie-arc-label-plot.json index 027cbb4ff008..9cbd37dbb877 100644 --- a/docs/translations/api-docs/charts/pie-arc-label-plot.json +++ b/docs/translations/api-docs/charts/pie-arc-label-plot.json @@ -11,6 +11,11 @@ "deprecated": "", "typeDescriptions": {} }, + "arcLabelRadius": { + "description": "The radius between circle center and the arc label in px.", + "deprecated": "", + "typeDescriptions": {} + }, "cornerRadius": { "description": "The radius applied to arc corners (similar to border radius).", "deprecated": "", diff --git a/docs/translations/api-docs/charts/pie-arc-plot.json b/docs/translations/api-docs/charts/pie-arc-plot.json index 57564e39d8e4..a16d5b174a59 100644 --- a/docs/translations/api-docs/charts/pie-arc-plot.json +++ b/docs/translations/api-docs/charts/pie-arc-plot.json @@ -1,6 +1,11 @@ { "componentDescription": "", "propDescriptions": { + "arcLabelRadius": { + "description": "The radius between circle center and the arc label in px.", + "deprecated": "", + "typeDescriptions": {} + }, "cornerRadius": { "description": "The radius applied to arc corners (similar to border radius).", "deprecated": "", diff --git a/packages/x-charts/src/PieChart/PieArcLabel.tsx b/packages/x-charts/src/PieChart/PieArcLabel.tsx index c8610ed65a78..d4432741cd07 100644 --- a/packages/x-charts/src/PieChart/PieArcLabel.tsx +++ b/packages/x-charts/src/PieChart/PieArcLabel.tsx @@ -61,6 +61,7 @@ export type PieArcLabelProps = PieArcLabelOwnerState & endAngle: SpringValue; innerRadius: SpringValue; outerRadius: SpringValue; + arcLabelRadius: SpringValue; cornerRadius: SpringValue; paddingAngle: SpringValue; } & { @@ -77,8 +78,7 @@ const getLabelPosition = startAngle: number, endAngle: number, padAngle: number, - innerRadius: number, - outerRadius: number, + arcLabelRadius: number, cornerRadius: number, ) => { if (!formattedArcLabel) { @@ -88,8 +88,8 @@ const getLabelPosition = padAngle, startAngle, endAngle, - innerRadius, - outerRadius, + innerRadius: arcLabelRadius, + outerRadius: arcLabelRadius, })!; if (variable === 'x') { return x; @@ -105,8 +105,7 @@ function PieArcLabel(props: PieArcLabelProps) { startAngle, endAngle, paddingAngle, - innerRadius, - outerRadius, + arcLabelRadius, cornerRadius, formattedArcLabel, isHighlighted, @@ -130,11 +129,11 @@ function PieArcLabel(props: PieArcLabelProps) { {...other} style={{ x: to( - [startAngle, endAngle, paddingAngle, innerRadius, outerRadius, cornerRadius], + [startAngle, endAngle, paddingAngle, arcLabelRadius, cornerRadius], getLabelPosition(formattedArcLabel, 'x'), ), y: to( - [startAngle, endAngle, paddingAngle, innerRadius, outerRadius, cornerRadius], + [startAngle, endAngle, paddingAngle, arcLabelRadius, cornerRadius], getLabelPosition(formattedArcLabel, 'y'), ), ...style, diff --git a/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx b/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx index 0e8b80af0822..e9f293fff458 100644 --- a/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx +++ b/packages/x-charts/src/PieChart/PieArcLabelPlot.tsx @@ -80,8 +80,9 @@ function PieArcLabelPlot(props: PieArcLabelPlotProps) { const { slots, slotProps, - innerRadius = 0, + innerRadius, outerRadius, + arcLabelRadius, cornerRadius = 0, paddingAngle = 0, id, @@ -98,6 +99,7 @@ function PieArcLabelPlot(props: PieArcLabelPlotProps) { const transformedData = useTransformData({ innerRadius, outerRadius, + arcLabelRadius, cornerRadius, paddingAngle, id, @@ -127,6 +129,7 @@ function PieArcLabelPlot(props: PieArcLabelPlotProps) { paddingAngle: pA, innerRadius: iR, outerRadius: oR, + arcLabelRadius: aLR, cornerRadius: cR, ...style }, @@ -139,6 +142,7 @@ function PieArcLabelPlot(props: PieArcLabelPlotProps) { paddingAngle={pA} innerRadius={iR} outerRadius={oR} + arcLabelRadius={aLR} cornerRadius={cR} style={style} id={id} @@ -171,6 +175,11 @@ PieArcLabelPlot.propTypes = { * The minimal angle required to display the arc label. */ arcLabelMinAngle: PropTypes.number, + /** + * The radius between circle center and the arc label in px. + * @default (innerRadius - outerRadius) / 2 + */ + arcLabelRadius: PropTypes.number, /** * The radius applied to arc corners (similar to border radius). * @default 0 @@ -194,6 +203,7 @@ PieArcLabelPlot.propTypes = { */ faded: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, @@ -205,6 +215,7 @@ PieArcLabelPlot.propTypes = { */ highlighted: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, diff --git a/packages/x-charts/src/PieChart/PieArcPlot.tsx b/packages/x-charts/src/PieChart/PieArcPlot.tsx index 14d7cf0ff1b4..64b7a3b15535 100644 --- a/packages/x-charts/src/PieChart/PieArcPlot.tsx +++ b/packages/x-charts/src/PieChart/PieArcPlot.tsx @@ -106,6 +106,7 @@ function PieArcPlot(props: PieArcPlotProps) { endAngle, paddingAngle: pA, innerRadius: iR, + arcLabelRadius, outerRadius: oR, cornerRadius: cR, ...style @@ -149,6 +150,11 @@ PieArcPlot.propTypes = { // | These PropTypes are generated from the TypeScript type definitions | // | To update them edit the TypeScript types and run "yarn proptypes" | // ---------------------------------------------------------------------- + /** + * The radius between circle center and the arc label in px. + * @default (innerRadius - outerRadius) / 2 + */ + arcLabelRadius: PropTypes.number, /** * The radius applied to arc corners (similar to border radius). * @default 0 @@ -172,6 +178,7 @@ PieArcPlot.propTypes = { */ faded: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, @@ -183,6 +190,7 @@ PieArcPlot.propTypes = { */ highlighted: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, diff --git a/packages/x-charts/src/PieChart/PieChart.tsx b/packages/x-charts/src/PieChart/PieChart.tsx index c753a578d66d..8b3e84af99d8 100644 --- a/packages/x-charts/src/PieChart/PieChart.tsx +++ b/packages/x-charts/src/PieChart/PieChart.tsx @@ -308,6 +308,7 @@ PieChart.propTypes = { PropTypes.func, ]), arcLabelMinAngle: PropTypes.number, + arcLabelRadius: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), color: PropTypes.string, cornerRadius: PropTypes.number, cx: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), @@ -323,6 +324,7 @@ PieChart.propTypes = { endAngle: PropTypes.number, faded: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, @@ -331,6 +333,7 @@ PieChart.propTypes = { }), highlighted: PropTypes.shape({ additionalRadius: PropTypes.number, + arcLabelRadius: PropTypes.number, color: PropTypes.string, cornerRadius: PropTypes.number, innerRadius: PropTypes.number, diff --git a/packages/x-charts/src/PieChart/PiePlot.tsx b/packages/x-charts/src/PieChart/PiePlot.tsx index a0c29243521b..fd6253a52f40 100644 --- a/packages/x-charts/src/PieChart/PiePlot.tsx +++ b/packages/x-charts/src/PieChart/PiePlot.tsx @@ -111,6 +111,7 @@ function PiePlot(props: PiePlotProps) { const { innerRadius: innerRadiusParam, outerRadius: outerRadiusParam, + arcLabelRadius: arcLabelRadiusParam, cornerRadius, paddingAngle, arcLabel, @@ -125,6 +126,12 @@ function PiePlot(props: PiePlotProps) { availableRadius, ); const innerRadius = getPercentageValue(innerRadiusParam ?? 0, availableRadius); + + const arcLabelRadius = + arcLabelRadiusParam === undefined + ? (outerRadius + innerRadius) / 2 + : getPercentageValue(arcLabelRadiusParam, availableRadius); + const cx = getPercentageValue(cxParam ?? '50%', width); const cy = getPercentageValue(cyParam ?? '50%', height); return ( @@ -132,6 +139,7 @@ function PiePlot(props: PiePlotProps) { = { export const defaultLabelTransitionConfig: UseTransitionProps = { keys: (item) => item.id, - from: ({ innerRadius, outerRadius, cornerRadius, startAngle, endAngle, paddingAngle }) => ({ + from: ({ + innerRadius, + outerRadius, + arcLabelRadius, + cornerRadius, + startAngle, + endAngle, + paddingAngle, + }) => ({ innerRadius, outerRadius: (innerRadius + outerRadius) / 2, cornerRadius, + arcLabelRadius, startAngle: (startAngle + endAngle) / 2, endAngle: (startAngle + endAngle) / 2, paddingAngle, @@ -75,24 +84,35 @@ export const defaultLabelTransitionConfig: UseTransitionProps ({ innerRadius, outerRadius: innerRadius, + arcLabelRadius: innerRadius, startAngle: (startAngle + endAngle) / 2, endAngle: (startAngle + endAngle) / 2, opacity: 0, }), - enter: ({ innerRadius, outerRadius, startAngle, endAngle }) => ({ + enter: ({ innerRadius, outerRadius, startAngle, endAngle, arcLabelRadius }) => ({ innerRadius, outerRadius, startAngle, endAngle, + arcLabelRadius, opacity: 1, }), - update: ({ innerRadius, outerRadius, cornerRadius, startAngle, endAngle, paddingAngle }) => ({ + update: ({ + innerRadius, + outerRadius, + cornerRadius, + startAngle, + endAngle, + paddingAngle, + arcLabelRadius, + }) => ({ innerRadius, outerRadius, cornerRadius, startAngle, endAngle, paddingAngle, + arcLabelRadius, opacity: 1, }), config: { diff --git a/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts b/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts index c3fc6ee65829..900092ba66fd 100644 --- a/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts +++ b/packages/x-charts/src/PieChart/dataTransform/useTransformData.ts @@ -10,6 +10,7 @@ import { getIsHighlighted, getIsFaded } from '../../hooks/useInteractionItemProp export interface AnimatedObject { innerRadius: number; outerRadius: number; + arcLabelRadius: number; cornerRadius: number; startAngle: number; endAngle: number; @@ -36,6 +37,7 @@ export function useTransformData( highlighted, paddingAngle: basePaddingAngle = 0, innerRadius: baseInnerRadius = 0, + arcLabelRadius: baseArcLabelRadius, outerRadius: baseOuterRadius, cornerRadius: baseCornerRadius = 0, } = series; @@ -63,31 +65,37 @@ export function useTransformData( data.map((item, itemIndex) => { const { isHighlighted, isFaded } = getHighlightStatus(itemIndex); - const attibuesOverride = { + const attributesOverride = { additionalRadius: 0, ...((isFaded && faded) || (isHighlighted && highlighted) || {}), }; const paddingAngle = Math.max( 0, - (Math.PI * (attibuesOverride.paddingAngle ?? basePaddingAngle)) / 180, + (Math.PI * (attributesOverride.paddingAngle ?? basePaddingAngle)) / 180, ); - const innerRadius = Math.max(0, attibuesOverride.innerRadius ?? baseInnerRadius); + const innerRadius = Math.max(0, attributesOverride.innerRadius ?? baseInnerRadius); const outerRadius = Math.max( 0, - attibuesOverride.outerRadius ?? baseOuterRadius + attibuesOverride.additionalRadius, + attributesOverride.outerRadius ?? baseOuterRadius + attributesOverride.additionalRadius, ); - const cornerRadius = attibuesOverride.cornerRadius ?? baseCornerRadius; + const cornerRadius = attributesOverride.cornerRadius ?? baseCornerRadius; + + const arcLabelRadius = + attributesOverride.arcLabelRadius ?? + baseArcLabelRadius ?? + (innerRadius + outerRadius) / 2; return { ...item, - ...attibuesOverride, + ...attributesOverride, isFaded, isHighlighted, paddingAngle, innerRadius, outerRadius, cornerRadius, + arcLabelRadius, }; }), [ @@ -95,6 +103,7 @@ export function useTransformData( baseInnerRadius, baseOuterRadius, basePaddingAngle, + baseArcLabelRadius, data, faded, getHighlightStatus, diff --git a/packages/x-charts/src/models/seriesType/pie.ts b/packages/x-charts/src/models/seriesType/pie.ts index 2f75de4bff64..5405c1a45ec0 100644 --- a/packages/x-charts/src/models/seriesType/pie.ts +++ b/packages/x-charts/src/models/seriesType/pie.ts @@ -31,6 +31,13 @@ export interface PieSeriesType extends CommonSeriesType extends CommonSeriesType extends CommonSeriesType