@cdc/chart 4.26.1 → 4.26.3

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 (173) hide show
  1. package/CLAUDE.local.md +79 -0
  2. package/LICENSE +201 -0
  3. package/dist/{cdcchart-dgT_1dIT.es.js → cdcchart-DQ00cQCm.es.js} +1 -20
  4. package/dist/cdcchart.js +54742 -49796
  5. package/examples/data/data-with-metadata.json +10 -0
  6. package/examples/default.json +378 -0
  7. package/examples/feature/__data__/horizon-chart-data.json +373 -0
  8. package/examples/feature/annotations/index.json +3 -6
  9. package/examples/feature/horizon/horizon-chart.json +395 -0
  10. package/examples/feature/pie/planet-pie-example-config.json +2 -1
  11. package/examples/line-chart-states.json +1085 -0
  12. package/examples/metadata-variables.json +58 -0
  13. package/examples/private/123.json +694 -0
  14. package/examples/private/anchor-issue.json +4094 -0
  15. package/examples/private/backwards-slider.json +10430 -0
  16. package/examples/private/georgia.csv +160 -0
  17. package/examples/private/timeline-data.json +1 -0
  18. package/examples/private/timeline.json +389 -0
  19. package/examples/radar-chart-simple.json +133 -0
  20. package/examples/radar-chart.json +148 -0
  21. package/index.html +1 -31
  22. package/package.json +57 -59
  23. package/src/CdcChart.tsx +8 -4
  24. package/src/CdcChartComponent.tsx +398 -284
  25. package/src/_stories/Chart.Anchors.stories.tsx +10 -0
  26. package/src/_stories/Chart.BoxPlot.stories.tsx +7 -0
  27. package/src/_stories/Chart.CI.stories.tsx +13 -0
  28. package/src/_stories/Chart.Combo.stories.tsx +17 -0
  29. package/src/_stories/Chart.CustomColors.stories.tsx +78 -0
  30. package/src/_stories/Chart.Defaults.stories.tsx +95 -0
  31. package/src/_stories/Chart.DynamicSeries.stories.tsx +19 -0
  32. package/src/_stories/Chart.Filters.stories.tsx +4 -0
  33. package/src/_stories/Chart.Forecast.stories.tsx +4 -0
  34. package/src/_stories/Chart.HTMLInDataTable.stories.tsx +22 -0
  35. package/src/_stories/Chart.Legend.Gradient.stories.tsx +28 -0
  36. package/src/_stories/Chart.Patterns.stories.tsx +4 -0
  37. package/src/_stories/Chart.PreserveDecimals.stories.tsx +25 -0
  38. package/src/_stories/Chart.Regions.Categorical.stories.tsx +13 -0
  39. package/src/_stories/Chart.Regions.DateScale.stories.tsx +19 -0
  40. package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +25 -10
  41. package/src/_stories/Chart.ScatterPlot.stories.tsx +4 -0
  42. package/src/_stories/Chart.SmallMultiples.stories.tsx +16 -0
  43. package/src/_stories/Chart.SmallestLeftAxisMax.stories.tsx +64 -0
  44. package/src/_stories/Chart.stories.tsx +72 -1
  45. package/src/_stories/Chart.tooltip.stories.tsx +7 -0
  46. package/src/_stories/ChartAnnotation.stories.tsx +10 -0
  47. package/src/_stories/ChartAxisLabels.stories.tsx +4 -0
  48. package/src/_stories/ChartAxisTitles.stories.tsx +10 -0
  49. package/src/_stories/ChartBar.Editor.stories.tsx +97 -38
  50. package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
  51. package/src/_stories/ChartBrush.Matrix.Continuous.stories.tsx +41 -0
  52. package/src/_stories/ChartBrush.Matrix.Date.stories.tsx +114 -0
  53. package/src/_stories/ChartBrush.Matrix.DateTime.stories.tsx +78 -0
  54. package/src/_stories/ChartBrush.stories.tsx +7 -0
  55. package/src/_stories/ChartEditor.Editor.stories.tsx +1 -1
  56. package/src/_stories/ChartEditor.stories.tsx +7 -0
  57. package/src/_stories/ChartLine.QuadrantAngles.stories.tsx +89 -0
  58. package/src/_stories/ChartLine.Suppression.stories.tsx +7 -0
  59. package/src/_stories/ChartLine.Symbols.stories.tsx +4 -0
  60. package/src/_stories/ChartPrefixSuffix.stories.tsx +46 -1
  61. package/src/_stories/TechAdoptionWithLinks.stories.tsx +7 -0
  62. package/src/_stories/_mock/brush_continuous.json +86 -0
  63. package/src/_stories/_mock/brush_date_large.json +176 -0
  64. package/src/_stories/_mock/line_chart_angle_near_zero_fall.json +195 -0
  65. package/src/_stories/_mock/line_chart_angle_near_zero_rise.json +195 -0
  66. package/src/_stories/_mock/line_chart_angle_q1_steep_upward.json +195 -0
  67. package/src/_stories/_mock/line_chart_angle_q2_gentle_downward.json +195 -0
  68. package/src/_stories/_mock/line_chart_angle_q3_steep_downward.json +195 -0
  69. package/src/_stories/_mock/line_chart_angle_q4_gentle_upward.json +195 -0
  70. package/src/_stories/_mock/line_chart_quadrant_angles.json +264 -0
  71. package/src/_stories/_mock/paired-bar-abbr.json +421 -0
  72. package/src/_stories/_mock/pie_custom_colors.json +268 -0
  73. package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
  74. package/src/components/Annotations/components/AnnotationDraggable.styles.css +14 -20
  75. package/src/components/Annotations/components/AnnotationDraggable.tsx +240 -116
  76. package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -2
  77. package/src/components/Annotations/components/AnnotationDropdown.tsx +8 -12
  78. package/src/components/Annotations/components/AnnotationList.styles.css +12 -18
  79. package/src/components/Annotations/components/AnnotationList.tsx +5 -4
  80. package/src/components/Annotations/components/findNearestDatum.ts +75 -85
  81. package/src/components/Annotations/helpers/getVisibleAnnotations.ts +38 -0
  82. package/src/components/Axis/BottomAxis.tsx +277 -0
  83. package/src/components/Axis/LeftAxis.tsx +404 -0
  84. package/src/components/Axis/LeftAxisGridlines.tsx +77 -0
  85. package/src/components/Axis/PairedBarAxis.tsx +192 -0
  86. package/src/components/Axis/README.md +94 -0
  87. package/src/components/Axis/RightAxis.tsx +108 -0
  88. package/src/components/Axis/axis.constants.ts +21 -0
  89. package/src/components/Axis/index.ts +7 -0
  90. package/src/components/BarChart/components/BarChart.Horizontal.tsx +12 -28
  91. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +12 -30
  92. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +12 -31
  93. package/src/components/BarChart/components/BarChart.Vertical.tsx +12 -28
  94. package/src/components/BarChart/components/BarChart.tsx +7 -1
  95. package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
  96. package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
  97. package/src/components/BarChart/helpers/useBarChart.ts +3 -0
  98. package/src/components/Brush/BrushSelector.tsx +155 -22
  99. package/src/components/Brush/MiniChartPreview.tsx +133 -21
  100. package/src/components/EditorPanel/EditorPanel.tsx +81 -54
  101. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +67 -29
  102. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
  103. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +120 -2
  104. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +25 -43
  105. package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +353 -0
  106. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +83 -3
  107. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +66 -43
  108. package/src/components/EditorPanel/components/Panels/index.tsx +2 -0
  109. package/src/components/EditorPanel/editor-panel.scss +1 -1
  110. package/src/components/EditorPanel/useEditorPermissions.ts +55 -26
  111. package/src/components/ForestPlot/ForestPlot.tsx +26 -22
  112. package/src/components/HorizonChart/HorizonChart.tsx +131 -0
  113. package/src/components/HorizonChart/components/HorizonBand.tsx +160 -0
  114. package/src/components/HorizonChart/helpers/calculateHorizonBands.ts +27 -0
  115. package/src/components/HorizonChart/helpers/getHorizonLayerColors.ts +40 -0
  116. package/src/components/HorizonChart/index.tsx +3 -0
  117. package/src/components/Legend/Legend.Component.tsx +52 -4
  118. package/src/components/Legend/Legend.tsx +1 -1
  119. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +4 -4
  120. package/src/components/Legend/LegendValueRange.tsx +77 -0
  121. package/src/components/Legend/helpers/createFormatLabels.tsx +16 -2
  122. package/src/components/Legend/helpers/generateValueRanges.ts +92 -0
  123. package/src/components/LineChart/helpers/README.md +292 -0
  124. package/src/components/LineChart/helpers/labelPositioning.test.ts +245 -0
  125. package/src/components/LineChart/helpers/labelPositioning.ts +304 -0
  126. package/src/components/LineChart/index.tsx +44 -8
  127. package/src/components/LinearChart/README.md +109 -0
  128. package/src/components/LinearChart/VisualizationRenderer.tsx +267 -0
  129. package/src/components/LinearChart/linearChart.constants.ts +84 -0
  130. package/src/components/LinearChart/tests/LinearChart.test.tsx +278 -0
  131. package/src/components/LinearChart/tests/mockConfigContext.ts +131 -0
  132. package/src/components/LinearChart/utils/tickFormatting.ts +146 -0
  133. package/src/components/LinearChart.tsx +268 -1057
  134. package/src/components/PieChart/PieChart.tsx +20 -5
  135. package/src/components/RadarChart/RadarAxis.tsx +78 -0
  136. package/src/components/RadarChart/RadarChart.tsx +298 -0
  137. package/src/components/RadarChart/RadarGrid.tsx +64 -0
  138. package/src/components/RadarChart/RadarPolygon.tsx +91 -0
  139. package/src/components/RadarChart/helpers.ts +83 -0
  140. package/src/components/RadarChart/index.tsx +3 -0
  141. package/src/components/Regions/components/Regions.tsx +6 -6
  142. package/src/components/Sankey/components/Sankey.tsx +3 -3
  143. package/src/components/Sankey/sankey.scss +1 -1
  144. package/src/components/SmallMultiples/SmallMultiples.css +5 -5
  145. package/src/components/Sparkline/index.scss +4 -2
  146. package/src/components/WarmingStripes/WarmingStripes.tsx +95 -25
  147. package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
  148. package/src/data/initial-state.js +37 -15
  149. package/src/data/legacy-defaults.ts +18 -0
  150. package/src/helpers/abbreviateNumber.ts +24 -17
  151. package/src/helpers/getChartPatternId.ts +17 -0
  152. package/src/helpers/getExcludedData.ts +4 -0
  153. package/src/helpers/getMinMax.ts +16 -2
  154. package/src/helpers/handleChartAriaLabels.ts +19 -19
  155. package/src/helpers/handleLineType.ts +22 -18
  156. package/src/helpers/seriesColumnSettings.ts +114 -0
  157. package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
  158. package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
  159. package/src/hooks/useProgrammaticTooltip.ts +23 -2
  160. package/src/hooks/useRightAxis.ts +14 -0
  161. package/src/hooks/useScales.ts +99 -56
  162. package/src/hooks/useTooltip.tsx +23 -3
  163. package/src/scss/main.scss +157 -79
  164. package/src/selectors/README.md +68 -0
  165. package/src/store/chart.reducer.ts +2 -0
  166. package/src/test/CdcChart.test.jsx +2 -2
  167. package/src/types/ChartConfig.ts +22 -0
  168. package/src/types/ChartContext.ts +1 -0
  169. package/src/types/Horizon.ts +64 -0
  170. package/tests/fixtures/chart-config-with-metadata.json +29 -0
  171. package/tests/fixtures/data-with-metadata.json +10 -0
  172. package/preview.html +0 -1616
  173. package/src/components/Annotations/components/helpers/index.tsx +0 -46
@@ -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
 
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChart'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
4
 
4
5
  const meta: Meta<typeof Chart> = {
5
6
  title: 'Components/Templates/Chart/Regions/Categorical',
@@ -70,6 +71,9 @@ export const Line_Fixed_From_Fixed_To: Story = {
70
71
  ]
71
72
  },
72
73
  isEditor: true
74
+ },
75
+ play: async ({ canvasElement }) => {
76
+ await assertVisualizationRendered(canvasElement)
73
77
  }
74
78
  }
75
79
 
@@ -92,6 +96,9 @@ export const Line_Fixed_From_Last_Date: Story = {
92
96
  ]
93
97
  },
94
98
  isEditor: true
99
+ },
100
+ play: async ({ canvasElement }) => {
101
+ await assertVisualizationRendered(canvasElement)
95
102
  }
96
103
  }
97
104
 
@@ -118,6 +125,9 @@ export const Bar_Fixed_From_Fixed_To: Story = {
118
125
  ]
119
126
  },
120
127
  isEditor: true
128
+ },
129
+ play: async ({ canvasElement }) => {
130
+ await assertVisualizationRendered(canvasElement)
121
131
  }
122
132
  }
123
133
 
@@ -142,6 +152,9 @@ export const Bar_Fixed_From_Last_Date: Story = {
142
152
  ]
143
153
  },
144
154
  isEditor: true
155
+ },
156
+ play: async ({ canvasElement }) => {
157
+ await assertVisualizationRendered(canvasElement)
145
158
  }
146
159
  }
147
160
 
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChart'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
4
 
4
5
  const meta: Meta<typeof Chart> = {
5
6
  title: 'Components/Templates/Chart/Regions/Date Scale (Band)',
@@ -73,6 +74,9 @@ export const Line_Fixed_From_Fixed_To: Story = {
73
74
  ]
74
75
  },
75
76
  isEditor: true
77
+ },
78
+ play: async ({ canvasElement }) => {
79
+ await assertVisualizationRendered(canvasElement)
76
80
  }
77
81
  }
78
82
 
@@ -95,6 +99,9 @@ export const Line_Fixed_From_Last_Date: Story = {
95
99
  ]
96
100
  },
97
101
  isEditor: true
102
+ },
103
+ play: async ({ canvasElement }) => {
104
+ await assertVisualizationRendered(canvasElement)
98
105
  }
99
106
  }
100
107
 
@@ -117,6 +124,9 @@ export const Line_Previous_Days_Last_Date: Story = {
117
124
  ]
118
125
  },
119
126
  isEditor: true
127
+ },
128
+ play: async ({ canvasElement }) => {
129
+ await assertVisualizationRendered(canvasElement)
120
130
  }
121
131
  }
122
132
 
@@ -143,6 +153,9 @@ export const Bar_Fixed_From_Fixed_To: Story = {
143
153
  ]
144
154
  },
145
155
  isEditor: true
156
+ },
157
+ play: async ({ canvasElement }) => {
158
+ await assertVisualizationRendered(canvasElement)
146
159
  }
147
160
  }
148
161
 
@@ -167,6 +180,9 @@ export const Bar_Fixed_From_Last_Date: Story = {
167
180
  ]
168
181
  },
169
182
  isEditor: true
183
+ },
184
+ play: async ({ canvasElement }) => {
185
+ await assertVisualizationRendered(canvasElement)
170
186
  }
171
187
  }
172
188
 
@@ -191,6 +207,9 @@ export const Bar_Previous_Days_Last_Date: Story = {
191
207
  ]
192
208
  },
193
209
  isEditor: true
210
+ },
211
+ play: async ({ canvasElement }) => {
212
+ await assertVisualizationRendered(canvasElement)
194
213
  }
195
214
  }
196
215
 
@@ -1,5 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChart'
3
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
3
4
 
4
5
  const meta: Meta<typeof Chart> = {
5
6
  title: 'Components/Templates/Chart/Regions/Date-Time Scale (Continuous)',
@@ -52,6 +53,10 @@ const baseDateTimeConfig = {
52
53
  regions: []
53
54
  }
54
55
 
56
+ const play = async ({ canvasElement }) => {
57
+ await assertVisualizationRendered(canvasElement)
58
+ }
59
+
55
60
  // LINE CHARTS
56
61
 
57
62
  export const Line_Fixed_From_Fixed_To: Story = {
@@ -73,7 +78,8 @@ export const Line_Fixed_From_Fixed_To: Story = {
73
78
  ]
74
79
  },
75
80
  isEditor: true
76
- }
81
+ },
82
+ play
77
83
  }
78
84
 
79
85
  export const Line_Fixed_From_Last_Date: Story = {
@@ -95,7 +101,8 @@ export const Line_Fixed_From_Last_Date: Story = {
95
101
  ]
96
102
  },
97
103
  isEditor: true
98
- }
104
+ },
105
+ play
99
106
  }
100
107
 
101
108
  export const Line_Previous_Days_Last_Date: Story = {
@@ -117,7 +124,8 @@ export const Line_Previous_Days_Last_Date: Story = {
117
124
  ]
118
125
  },
119
126
  isEditor: true
120
- }
127
+ },
128
+ play
121
129
  }
122
130
 
123
131
  // BAR CHARTS
@@ -143,7 +151,8 @@ export const Bar_Fixed_From_Fixed_To: Story = {
143
151
  ]
144
152
  },
145
153
  isEditor: true
146
- }
154
+ },
155
+ play
147
156
  }
148
157
 
149
158
  export const Bar_Fixed_From_Last_Date: Story = {
@@ -167,7 +176,8 @@ export const Bar_Fixed_From_Last_Date: Story = {
167
176
  ]
168
177
  },
169
178
  isEditor: true
170
- }
179
+ },
180
+ play
171
181
  }
172
182
 
173
183
  export const Bar_Previous_Days_Last_Date: Story = {
@@ -191,7 +201,8 @@ export const Bar_Previous_Days_Last_Date: Story = {
191
201
  ]
192
202
  },
193
203
  isEditor: true
194
- }
204
+ },
205
+ play
195
206
  }
196
207
 
197
208
  // EDGE CASES
@@ -215,7 +226,8 @@ export const Edge_Region_At_Start: Story = {
215
226
  ]
216
227
  },
217
228
  isEditor: true
218
- }
229
+ },
230
+ play
219
231
  }
220
232
 
221
233
  export const Edge_Region_At_End: Story = {
@@ -237,7 +249,8 @@ export const Edge_Region_At_End: Story = {
237
249
  ]
238
250
  },
239
251
  isEditor: true
240
- }
252
+ },
253
+ play
241
254
  }
242
255
 
243
256
  export const Edge_Full_Coverage: Story = {
@@ -259,7 +272,8 @@ export const Edge_Full_Coverage: Story = {
259
272
  ]
260
273
  },
261
274
  isEditor: true
262
- }
275
+ },
276
+ play
263
277
  }
264
278
 
265
279
  export const Multiple_Regions: Story = {
@@ -291,7 +305,8 @@ export const Multiple_Regions: Story = {
291
305
  ]
292
306
  },
293
307
  isEditor: true
294
- }
308
+ },
309
+ play
295
310
  }
296
311
 
297
312
  export default meta
@@ -1,6 +1,7 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  import Chart from '../CdcChartComponent'
3
3
  import scatterPlotDownloadImage from './_mock/scatterplot-image-download.json'
4
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
4
5
 
5
6
  const meta: Meta<typeof Chart> = {
6
7
  title: 'Components/Templates/Chart/Scatter Plot Download Image',
@@ -13,6 +14,9 @@ export const ScatterPlot_Download_Image: Story = {
13
14
  args: {
14
15
  config: scatterPlotDownloadImage,
15
16
  isEditor: false
17
+ },
18
+ play: async ({ canvasElement }) => {
19
+ await assertVisualizationRendered(canvasElement)
16
20
  }
17
21
  }
18
22
 
@@ -5,6 +5,7 @@ import smallMultiplesBigDataBars from './_mock/small_multiples/small_multiples_b
5
5
  import smallMultiplesLinesColors from './_mock/small_multiples/small_multiples_lines_colors.json'
6
6
  import smallMultiplesLines from './_mock/small_multiples/small_multiples_lines.json'
7
7
  import smallMultiplesStackedBars from './_mock/small_multiples/small_multiples_stacked_bars.json'
8
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
8
9
 
9
10
  const meta: Meta<typeof Chart> = {
10
11
  title: 'Components/Templates/Chart/Small Multiples',
@@ -17,6 +18,9 @@ export const smallMultiples_Bars: Story = {
17
18
  args: {
18
19
  config: smallMultiplesBars,
19
20
  isEditor: false
21
+ },
22
+ play: async ({ canvasElement }) => {
23
+ await assertVisualizationRendered(canvasElement)
20
24
  }
21
25
  }
22
26
 
@@ -24,24 +28,36 @@ export const smallMultiples_BigDataBars: Story = {
24
28
  args: {
25
29
  config: smallMultiplesBigDataBars,
26
30
  isEditor: false
31
+ },
32
+ play: async ({ canvasElement }) => {
33
+ await assertVisualizationRendered(canvasElement)
27
34
  }
28
35
  }
29
36
  export const smallMultiples_LinesColors: Story = {
30
37
  args: {
31
38
  config: smallMultiplesLinesColors,
32
39
  isEditor: false
40
+ },
41
+ play: async ({ canvasElement }) => {
42
+ await assertVisualizationRendered(canvasElement)
33
43
  }
34
44
  }
35
45
  export const smallMultiples_Lines: Story = {
36
46
  args: {
37
47
  config: smallMultiplesLines,
38
48
  isEditor: false
49
+ },
50
+ play: async ({ canvasElement }) => {
51
+ await assertVisualizationRendered(canvasElement)
39
52
  }
40
53
  }
41
54
  export const smallMultiples_StackedBars: Story = {
42
55
  args: {
43
56
  config: smallMultiplesStackedBars,
44
57
  isEditor: false
58
+ },
59
+ play: async ({ canvasElement }) => {
60
+ await assertVisualizationRendered(canvasElement)
45
61
  }
46
62
  }
47
63
  export default meta
@@ -0,0 +1,64 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import Chart from '../CdcChartComponent'
3
+ import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
4
+ import smallestLeftAxisMaxConfig from './_mock/smallest_left_axis_max.json'
5
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
6
+
7
+ const meta: Meta<typeof Chart> = {
8
+ title: 'Components/Templates/Chart/Smallest Left Axis Maximum',
9
+ component: Chart
10
+ }
11
+
12
+ type Story = StoryObj<typeof Chart>
13
+
14
+ /**
15
+ * Region B is the default filter — data only goes up to 1.
16
+ * Without smallestLeftAxisMax, the Y axis would show decimal ticks (0, 0.2, 0.4…).
17
+ * With smallestLeftAxisMax: 5, the axis extends to at least 5, producing clean integer ticks.
18
+ */
19
+ export const WithSmallestLeftAxisMax: Story = {
20
+ args: {
21
+ config: smallestLeftAxisMaxConfig
22
+ },
23
+ play: async ({ canvasElement }) => {
24
+ await assertVisualizationRendered(canvasElement)
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Same chart without the smallestLeftAxisMax setting.
30
+ * Region B data (max 1) causes decimal ticks on the Y axis — the problem this feature solves.
31
+ */
32
+ export const WithoutSmallestLeftAxisMax: Story = {
33
+ args: {
34
+ config: editConfigKeys(smallestLeftAxisMaxConfig, [{ path: ['yAxis', 'smallestLeftAxisMax'], value: undefined }])
35
+ },
36
+ play: async ({ canvasElement }) => {
37
+ await assertVisualizationRendered(canvasElement)
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Region A has data up to 28, well above the smallestLeftAxisMax of 5.
43
+ * The axis naturally scales to the data — the setting has no effect here.
44
+ */
45
+ export const LargerDataUnaffected: Story = {
46
+ args: {
47
+ config: editConfigKeys(smallestLeftAxisMaxConfig, [{ path: ['filters', '0', 'active'], value: 'Region A' }])
48
+ },
49
+ play: async ({ canvasElement }) => {
50
+ await assertVisualizationRendered(canvasElement)
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Editor view so you can see the Smallest Left Axis Maximum field in the Left Value Axis section.
56
+ */
57
+ export const Editor: Story = {
58
+ args: {
59
+ config: smallestLeftAxisMaxConfig,
60
+ isEditor: true
61
+ }
62
+ }
63
+
64
+ export default meta
@@ -6,6 +6,7 @@ import lineChartTwoPointsNewChart from './_mock/line_chart_two_points_new_chart.
6
6
  import lollipop from './_mock/lollipop.json'
7
7
  import forestPlot from '../../examples/feature/forest-plot/forest-plot.json'
8
8
  import pairedBar from './_mock/paired-bar.json'
9
+ import pairedBarAbbreviated from './_mock/paired-bar-abbr.json'
9
10
  import horizontalBarConfig from './_mock/horizontal_bar.json'
10
11
  import horizontalBarsDynamicYAxis from './_mock/horizontal-bars-dynamic-y-axis.json'
11
12
  import barChartLabels from './_mock/barchart_labels.mock.json'
@@ -14,6 +15,8 @@ import pieCalculatedArea from './_mock/pie_calculated_area.json'
14
15
  import areaChartStacked from './_mock/area_chart_stacked.json'
15
16
  import multipleLines from './_mock/short_dates.json'
16
17
  import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
18
+ import { assertVisualizationRendered, waitForPresence } from '@cdc/core/helpers/testing'
19
+ import { expect } from 'storybook/test'
17
20
 
18
21
  const meta: Meta<typeof Chart> = {
19
22
  title: 'Components/Templates/Chart',
@@ -26,18 +29,27 @@ export const line_Chart_Two_Points_Regression_Test: Story = {
26
29
  args: {
27
30
  config: lineChartTwoPointsRegressionTest,
28
31
  isEditor: false
32
+ },
33
+ play: async ({ canvasElement }) => {
34
+ await assertVisualizationRendered(canvasElement)
29
35
  }
30
36
  }
31
37
  export const line_Chart_Two_Points_New_Chart: Story = {
32
38
  args: {
33
39
  config: lineChartTwoPointsNewChart,
34
40
  isEditor: false
41
+ },
42
+ play: async ({ canvasElement }) => {
43
+ await assertVisualizationRendered(canvasElement)
35
44
  }
36
45
  }
37
46
 
38
47
  export const multiple_lines: Story = {
39
48
  args: {
40
49
  config: editConfigKeys(multipleLines, [{ path: ['tooltips', 'dateDisplayFormat'], value: '%b. %d %Y' }])
50
+ },
51
+ play: async ({ canvasElement }) => {
52
+ await assertVisualizationRendered(canvasElement)
41
53
  }
42
54
  }
43
55
 
@@ -45,18 +57,28 @@ export const Lollipop: Story = {
45
57
  args: {
46
58
  config: lollipop,
47
59
  isEditor: false
60
+ },
61
+ play: async ({ canvasElement }) => {
62
+ await assertVisualizationRendered(canvasElement)
48
63
  }
49
64
  }
50
65
 
51
66
  export const Forest_Plot: Story = {
52
67
  args: {
53
- config: forestPlot
68
+ config: forestPlot,
69
+ isEditor: true
70
+ },
71
+ play: async ({ canvasElement }) => {
72
+ await assertVisualizationRendered(canvasElement)
54
73
  }
55
74
  }
56
75
 
57
76
  export const Horizontal_Bar: Story = {
58
77
  args: {
59
78
  config: horizontalBarConfig
79
+ },
80
+ play: async ({ canvasElement }) => {
81
+ await assertVisualizationRendered(canvasElement)
60
82
  }
61
83
  }
62
84
 
@@ -64,12 +86,18 @@ export const Horizontal_Bars_Dynamic_Y_Axis: Story = {
64
86
  args: {
65
87
  config: horizontalBarsDynamicYAxis,
66
88
  isEditor: false
89
+ },
90
+ play: async ({ canvasElement }) => {
91
+ await assertVisualizationRendered(canvasElement)
67
92
  }
68
93
  }
69
94
 
70
95
  export const BarChart_Labels: Story = {
71
96
  args: {
72
97
  config: barChartLabels
98
+ },
99
+ play: async ({ canvasElement }) => {
100
+ await assertVisualizationRendered(canvasElement)
73
101
  }
74
102
  }
75
103
 
@@ -77,12 +105,18 @@ export const Pie: Story = {
77
105
  args: {
78
106
  config: pieConfig,
79
107
  isEditor: true
108
+ },
109
+ play: async ({ canvasElement }) => {
110
+ await assertVisualizationRendered(canvasElement)
80
111
  }
81
112
  }
82
113
  export const Pie_Calculated_Area: Story = {
83
114
  args: {
84
115
  config: pieCalculatedArea,
85
116
  isEditor: true
117
+ },
118
+ play: async ({ canvasElement }) => {
119
+ await assertVisualizationRendered(canvasElement)
86
120
  }
87
121
  }
88
122
 
@@ -90,6 +124,19 @@ export const Paired_Bar: Story = {
90
124
  args: {
91
125
  config: pairedBar,
92
126
  isEditor: true
127
+ },
128
+ play: async ({ canvasElement }) => {
129
+ await assertVisualizationRendered(canvasElement)
130
+ }
131
+ }
132
+
133
+ export const Paired_Bar_Year_Tick_Format_Regression: Story = {
134
+ args: {
135
+ config: pairedBarAbbreviated,
136
+ isEditor: true
137
+ },
138
+ play: async ({ canvasElement }) => {
139
+ await assertVisualizationRendered(canvasElement)
93
140
  }
94
141
  }
95
142
 
@@ -97,6 +144,30 @@ export const Area_Chart_stacked: Story = {
97
144
  args: {
98
145
  config: areaChartStacked,
99
146
  isEditor: false
147
+ },
148
+ play: async ({ canvasElement }) => {
149
+ await assertVisualizationRendered(canvasElement)
150
+ }
151
+ }
152
+
153
+ export const Metadata_In_Description: Story = {
154
+ args: {
155
+ configUrl: '/packages/chart/tests/fixtures/chart-config-with-metadata.json'
156
+ },
157
+ play: async ({ canvasElement }) => {
158
+ await assertVisualizationRendered(canvasElement)
159
+ const subtext = await waitForPresence('.subtext', canvasElement)
160
+ expect(subtext?.textContent).toContain('January 15, 2026')
161
+ }
162
+ }
163
+
164
+ export const Metadata_Backward_Compat_Plain_Array: Story = {
165
+ args: {
166
+ config: lineChartTwoPointsRegressionTest,
167
+ isEditor: false
168
+ },
169
+ play: async ({ canvasElement }) => {
170
+ await assertVisualizationRendered(canvasElement)
100
171
  }
101
172
  }
102
173
 
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
3
3
  import Chart from '../CdcChartComponent'
4
4
  import barChartStacked from './_mock/barchart_labels.mock.json'
5
5
  import barChartSuppressed from './_mock/bar-chart-suppressed.json'
6
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
6
7
  const meta: Meta<typeof Chart> = {
7
8
  title: 'Components/Templates/Chart/Tooltip',
8
9
  component: Chart
@@ -20,6 +21,9 @@ export const Increased_Tooltip_Range: Story = {
20
21
  singleSeries: true
21
22
  }
22
23
  }
24
+ },
25
+ play: async ({ canvasElement }) => {
26
+ await assertVisualizationRendered(canvasElement)
23
27
  }
24
28
  }
25
29
 
@@ -58,6 +62,9 @@ export const Additional_Tooltip: Story = {
58
62
  }
59
63
  }
60
64
  }
65
+ },
66
+ play: async ({ canvasElement }) => {
67
+ await assertVisualizationRendered(canvasElement)
61
68
  }
62
69
  }
63
70
 
@@ -3,6 +3,7 @@ import annotationConfig from './_mock/annotation_category_mock.json'
3
3
  import annotationConfigDateLinear from './_mock/annotation_date-linear_mock.json'
4
4
  import annotationConfigDateTime from './_mock/annotation_date-time_mock.json'
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/Annotation',
@@ -15,6 +16,9 @@ export const Chart_Annotation_Categorical: Story = {
15
16
  args: {
16
17
  config: annotationConfig,
17
18
  isEditor: true
19
+ },
20
+ play: async ({ canvasElement }) => {
21
+ await assertVisualizationRendered(canvasElement)
18
22
  }
19
23
  }
20
24
 
@@ -22,6 +26,9 @@ export const Chart_Annotation_Date_Linear: Story = {
22
26
  args: {
23
27
  config: annotationConfigDateLinear,
24
28
  isEditor: true
29
+ },
30
+ play: async ({ canvasElement }) => {
31
+ await assertVisualizationRendered(canvasElement)
25
32
  }
26
33
  }
27
34
 
@@ -29,6 +36,9 @@ export const Chart_Annotation_Date_Time: Story = {
29
36
  args: {
30
37
  config: annotationConfigDateTime,
31
38
  isEditor: true
39
+ },
40
+ play: async ({ canvasElement }) => {
41
+ await assertVisualizationRendered(canvasElement)
32
42
  }
33
43
  }
34
44
 
@@ -3,6 +3,7 @@ import SimplifiedLineConfig from './_mock/simplified_line.json'
3
3
 
4
4
  import Chart from '../CdcChartComponent'
5
5
  import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
6
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
6
7
 
7
8
  const meta: Meta<typeof Chart> = {
8
9
  title: 'Components/Templates/Chart/Axis Labels',
@@ -17,6 +18,9 @@ export const Abbreviated_Dates: Story = {
17
18
  { path: ['xAxis', 'showYearsOnce'], value: true },
18
19
  { path: ['tooltips', 'dateDisplayFormat'], value: '%b. %d %Y' }
19
20
  ])
21
+ },
22
+ play: async ({ canvasElement }) => {
23
+ await assertVisualizationRendered(canvasElement)
20
24
  }
21
25
  }
22
26