@automattic/charts 0.56.5 → 0.56.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. package/AGENTS.md +135 -0
  2. package/CHANGELOG.md +17 -0
  3. package/README.md +2 -1
  4. package/dist/charts/bar-chart/index.cjs +6 -6
  5. package/dist/charts/bar-chart/index.css +1 -4
  6. package/dist/charts/bar-chart/index.css.map +1 -1
  7. package/dist/charts/bar-chart/index.d.cts +2 -8
  8. package/dist/charts/bar-chart/index.d.ts +2 -8
  9. package/dist/charts/bar-chart/index.js +5 -5
  10. package/dist/charts/bar-list-chart/index.cjs +7 -7
  11. package/dist/charts/bar-list-chart/index.css +1 -4
  12. package/dist/charts/bar-list-chart/index.css.map +1 -1
  13. package/dist/charts/bar-list-chart/index.d.cts +2 -2
  14. package/dist/charts/bar-list-chart/index.d.ts +2 -2
  15. package/dist/charts/bar-list-chart/index.js +6 -6
  16. package/dist/charts/conversion-funnel-chart/index.cjs +5 -5
  17. package/dist/charts/conversion-funnel-chart/index.css +1 -4
  18. package/dist/charts/conversion-funnel-chart/index.css.map +1 -1
  19. package/dist/charts/conversion-funnel-chart/index.d.cts +2 -1
  20. package/dist/charts/conversion-funnel-chart/index.d.ts +2 -1
  21. package/dist/charts/conversion-funnel-chart/index.js +4 -4
  22. package/dist/charts/geo-chart/index.cjs +4 -4
  23. package/dist/charts/geo-chart/index.css +1 -4
  24. package/dist/charts/geo-chart/index.css.map +1 -1
  25. package/dist/charts/geo-chart/index.d.cts +2 -1
  26. package/dist/charts/geo-chart/index.d.ts +2 -1
  27. package/dist/charts/geo-chart/index.js +3 -3
  28. package/dist/charts/leaderboard-chart/index.cjs +5 -5
  29. package/dist/charts/leaderboard-chart/index.css +1 -4
  30. package/dist/charts/leaderboard-chart/index.css.map +1 -1
  31. package/dist/charts/leaderboard-chart/index.d.cts +3 -2
  32. package/dist/charts/leaderboard-chart/index.d.ts +3 -2
  33. package/dist/charts/leaderboard-chart/index.js +4 -4
  34. package/dist/charts/line-chart/index.cjs +6 -6
  35. package/dist/charts/line-chart/index.css +1 -4
  36. package/dist/charts/line-chart/index.css.map +1 -1
  37. package/dist/charts/line-chart/index.d.cts +2 -8
  38. package/dist/charts/line-chart/index.d.ts +2 -8
  39. package/dist/charts/line-chart/index.js +5 -5
  40. package/dist/charts/pie-chart/index.cjs +6 -4
  41. package/dist/charts/pie-chart/index.cjs.map +1 -1
  42. package/dist/charts/pie-chart/index.css +13 -7
  43. package/dist/charts/pie-chart/index.css.map +1 -1
  44. package/dist/charts/pie-chart/index.d.cts +2 -1
  45. package/dist/charts/pie-chart/index.d.ts +2 -1
  46. package/dist/charts/pie-chart/index.js +5 -3
  47. package/dist/charts/pie-semi-circle-chart/index.cjs +6 -4
  48. package/dist/charts/pie-semi-circle-chart/index.cjs.map +1 -1
  49. package/dist/charts/pie-semi-circle-chart/index.css +12 -13
  50. package/dist/charts/pie-semi-circle-chart/index.css.map +1 -1
  51. package/dist/charts/pie-semi-circle-chart/index.d.cts +5 -2
  52. package/dist/charts/pie-semi-circle-chart/index.d.ts +5 -2
  53. package/dist/charts/pie-semi-circle-chart/index.js +5 -3
  54. package/dist/charts/sparkline/index.cjs +7 -7
  55. package/dist/charts/sparkline/index.css +1 -4
  56. package/dist/charts/sparkline/index.css.map +1 -1
  57. package/dist/charts/sparkline/index.js +6 -6
  58. package/dist/{chunk-NGHXTIUE.cjs → chunk-3EXJP67N.cjs} +7 -7
  59. package/dist/{chunk-NGHXTIUE.cjs.map → chunk-3EXJP67N.cjs.map} +1 -1
  60. package/dist/{chunk-FIFSYVN6.cjs → chunk-55ZCOYDF.cjs} +117 -132
  61. package/dist/chunk-55ZCOYDF.cjs.map +1 -0
  62. package/dist/{chunk-LT4YOIMM.js → chunk-7FDQGBY7.js} +145 -119
  63. package/dist/chunk-7FDQGBY7.js.map +1 -0
  64. package/dist/{chunk-7QDEU3KN.cjs → chunk-ASLARV7L.cjs} +6 -6
  65. package/dist/chunk-ASLARV7L.cjs.map +1 -0
  66. package/dist/chunk-BXFD7JIG.cjs +401 -0
  67. package/dist/chunk-BXFD7JIG.cjs.map +1 -0
  68. package/dist/{chunk-XCXAWMJQ.cjs → chunk-CAFJRZPZ.cjs} +12 -12
  69. package/dist/{chunk-XCXAWMJQ.cjs.map → chunk-CAFJRZPZ.cjs.map} +1 -1
  70. package/dist/{chunk-KHRPRH4V.js → chunk-E62LCBGD.js} +4 -4
  71. package/dist/{chunk-PCOI2GT5.js → chunk-GWBS65VC.js} +3 -3
  72. package/dist/{chunk-MEIVKY4K.js → chunk-IS5YYLTV.js} +18 -18
  73. package/dist/{chunk-MEIVKY4K.js.map → chunk-IS5YYLTV.js.map} +1 -1
  74. package/dist/{chunk-Q6G3BGCL.cjs → chunk-K6TGILHX.cjs} +8 -8
  75. package/dist/{chunk-Q6G3BGCL.cjs.map → chunk-K6TGILHX.cjs.map} +1 -1
  76. package/dist/{chunk-X6GX4QUJ.js → chunk-KHQPN77E.js} +3 -3
  77. package/dist/{chunk-SEKPIG5K.js → chunk-KNIMXN6Z.js} +2 -2
  78. package/dist/{chunk-SEKPIG5K.js.map → chunk-KNIMXN6Z.js.map} +1 -1
  79. package/dist/{chunk-AFWQR3SM.js → chunk-MDRCAGKZ.js} +4 -4
  80. package/dist/{chunk-TKPK4RFS.cjs → chunk-NQJE2CC7.cjs} +120 -98
  81. package/dist/chunk-NQJE2CC7.cjs.map +1 -0
  82. package/dist/{chunk-FY325WQ4.cjs → chunk-O2JIANHK.cjs} +25 -25
  83. package/dist/chunk-O2JIANHK.cjs.map +1 -0
  84. package/dist/{chunk-DLSUC7RN.js → chunk-OMS5QIJN.js} +6 -6
  85. package/dist/chunk-OMS5QIJN.js.map +1 -0
  86. package/dist/{chunk-TYIH5LMV.js → chunk-OP6PHB2U.js} +6 -6
  87. package/dist/chunk-OP6PHB2U.js.map +1 -0
  88. package/dist/{chunk-32ESS4MV.js → chunk-RFSHE3HL.js} +17 -7
  89. package/dist/chunk-RFSHE3HL.js.map +1 -0
  90. package/dist/{chunk-KXSLMOW5.js → chunk-SSFFCBCF.js} +6 -6
  91. package/dist/chunk-SSFFCBCF.js.map +1 -0
  92. package/dist/{chunk-I5467ZJ5.cjs → chunk-SUDERBUA.cjs} +2 -2
  93. package/dist/{chunk-I5467ZJ5.cjs.map → chunk-SUDERBUA.cjs.map} +1 -1
  94. package/dist/{chunk-SH32YSZO.cjs → chunk-UFRBUT2D.cjs} +19 -19
  95. package/dist/{chunk-SH32YSZO.cjs.map → chunk-UFRBUT2D.cjs.map} +1 -1
  96. package/dist/{chunk-7TQSPLIN.js → chunk-VPAEBI2F.js} +109 -87
  97. package/dist/chunk-VPAEBI2F.js.map +1 -0
  98. package/dist/{chunk-IHESL7H5.cjs → chunk-X7JL2NYJ.cjs} +24 -24
  99. package/dist/chunk-X7JL2NYJ.cjs.map +1 -0
  100. package/dist/{chunk-DBY6C4O2.js → chunk-XD2HV7M5.js} +77 -92
  101. package/dist/chunk-XD2HV7M5.js.map +1 -0
  102. package/dist/{chunk-LTPJPIDP.cjs → chunk-YAXY5L7I.cjs} +7 -7
  103. package/dist/{chunk-LTPJPIDP.cjs.map → chunk-YAXY5L7I.cjs.map} +1 -1
  104. package/dist/{chunk-EJJO2QNB.cjs → chunk-YDVHT7GS.cjs} +17 -7
  105. package/dist/chunk-YDVHT7GS.cjs.map +1 -0
  106. package/dist/components/legend/index.cjs +2 -2
  107. package/dist/components/legend/index.css +1 -4
  108. package/dist/components/legend/index.css.map +1 -1
  109. package/dist/components/legend/index.d.cts +2 -1
  110. package/dist/components/legend/index.d.ts +2 -1
  111. package/dist/components/legend/index.js +1 -1
  112. package/dist/components/tooltip/index.d.cts +2 -1
  113. package/dist/components/tooltip/index.d.ts +2 -1
  114. package/dist/hooks/index.cjs +2 -2
  115. package/dist/hooks/index.cjs.map +1 -1
  116. package/dist/hooks/index.css +1 -4
  117. package/dist/hooks/index.css.map +1 -1
  118. package/dist/hooks/index.d.cts +10 -7
  119. package/dist/hooks/index.d.ts +10 -7
  120. package/dist/hooks/index.js +3 -3
  121. package/dist/index.cjs +14 -14
  122. package/dist/index.css +24 -16
  123. package/dist/index.css.map +1 -1
  124. package/dist/index.d.cts +4 -4
  125. package/dist/index.d.ts +4 -4
  126. package/dist/index.js +13 -13
  127. package/dist/{leaderboard-chart-B5gWcqe7.d.ts → leaderboard-chart-BSgEw_Um.d.ts} +1 -1
  128. package/dist/{leaderboard-chart-C_6QDcqj.d.cts → leaderboard-chart-COtgamhe.d.cts} +1 -1
  129. package/dist/providers/index.cjs +2 -2
  130. package/dist/providers/index.css +1 -4
  131. package/dist/providers/index.css.map +1 -1
  132. package/dist/providers/index.d.cts +3 -2
  133. package/dist/providers/index.d.ts +3 -2
  134. package/dist/providers/index.js +1 -1
  135. package/dist/{themes-BDVaIfBz.d.cts → themes-CVR5rmIs.d.cts} +1 -1
  136. package/dist/{themes-mcS8QNkQ.d.ts → themes-DQzmaSze.d.ts} +1 -1
  137. package/dist/{types-BCFQlzTM.d.ts → types-CzdN7rUe.d.cts} +12 -3
  138. package/dist/{types-BCFQlzTM.d.cts → types-CzdN7rUe.d.ts} +12 -3
  139. package/dist/utils/index.d.cts +2 -1
  140. package/dist/utils/index.d.ts +2 -1
  141. package/package.json +9 -9
  142. package/src/charts/bar-chart/bar-chart.tsx +2 -9
  143. package/src/charts/bar-chart/test/bar-chart.test.tsx +3 -3
  144. package/src/charts/line-chart/line-chart.tsx +2 -2
  145. package/src/charts/line-chart/test/line-chart.test.tsx +3 -3
  146. package/src/charts/line-chart/types.ts +0 -7
  147. package/src/charts/pie-chart/pie-chart.module.scss +14 -3
  148. package/src/charts/pie-chart/pie-chart.tsx +172 -148
  149. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +17 -11
  150. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +147 -119
  151. package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +46 -6
  152. package/src/charts/private/with-responsive/test/with-responsive.test.tsx +5 -5
  153. package/src/charts/private/with-responsive/with-responsive.tsx +8 -7
  154. package/src/hooks/index.ts +1 -1
  155. package/src/hooks/test/{use-element-height.test.tsx → use-element-size.test.tsx} +45 -36
  156. package/src/hooks/use-element-size.ts +43 -0
  157. package/src/hooks/use-tooltip-portal-relocator.module.scss +1 -4
  158. package/src/hooks/use-tooltip-portal-relocator.ts +11 -0
  159. package/src/types.ts +13 -3
  160. package/dist/chunk-32ESS4MV.js.map +0 -1
  161. package/dist/chunk-7QDEU3KN.cjs.map +0 -1
  162. package/dist/chunk-7TQSPLIN.js.map +0 -1
  163. package/dist/chunk-DBY6C4O2.js.map +0 -1
  164. package/dist/chunk-DLSUC7RN.js.map +0 -1
  165. package/dist/chunk-EJJO2QNB.cjs.map +0 -1
  166. package/dist/chunk-FIFSYVN6.cjs.map +0 -1
  167. package/dist/chunk-FY325WQ4.cjs.map +0 -1
  168. package/dist/chunk-IHESL7H5.cjs.map +0 -1
  169. package/dist/chunk-JL4ZKKZU.cjs +0 -375
  170. package/dist/chunk-JL4ZKKZU.cjs.map +0 -1
  171. package/dist/chunk-KXSLMOW5.js.map +0 -1
  172. package/dist/chunk-LT4YOIMM.js.map +0 -1
  173. package/dist/chunk-TKPK4RFS.cjs.map +0 -1
  174. package/dist/chunk-TYIH5LMV.js.map +0 -1
  175. package/src/hooks/use-element-height.ts +0 -37
  176. /package/dist/{chunk-KHRPRH4V.js.map → chunk-E62LCBGD.js.map} +0 -0
  177. /package/dist/{chunk-PCOI2GT5.js.map → chunk-GWBS65VC.js.map} +0 -0
  178. /package/dist/{chunk-X6GX4QUJ.js.map → chunk-KHQPN77E.js.map} +0 -0
  179. /package/dist/{chunk-AFWQR3SM.js.map → chunk-MDRCAGKZ.js.map} +0 -0
@@ -2,11 +2,12 @@ import { Group } from '@visx/group';
2
2
  import { Pie } from '@visx/shape';
3
3
  import { useTooltip, useTooltipInPortal } from '@visx/tooltip';
4
4
  import { __ } from '@wordpress/i18n';
5
+ import { Stack } from '@wordpress/ui';
5
6
  import clsx from 'clsx';
6
7
  import { useCallback, useContext, useMemo } from 'react';
7
8
  import { Legend, useChartLegendItems } from '../../components/legend';
8
9
  import { BaseTooltip } from '../../components/tooltip';
9
- import { useElementHeight, useInteractiveLegendData, usePrefersReducedMotion } from '../../hooks';
10
+ import { useElementSize, useInteractiveLegendData, usePrefersReducedMotion } from '../../hooks';
10
11
  import {
11
12
  GlobalChartsProvider,
12
13
  useChartId,
@@ -175,6 +176,8 @@ const PieChartInternal = ( {
175
176
  legendTextOverflow = 'wrap',
176
177
  legendItemClassName,
177
178
  legendShape = 'circle',
179
+ width: propWidth,
180
+ height: propHeight,
178
181
  size,
179
182
  animation,
180
183
  thickness = 1,
@@ -188,10 +191,11 @@ const PieChartInternal = ( {
188
191
  tooltipOffsetX = 0,
189
192
  tooltipOffsetY = -15,
190
193
  renderTooltip = renderDefaultPieTooltip,
194
+ gap = 'md',
191
195
  }: PieChartProps ) => {
192
196
  const providerTheme = useGlobalChartsTheme();
193
197
  const chartId = useChartId( providedChartId );
194
- const [ legendRef, legendHeight ] = useElementHeight< HTMLDivElement >();
198
+ const [ svgWrapperRef, svgWrapperWidth, svgWrapperHeight ] = useElementSize< HTMLDivElement >();
195
199
  const { tooltipOpen, tooltipLeft, tooltipTop, tooltipData, hideTooltip, showTooltip } =
196
200
  useTooltip< DataPointPercentage >();
197
201
 
@@ -263,16 +267,24 @@ const PieChartInternal = ( {
263
267
  );
264
268
  }
265
269
 
266
- const width = size;
267
- const height = size;
268
- const adjustedHeight = showLegend && legendPosition === 'top' ? height - legendHeight : height;
270
+ // Calculate the actual pie size:
271
+ // - Measure available space from the svg-wrapper
272
+ // - If size prop provided: use it as max, but shrink if container is smaller
273
+ // - If no size prop: fill available space
274
+ const availableWidth = svgWrapperWidth > 0 ? svgWrapperWidth : 300;
275
+ const availableHeight = svgWrapperHeight > 0 ? svgWrapperHeight : 300;
276
+ const availableSize = Math.min( availableWidth, availableHeight );
277
+ const actualSize = size ? Math.min( size, availableSize ) : availableSize;
278
+
279
+ const width = actualSize;
280
+ const height = actualSize;
269
281
 
270
282
  // Calculate radius based on width/height
271
- const radius = Math.min( width, adjustedHeight ) / 2;
283
+ const radius = Math.min( width, height ) / 2;
272
284
 
273
285
  // Center the chart in the available space
274
286
  const centerX = width / 2;
275
- const centerY = adjustedHeight / 2;
287
+ const centerY = height / 2;
276
288
 
277
289
  // Calculate the angle between each (use original data length for consistent spacing)
278
290
  const padAngle = gapScale * ( ( 2 * Math.PI ) / data.length );
@@ -300,165 +312,177 @@ const PieChartInternal = ( {
300
312
  },
301
313
  };
302
314
 
315
+ const legendElement = showLegend && (
316
+ <Legend
317
+ orientation={ legendOrientation }
318
+ position={ legendPosition }
319
+ alignment={ legendAlignment }
320
+ maxWidth={ legendMaxWidth }
321
+ textOverflow={ legendTextOverflow }
322
+ legendItemClassName={ legendItemClassName }
323
+ shape={ legendShape }
324
+ chartId={ chartId }
325
+ interactive={ legendInteractive }
326
+ />
327
+ );
328
+
303
329
  return (
304
330
  <SingleChartContext.Provider
305
331
  value={ {
306
332
  chartId,
307
333
  chartWidth: width,
308
- chartHeight: adjustedHeight,
334
+ chartHeight: height,
309
335
  } }
310
336
  >
311
- <div
337
+ <Stack
312
338
  ref={ containerRef }
339
+ direction="column"
340
+ gap={ gap }
313
341
  className={ clsx(
314
342
  'pie-chart',
315
343
  styles[ 'pie-chart' ],
316
- { [ styles[ 'pie-chart--legend-top' ] ]: showLegend && legendPosition === 'top' },
344
+ // Fill parent when no explicit dimensions provided
345
+ { [ styles[ 'pie-chart--responsive' ] ]: ! propWidth && ! propHeight },
317
346
  className
318
347
  ) }
348
+ style={ {
349
+ width: propWidth || undefined,
350
+ height: propHeight || undefined,
351
+ } }
319
352
  >
320
- <svg
321
- viewBox={ `0 0 ${ width } ${ adjustedHeight }` }
322
- preserveAspectRatio="xMidYMid meet"
323
- width={ width }
324
- height={ adjustedHeight }
325
- >
326
- <defs>
327
- <RadialWipeAnimation
328
- id={ `radial-wipe-${ chartId }` }
329
- radius={ outerRadius }
330
- innerRadius={ innerRadius }
331
- />
332
- </defs>
333
-
334
- <Group
335
- top={ centerY }
336
- left={ centerX }
337
- mask={ animation && ! prefersReducedMotion ? `url(#radial-wipe-${ chartId })` : null }
353
+ { legendPosition === 'top' && legendElement }
354
+
355
+ <div className={ styles[ 'pie-chart__svg-wrapper' ] } ref={ svgWrapperRef }>
356
+ <svg
357
+ viewBox={ `0 0 ${ width } ${ height }` }
358
+ preserveAspectRatio="xMidYMid meet"
359
+ width={ width }
360
+ height={ height }
338
361
  >
339
- { allSegmentsHidden ? (
340
- <text
341
- textAnchor="middle"
342
- dy=".33em"
343
- fill={ providerTheme.gridColor || '#ccc' }
344
- fontSize="14"
345
- fontFamily="-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif"
346
- >
347
- { __(
348
- 'All segments are hidden. Click legend items to show data.',
349
- 'jetpack-charts'
350
- ) }
351
- </text>
352
- ) : (
353
- <Pie< DataPointPercentage & { index: number } >
354
- data={ dataWithIndex }
355
- pieValue={ accessors.value }
356
- outerRadius={ outerRadius }
362
+ <defs>
363
+ <RadialWipeAnimation
364
+ id={ `radial-wipe-${ chartId }` }
365
+ radius={ outerRadius }
357
366
  innerRadius={ innerRadius }
358
- padAngle={ padAngle }
359
- cornerRadius={ cornerRadius }
360
- >
361
- { pie => {
362
- return pie.arcs.map( ( arc, index ) => {
363
- const [ centroidX, centroidY ] = pie.path.centroid( arc );
364
- const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.25;
365
- const handleMouseMove = ( event: MouseEvent< SVGElement > ) => {
366
- if ( ! withTooltips ) {
367
- return;
367
+ />
368
+ </defs>
369
+
370
+ <Group
371
+ top={ centerY }
372
+ left={ centerX }
373
+ mask={ animation && ! prefersReducedMotion ? `url(#radial-wipe-${ chartId })` : null }
374
+ >
375
+ { allSegmentsHidden ? (
376
+ <text
377
+ textAnchor="middle"
378
+ dy=".33em"
379
+ fill={ providerTheme.gridColor || '#ccc' }
380
+ fontSize="14"
381
+ fontFamily="-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif"
382
+ >
383
+ { __(
384
+ 'All segments are hidden. Click legend items to show data.',
385
+ 'jetpack-charts'
386
+ ) }
387
+ </text>
388
+ ) : (
389
+ <Pie< DataPointPercentage & { index: number } >
390
+ data={ dataWithIndex }
391
+ pieValue={ accessors.value }
392
+ outerRadius={ outerRadius }
393
+ innerRadius={ innerRadius }
394
+ padAngle={ padAngle }
395
+ cornerRadius={ cornerRadius }
396
+ >
397
+ { pie => {
398
+ return pie.arcs.map( ( arc, index ) => {
399
+ const [ centroidX, centroidY ] = pie.path.centroid( arc );
400
+ const hasSpaceForLabel = arc.endAngle - arc.startAngle >= 0.25;
401
+ const handleMouseMove = ( event: MouseEvent< SVGElement > ) => {
402
+ if ( ! withTooltips ) {
403
+ return;
404
+ }
405
+
406
+ // Don't show tooltip until container bounds are measured
407
+ if ( containerBounds.width === 0 || containerBounds.height === 0 ) {
408
+ return;
409
+ }
410
+
411
+ // Use clientX/Y and subtract containerBounds to cancel out any stale offset.
412
+ // TooltipInPortal calculates: tooltipLeft + containerBounds.left + scrollX
413
+ // By passing (clientX - containerBounds.left), we get:
414
+ // (clientX - containerBounds.left) + containerBounds.left + scrollX = clientX + scrollX
415
+ // This gives correct page coordinates regardless of stale bounds.
416
+ showTooltip( {
417
+ tooltipData: arc.data,
418
+ tooltipLeft: event.clientX - containerBounds.left + tooltipOffsetX,
419
+ tooltipTop: event.clientY - containerBounds.top + tooltipOffsetY,
420
+ } );
421
+ };
422
+
423
+ const pathProps: SVGProps< SVGPathElement > & { 'data-testid'?: string } = {
424
+ d: pie.path( arc ) || '',
425
+ fill: accessors.fill( arc.data ),
426
+ 'data-testid': 'pie-segment',
427
+ };
428
+
429
+ const groupProps: SVGProps< SVGGElement > = {};
430
+ if ( withTooltips ) {
431
+ groupProps.onMouseMove = handleMouseMove;
432
+ groupProps.onMouseLeave = onMouseLeave;
368
433
  }
369
434
 
370
- // Don't show tooltip until container bounds are measured
371
- if ( containerBounds.width === 0 || containerBounds.height === 0 ) {
372
- return;
373
- }
374
-
375
- // Use clientX/Y and subtract containerBounds to cancel out any stale offset.
376
- // TooltipInPortal calculates: tooltipLeft + containerBounds.left + scrollX
377
- // By passing (clientX - containerBounds.left), we get:
378
- // (clientX - containerBounds.left) + containerBounds.left + scrollX = clientX + scrollX
379
- // This gives correct page coordinates regardless of stale bounds.
380
- showTooltip( {
381
- tooltipData: arc.data,
382
- tooltipLeft: event.clientX - containerBounds.left + tooltipOffsetX,
383
- tooltipTop: event.clientY - containerBounds.top + tooltipOffsetY,
384
- } );
385
- };
386
-
387
- const pathProps: SVGProps< SVGPathElement > = {
388
- d: pie.path( arc ) || '',
389
- fill: accessors.fill( arc.data ),
390
- };
391
-
392
- const groupProps: SVGProps< SVGGElement > = {};
393
- if ( withTooltips ) {
394
- groupProps.onMouseMove = handleMouseMove;
395
- groupProps.onMouseLeave = onMouseLeave;
396
- }
397
-
398
- // Estimate text width more accurately for background sizing
399
- const fontSize = 12;
400
- const estimatedTextWidth = getStringWidth( arc.data.label, { fontSize } );
401
- const labelPadding = 6;
402
- const backgroundWidth = estimatedTextWidth + labelPadding * 2;
403
- const backgroundHeight = fontSize + labelPadding * 2;
404
-
405
- return (
406
- <g key={ `arc-${ index }` } { ...groupProps }>
407
- <path { ...pathProps } data-testid="pie-segment" />
408
- { showLabels && hasSpaceForLabel && (
409
- <g>
410
- { providerTheme.labelBackgroundColor && (
411
- <rect
412
- x={ centroidX - backgroundWidth / 2 }
413
- y={ centroidY - backgroundHeight / 2 }
414
- width={ backgroundWidth }
415
- height={ backgroundHeight }
416
- fill={ providerTheme.labelBackgroundColor }
417
- rx={ 4 }
418
- ry={ 4 }
435
+ // Estimate text width more accurately for background sizing
436
+ const fontSize = 12;
437
+ const estimatedTextWidth = getStringWidth( arc.data.label, { fontSize } );
438
+ const labelPadding = 6;
439
+ const backgroundWidth = estimatedTextWidth + labelPadding * 2;
440
+ const backgroundHeight = fontSize + labelPadding * 2;
441
+
442
+ return (
443
+ <g key={ `arc-${ index }` } { ...groupProps }>
444
+ <path { ...pathProps } />
445
+ { showLabels && hasSpaceForLabel && (
446
+ <g>
447
+ { providerTheme.labelBackgroundColor && (
448
+ <rect
449
+ x={ centroidX - backgroundWidth / 2 }
450
+ y={ centroidY - backgroundHeight / 2 }
451
+ width={ backgroundWidth }
452
+ height={ backgroundHeight }
453
+ fill={ providerTheme.labelBackgroundColor }
454
+ rx={ 4 }
455
+ ry={ 4 }
456
+ pointerEvents="none"
457
+ />
458
+ ) }
459
+ <text
460
+ x={ centroidX }
461
+ y={ centroidY }
462
+ dy=".33em"
463
+ fill={ providerTheme.labelTextColor || '#333' }
464
+ fontSize={ fontSize }
465
+ textAnchor="middle"
419
466
  pointerEvents="none"
420
- />
421
- ) }
422
- <text
423
- x={ centroidX }
424
- y={ centroidY }
425
- dy=".33em"
426
- fill={ providerTheme.labelTextColor || '#333' }
427
- fontSize={ fontSize }
428
- textAnchor="middle"
429
- pointerEvents="none"
430
- >
431
- { arc.data.label }
432
- </text>
433
- </g>
434
- ) }
435
- </g>
436
- );
437
- } );
438
- } }
439
- </Pie>
440
- ) }
441
-
442
- { /* Render SVG children (like Group, Text) inside the SVG */ }
443
- { ! allSegmentsHidden && svgChildren }
444
- </Group>
445
- </svg>
446
-
447
- { showLegend && (
448
- <Legend
449
- orientation={ legendOrientation }
450
- position={ legendPosition }
451
- alignment={ legendAlignment }
452
- maxWidth={ legendMaxWidth }
453
- textOverflow={ legendTextOverflow }
454
- legendItemClassName={ legendItemClassName }
455
- className={ styles[ 'pie-chart-legend' ] }
456
- shape={ legendShape }
457
- ref={ legendRef }
458
- chartId={ chartId }
459
- interactive={ legendInteractive }
460
- />
461
- ) }
467
+ >
468
+ { arc.data.label }
469
+ </text>
470
+ </g>
471
+ ) }
472
+ </g>
473
+ );
474
+ } );
475
+ } }
476
+ </Pie>
477
+ ) }
478
+
479
+ { /* Render SVG children (like Group, Text) inside the SVG */ }
480
+ { ! allSegmentsHidden && svgChildren }
481
+ </Group>
482
+ </svg>
483
+ </div>
484
+
485
+ { legendPosition === 'bottom' && legendElement }
462
486
 
463
487
  { withTooltips && tooltipOpen && tooltipData && (
464
488
  <TooltipInPortal top={ tooltipTop || 0 } left={ tooltipLeft || 0 }>
@@ -471,7 +495,7 @@ const PieChartInternal = ( {
471
495
 
472
496
  { /* Render other React children for backward compatibility */ }
473
497
  { otherChildren }
474
- </div>
498
+ </Stack>
475
499
  </SingleChartContext.Provider>
476
500
  );
477
501
  };
@@ -1,21 +1,27 @@
1
1
  .pie-semi-circle-chart {
2
- display: flex;
3
- flex-direction: column;
4
- text-align: center;
5
- gap: 20px;
2
+ // Fill parent when no explicit width/height provided
3
+ &--responsive {
4
+ height: 100%;
5
+ width: 100%;
6
+ }
6
7
 
7
- &--legend-top {
8
- flex-direction: column-reverse;
8
+ // Flex wrapper that fills remaining Stack space and measures the SVG area
9
+ &__svg-wrapper {
10
+ flex: 1;
11
+ min-height: 0; // Required for flex shrinking
12
+ min-width: 0; // Required for flex shrinking
13
+ width: 100%;
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: center;
9
17
  }
10
18
 
11
19
  .label {
12
- margin-bottom: 0; // Add space between label and pie chart
13
- font-weight: 600; // Make label more prominent than note
14
- font-size: 16px; // Set explicit font size
20
+ font-weight: 600;
21
+ font-size: 16px;
15
22
  }
16
23
 
17
24
  .note {
18
- margin-top: 0; // Add space between pie chart and note
19
- font-size: 14px; // Slightly smaller text for hierarchy
25
+ font-size: 14px;
20
26
  }
21
27
  }