@cdc/chart 4.25.11 → 4.26.2

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 (181) hide show
  1. package/CLAUDE.local.md +79 -0
  2. package/dist/{cdcchart-dgT_1dIT.es.js → cdcchart-DQ00cQCm.es.js} +1 -20
  3. package/dist/cdcchart.js +51401 -50814
  4. package/examples/default.json +378 -0
  5. package/examples/feature/__data__/horizon-chart-data.json +373 -0
  6. package/examples/feature/annotations/index.json +3 -6
  7. package/examples/feature/horizon/horizon-chart.json +395 -0
  8. package/examples/feature/pie/planet-pie-example-config.json +48 -2
  9. package/examples/line-chart-states.json +1085 -0
  10. package/examples/private/123.json +694 -0
  11. package/examples/private/DEV-12100.json +1303 -0
  12. package/examples/private/anchor-issue.json +4094 -0
  13. package/examples/private/backwards-slider.json +10430 -0
  14. package/examples/private/cat-y.json +1235 -0
  15. package/examples/private/data-points.json +228 -0
  16. package/examples/private/georgia.csv +160 -0
  17. package/examples/private/height.json +3915 -0
  18. package/examples/private/links.json +569 -0
  19. package/examples/private/quadrant.txt +30 -0
  20. package/examples/private/test-forecast.json +5510 -0
  21. package/examples/private/timeline-data.json +1 -0
  22. package/examples/private/timeline.json +389 -0
  23. package/examples/private/warming-stripe-test.json +2578 -0
  24. package/examples/private/warming-stripes.json +4763 -0
  25. package/examples/radar-chart-simple.json +133 -0
  26. package/examples/radar-chart.json +148 -0
  27. package/examples/tech-adoption-with-links.json +560 -0
  28. package/index.html +1 -36
  29. package/package.json +59 -60
  30. package/src/CdcChartComponent.tsx +206 -89
  31. package/src/_stories/Chart.Anchors.stories.tsx +10 -0
  32. package/src/_stories/Chart.BoxPlot.stories.tsx +7 -0
  33. package/src/_stories/Chart.CI.stories.tsx +13 -0
  34. package/src/_stories/Chart.Combo.stories.tsx +17 -0
  35. package/src/_stories/Chart.CustomColors.stories.tsx +4 -0
  36. package/src/_stories/Chart.DynamicSeries.stories.tsx +19 -0
  37. package/src/_stories/Chart.Filters.stories.tsx +4 -0
  38. package/src/_stories/Chart.Forecast.stories.tsx +4 -0
  39. package/src/_stories/Chart.HTMLInDataTable.stories.tsx +22 -0
  40. package/src/_stories/Chart.Legend.Gradient.stories.tsx +28 -0
  41. package/src/_stories/Chart.Patterns.stories.tsx +4 -0
  42. package/src/_stories/Chart.PreserveDecimals.stories.tsx +25 -0
  43. package/src/_stories/Chart.Regions.Categorical.stories.tsx +161 -0
  44. package/src/_stories/Chart.Regions.DateScale.stories.tsx +216 -0
  45. package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +312 -0
  46. package/src/_stories/Chart.ScatterPlot.stories.tsx +4 -0
  47. package/src/_stories/Chart.SmallMultiples.stories.tsx +16 -0
  48. package/src/_stories/Chart.stories.tsx +45 -0
  49. package/src/_stories/Chart.tooltip.stories.tsx +7 -0
  50. package/src/_stories/ChartAnnotation.stories.tsx +10 -0
  51. package/src/_stories/ChartAxisLabels.stories.tsx +4 -0
  52. package/src/_stories/ChartAxisTitles.stories.tsx +10 -0
  53. package/src/_stories/ChartBar.Editor.stories.tsx +11 -6
  54. package/src/_stories/ChartBrush.Editor.stories.tsx +295 -0
  55. package/src/_stories/ChartBrush.Matrix.Continuous.stories.tsx +41 -0
  56. package/src/_stories/ChartBrush.Matrix.Date.stories.tsx +114 -0
  57. package/src/_stories/ChartBrush.Matrix.DateTime.stories.tsx +78 -0
  58. package/src/_stories/ChartBrush.stories.tsx +57 -0
  59. package/src/_stories/ChartEditor.Editor.stories.tsx +3 -5
  60. package/src/_stories/ChartEditor.stories.tsx +7 -0
  61. package/src/_stories/ChartLine.QuadrantAngles.stories.tsx +89 -0
  62. package/src/_stories/ChartLine.Suppression.stories.tsx +7 -0
  63. package/src/_stories/ChartLine.Symbols.stories.tsx +4 -0
  64. package/src/_stories/ChartPrefixSuffix.stories.tsx +46 -1
  65. package/src/_stories/TechAdoptionWithLinks.stories.tsx +34 -0
  66. package/src/_stories/_mock/brush_continuous.json +86 -0
  67. package/src/_stories/_mock/brush_date_large.json +176 -0
  68. package/src/_stories/_mock/brush_enabled.json +326 -0
  69. package/src/_stories/_mock/brush_mock.json +2 -69
  70. package/src/_stories/_mock/horizontal-bars-dynamic-y-axis.json +413 -0
  71. package/src/_stories/_mock/line_chart_angle_near_zero_fall.json +195 -0
  72. package/src/_stories/_mock/line_chart_angle_near_zero_rise.json +195 -0
  73. package/src/_stories/_mock/line_chart_angle_q1_steep_upward.json +195 -0
  74. package/src/_stories/_mock/line_chart_angle_q2_gentle_downward.json +195 -0
  75. package/src/_stories/_mock/line_chart_angle_q3_steep_downward.json +195 -0
  76. package/src/_stories/_mock/line_chart_angle_q4_gentle_upward.json +195 -0
  77. package/src/_stories/_mock/line_chart_quadrant_angles.json +264 -0
  78. package/src/components/Annotations/components/AnnotationDraggable.styles.css +11 -17
  79. package/src/components/Annotations/components/AnnotationDraggable.tsx +240 -116
  80. package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -2
  81. package/src/components/Annotations/components/AnnotationDropdown.tsx +8 -12
  82. package/src/components/Annotations/components/AnnotationList.styles.css +4 -10
  83. package/src/components/Annotations/components/AnnotationList.tsx +5 -4
  84. package/src/components/Annotations/components/findNearestDatum.ts +75 -85
  85. package/src/components/Annotations/helpers/getVisibleAnnotations.ts +38 -0
  86. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +1 -2
  87. package/src/components/Axis/BottomAxis.tsx +270 -0
  88. package/src/components/Axis/Categorical.Axis.tsx +6 -7
  89. package/src/components/Axis/LeftAxis.tsx +404 -0
  90. package/src/components/Axis/LeftAxisGridlines.tsx +77 -0
  91. package/src/components/Axis/PairedBarAxis.tsx +186 -0
  92. package/src/components/Axis/README.md +94 -0
  93. package/src/components/Axis/RightAxis.tsx +108 -0
  94. package/src/components/Axis/axis.constants.ts +21 -0
  95. package/src/components/Axis/index.ts +7 -0
  96. package/src/components/BarChart/components/BarChart.Horizontal.tsx +178 -24
  97. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +3 -1
  98. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +1 -0
  99. package/src/components/BarChart/components/BarChart.Vertical.tsx +6 -8
  100. package/src/components/BarChart/components/BarChart.tsx +7 -1
  101. package/src/components/BarChart/components/context.tsx +1 -0
  102. package/src/components/BarChart/helpers/useBarChart.ts +14 -2
  103. package/src/components/Brush/BrushSelector.tsx +1390 -0
  104. package/src/components/Brush/MiniChartPreview.tsx +400 -0
  105. package/src/components/DeviationBar.jsx +9 -7
  106. package/src/components/EditorPanel/EditorPanel.tsx +2734 -2595
  107. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +60 -22
  108. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +56 -34
  109. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +137 -30
  110. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +2 -0
  111. package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +353 -0
  112. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +0 -1
  113. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +30 -25
  114. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +42 -28
  115. package/src/components/EditorPanel/components/Panels/index.tsx +2 -0
  116. package/src/components/EditorPanel/useEditorPermissions.ts +81 -39
  117. package/src/components/HorizonChart/HorizonChart.tsx +131 -0
  118. package/src/components/HorizonChart/components/HorizonBand.tsx +160 -0
  119. package/src/components/HorizonChart/helpers/calculateHorizonBands.ts +27 -0
  120. package/src/components/HorizonChart/helpers/getHorizonLayerColors.ts +40 -0
  121. package/src/components/HorizonChart/index.tsx +3 -0
  122. package/src/components/Legend/Legend.Component.tsx +52 -4
  123. package/src/components/Legend/Legend.tsx +4 -3
  124. package/src/components/Legend/LegendValueRange.tsx +77 -0
  125. package/src/components/Legend/helpers/createFormatLabels.tsx +164 -2
  126. package/src/components/Legend/helpers/generateValueRanges.ts +92 -0
  127. package/src/components/Legend/helpers/index.ts +10 -6
  128. package/src/components/LineChart/helpers/README.md +292 -0
  129. package/src/components/LineChart/helpers/labelPositioning.test.ts +245 -0
  130. package/src/components/LineChart/helpers/labelPositioning.ts +304 -0
  131. package/src/components/LineChart/index.tsx +44 -8
  132. package/src/components/LinearChart/README.md +109 -0
  133. package/src/components/LinearChart/VisualizationRenderer.tsx +267 -0
  134. package/src/components/LinearChart/linearChart.constants.ts +84 -0
  135. package/src/components/LinearChart/tests/LinearChart.test.tsx +201 -0
  136. package/src/components/LinearChart/tests/mockConfigContext.ts +129 -0
  137. package/src/components/LinearChart/utils/tickFormatting.ts +146 -0
  138. package/src/components/LinearChart.tsx +338 -1082
  139. package/src/components/PairedBarChart.jsx +20 -3
  140. package/src/components/PieChart/PieChart.tsx +1 -1
  141. package/src/components/RadarChart/RadarAxis.tsx +78 -0
  142. package/src/components/RadarChart/RadarChart.tsx +298 -0
  143. package/src/components/RadarChart/RadarGrid.tsx +64 -0
  144. package/src/components/RadarChart/RadarPolygon.tsx +91 -0
  145. package/src/components/RadarChart/helpers.ts +83 -0
  146. package/src/components/RadarChart/index.tsx +3 -0
  147. package/src/components/Regions/components/Regions.tsx +365 -122
  148. package/src/components/ScatterPlot/ScatterPlot.jsx +2 -2
  149. package/src/components/SmallMultiples/SmallMultipleTile.tsx +5 -1
  150. package/src/components/WarmingStripes/WarmingStripes.tsx +230 -0
  151. package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +35 -0
  152. package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +104 -0
  153. package/src/components/WarmingStripes/index.tsx +3 -0
  154. package/src/data/initial-state.js +17 -2
  155. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +57 -0
  156. package/src/helpers/getExcludedData.ts +4 -0
  157. package/src/helpers/getMinMax.ts +12 -7
  158. package/src/helpers/handleChartAriaLabels.ts +19 -19
  159. package/src/helpers/handleLineType.ts +22 -18
  160. package/src/helpers/sizeHelpers.ts +0 -20
  161. package/src/helpers/smallMultiplesHelpers.ts +1 -1
  162. package/src/hooks/useChartHoverAnalytics.tsx +10 -9
  163. package/src/hooks/useProgrammaticTooltip.ts +23 -2
  164. package/src/hooks/useScales.ts +18 -1
  165. package/src/hooks/useTooltip.tsx +34 -10
  166. package/src/scss/DataTable.scss +0 -4
  167. package/src/scss/main.scss +22 -3
  168. package/src/selectors/README.md +68 -0
  169. package/src/store/chart.reducer.ts +2 -0
  170. package/src/test/CdcChart.test.jsx +1 -1
  171. package/src/types/ChartConfig.ts +21 -0
  172. package/src/types/ChartContext.ts +1 -0
  173. package/src/types/Horizon.ts +64 -0
  174. package/src/types/Label.ts +1 -0
  175. package/src/utils/analyticsTracking.ts +19 -0
  176. package/LICENSE +0 -201
  177. package/src/components/Annotations/components/helpers/index.tsx +0 -46
  178. package/src/components/Brush/BrushChart.tsx +0 -128
  179. package/src/components/Brush/BrushController.tsx +0 -71
  180. package/src/components/Brush/types.tsx +0 -8
  181. package/src/components/BrushChart.tsx +0 -223
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import boxPlotConfig from './_mock/boxplot_multiseries.json'
3
3
  import Chart from '../CdcChartComponent'
4
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
4
5
 
5
6
  const meta: Meta<typeof Chart> = {
6
7
  title: 'Components/Templates/Chart/Box Plot',
@@ -17,6 +18,9 @@ export const BoxPlot_Vertical: Story = {
17
18
  title: 'Vertical Multiseries Box Plot',
18
19
  isEditor: false
19
20
  }
21
+ },
22
+ play: async ({ canvasElement }) => {
23
+ await assertVisualizationRendered(canvasElement)
20
24
  }
21
25
  }
22
26
 
@@ -29,6 +33,9 @@ export const BoxPlot_Horizontal: Story = {
29
33
  yAxis: { ...boxPlotConfig.yAxis, labelPlacement: 'Above Bar' }
30
34
  },
31
35
  isEditor: false
36
+ },
37
+ play: async ({ canvasElement }) => {
38
+ await assertVisualizationRendered(canvasElement)
32
39
  }
33
40
  }
34
41
 
@@ -4,6 +4,7 @@ import lineChartDynamicCI from './_mock/line_chart_dynamic_ci.json'
4
4
  import lineChartNonDynamicCI from './_mock/line_chart_non_dynamic_ci.json'
5
5
 
6
6
  import Chart from '../CdcChartComponent'
7
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
7
8
 
8
9
  const meta: Meta<typeof Chart> = {
9
10
  title: 'Components/Templates/Chart/Confidence Intervals',
@@ -14,6 +15,9 @@ export const bar_chart_with_labels: Story = {
14
15
  args: {
15
16
  config: barChartCiLabels,
16
17
  isEditor: false
18
+ },
19
+ play: async ({ canvasElement }) => {
20
+ await assertVisualizationRendered(canvasElement)
17
21
  }
18
22
  }
19
23
  export const bar_chart_horizontal_labels: Story = {
@@ -24,6 +28,9 @@ export const bar_chart_horizontal_labels: Story = {
24
28
  yAxis: { ...barChartCiLabels.yAxis, displayNumbersOnBar: true }
25
29
  },
26
30
  isEditor: false
31
+ },
32
+ play: async ({ canvasElement }) => {
33
+ await assertVisualizationRendered(canvasElement)
27
34
  }
28
35
  }
29
36
 
@@ -31,6 +38,9 @@ export const line_Chart_Dynamic_Confidence_Intervals: Story = {
31
38
  args: {
32
39
  config: lineChartDynamicCI,
33
40
  isEditor: false
41
+ },
42
+ play: async ({ canvasElement }) => {
43
+ await assertVisualizationRendered(canvasElement)
34
44
  }
35
45
  }
36
46
 
@@ -38,6 +48,9 @@ export const line_Chart_Non_Dynamic_Confidence_Intervals: Story = {
38
48
  args: {
39
49
  config: lineChartNonDynamicCI,
40
50
  isEditor: false
51
+ },
52
+ play: async ({ canvasElement }) => {
53
+ await assertVisualizationRendered(canvasElement)
41
54
  }
42
55
  }
43
56
  export default meta
@@ -2,6 +2,8 @@
2
2
  import React from 'react'
3
3
  import { Meta, Story } from '@storybook/react'
4
4
  import CdcChart from '@cdc/chart/src/CdcChart'
5
+ import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
6
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
5
7
  import comboChartConfig from './_mock/combo.json'
6
8
 
7
9
  export default {
@@ -16,3 +18,18 @@ ComboChart.args = {
16
18
  config: comboChartConfig,
17
19
  isEditor: true
18
20
  }
21
+ ComboChart.play = async ({ canvasElement }) => {
22
+ await assertVisualizationRendered(canvasElement)
23
+ }
24
+
25
+ export const ComboChartWithBrush = Template.bind({})
26
+ ComboChartWithBrush.args = {
27
+ config: editConfigKeys(comboChartConfig, [
28
+ { path: ['xAxis', 'brushActive'], value: true },
29
+ { path: ['xAxis', 'brushDefaultRecentDateCount'], value: 12 }
30
+ ]),
31
+ isEditor: true
32
+ }
33
+ ComboChartWithBrush.play = async ({ canvasElement }) => {
34
+ await assertVisualizationRendered(canvasElement)
35
+ }
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChartComponent'
3
3
  import scatterPlotCustomColorConfig from './_mock/scatterplot_mock.json'
4
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
4
5
 
5
6
  const meta: Meta<typeof Chart> = {
6
7
  title: 'Components/Templates/Chart/Custom Colors',
@@ -13,6 +14,9 @@ export const ScatterPlot: Story = {
13
14
  args: {
14
15
  config: scatterPlotCustomColorConfig,
15
16
  isEditor: false
17
+ },
18
+ play: async ({ canvasElement }) => {
19
+ await assertVisualizationRendered(canvasElement)
16
20
  }
17
21
  }
18
22
 
@@ -3,6 +3,7 @@ import DynamicSeriesBarConfig from './_mock/dynamic_series_bar_config.json'
3
3
  import DynamicSeriesSuppression from './_mock/dynamic_series_suppression_mock.json'
4
4
  import { Meta, StoryObj } from '@storybook/react-vite'
5
5
  import Chart from '../CdcChartComponent'
6
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
6
7
 
7
8
  const meta: Meta<typeof Chart> = {
8
9
  title: 'Components/Templates/Chart/Dynamic Series',
@@ -23,6 +24,9 @@ export const LineShowPoints: Story = {
23
24
  lineDatapointStyle: 'always show'
24
25
  },
25
26
  isEditor: false
27
+ },
28
+ play: async ({ canvasElement }) => {
29
+ await assertVisualizationRendered(canvasElement)
26
30
  }
27
31
  }
28
32
 
@@ -30,6 +34,9 @@ export const LineSuppression: Story = {
30
34
  args: {
31
35
  config: DynamicSeriesSuppression,
32
36
  isEditor: false
37
+ },
38
+ play: async ({ canvasElement }) => {
39
+ await assertVisualizationRendered(canvasElement)
33
40
  }
34
41
  }
35
42
 
@@ -37,6 +44,9 @@ export const LineHoverPoints: Story = {
37
44
  args: {
38
45
  config: DynamicSeriesConfig,
39
46
  isEditor: false
47
+ },
48
+ play: async ({ canvasElement }) => {
49
+ await assertVisualizationRendered(canvasElement)
40
50
  }
41
51
  }
42
52
 
@@ -44,6 +54,9 @@ export const Bar_Vertical: Story = {
44
54
  args: {
45
55
  config: DynamicSeriesBarConfig,
46
56
  isEditor: true
57
+ },
58
+ play: async ({ canvasElement }) => {
59
+ await assertVisualizationRendered(canvasElement)
47
60
  }
48
61
  }
49
62
 
@@ -51,6 +64,9 @@ export const Bar_Horizontal: Story = {
51
64
  args: {
52
65
  config: { ...DynamicSeriesBarConfig, orientation: 'horizontal' },
53
66
  isEditor: false
67
+ },
68
+ play: async ({ canvasElement }) => {
69
+ await assertVisualizationRendered(canvasElement)
54
70
  }
55
71
  }
56
72
 
@@ -62,6 +78,9 @@ export const Legend_Order: Story = {
62
78
  legend: { ...DynamicSeriesBarConfig, order: 'desc' }
63
79
  },
64
80
  isEditor: false
81
+ },
82
+ play: async ({ canvasElement }) => {
83
+ await assertVisualizationRendered(canvasElement)
65
84
  }
66
85
  }
67
86
 
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChartComponent'
3
3
  import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
4
4
  import scatterPlotDownloadImage from './_mock/scatterplot-image-download.json'
5
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
5
6
 
6
7
  const meta: Meta<typeof Chart> = {
7
8
  title: 'Components/Templates/Chart/Filters',
@@ -13,6 +14,9 @@ type Story = StoryObj<typeof Chart>
13
14
  export const Tab_Simple: Story = {
14
15
  args: {
15
16
  config: editConfigKeys(scatterPlotDownloadImage, [{ path: ['filters', '0', 'filterStyle'], value: 'tab-simple' }])
17
+ },
18
+ play: async ({ canvasElement }) => {
19
+ await assertVisualizationRendered(canvasElement)
16
20
  }
17
21
  }
18
22
 
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
 
3
3
  import Chart from '../CdcChart'
4
4
  import forecastComboWithGaps from './_mock/forecast_combo_with_gaps.json'
5
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
5
6
 
6
7
  const meta: Meta<typeof Chart> = {
7
8
  title: 'Components/Templates/Chart/Forecast Chart',
@@ -30,6 +31,9 @@ export const Forecast_Combo_With_Gaps: Story = {
30
31
  'A combo chart with forecast confidence intervals that demonstrates proper gap handling. The forecast areas and lines are split into separate segments when gaps are detected, preventing misleading connections across missing data periods. Invalid data points (NA values) are automatically filtered out.'
31
32
  }
32
33
  }
34
+ },
35
+ play: async ({ canvasElement }) => {
36
+ await assertVisualizationRendered(canvasElement)
33
37
  }
34
38
  }
35
39
 
@@ -1,5 +1,6 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import CdcChart from '../CdcChartComponent'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
4
 
4
5
  const meta: Meta<typeof CdcChart> = {
5
6
  title: 'Components/Templates/Chart/HTML in Data Table',
@@ -148,6 +149,9 @@ export const BasicHTMLInFootnoteColumn: Story = {
148
149
  }
149
150
  },
150
151
  isEditor: true
152
+ },
153
+ play: async ({ canvasElement }) => {
154
+ await assertVisualizationRendered(canvasElement)
151
155
  }
152
156
  }
153
157
 
@@ -208,6 +212,9 @@ export const HTMLWithLinksAndFormatting: Story = {
208
212
  }
209
213
  },
210
214
  isEditor: true
215
+ },
216
+ play: async ({ canvasElement }) => {
217
+ await assertVisualizationRendered(canvasElement)
211
218
  }
212
219
  }
213
220
 
@@ -265,6 +272,9 @@ export const HTMLWithLineBreaks: Story = {
265
272
  }
266
273
  },
267
274
  isEditor: true
275
+ },
276
+ play: async ({ canvasElement }) => {
277
+ await assertVisualizationRendered(canvasElement)
268
278
  }
269
279
  }
270
280
 
@@ -315,6 +325,9 @@ export const ComplexHTMLWithLists: Story = {
315
325
  }
316
326
  },
317
327
  isEditor: true
328
+ },
329
+ play: async ({ canvasElement }) => {
330
+ await assertVisualizationRendered(canvasElement)
318
331
  }
319
332
  }
320
333
 
@@ -368,6 +381,9 @@ export const HTMLWithInlineStyles: Story = {
368
381
  }
369
382
  },
370
383
  isEditor: true
384
+ },
385
+ play: async ({ canvasElement }) => {
386
+ await assertVisualizationRendered(canvasElement)
371
387
  }
372
388
  }
373
389
 
@@ -444,6 +460,9 @@ export const LineChartWithHTMLFootnotes: Story = {
444
460
  }
445
461
  },
446
462
  isEditor: true
463
+ },
464
+ play: async ({ canvasElement }) => {
465
+ await assertVisualizationRendered(canvasElement)
447
466
  }
448
467
  }
449
468
 
@@ -516,5 +535,8 @@ export const PieChartWithHTMLFootnotes: Story = {
516
535
  }
517
536
  },
518
537
  isEditor: true
538
+ },
539
+ play: async ({ canvasElement }) => {
540
+ await assertVisualizationRendered(canvasElement)
519
541
  }
520
542
  }
@@ -5,6 +5,7 @@ import SimplifiedLineConfig from './_mock/simplified_line.json'
5
5
 
6
6
  import Chart from '../CdcChartComponent'
7
7
  import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
8
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
8
9
 
9
10
  const meta: Meta<typeof Chart> = {
10
11
  title: 'Components/Templates/Chart/Legend',
@@ -16,41 +17,62 @@ type Story = StoryObj<typeof Chart>
16
17
  export const Legend_Gradient_Smooth: Story = {
17
18
  args: {
18
19
  config: chartGradientConfig
20
+ },
21
+ play: async ({ canvasElement }) => {
22
+ await assertVisualizationRendered(canvasElement)
19
23
  }
20
24
  }
21
25
  export const Legend_Group_By: Story = {
22
26
  args: {
23
27
  config: chartGroupedLagend
28
+ },
29
+ play: async ({ canvasElement }) => {
30
+ await assertVisualizationRendered(canvasElement)
24
31
  }
25
32
  }
26
33
 
27
34
  export const Legend_Gradient_Linear_Blocks: Story = {
28
35
  args: {
29
36
  config: editConfigKeys(chartGradientConfig, [{ path: ['legend', 'subStyle'], value: 'linear blocks' }])
37
+ },
38
+ play: async ({ canvasElement }) => {
39
+ await assertVisualizationRendered(canvasElement)
30
40
  }
31
41
  }
32
42
 
33
43
  export const Labels_On_Line_Legend_On_Top: Story = {
34
44
  args: {
35
45
  config: editConfigKeys(chartGradientConfig, [{ path: ['yAxis', 'labelsAboveGridlines'], value: true }])
46
+ },
47
+ play: async ({ canvasElement }) => {
48
+ await assertVisualizationRendered(canvasElement)
36
49
  }
37
50
  }
38
51
 
39
52
  export const Legend_On_Right: Story = {
40
53
  args: {
41
54
  config: SimplifiedLineConfig
55
+ },
56
+ play: async ({ canvasElement }) => {
57
+ await assertVisualizationRendered(canvasElement)
42
58
  }
43
59
  }
44
60
 
45
61
  export const Legend_On_Right_With_Box: Story = {
46
62
  args: {
47
63
  config: editConfigKeys(SimplifiedLineConfig, [{ path: ['legend', 'hideBorder'], value: false }])
64
+ },
65
+ play: async ({ canvasElement }) => {
66
+ await assertVisualizationRendered(canvasElement)
48
67
  }
49
68
  }
50
69
 
51
70
  export const Legend_Gradient_With_box: Story = {
52
71
  args: {
53
72
  config: editConfigKeys(chartGradientConfig, [{ path: ['legend', 'hideBorder'], value: false }])
73
+ },
74
+ play: async ({ canvasElement }) => {
75
+ await assertVisualizationRendered(canvasElement)
54
76
  }
55
77
  }
56
78
 
@@ -61,6 +83,9 @@ export const Legend_Gradient_With_Text: Story = {
61
83
  { path: ['legend', 'description'], value: 'Description' },
62
84
  { path: ['legend', 'hideBorder'], value: false }
63
85
  ])
86
+ },
87
+ play: async ({ canvasElement }) => {
88
+ await assertVisualizationRendered(canvasElement)
64
89
  }
65
90
  }
66
91
  export const Legend_Gradient_Wrapping_Label: Story = {
@@ -74,6 +99,9 @@ export const Legend_Gradient_Wrapping_Label: Story = {
74
99
  ])
75
100
  ).replace(/Data 1/g, 'This is a long string that should wrap')
76
101
  )
102
+ },
103
+ play: async ({ canvasElement }) => {
104
+ await assertVisualizationRendered(canvasElement)
77
105
  }
78
106
  }
79
107
 
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react'
2
2
  import StackedPattern from './_mock/stacked-pattern-test.json'
3
3
 
4
4
  import Chart from '../CdcChartComponent'
5
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
5
6
 
6
7
  const meta: Meta<typeof Chart> = {
7
8
  title: 'Components/Templates/Chart/Patterns',
@@ -14,6 +15,9 @@ export const Stacked_Bar_Pattern: Story = {
14
15
  args: {
15
16
  config: StackedPattern,
16
17
  isEditor: true
18
+ },
19
+ play: async ({ canvasElement }) => {
20
+ await assertVisualizationRendered(canvasElement)
17
21
  }
18
22
  }
19
23
 
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChartComponent'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
4
 
4
5
  const meta: Meta<typeof Chart> = {
5
6
  title: 'Components/Templates/Chart/Preserve Original Decimals',
@@ -56,6 +57,9 @@ export const Default_With_Forced_Rounding: Story = {
56
57
  'Default behavior forces all numbers to 1 decimal place. Notice how whole numbers like 1000 become "1,000.0" and 89.23 gets rounded to "89.2".'
57
58
  }
58
59
  }
60
+ },
61
+ play: async ({ canvasElement }) => {
62
+ await assertVisualizationRendered(canvasElement)
59
63
  }
60
64
  }
61
65
 
@@ -77,6 +81,9 @@ export const Preserve_Original_Decimals_Enabled: Story = {
77
81
  'With "Preserve Original Decimals" enabled, numbers display exactly as they appear in the data: 1000 shows as "1,000", 45.7 shows as "45.7", and 89.23 shows as "89.23". The roundTo setting is ignored.'
78
82
  }
79
83
  }
84
+ },
85
+ play: async ({ canvasElement }) => {
86
+ await assertVisualizationRendered(canvasElement)
80
87
  }
81
88
  }
82
89
 
@@ -97,6 +104,9 @@ export const Comparison_No_Decimals: Story = {
97
104
  'Forcing 0 decimal places rounds everything to whole numbers: 45.7 becomes "46", 89.23 becomes "89". This loses precision from the original data.'
98
105
  }
99
106
  }
107
+ },
108
+ play: async ({ canvasElement }) => {
109
+ await assertVisualizationRendered(canvasElement)
100
110
  }
101
111
  }
102
112
 
@@ -117,6 +127,9 @@ export const Comparison_Two_Decimals: Story = {
117
127
  'Forcing 2 decimal places adds unnecessary zeros: 1000 becomes "1,000.00", 45.7 becomes "45.70". This can look cluttered for whole numbers.'
118
128
  }
119
129
  }
130
+ },
131
+ play: async ({ canvasElement }) => {
132
+ await assertVisualizationRendered(canvasElement)
120
133
  }
121
134
  }
122
135
 
@@ -139,6 +152,9 @@ export const With_Prefix_And_Suffix: Story = {
139
152
  'Preserve Original Decimals works seamlessly with prefix and suffix formatting. Numbers show as "$1,000 USD", "$45.7 USD", etc.'
140
153
  }
141
154
  }
155
+ },
156
+ play: async ({ canvasElement }) => {
157
+ await assertVisualizationRendered(canvasElement)
142
158
  }
143
159
  }
144
160
 
@@ -167,6 +183,9 @@ export const Percentage_Data_Mixed_Precision: Story = {
167
183
  'Perfect for percentage data where some values are whole (25%, 50%) and others need decimals (33.3%, 12.75%). Each value displays naturally without forced rounding.'
168
184
  }
169
185
  }
186
+ },
187
+ play: async ({ canvasElement }) => {
188
+ await assertVisualizationRendered(canvasElement)
170
189
  }
171
190
  }
172
191
 
@@ -193,6 +212,9 @@ export const Line_Chart_With_Table: Story = {
193
212
  'When enabled, the preserve decimals setting applies to both the chart axis/tooltips AND the data table, ensuring consistency across all displays.'
194
213
  }
195
214
  }
215
+ },
216
+ play: async ({ canvasElement }) => {
217
+ await assertVisualizationRendered(canvasElement)
196
218
  }
197
219
  }
198
220
 
@@ -214,6 +236,9 @@ export const Editor_Mode: Story = {
214
236
  'In editor mode, look for the "Preserve Original Decimal Places" checkbox in the Number Formatting section, right below the "Round to decimal point" field. Toggle it to see the effect in real-time.'
215
237
  }
216
238
  }
239
+ },
240
+ play: async ({ canvasElement }) => {
241
+ await assertVisualizationRendered(canvasElement)
217
242
  }
218
243
  }
219
244
 
@@ -0,0 +1,161 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import Chart from '../CdcChart'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
4
+
5
+ const meta: Meta<typeof Chart> = {
6
+ title: 'Components/Templates/Chart/Regions/Categorical',
7
+ component: Chart
8
+ }
9
+
10
+ type Story = StoryObj<typeof Chart>
11
+
12
+ const categoricalData = [
13
+ { category: 'Jan 1', value: 10 },
14
+ { category: 'Jan 8', value: 25 },
15
+ { category: 'Jan 15', value: 35 },
16
+ { category: 'Jan 22', value: 45 },
17
+ { category: 'Jan 29', value: 55 },
18
+ { category: 'Feb 5', value: 40 },
19
+ { category: 'Feb 12', value: 60 },
20
+ { category: 'Feb 19', value: 75 },
21
+ { category: 'Feb 26', value: 65 },
22
+ { category: 'Mar 4', value: 80 }
23
+ ]
24
+
25
+ const baseCategoricalConfig = {
26
+ type: 'chart',
27
+ visualizationType: 'Line',
28
+ orientation: 'vertical',
29
+ showTitle: true,
30
+ theme: 'theme-blue',
31
+ animate: false,
32
+ xAxis: {
33
+ type: 'categorical',
34
+ dataKey: 'category',
35
+ size: '0',
36
+ hideAxis: false,
37
+ hideTicks: false
38
+ },
39
+ yAxis: {
40
+ size: '50',
41
+ hideAxis: false,
42
+ hideTicks: false,
43
+ gridLines: true,
44
+ min: '0',
45
+ max: '100'
46
+ },
47
+ series: [{ dataKey: 'value', type: 'Line', axis: 'Left', tooltip: true, name: 'Value' }],
48
+ legend: { hide: true },
49
+ data: categoricalData,
50
+ regions: []
51
+ }
52
+
53
+ // LINE CHARTS
54
+
55
+ export const Line_Fixed_From_Fixed_To: Story = {
56
+ args: {
57
+ config: {
58
+ ...baseCategoricalConfig,
59
+ title: 'Categorical - Line: Fixed From + Fixed To',
60
+ regions: [
61
+ {
62
+ from: 'Jan 15',
63
+ to: 'Feb 12',
64
+ fromType: 'Fixed',
65
+ toType: 'Fixed',
66
+ label: 'Fixed Region',
67
+ background: '#0077cc',
68
+ color: '#000000',
69
+ range: 'Custom'
70
+ }
71
+ ]
72
+ },
73
+ isEditor: true
74
+ },
75
+ play: async ({ canvasElement }) => {
76
+ await assertVisualizationRendered(canvasElement)
77
+ }
78
+ }
79
+
80
+ export const Line_Fixed_From_Last_Date: Story = {
81
+ args: {
82
+ config: {
83
+ ...baseCategoricalConfig,
84
+ title: 'Categorical - Line: Fixed From + Last Date',
85
+ regions: [
86
+ {
87
+ from: 'Feb 5',
88
+ to: '',
89
+ fromType: 'Fixed',
90
+ toType: 'Last Date',
91
+ label: 'To Last Date',
92
+ background: '#00aa55',
93
+ color: '#000000',
94
+ range: 'Custom'
95
+ }
96
+ ]
97
+ },
98
+ isEditor: true
99
+ },
100
+ play: async ({ canvasElement }) => {
101
+ await assertVisualizationRendered(canvasElement)
102
+ }
103
+ }
104
+
105
+ // BAR CHARTS
106
+
107
+ export const Bar_Fixed_From_Fixed_To: Story = {
108
+ args: {
109
+ config: {
110
+ ...baseCategoricalConfig,
111
+ visualizationType: 'Bar',
112
+ barThickness: 0.7,
113
+ title: 'Categorical - Bar: Fixed From + Fixed To',
114
+ regions: [
115
+ {
116
+ from: 'Jan 15',
117
+ to: 'Feb 12',
118
+ fromType: 'Fixed',
119
+ toType: 'Fixed',
120
+ label: 'Fixed Region',
121
+ background: '#0077cc',
122
+ color: '#000000',
123
+ range: 'Custom'
124
+ }
125
+ ]
126
+ },
127
+ isEditor: true
128
+ },
129
+ play: async ({ canvasElement }) => {
130
+ await assertVisualizationRendered(canvasElement)
131
+ }
132
+ }
133
+
134
+ export const Bar_Fixed_From_Last_Date: Story = {
135
+ args: {
136
+ config: {
137
+ ...baseCategoricalConfig,
138
+ visualizationType: 'Bar',
139
+ barThickness: 0.7,
140
+ title: 'Categorical - Bar: Fixed From + Last Date',
141
+ regions: [
142
+ {
143
+ from: 'Feb 5',
144
+ to: '',
145
+ fromType: 'Fixed',
146
+ toType: 'Last Date',
147
+ label: 'To Last Date',
148
+ background: '#00aa55',
149
+ color: '#000000',
150
+ range: 'Custom'
151
+ }
152
+ ]
153
+ },
154
+ isEditor: true
155
+ },
156
+ play: async ({ canvasElement }) => {
157
+ await assertVisualizationRendered(canvasElement)
158
+ }
159
+ }
160
+
161
+ export default meta