@automattic/charts 0.58.0 → 0.59.0

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 (253) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +7 -54
  3. package/dist/index.cjs +9606 -22
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.css +20 -25
  6. package/dist/index.css.map +1 -1
  7. package/dist/index.d.cts +1612 -33
  8. package/dist/index.d.ts +1612 -33
  9. package/dist/index.js +9640 -56
  10. package/dist/index.js.map +1 -1
  11. package/package.json +8 -125
  12. package/src/charts/bar-chart/bar-chart.module.scss +0 -5
  13. package/src/charts/bar-chart/bar-chart.tsx +131 -137
  14. package/src/charts/leaderboard-chart/leaderboard-chart.tsx +23 -40
  15. package/src/charts/line-chart/line-chart.module.scss +0 -5
  16. package/src/charts/line-chart/line-chart.tsx +190 -183
  17. package/src/charts/line-chart/private/line-chart-annotations-overlay.tsx +1 -2
  18. package/src/charts/pie-chart/pie-chart.module.scss +2 -10
  19. package/src/charts/pie-chart/pie-chart.tsx +198 -199
  20. package/src/charts/pie-chart/test/composition-api.test.tsx +3 -3
  21. package/src/charts/pie-chart/test/pie-chart.test.tsx +42 -35
  22. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.module.scss +2 -8
  23. package/src/charts/pie-semi-circle-chart/pie-semi-circle-chart.tsx +155 -155
  24. package/src/charts/pie-semi-circle-chart/test/pie-semi-circle-chart.test.tsx +25 -25
  25. package/src/charts/private/chart-layout/chart-layout.module.scss +7 -0
  26. package/src/charts/private/chart-layout/chart-layout.tsx +106 -0
  27. package/src/charts/private/chart-layout/index.ts +2 -0
  28. package/src/charts/private/chart-layout/test/chart-layout.test.tsx +167 -0
  29. package/src/charts/private/single-chart-context/single-chart-context.tsx +2 -2
  30. package/src/charts/private/svg-empty-state/index.ts +1 -0
  31. package/src/charts/private/svg-empty-state/svg-empty-state.module.scss +7 -0
  32. package/src/charts/private/svg-empty-state/svg-empty-state.tsx +40 -0
  33. package/src/components/legend/hooks/test/use-chart-legend-items.test.tsx +12 -8
  34. package/src/components/legend/hooks/use-chart-legend-items.ts +12 -13
  35. package/src/components/legend/legend.tsx +33 -8
  36. package/src/components/legend/test/legend.test.tsx +93 -1
  37. package/src/hooks/index.ts +1 -0
  38. package/src/hooks/use-data-with-percentages.ts +24 -0
  39. package/src/hooks/use-interactive-legend-data.ts +18 -15
  40. package/src/index.ts +65 -2
  41. package/src/providers/chart-context/global-charts-provider.tsx +7 -1
  42. package/src/providers/chart-context/hooks/use-chart-registration.ts +2 -1
  43. package/src/providers/chart-context/types.ts +2 -2
  44. package/src/types.ts +27 -7
  45. package/src/utils/test/resolve-css-var.test.ts +2 -0
  46. package/dist/base-tooltip-DOq93wjU.d.cts +0 -38
  47. package/dist/base-tooltip-DOq93wjU.d.ts +0 -38
  48. package/dist/charts/bar-chart/index.cjs +0 -17
  49. package/dist/charts/bar-chart/index.cjs.map +0 -1
  50. package/dist/charts/bar-chart/index.css +0 -141
  51. package/dist/charts/bar-chart/index.css.map +0 -1
  52. package/dist/charts/bar-chart/index.d.cts +0 -36
  53. package/dist/charts/bar-chart/index.d.ts +0 -36
  54. package/dist/charts/bar-chart/index.js +0 -17
  55. package/dist/charts/bar-chart/index.js.map +0 -1
  56. package/dist/charts/bar-list-chart/index.cjs +0 -18
  57. package/dist/charts/bar-list-chart/index.cjs.map +0 -1
  58. package/dist/charts/bar-list-chart/index.css +0 -141
  59. package/dist/charts/bar-list-chart/index.css.map +0 -1
  60. package/dist/charts/bar-list-chart/index.d.cts +0 -92
  61. package/dist/charts/bar-list-chart/index.d.ts +0 -92
  62. package/dist/charts/bar-list-chart/index.js +0 -18
  63. package/dist/charts/bar-list-chart/index.js.map +0 -1
  64. package/dist/charts/conversion-funnel-chart/index.cjs +0 -11
  65. package/dist/charts/conversion-funnel-chart/index.cjs.map +0 -1
  66. package/dist/charts/conversion-funnel-chart/index.css +0 -157
  67. package/dist/charts/conversion-funnel-chart/index.css.map +0 -1
  68. package/dist/charts/conversion-funnel-chart/index.d.cts +0 -97
  69. package/dist/charts/conversion-funnel-chart/index.d.ts +0 -97
  70. package/dist/charts/conversion-funnel-chart/index.js +0 -11
  71. package/dist/charts/conversion-funnel-chart/index.js.map +0 -1
  72. package/dist/charts/geo-chart/index.cjs +0 -13
  73. package/dist/charts/geo-chart/index.cjs.map +0 -1
  74. package/dist/charts/geo-chart/index.css +0 -23
  75. package/dist/charts/geo-chart/index.css.map +0 -1
  76. package/dist/charts/geo-chart/index.d.cts +0 -67
  77. package/dist/charts/geo-chart/index.d.ts +0 -67
  78. package/dist/charts/geo-chart/index.js +0 -13
  79. package/dist/charts/geo-chart/index.js.map +0 -1
  80. package/dist/charts/leaderboard-chart/index.cjs +0 -21
  81. package/dist/charts/leaderboard-chart/index.cjs.map +0 -1
  82. package/dist/charts/leaderboard-chart/index.css +0 -160
  83. package/dist/charts/leaderboard-chart/index.css.map +0 -1
  84. package/dist/charts/leaderboard-chart/index.d.cts +0 -46
  85. package/dist/charts/leaderboard-chart/index.d.ts +0 -46
  86. package/dist/charts/leaderboard-chart/index.js +0 -21
  87. package/dist/charts/leaderboard-chart/index.js.map +0 -1
  88. package/dist/charts/line-chart/index.cjs +0 -17
  89. package/dist/charts/line-chart/index.cjs.map +0 -1
  90. package/dist/charts/line-chart/index.css +0 -213
  91. package/dist/charts/line-chart/index.css.map +0 -1
  92. package/dist/charts/line-chart/index.d.cts +0 -98
  93. package/dist/charts/line-chart/index.d.ts +0 -98
  94. package/dist/charts/line-chart/index.js +0 -17
  95. package/dist/charts/line-chart/index.js.map +0 -1
  96. package/dist/charts/pie-chart/index.cjs +0 -19
  97. package/dist/charts/pie-chart/index.cjs.map +0 -1
  98. package/dist/charts/pie-chart/index.css +0 -131
  99. package/dist/charts/pie-chart/index.css.map +0 -1
  100. package/dist/charts/pie-chart/index.d.cts +0 -91
  101. package/dist/charts/pie-chart/index.d.ts +0 -91
  102. package/dist/charts/pie-chart/index.js +0 -19
  103. package/dist/charts/pie-chart/index.js.map +0 -1
  104. package/dist/charts/pie-semi-circle-chart/index.cjs +0 -18
  105. package/dist/charts/pie-semi-circle-chart/index.cjs.map +0 -1
  106. package/dist/charts/pie-semi-circle-chart/index.css +0 -132
  107. package/dist/charts/pie-semi-circle-chart/index.css.map +0 -1
  108. package/dist/charts/pie-semi-circle-chart/index.d.cts +0 -88
  109. package/dist/charts/pie-semi-circle-chart/index.d.ts +0 -88
  110. package/dist/charts/pie-semi-circle-chart/index.js +0 -18
  111. package/dist/charts/pie-semi-circle-chart/index.js.map +0 -1
  112. package/dist/charts/sparkline/index.cjs +0 -18
  113. package/dist/charts/sparkline/index.cjs.map +0 -1
  114. package/dist/charts/sparkline/index.css +0 -230
  115. package/dist/charts/sparkline/index.css.map +0 -1
  116. package/dist/charts/sparkline/index.d.cts +0 -113
  117. package/dist/charts/sparkline/index.d.ts +0 -113
  118. package/dist/charts/sparkline/index.js +0 -18
  119. package/dist/charts/sparkline/index.js.map +0 -1
  120. package/dist/chunk-2A34OA5O.cjs +0 -51
  121. package/dist/chunk-2A34OA5O.cjs.map +0 -1
  122. package/dist/chunk-2I67QUIV.js +0 -895
  123. package/dist/chunk-2I67QUIV.js.map +0 -1
  124. package/dist/chunk-2ICEEQOC.js +0 -1071
  125. package/dist/chunk-2ICEEQOC.js.map +0 -1
  126. package/dist/chunk-4B7BL2DD.js +0 -120
  127. package/dist/chunk-4B7BL2DD.js.map +0 -1
  128. package/dist/chunk-4OXMTKAL.js +0 -401
  129. package/dist/chunk-4OXMTKAL.js.map +0 -1
  130. package/dist/chunk-ASLARV7L.cjs +0 -81
  131. package/dist/chunk-ASLARV7L.cjs.map +0 -1
  132. package/dist/chunk-B6NLZFRW.js +0 -617
  133. package/dist/chunk-B6NLZFRW.js.map +0 -1
  134. package/dist/chunk-BBAUQOW6.cjs +0 -120
  135. package/dist/chunk-BBAUQOW6.cjs.map +0 -1
  136. package/dist/chunk-BPYKWMI7.js +0 -194
  137. package/dist/chunk-BPYKWMI7.js.map +0 -1
  138. package/dist/chunk-CMMHCTBX.cjs +0 -373
  139. package/dist/chunk-CMMHCTBX.cjs.map +0 -1
  140. package/dist/chunk-CPPXJATQ.cjs +0 -1071
  141. package/dist/chunk-CPPXJATQ.cjs.map +0 -1
  142. package/dist/chunk-DKU775VC.js +0 -219
  143. package/dist/chunk-DKU775VC.js.map +0 -1
  144. package/dist/chunk-GRA7Y2ZG.cjs +0 -401
  145. package/dist/chunk-GRA7Y2ZG.cjs.map +0 -1
  146. package/dist/chunk-I2276W3I.cjs +0 -66
  147. package/dist/chunk-I2276W3I.cjs.map +0 -1
  148. package/dist/chunk-JJIMABHT.js +0 -351
  149. package/dist/chunk-JJIMABHT.js.map +0 -1
  150. package/dist/chunk-KJHWXOCZ.js +0 -421
  151. package/dist/chunk-KJHWXOCZ.js.map +0 -1
  152. package/dist/chunk-KRWGSOJ2.js +0 -91
  153. package/dist/chunk-KRWGSOJ2.js.map +0 -1
  154. package/dist/chunk-KXRWNFQJ.js +0 -51
  155. package/dist/chunk-KXRWNFQJ.js.map +0 -1
  156. package/dist/chunk-LTFH7SEG.js +0 -373
  157. package/dist/chunk-LTFH7SEG.js.map +0 -1
  158. package/dist/chunk-MUNOKLLE.js +0 -165
  159. package/dist/chunk-MUNOKLLE.js.map +0 -1
  160. package/dist/chunk-MXGLYWVP.cjs +0 -351
  161. package/dist/chunk-MXGLYWVP.cjs.map +0 -1
  162. package/dist/chunk-OP6PHB2U.js +0 -81
  163. package/dist/chunk-OP6PHB2U.js.map +0 -1
  164. package/dist/chunk-OYC34VTO.cjs +0 -3957
  165. package/dist/chunk-OYC34VTO.cjs.map +0 -1
  166. package/dist/chunk-PQL5I3F6.cjs +0 -421
  167. package/dist/chunk-PQL5I3F6.cjs.map +0 -1
  168. package/dist/chunk-REZTQ4PH.cjs +0 -488
  169. package/dist/chunk-REZTQ4PH.cjs.map +0 -1
  170. package/dist/chunk-TZRUHQOH.cjs +0 -91
  171. package/dist/chunk-TZRUHQOH.cjs.map +0 -1
  172. package/dist/chunk-UTYVIOWZ.js +0 -3957
  173. package/dist/chunk-UTYVIOWZ.js.map +0 -1
  174. package/dist/chunk-W2LDIX26.cjs +0 -165
  175. package/dist/chunk-W2LDIX26.cjs.map +0 -1
  176. package/dist/chunk-WSG64BVN.cjs +0 -219
  177. package/dist/chunk-WSG64BVN.cjs.map +0 -1
  178. package/dist/chunk-WTQYGUNF.js +0 -400
  179. package/dist/chunk-WTQYGUNF.js.map +0 -1
  180. package/dist/chunk-WYK7EL5R.cjs +0 -895
  181. package/dist/chunk-WYK7EL5R.cjs.map +0 -1
  182. package/dist/chunk-XC4KHJYX.cjs +0 -617
  183. package/dist/chunk-XC4KHJYX.cjs.map +0 -1
  184. package/dist/chunk-XVBH5XHE.cjs +0 -400
  185. package/dist/chunk-XVBH5XHE.cjs.map +0 -1
  186. package/dist/chunk-XWYZIFZW.js +0 -66
  187. package/dist/chunk-XWYZIFZW.js.map +0 -1
  188. package/dist/chunk-Y3NNQMAX.cjs +0 -194
  189. package/dist/chunk-Y3NNQMAX.cjs.map +0 -1
  190. package/dist/chunk-YAFQVVDI.js +0 -488
  191. package/dist/chunk-YAFQVVDI.js.map +0 -1
  192. package/dist/components/legend/index.cjs +0 -12
  193. package/dist/components/legend/index.cjs.map +0 -1
  194. package/dist/components/legend/index.css +0 -91
  195. package/dist/components/legend/index.css.map +0 -1
  196. package/dist/components/legend/index.d.cts +0 -37
  197. package/dist/components/legend/index.d.ts +0 -37
  198. package/dist/components/legend/index.js +0 -12
  199. package/dist/components/legend/index.js.map +0 -1
  200. package/dist/components/tooltip/index.cjs +0 -12
  201. package/dist/components/tooltip/index.cjs.map +0 -1
  202. package/dist/components/tooltip/index.css +0 -13
  203. package/dist/components/tooltip/index.css.map +0 -1
  204. package/dist/components/tooltip/index.d.cts +0 -71
  205. package/dist/components/tooltip/index.d.ts +0 -71
  206. package/dist/components/tooltip/index.js +0 -12
  207. package/dist/components/tooltip/index.js.map +0 -1
  208. package/dist/components/trend-indicator/index.cjs +0 -8
  209. package/dist/components/trend-indicator/index.cjs.map +0 -1
  210. package/dist/components/trend-indicator/index.css +0 -27
  211. package/dist/components/trend-indicator/index.css.map +0 -1
  212. package/dist/components/trend-indicator/index.d.cts +0 -44
  213. package/dist/components/trend-indicator/index.d.ts +0 -44
  214. package/dist/components/trend-indicator/index.js +0 -8
  215. package/dist/components/trend-indicator/index.js.map +0 -1
  216. package/dist/format-metric-value-MXm5DtQ_.d.cts +0 -24
  217. package/dist/format-metric-value-MXm5DtQ_.d.ts +0 -24
  218. package/dist/hooks/index.cjs +0 -29
  219. package/dist/hooks/index.cjs.map +0 -1
  220. package/dist/hooks/index.css +0 -9
  221. package/dist/hooks/index.css.map +0 -1
  222. package/dist/hooks/index.d.cts +0 -264
  223. package/dist/hooks/index.d.ts +0 -264
  224. package/dist/hooks/index.js +0 -29
  225. package/dist/hooks/index.js.map +0 -1
  226. package/dist/leaderboard-chart-BSbg0ufV.d.cts +0 -79
  227. package/dist/leaderboard-chart-odEYxxEC.d.ts +0 -79
  228. package/dist/legend-DFkosEvC.d.cts +0 -9
  229. package/dist/legend-DLswHhOk.d.ts +0 -9
  230. package/dist/providers/index.cjs +0 -21
  231. package/dist/providers/index.cjs.map +0 -1
  232. package/dist/providers/index.css +0 -9
  233. package/dist/providers/index.css.map +0 -1
  234. package/dist/providers/index.d.cts +0 -28
  235. package/dist/providers/index.d.ts +0 -28
  236. package/dist/providers/index.js +0 -21
  237. package/dist/providers/index.js.map +0 -1
  238. package/dist/themes-D0qc5JaW.d.cts +0 -67
  239. package/dist/themes-itO4Ht5g.d.ts +0 -67
  240. package/dist/types-B5f6XQ7Q.d.cts +0 -19
  241. package/dist/types-BsHooDbM.d.ts +0 -19
  242. package/dist/types-BuSrRM4p.d.ts +0 -49
  243. package/dist/types-ChOUI9-N.d.cts +0 -545
  244. package/dist/types-ChOUI9-N.d.ts +0 -545
  245. package/dist/types-Dfw9VOKI.d.cts +0 -49
  246. package/dist/utils/index.cjs +0 -44
  247. package/dist/utils/index.cjs.map +0 -1
  248. package/dist/utils/index.d.cts +0 -226
  249. package/dist/utils/index.d.ts +0 -226
  250. package/dist/utils/index.js +0 -44
  251. package/dist/utils/index.js.map +0 -1
  252. package/dist/with-responsive-CNfhzAUu.d.cts +0 -18
  253. package/dist/with-responsive-CNfhzAUu.d.ts +0 -18
@@ -4,17 +4,23 @@ import { LinearGradient } from '@visx/gradient';
4
4
  import { scaleTime } from '@visx/scale';
5
5
  import { XYChart, AreaSeries, Grid, Axis, DataContext } from '@visx/xychart';
6
6
  import { __ } from '@wordpress/i18n';
7
- import { Stack } from '@wordpress/ui';
8
7
  import clsx from 'clsx';
9
8
  import { differenceInHours, differenceInYears } from 'date-fns';
10
- import { useMemo, useContext, forwardRef, useImperativeHandle, useState, useRef } from 'react';
9
+ import {
10
+ useMemo,
11
+ useContext,
12
+ forwardRef,
13
+ useImperativeHandle,
14
+ useState,
15
+ useRef,
16
+ useCallback,
17
+ } from 'react';
11
18
  import { Legend, useChartLegendItems } from '../../components/legend';
12
19
  import { AccessibleTooltip, useKeyboardNavigation } from '../../components/tooltip';
13
20
  import {
14
21
  useXYChartTheme,
15
22
  useChartDataTransform,
16
23
  useChartMargin,
17
- useElementSize,
18
24
  usePrefersReducedMotion,
19
25
  } from '../../hooks';
20
26
  import {
@@ -26,9 +32,11 @@ import {
26
32
  useGlobalChartsTheme,
27
33
  } from '../../providers';
28
34
  import { attachSubComponents } from '../../utils';
29
- import { useChartChildren, renderLegendSlot } from '../private/chart-composition';
35
+ import { useChartChildren } from '../private/chart-composition';
36
+ import { ChartLayout } from '../private/chart-layout';
30
37
  import { DefaultGlyph } from '../private/default-glyph';
31
38
  import { SingleChartContext, type SingleChartRef } from '../private/single-chart-context';
39
+ import { SvgEmptyState } from '../private/svg-empty-state';
32
40
  import { withResponsive } from '../private/with-responsive';
33
41
  import styles from './line-chart.module.scss';
34
42
  import { LineChartAnnotation, LineChartAnnotationsOverlay, LineChartGlyph } from './private';
@@ -285,7 +293,6 @@ const LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(
285
293
  const providerTheme = useGlobalChartsTheme();
286
294
  const theme = useXYChartTheme( data );
287
295
  const chartId = useChartId( providedChartId );
288
- const [ svgWrapperRef, , svgWrapperHeight ] = useElementSize< HTMLDivElement >();
289
296
  const chartRef = useRef< HTMLDivElement >( null );
290
297
  const [ selectedIndex, setSelectedIndex ] = useState< number | undefined >( undefined );
291
298
  const [ isNavigating, setIsNavigating ] = useState( false );
@@ -293,14 +300,17 @@ const LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(
293
300
 
294
301
  // Process children for composition API (Legend, etc.)
295
302
  const { legendChildren, nonLegendChildren } = useChartChildren( children, 'LineChart' );
296
- const hasLegendChild = legendChildren.length > 0;
297
-
298
- // Use the measured SVG wrapper height, falling back to the passed height if provided.
299
- // When there's a legend (via prop or composition), we must wait for measurement because
300
- // the legend takes space and the svg-wrapper height will be less than the total height.
301
- const chartHeight = svgWrapperHeight > 0 ? svgWrapperHeight : height;
302
- const hasLegend = showLegend || hasLegendChild;
303
- const isWaitingForMeasurement = hasLegend ? svgWrapperHeight === 0 : ! chartHeight;
303
+ const [ measuredChartHeight, setMeasuredChartHeight ] = useState< number | undefined >();
304
+
305
+ // Callback for ChartLayout to notify us when the measured content height changes.
306
+ // We compute chartHeight the same way the render prop does so the context stays in sync.
307
+ const handleContentHeightChange = useCallback(
308
+ ( contentHeight: number ) => {
309
+ const chartHeight = contentHeight > 0 ? contentHeight : height;
310
+ setMeasuredChartHeight( chartHeight );
311
+ },
312
+ [ height ]
313
+ );
304
314
 
305
315
  // Forward the external ref to the internal ref
306
316
  useImperativeHandle(
@@ -472,11 +482,13 @@ const LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(
472
482
  chartId,
473
483
  chartRef: internalChartRef,
474
484
  chartWidth: width,
475
- chartHeight,
485
+ chartHeight: measuredChartHeight || 0,
476
486
  } }
477
487
  >
478
- <Stack
479
- direction="column"
488
+ <ChartLayout
489
+ legendPosition={ legendPosition }
490
+ legendElement={ legendElement }
491
+ legendChildren={ legendChildren }
480
492
  gap={ gap }
481
493
  className={ clsx(
482
494
  'line-chart',
@@ -484,181 +496,176 @@ const LineChartInternal = forwardRef< SingleChartRef, LineChartProps >(
484
496
  { [ styles[ 'line-chart--animated' ] ]: animation && ! prefersReducedMotion },
485
497
  className
486
498
  ) }
499
+ style={ { width, height } }
487
500
  data-testid="line-chart"
488
- style={ {
489
- width,
490
- height,
491
- visibility: isWaitingForMeasurement ? 'hidden' : 'visible',
492
- } }
501
+ trailingContent={ nonLegendChildren }
502
+ onContentHeightChange={ handleContentHeightChange }
493
503
  >
494
- { legendPosition === 'top' && legendElement }
495
- { renderLegendSlot( legendChildren, 'top' ) }
496
-
497
- <div
498
- className={ styles[ 'line-chart__svg-wrapper' ] }
499
- ref={ svgWrapperRef }
500
- role="grid"
501
- aria-label={ __( 'Line chart', 'jetpack-charts' ) }
502
- tabIndex={ 0 }
503
- onKeyDown={ onChartKeyDown }
504
- onFocus={ onChartFocus }
505
- onBlur={ onChartBlur }
506
- >
507
- { ! isWaitingForMeasurement && (
508
- <div ref={ chartRef }>
509
- <XYChart
510
- theme={ theme }
511
- width={ width }
512
- height={ chartHeight }
513
- margin={ {
514
- ...defaultMargin,
515
- ...margin,
516
- } }
517
- // xScale and yScale could be set in Axis as well, but they are `scale` props there.
518
- xScale={ chartOptions.xScale }
519
- yScale={ chartOptions.yScale }
520
- onPointerDown={ onPointerDown }
521
- onPointerUp={ onPointerUp }
522
- onPointerMove={ onPointerMove }
523
- onPointerOut={ onPointerOut }
524
- pointerEventsDataKey="nearest"
525
- >
526
- { gridVisibility !== 'none' && <Grid columns={ false } numTicks={ 4 } /> }
527
- { chartOptions.axis.x.display && <Axis { ...chartOptions.axis.x } /> }
528
- { chartOptions.axis.y.display && <Axis { ...chartOptions.axis.y } /> }
529
-
530
- { allSeriesHidden ? (
531
- <text
532
- x={ width / 2 }
533
- y={ chartHeight / 2 }
534
- textAnchor="middle"
535
- fill={ providerTheme.gridStyles?.stroke || '#ccc' }
536
- fontSize="14"
537
- fontFamily="-apple-system,BlinkMacSystemFont,Roboto,Helvetica Neue,sans-serif"
504
+ { ( { contentHeight } ) => {
505
+ // Use the measured height, falling back to the passed height if provided.
506
+ const chartHeight = contentHeight > 0 ? contentHeight : height;
507
+
508
+ return (
509
+ <div
510
+ role="grid"
511
+ aria-label={ __( 'Line chart', 'jetpack-charts' ) }
512
+ tabIndex={ 0 }
513
+ onKeyDown={ onChartKeyDown }
514
+ onFocus={ onChartFocus }
515
+ onBlur={ onChartBlur }
516
+ >
517
+ { chartHeight > 0 && (
518
+ <div ref={ chartRef }>
519
+ <XYChart
520
+ theme={ theme }
521
+ width={ width }
522
+ height={ chartHeight }
523
+ margin={ {
524
+ ...defaultMargin,
525
+ ...margin,
526
+ } }
527
+ // xScale and yScale could be set in Axis as well, but they are `scale` props there.
528
+ xScale={ chartOptions.xScale }
529
+ yScale={ chartOptions.yScale }
530
+ onPointerDown={ onPointerDown }
531
+ onPointerUp={ onPointerUp }
532
+ onPointerMove={ onPointerMove }
533
+ onPointerOut={ onPointerOut }
534
+ pointerEventsDataKey="nearest"
538
535
  >
539
- { __(
540
- 'All series are hidden. Click legend items to show data.',
541
- 'jetpack-charts'
542
- ) }
543
- </text>
544
- ) : null }
545
-
546
- { seriesWithVisibility.map( ( { series: seriesData, index, isVisible } ) => {
547
- // Skip rendering invisible series
548
- if ( ! isVisible ) {
549
- return null;
550
- }
551
-
552
- const { color, lineStyles, glyph } = getElementStyles( {
553
- data: seriesData,
554
- index,
555
- } );
556
-
557
- const lineProps = {
558
- stroke: color,
559
- ...lineStyles,
560
- };
561
-
562
- return (
563
- <g key={ seriesData?.label || index }>
564
- { withGradientFill && (
565
- <LinearGradient
566
- id={ `area-gradient-${ chartId }-${ index + 1 }` }
567
- from={ color }
568
- fromOpacity={ 0.4 }
569
- toOpacity={ 0.1 }
570
- to={ providerTheme.backgroundColor }
571
- { ...seriesData.options?.gradient }
572
- data-testid="line-gradient"
573
- >
574
- { seriesData.options?.gradient?.stops?.map( ( stop, stopIndex ) => (
575
- <stop
576
- key={ `${ stop.offset }-${ stop.color || color }` }
577
- offset={ stop.offset }
578
- stopColor={ stop.color || color }
579
- stopOpacity={ stop.opacity ?? 1 }
580
- data-testid={ `line-gradient-stop-${ chartId }-${ index }-${ stopIndex }` }
536
+ { gridVisibility !== 'none' && <Grid columns={ false } numTicks={ 4 } /> }
537
+ { chartOptions.axis.x.display && <Axis { ...chartOptions.axis.x } /> }
538
+ { chartOptions.axis.y.display && <Axis { ...chartOptions.axis.y } /> }
539
+
540
+ { allSeriesHidden ? (
541
+ <SvgEmptyState
542
+ x={ width / 2 }
543
+ y={ chartHeight / 2 }
544
+ width={ width }
545
+ height={ chartHeight }
546
+ >
547
+ { __(
548
+ 'All series are hidden. Click legend items to show data.',
549
+ 'jetpack-charts'
550
+ ) }
551
+ </SvgEmptyState>
552
+ ) : null }
553
+
554
+ { seriesWithVisibility.map( ( { series: seriesData, index, isVisible } ) => {
555
+ // Skip rendering invisible series
556
+ if ( ! isVisible ) {
557
+ return null;
558
+ }
559
+
560
+ const { color, lineStyles, glyph } = getElementStyles( {
561
+ data: seriesData,
562
+ index,
563
+ } );
564
+
565
+ const lineProps = {
566
+ stroke: color,
567
+ ...lineStyles,
568
+ };
569
+
570
+ return (
571
+ <g key={ seriesData?.label || index }>
572
+ { withGradientFill && (
573
+ <LinearGradient
574
+ id={ `area-gradient-${ chartId }-${ index + 1 }` }
575
+ from={ color }
576
+ fromOpacity={ 0.4 }
577
+ toOpacity={ 0.1 }
578
+ to={ providerTheme.backgroundColor }
579
+ { ...seriesData.options?.gradient }
580
+ data-testid="line-gradient"
581
+ >
582
+ { seriesData.options?.gradient?.stops?.map( ( stop, stopIndex ) => (
583
+ <stop
584
+ key={ `${ stop.offset }-${ stop.color || color }` }
585
+ offset={ stop.offset }
586
+ stopColor={ stop.color || color }
587
+ stopOpacity={ stop.opacity ?? 1 }
588
+ data-testid={ `line-gradient-stop-${ chartId }-${ index }-${ stopIndex }` }
589
+ />
590
+ ) ) }
591
+ </LinearGradient>
592
+ ) }
593
+ <AreaSeries
594
+ key={ seriesData?.label }
595
+ dataKey={ seriesData?.label }
596
+ data={ seriesData.data as DataPointDate[] }
597
+ { ...accessors }
598
+ fill={
599
+ withGradientFill
600
+ ? `url(#area-gradient-${ chartId }-${ index + 1 })`
601
+ : 'transparent'
602
+ }
603
+ renderLine={ true }
604
+ curve={ getCurveType( curveType, smoothing ) }
605
+ lineProps={ lineProps }
606
+ />
607
+
608
+ { withStartGlyphs && (
609
+ <LineChartGlyph
610
+ index={ index }
611
+ data={ seriesData }
612
+ color={ color }
613
+ renderGlyph={ glyph ?? renderGlyph }
614
+ accessors={ accessors }
615
+ glyphStyle={ glyphStyle }
616
+ position="start"
581
617
  />
582
- ) ) }
583
- </LinearGradient>
584
- ) }
585
- <AreaSeries
586
- key={ seriesData?.label }
587
- dataKey={ seriesData?.label }
588
- data={ seriesData.data as DataPointDate[] }
589
- { ...accessors }
590
- fill={
591
- withGradientFill
592
- ? `url(#area-gradient-${ chartId }-${ index + 1 })`
593
- : 'transparent'
618
+ ) }
619
+
620
+ { withEndGlyphs && (
621
+ <LineChartGlyph
622
+ index={ index }
623
+ data={ seriesData }
624
+ color={ color }
625
+ renderGlyph={ glyph ?? renderGlyph }
626
+ accessors={ accessors }
627
+ glyphStyle={ glyphStyle }
628
+ position="end"
629
+ />
630
+ ) }
631
+ </g>
632
+ );
633
+ } ) }
634
+
635
+ { withTooltips && (
636
+ <AccessibleTooltip
637
+ detectBounds
638
+ snapTooltipToDatumX
639
+ snapTooltipToDatumY
640
+ showSeriesGlyphs
641
+ renderTooltip={ renderTooltip }
642
+ renderGlyph={ tooltipRenderGlyph }
643
+ glyphStyle={ glyphStyle }
644
+ showVerticalCrosshair={ withTooltipCrosshairs?.showVertical }
645
+ showHorizontalCrosshair={ withTooltipCrosshairs?.showHorizontal }
646
+ selectedIndex={ selectedIndex }
647
+ tooltipRef={ tooltipRef }
648
+ keyboardFocusedClassName={
649
+ styles[ 'line-chart__tooltip--keyboard-focused' ]
594
650
  }
595
- renderLine={ true }
596
- curve={ getCurveType( curveType, smoothing ) }
597
- lineProps={ lineProps }
651
+ series={ dataSorted }
598
652
  />
653
+ ) }
599
654
 
600
- { withStartGlyphs && (
601
- <LineChartGlyph
602
- index={ index }
603
- data={ seriesData }
604
- color={ color }
605
- renderGlyph={ glyph ?? renderGlyph }
606
- accessors={ accessors }
607
- glyphStyle={ glyphStyle }
608
- position="start"
609
- />
610
- ) }
611
-
612
- { withEndGlyphs && (
613
- <LineChartGlyph
614
- index={ index }
615
- data={ seriesData }
616
- color={ color }
617
- renderGlyph={ glyph ?? renderGlyph }
618
- accessors={ accessors }
619
- glyphStyle={ glyphStyle }
620
- position="end"
621
- />
622
- ) }
623
- </g>
624
- );
625
- } ) }
626
-
627
- { withTooltips && (
628
- <AccessibleTooltip
629
- detectBounds
630
- snapTooltipToDatumX
631
- snapTooltipToDatumY
632
- showSeriesGlyphs
633
- renderTooltip={ renderTooltip }
634
- renderGlyph={ tooltipRenderGlyph }
635
- glyphStyle={ glyphStyle }
636
- showVerticalCrosshair={ withTooltipCrosshairs?.showVertical }
637
- showHorizontalCrosshair={ withTooltipCrosshairs?.showHorizontal }
638
- selectedIndex={ selectedIndex }
639
- tooltipRef={ tooltipRef }
640
- keyboardFocusedClassName={ styles[ 'line-chart__tooltip--keyboard-focused' ] }
641
- series={ dataSorted }
642
- />
643
- ) }
644
-
645
- { /* Component to expose scale data via ref */ }
646
- <LineChartScalesRef
647
- chartRef={ internalChartRef }
648
- width={ width }
649
- height={ height }
650
- margin={ margin }
651
- />
652
- </XYChart>
655
+ { /* Component to expose scale data via ref */ }
656
+ <LineChartScalesRef
657
+ chartRef={ internalChartRef }
658
+ width={ width }
659
+ height={ height }
660
+ margin={ margin }
661
+ />
662
+ </XYChart>
663
+ </div>
664
+ ) }
653
665
  </div>
654
- ) }
655
- </div>
656
-
657
- { legendPosition === 'bottom' && legendElement }
658
- { renderLegendSlot( legendChildren, 'bottom' ) }
659
-
660
- { nonLegendChildren }
661
- </Stack>
666
+ );
667
+ } }
668
+ </ChartLayout>
662
669
  </SingleChartContext.Provider>
663
670
  );
664
671
  }
@@ -99,8 +99,7 @@ const LineChartAnnotationsOverlay: FC< LineChartAnnotationsProps > = ( { childre
99
99
  };
100
100
  }, [ getScalesData, chartWidth, chartHeight ] );
101
101
 
102
- // Early return if no chart data available
103
- if ( ! chartRef || ! children ) {
102
+ if ( ! chartRef || ! children || ! chartWidth || ! chartHeight ) {
104
103
  return null;
105
104
  }
106
105
 
@@ -1,8 +1,5 @@
1
1
  .pie-chart {
2
- display: flex;
3
- flex-direction: column;
4
2
  overflow: hidden;
5
- align-items: center;
6
3
 
7
4
  // Fill parent when no explicit width/height provided
8
5
  &--responsive {
@@ -10,13 +7,8 @@
10
7
  width: 100%;
11
8
  }
12
9
 
13
- &__svg-wrapper {
14
- flex: 1;
15
- min-height: 0; // Required for flex shrinking
16
- min-width: 0; // Required for flex shrinking
10
+ &__centering {
17
11
  width: 100%;
18
- display: flex;
19
- align-items: center;
20
- justify-content: center;
12
+ height: 100%;
21
13
  }
22
14
  }