@cdc/chart 4.26.6 → 4.26.10

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 (276) hide show
  1. package/CONFIG.md +504 -368
  2. package/dist/cdcchart-CYc-Kayd.es.js +22488 -0
  3. package/dist/cdcchart-DCKn8NmI.es.js +20695 -0
  4. package/dist/cdcchart-Dyui9nk_.es.js +45828 -0
  5. package/dist/cdcchart.js +4 -96498
  6. package/examples/__data__/vega-remote-data.json +6 -0
  7. package/examples/dendrogram.json +18 -0
  8. package/examples/feature/bar/bar-chart-race-annual-change.json +68 -0
  9. package/examples/feature/heatmap/average-age-categorical.json +2 -2
  10. package/examples/feature/heatmap/calendar-heatmap.json +2 -2
  11. package/examples/feature/heatmap/cell-values-bottom-axis.json +2 -2
  12. package/examples/feature/heatmap/sparse-aggregation.json +2 -2
  13. package/examples/feature/line/line-chart-race.json +50 -0
  14. package/examples/feature/sankey/sankey-example-data.json +40 -1441
  15. package/examples/feature/sankey/sankey_chart_data.csv +9 -20
  16. package/examples/network.json +31 -0
  17. package/examples/private/box-plot.json +573 -0
  18. package/examples/private/custom-color-issue.json +625 -0
  19. package/examples/private/custom-colors.json +522 -0
  20. package/examples/private/cutoff.json +10750 -0
  21. package/examples/private/flueview.json +22051 -0
  22. package/examples/private/overlay-legend.json +485 -0
  23. package/examples/private/pie-test.json +469 -0
  24. package/examples/vega-remote.json +22 -0
  25. package/package.json +11 -13
  26. package/src/CdcChart.tsx +2 -2
  27. package/src/CdcChartComponent.tsx +444 -217
  28. package/src/_stories/Chart.BarRace.stories.tsx +443 -0
  29. package/src/_stories/Chart.BoxPlotNumericSort.stories.tsx +189 -0
  30. package/src/_stories/Chart.BoxPlotStatsParity.stories.tsx +207 -0
  31. package/src/_stories/Chart.ColorDistribution.stories.tsx +299 -0
  32. package/src/_stories/Chart.DataCutoff.stories.tsx +147 -0
  33. package/src/_stories/Chart.DataTableDownloadFilename.stories.tsx +60 -0
  34. package/src/_stories/Chart.Dendrogram.stories.tsx +373 -0
  35. package/src/_stories/Chart.Forecast.CILegend.stories.tsx +236 -0
  36. package/src/_stories/Chart.HeatMap.stories.tsx +170 -4
  37. package/src/_stories/Chart.Legend.AxisAlign.stories.tsx +119 -0
  38. package/src/_stories/Chart.LineRace.stories.tsx +149 -0
  39. package/src/_stories/Chart.Network.stories.tsx +432 -0
  40. package/src/_stories/Chart.PaletteConversion.Editor.stories.tsx +208 -0
  41. package/src/_stories/Chart.Patterns.smoke.stories.tsx +31 -0
  42. package/src/_stories/Chart.PercentageValue.stories.tsx +311 -0
  43. package/src/_stories/Chart.PieLabels.stories.tsx +49 -0
  44. package/src/_stories/Chart.RankByValueMutation.stories.tsx +206 -0
  45. package/src/_stories/Chart.RequiredFields.stories.tsx +681 -0
  46. package/src/_stories/Chart.Sankey.stories.tsx +417 -0
  47. package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +47 -0
  48. package/src/_stories/Chart.SmallMultiplesNumericTileOrder.stories.tsx +137 -0
  49. package/src/_stories/Chart.TooltipSeriesLabels.stories.tsx +43 -0
  50. package/src/_stories/Chart.VegaRemoteData.stories.tsx +31 -0
  51. package/src/_stories/Chart.smoke.stories.tsx +14 -1
  52. package/src/_stories/ChartAnnotation.Editor.stories.tsx +78 -0
  53. package/src/_stories/ChartAxisTitles.smoke.stories.tsx +48 -0
  54. package/src/_stories/ChartBar.Editor.stories.tsx +499 -57
  55. package/src/_stories/ChartBrush.Editor.stories.tsx +46 -67
  56. package/src/_stories/ChartBrush.Regression.stories.tsx +135 -0
  57. package/src/_stories/ChartEditor.Editor.stories.tsx +33 -3
  58. package/src/_stories/ChartLine.EffectCompatibility.stories.tsx +120 -0
  59. package/src/_stories/ChartPrefixSuffix.smoke.stories.tsx +28 -1
  60. package/src/_stories/_mock/annotation_event-line_mock.json +2 -2
  61. package/src/_stories/_mock/editor-test-configs.json +20 -10
  62. package/src/_stories/_mock/editor-test-datasets.json +38 -42
  63. package/src/_stories/_mock/heatmap-average-age-categorical.json +2 -2
  64. package/src/_stories/_mock/heatmap.json +2 -2
  65. package/src/_stories/_mock/legend-axis-align-stacked-bar.json +125 -0
  66. package/src/_stories/_mock/sankey_mock.json +23 -27
  67. package/src/components/Annotations/components/AnnotationDraggable.styles.css +52 -0
  68. package/src/components/Annotations/components/AnnotationDraggable.tsx +639 -139
  69. package/src/components/Annotations/components/AnnotationDropdown.styles.css +44 -4
  70. package/src/components/Annotations/components/AnnotationDropdown.tsx +10 -32
  71. package/src/components/Annotations/helpers/resolveAnnotationLayout.ts +212 -0
  72. package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +612 -19
  73. package/src/components/Annotations/tests/AnnotationDropdown.test.tsx +50 -0
  74. package/src/components/Annotations/tests/resolveAnnotationLayout.test.ts +203 -0
  75. package/src/components/Axis/BottomAxis.tsx +1 -1
  76. package/src/components/Axis/Categorical.Axis.tsx +3 -3
  77. package/src/components/Axis/RightAxis.tsx +21 -13
  78. package/src/components/BarChart/components/BarChart.Horizontal.tsx +39 -8
  79. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +13 -4
  80. package/src/components/BarChart/components/BarChart.StackedVertical.test.ts +28 -0
  81. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +30 -26
  82. package/src/components/BarChart/components/BarChart.Vertical.tsx +38 -28
  83. package/src/components/BarChart/components/PortionPatternOverlay.tsx +61 -0
  84. package/src/components/BarChart/components/context.tsx +6 -0
  85. package/src/components/BarChart/helpers/getBarData.ts +28 -28
  86. package/src/components/BarChart/helpers/getBarHeights.ts +2 -2
  87. package/src/components/BarChart/helpers/getPatternUrl.ts +2 -5
  88. package/src/components/BarChart/helpers/index.ts +8 -0
  89. package/src/components/BarChart/helpers/portionPattern.ts +243 -0
  90. package/src/components/BarChart/helpers/tests/addMinimumBarHeights.test.ts +42 -0
  91. package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +13 -0
  92. package/src/components/BarChart/helpers/tests/portionPattern.test.ts +280 -0
  93. package/src/components/BarChart/helpers/tests/useBarChart.test.tsx +202 -0
  94. package/src/components/BarChart/helpers/useBarChart.ts +60 -60
  95. package/src/components/BarChartRace/BarChartRace.test.tsx +199 -0
  96. package/src/components/BarChartRace/BarChartRace.tsx +230 -0
  97. package/src/components/BarChartRace/BarChartRaceFallback.test.tsx +61 -0
  98. package/src/components/BarChartRace/BarChartRaceFallback.tsx +48 -0
  99. package/src/components/BarChartRace/bar-chart-race.css +160 -0
  100. package/src/components/BarChartRace/helpers.test.ts +114 -0
  101. package/src/components/BarChartRace/helpers.ts +185 -0
  102. package/src/components/BarChartRace/index.ts +3 -0
  103. package/src/components/BoxPlot/BoxPlot.Horizontal.tsx +7 -6
  104. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +9 -7
  105. package/src/components/BoxPlot/helpers/index.ts +13 -83
  106. package/src/components/Brush/BrushSelector.tsx +10 -24
  107. package/src/components/Brush/MiniChartPreview.tsx +33 -1
  108. package/src/components/Dendrogram/components/Dendrogram.tsx +374 -0
  109. package/src/components/Dendrogram/dendrogram.css +113 -0
  110. package/src/components/Dendrogram/helpers/layoutDendrogram.test.ts +95 -0
  111. package/src/components/Dendrogram/helpers/layoutDendrogram.ts +56 -0
  112. package/src/components/Dendrogram/helpers/prepareDendrogramData.test.ts +135 -0
  113. package/src/components/Dendrogram/helpers/prepareDendrogramData.ts +166 -0
  114. package/src/components/Dendrogram/helpers/resolveDendrogramLabels.test.ts +196 -0
  115. package/src/components/Dendrogram/helpers/resolveDendrogramLabels.ts +418 -0
  116. package/src/components/Dendrogram/index.tsx +1 -0
  117. package/src/components/Dendrogram/types/index.ts +66 -0
  118. package/src/components/EditorPanel/EditorPanel.tsx +1111 -805
  119. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +50 -5
  120. package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.css +10 -0
  121. package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.tsx +211 -0
  122. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +19 -8
  123. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +104 -61
  124. package/src/components/EditorPanel/components/Panels/Panel.Network.css +9 -0
  125. package/src/components/EditorPanel/components/Panels/Panel.Network.tsx +202 -0
  126. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +236 -36
  127. package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +6 -1
  128. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +89 -105
  129. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +21 -6
  130. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +1 -1
  131. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +8 -66
  132. package/src/components/EditorPanel/components/Panels/RacingControls.test.tsx +131 -0
  133. package/src/components/EditorPanel/components/Panels/RacingControls.tsx +185 -0
  134. package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +2 -2
  135. package/src/components/EditorPanel/components/Panels/index.tsx +4 -0
  136. package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +20 -7
  137. package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +25 -2
  138. package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +5 -4
  139. package/src/components/EditorPanel/useEditorPermissions.test.tsx +94 -0
  140. package/src/components/EditorPanel/useEditorPermissions.ts +75 -25
  141. package/src/components/Forecasting/Forecasting.tsx +16 -7
  142. package/src/components/HeatMap/components/HeatMap.tsx +511 -178
  143. package/src/components/HeatMap/heatmap.constants.ts +7 -3
  144. package/src/components/HeatMap/heatmap.css +101 -2
  145. package/src/components/HeatMap/helpers/layout.ts +80 -0
  146. package/src/components/HeatMap/tests/HeatMap.test.tsx +339 -16
  147. package/src/components/HeatMap/tests/helpers.test.ts +79 -0
  148. package/src/components/Legend/Legend.Component.tsx +163 -148
  149. package/src/components/Legend/Legend.Suppression.tsx +3 -3
  150. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +7 -0
  151. package/src/components/Legend/LegendGroup/LegendGroup.tsx +47 -35
  152. package/src/components/Legend/helpers/createFormatLabels.test.ts +226 -0
  153. package/src/components/Legend/helpers/createFormatLabels.tsx +45 -51
  154. package/src/components/LineChart/components/LineChart.Circle.tsx +3 -3
  155. package/src/components/LineChart/helpers.test.ts +126 -38
  156. package/src/components/LineChart/helpers.ts +9 -6
  157. package/src/components/LineChart/index.tsx +71 -27
  158. package/src/components/LineChart/tests/LineChart.test.tsx +630 -0
  159. package/src/components/LineChartRace/LineChartRace.test.tsx +275 -0
  160. package/src/components/LineChartRace/LineChartRace.tsx +134 -0
  161. package/src/components/LineChartRace/LineChartRaceFallback.tsx +28 -0
  162. package/src/components/LineChartRace/helpers.test.ts +88 -0
  163. package/src/components/LineChartRace/helpers.ts +157 -0
  164. package/src/components/LineChartRace/index.ts +3 -0
  165. package/src/components/LineChartRace/line-chart-race.css +16 -0
  166. package/src/components/LinearChart/ValueAxisAnchors.tsx +58 -0
  167. package/src/components/LinearChart/VisualizationRenderer.tsx +18 -23
  168. package/src/components/LinearChart/tests/LinearChart.test.tsx +412 -13
  169. package/src/components/LinearChart/tests/VisualizationRenderer.test.tsx +141 -0
  170. package/src/components/LinearChart/tests/mockConfigContext.ts +2 -1
  171. package/src/components/LinearChart.tsx +85 -54
  172. package/src/components/Network/components/Network.tsx +372 -0
  173. package/src/components/Network/helpers/layoutNetwork.test.ts +68 -0
  174. package/src/components/Network/helpers/layoutNetwork.ts +87 -0
  175. package/src/components/Network/helpers/prepareNetworkData.test.ts +116 -0
  176. package/src/components/Network/helpers/prepareNetworkData.ts +101 -0
  177. package/src/components/Network/helpers/resolveNetworkLabels.test.ts +112 -0
  178. package/src/components/Network/helpers/resolveNetworkLabels.ts +206 -0
  179. package/src/components/Network/index.tsx +3 -0
  180. package/src/components/Network/network.css +107 -0
  181. package/src/components/Network/types/index.ts +56 -0
  182. package/src/components/PairedBarChart.jsx +5 -10
  183. package/src/components/PairedBarChart.test.tsx +71 -0
  184. package/src/components/PieChart/PieChart.tsx +121 -13
  185. package/src/components/PieChart/helpers/labelPlacement.test.ts +88 -0
  186. package/src/components/PieChart/helpers/labelPlacement.ts +95 -0
  187. package/src/components/RacingChartRenderer.tsx +44 -0
  188. package/src/components/Regions/components/Regions.test.tsx +179 -0
  189. package/src/components/Regions/components/Regions.tsx +104 -69
  190. package/src/components/Regions/index.tsx +2 -3
  191. package/src/components/Sankey/components/Sankey.tsx +264 -437
  192. package/src/components/Sankey/helpers/getSankeyTooltip.ts +12 -0
  193. package/src/components/Sankey/helpers/prepareSankeyData.test.ts +71 -0
  194. package/src/components/Sankey/helpers/prepareSankeyData.ts +90 -0
  195. package/src/components/Sankey/sankey.scss +57 -116
  196. package/src/components/Sankey/types/index.ts +41 -4
  197. package/src/components/ScatterPlot/ScatterPlot.jsx +28 -12
  198. package/src/components/ScatterPlot/ScatterPlot.test.tsx +60 -0
  199. package/src/components/SmallMultiples/SmallMultiples.tsx +12 -12
  200. package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +7 -5
  201. package/src/components/raceTiming.ts +18 -0
  202. package/src/data/initial-state.js +79 -31
  203. package/src/helpers/applyChartTypeContract.ts +71 -0
  204. package/src/helpers/axisLabelFontSize.ts +2 -2
  205. package/src/helpers/boxPlotStats.ts +60 -0
  206. package/src/helpers/bumpChartTooltip.ts +2 -1
  207. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.test.ts +37 -0
  208. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +3 -2
  209. package/src/helpers/calculateRightYAxisWidth.ts +60 -0
  210. package/src/helpers/categoryOrder.ts +60 -0
  211. package/src/helpers/colorAssignmentHelpers.ts +2 -2
  212. package/src/helpers/createNewChartConfig.ts +56 -0
  213. package/src/helpers/dataDrivenYAxisCategories.ts +18 -0
  214. package/src/helpers/forecastLegend.ts +88 -0
  215. package/src/helpers/getBoxPlotConfig.ts +26 -38
  216. package/src/helpers/getChartTypeDefaultPalette.ts +29 -0
  217. package/src/helpers/getColorCodeCategoryColorMap.ts +26 -0
  218. package/src/helpers/getColorScale.ts +31 -22
  219. package/src/helpers/getComboChartConfig.ts +0 -1
  220. package/src/helpers/getDynamicYAxisCategories.ts +69 -0
  221. package/src/helpers/getExcludedData.ts +0 -1
  222. package/src/helpers/getHasBoundarySuppression.ts +4 -3
  223. package/src/helpers/getMinMax.ts +11 -8
  224. package/src/helpers/getNewRuntime.ts +4 -3
  225. package/src/helpers/getPiePercent.ts +3 -3
  226. package/src/helpers/getStackedSeriesMax.ts +51 -0
  227. package/src/helpers/getV21ChartDistributionColors.ts +57 -0
  228. package/src/helpers/handleRankByValue.ts +15 -15
  229. package/src/helpers/isConvertLineToBarGraph.ts +2 -2
  230. package/src/helpers/seriesColumnSettings.ts +31 -3
  231. package/src/helpers/sizeHelpers.ts +4 -5
  232. package/src/helpers/smallMultiplesHelpers.ts +10 -13
  233. package/src/helpers/tests/applyChartTypeContract.test.ts +37 -0
  234. package/src/helpers/tests/boxPlotStats.test.ts +31 -0
  235. package/src/helpers/tests/bumpChartTooltip.test.ts +29 -0
  236. package/src/helpers/tests/calculateRightYAxisWidth.test.ts +105 -0
  237. package/src/helpers/tests/categoryOrder.test.ts +57 -0
  238. package/src/helpers/tests/countNumOfTicks.test.ts +11 -0
  239. package/src/helpers/tests/createNewChartConfig.test.ts +182 -0
  240. package/src/helpers/tests/getBoxPlotConfig.test.ts +70 -0
  241. package/src/helpers/tests/getColorCodeCategoryColorMap.test.ts +113 -0
  242. package/src/helpers/tests/getColorScale.test.ts +226 -1
  243. package/src/helpers/tests/getDynamicYAxisCategories.test.ts +61 -0
  244. package/src/helpers/tests/getMinMax.test.ts +41 -0
  245. package/src/helpers/tests/getStackedSeriesMax.test.ts +26 -0
  246. package/src/helpers/tests/handleRankByValue.test.ts +55 -37
  247. package/src/helpers/tests/seriesColumnSettings.test.ts +83 -0
  248. package/src/helpers/tests/smallMultiplesHelpers.test.ts +37 -1
  249. package/src/helpers/tests/tooltipHelpers.test.ts +80 -0
  250. package/src/helpers/tooltipHelpers.ts +16 -0
  251. package/src/hooks/tests/useRightAxis.test.tsx +143 -2
  252. package/src/hooks/tests/useScales.test.tsx +3 -6
  253. package/src/hooks/tests/useTooltip.test.tsx +484 -0
  254. package/src/hooks/usePrefersReducedMotion.ts +22 -0
  255. package/src/hooks/useReduceData.ts +4 -36
  256. package/src/hooks/useRightAxis.ts +19 -26
  257. package/src/hooks/useScales.ts +15 -0
  258. package/src/hooks/useTooltip.tsx +106 -71
  259. package/src/scss/main.scss +74 -2
  260. package/src/store/chart.reducer.ts +4 -4
  261. package/src/test/CdcChart.dataTable.test.tsx +582 -14
  262. package/src/test/CdcChart.dendrogram.test.tsx +277 -0
  263. package/src/test/CdcChart.finalization.test.tsx +143 -0
  264. package/src/test/CdcChart.network.test.tsx +271 -0
  265. package/src/types/ChartConfig.ts +91 -54
  266. package/src/types/ChartContext.ts +5 -0
  267. package/src/types/Horizon.ts +1 -1
  268. package/LICENSE +0 -201
  269. package/dist/cdcchart-BWVIUcAF.es.js +0 -4802
  270. package/src/_stories/Chart.Sankey.smoke.stories.tsx +0 -62
  271. package/src/components/Sankey/components/ColumnList.tsx +0 -19
  272. package/src/components/Sankey/helpers/getSankeyTooltip.tsx +0 -34
  273. package/src/components/Sankey/useSankeyAlert.tsx +0 -60
  274. package/src/data/legacy-defaults.ts +0 -18
  275. package/src/helpers/ensureSpecialChartAxisTypes.ts +0 -11
  276. package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +0 -30
@@ -1,18 +1,11 @@
1
- import { USE_V2_MIGRATION } from '@cdc/core/helpers/constants'
1
+ import { DEFAULT_RACE_SECONDS_PER_FRAME } from '../components/raceTiming'
2
2
 
3
- // Dynamic initial state based on migration flag
4
3
  const createInitialState = () => {
5
- const paletteDefaults = USE_V2_MIGRATION
6
- ? {
7
- isReversed: true,
8
- version: '2.0',
9
- name: 'sequential_bluereverse'
10
- }
11
- : {
12
- isReversed: true,
13
- version: '1.0',
14
- name: 'qualitative_bold'
15
- }
4
+ const paletteDefaults = {
5
+ isReversed: false,
6
+ version: '2.1',
7
+ name: 'sequential_blue'
8
+ }
16
9
 
17
10
  return {
18
11
  annotations: [],
@@ -26,11 +19,19 @@ const createInitialState = () => {
26
19
  titleStyle: 'small',
27
20
  showTitle: true,
28
21
  showDownloadMediaButton: false,
22
+ enableTooltips: false,
29
23
  theme: 'theme-blue',
30
24
  animate: false,
31
25
  lineDatapointStyle: 'hover',
32
26
  lineDatapointColor: 'Same as Line',
33
27
  barHasBorder: 'true',
28
+ barRace: {
29
+ maxBars: 10,
30
+ secondsPerFrame: DEFAULT_RACE_SECONDS_PER_FRAME
31
+ },
32
+ lineRace: {
33
+ secondsPerFrame: DEFAULT_RACE_SECONDS_PER_FRAME
34
+ },
34
35
  isLollipopChart: false,
35
36
  lollipopShape: 'circle',
36
37
  lollipopColorStyle: 'two-tone',
@@ -58,6 +59,7 @@ const createInitialState = () => {
58
59
  displayNumbersOnBar: false,
59
60
  hideLabel: false,
60
61
  hideTicks: true,
62
+ labelPlacement: 'On Date/Category Axis',
61
63
  size: 50,
62
64
  gridLines: true,
63
65
  enablePadding: false,
@@ -70,6 +72,7 @@ const createInitialState = () => {
70
72
  rightAxisSize: 0,
71
73
  rightLabel: '',
72
74
  rightLabelOffsetSize: 0,
75
+ rightTitlePlacement: 'top',
73
76
  rightAxisLabelColor: '#1c1d1f',
74
77
  rightAxisTickLabelColor: '#1c1d1f',
75
78
  rightAxisTickColor: '#1c1d1f',
@@ -80,6 +83,7 @@ const createInitialState = () => {
80
83
  tickRotation: 0,
81
84
  autoMaxStrategy: 'clean-top-tick',
82
85
  anchors: [],
86
+ rightAnchors: [],
83
87
  shoMissingDataLabel: true,
84
88
  showMissingDataLine: true,
85
89
  categories: []
@@ -112,8 +116,8 @@ const createInitialState = () => {
112
116
  },
113
117
 
114
118
  isLegendValue: false,
115
- barThickness: 0.35,
116
119
  barHeight: 25,
120
+ barThickness: 0.8,
117
121
  barSpace: 15,
118
122
  heights: {
119
123
  vertical: 300,
@@ -144,9 +148,12 @@ const createInitialState = () => {
144
148
  padding: 5,
145
149
  showYearsOnce: false,
146
150
  sortByRecentDate: false,
151
+ categoryOrder: [],
152
+ categoryOrderType: 'data',
147
153
  brushActive: false,
148
154
  brushDefaultRecentDateCount: undefined,
149
155
  brushDynamicYAxis: false,
156
+ brushHideHatching: false,
150
157
  viewportNumTicks: {
151
158
  xs: 4,
152
159
  xxs: 4
@@ -160,10 +167,11 @@ const createInitialState = () => {
160
167
  caption: '',
161
168
  showDownloadUrl: false,
162
169
  downloadUrlLabel: '',
163
- showDataTableLink: true,
170
+ showDataTableLink: false,
164
171
  showDownloadLinkBelow: true,
165
172
  search: false,
166
173
  searchPlaceholder: '',
174
+ stickyFirstColumn: false,
167
175
  indexLabel: '',
168
176
  download: false,
169
177
  showVertical: true,
@@ -173,7 +181,6 @@ const createInitialState = () => {
173
181
  collapsible: true
174
182
  },
175
183
  orientation: 'vertical',
176
- color: 'qualitative-bold',
177
184
  columns: {
178
185
  // start with a blank list
179
186
  },
@@ -313,10 +320,12 @@ const createInitialState = () => {
313
320
  },
314
321
  heatmap: {
315
322
  cellPadding: 1,
316
- rowLabelGap: 32,
317
- columnLabelGap: 56,
323
+ rowLabelGap: 0,
324
+ columnLabelGap: 20,
318
325
  xAxisPosition: 'top',
319
- showCellValues: false
326
+ showCellValues: false,
327
+ horizontalScroll: false,
328
+ minColumnWidth: 44
320
329
  },
321
330
  area: {
322
331
  isStacked: false
@@ -334,22 +343,20 @@ const createInitialState = () => {
334
343
  axisLabelOffset: 15
335
344
  },
336
345
  sankey: {
337
- title: {
338
- defaultColor: 'black'
339
- },
340
346
  iterations: 1,
341
347
  rxValue: 0.9,
342
- overallSize: {
343
- width: 900,
344
- height: 700
345
- },
348
+ horizontalScrollWidth: 900,
346
349
  margin: {
347
350
  margin_y: 25,
348
351
  margin_x: 0
349
352
  },
353
+ columns: {
354
+ source: 'source',
355
+ target: 'target',
356
+ value: 'value'
357
+ },
350
358
  nodeSize: {
351
- nodeWidth: 26,
352
- nodeHeight: 40
359
+ nodeWidth: 26
353
360
  },
354
361
  nodePadding: 55,
355
362
  nodeFontColor: 'black',
@@ -367,13 +374,54 @@ const createInitialState = () => {
367
374
  LinkOpacityDefault: 1.0,
368
375
  LinkOpacityInactive: 0.1
369
376
  },
370
- storyNodeFontColor: '#006778',
371
- storyNodeText: [],
372
377
  nodeValueStyle: {
373
378
  textBefore: '(',
374
379
  textAfter: ')'
380
+ }
381
+ },
382
+ network: {
383
+ columns: {
384
+ source: 'source',
385
+ target: 'target',
386
+ weight: '',
387
+ style: '',
388
+ nodeColor: ''
389
+ },
390
+ directed: false,
391
+ height: 500,
392
+ nodeRadius: 8,
393
+ nodeColor: '#005eaa',
394
+ linkColor: '#333333',
395
+ linkStyleLabels: {
396
+ solid: 'Solid',
397
+ dashed: 'Dashed'
398
+ },
399
+ linkDistance: 90,
400
+ chargeStrength: -240,
401
+ rotation: 0,
402
+ scale: 1,
403
+ offsetX: 0,
404
+ offsetY: 0
405
+ },
406
+ dendrogram: {
407
+ columns: {
408
+ node: 'node',
409
+ parent: 'parent',
410
+ style: 'linkStyle',
411
+ nodeColor: 'nodeColor'
412
+ },
413
+ connectionType: 'curve',
414
+ orientation: 'horizontal',
415
+ height: 500,
416
+ nodeRadius: 6,
417
+ nodeColor: '#005eaa',
418
+ linkColor: '#333333',
419
+ linkStyleLabels: {
420
+ solid: 'Solid',
421
+ dashed: 'Dashed'
375
422
  },
376
- data: []
423
+ leafSpacing: 40,
424
+ depthSpacing: 140
377
425
  },
378
426
  markupVariables: [],
379
427
  enableMarkupVariables: false
@@ -0,0 +1,71 @@
1
+ import type { ChartConfig } from '../types/ChartConfig'
2
+ import cloneDeep from 'lodash/cloneDeep'
3
+
4
+ /** Applies deterministic chart-type fields owned by current authoring paths. */
5
+ export const applyChartTypeContract = <T extends ChartConfig>(config: T): T => {
6
+ const nextConfig = cloneDeep(config)
7
+
8
+ if (Array.isArray(nextConfig.series)) {
9
+ nextConfig.series = nextConfig.series.map(series => ({ tooltip: true, axis: 'Left', ...series }))
10
+ }
11
+
12
+ switch (nextConfig.visualizationType) {
13
+ case 'Area Chart':
14
+ nextConfig.visualizationSubType = 'stacked'
15
+ break
16
+ case 'Forecasting':
17
+ if (!nextConfig.xAxis.type || nextConfig.xAxis.type === 'categorical') {
18
+ nextConfig.xAxis.type = 'date'
19
+ if (!nextConfig.xAxis.dateParseFormat) nextConfig.xAxis.dateParseFormat = '%Y-%m-%d'
20
+ if (!nextConfig.xAxis.dateDisplayFormat) nextConfig.xAxis.dateDisplayFormat = '%Y-%m-%d'
21
+ }
22
+ break
23
+ case 'HeatMap':
24
+ nextConfig.yAxis.type = 'categorical'
25
+ nextConfig.yAxis.titlePlacement = nextConfig.yAxis.titlePlacement || 'side'
26
+ nextConfig.legend.position = nextConfig.legend.position || 'top'
27
+ nextConfig.legend.style = nextConfig.legend.style || 'gradient'
28
+ nextConfig.legend.subStyle =
29
+ nextConfig.legend.subStyle === 'smooth' ? 'linear blocks' : nextConfig.legend.subStyle || 'linear blocks'
30
+ break
31
+ case 'Horizon Chart': {
32
+ nextConfig.horizon = {
33
+ numLayers: 4,
34
+ mode: 'offset',
35
+ bandGap: 15,
36
+ bottomPadding: 15,
37
+ ...nextConfig.horizon
38
+ }
39
+ if (!nextConfig.xAxis.type) nextConfig.xAxis.type = 'categorical'
40
+ const layerCount = nextConfig.horizon.numLayers ?? 4
41
+ const paletteCount = nextConfig.general.paletteColorCount ?? 4
42
+ nextConfig.general.paletteColorCount = Math.max(paletteCount, layerCount)
43
+ break
44
+ }
45
+ case 'Box Plot':
46
+ nextConfig.yAxis.labelPlacement = 'On Date/Category Axis'
47
+ break
48
+ case 'Paired Bar':
49
+ case 'Deviation Bar':
50
+ nextConfig.orientation = 'horizontal'
51
+ break
52
+ case 'Bump Chart':
53
+ nextConfig.xAxis.type = 'date-time'
54
+ break
55
+ }
56
+
57
+ if (
58
+ ['date', 'date-time'].includes(nextConfig.xAxis?.type) &&
59
+ nextConfig.xAxis?.dataKey &&
60
+ !nextConfig.table?.defaultSort?.column
61
+ ) {
62
+ nextConfig.table = {
63
+ ...nextConfig.table,
64
+ defaultSort: { column: nextConfig.xAxis.dataKey, sortDirection: 'desc' }
65
+ }
66
+ }
67
+
68
+ return nextConfig
69
+ }
70
+
71
+ export default applyChartTypeContract
@@ -1,8 +1,8 @@
1
1
  import { isMobileFontViewport } from '@cdc/core/helpers/viewports'
2
- import { ViewportSize } from '../types/ChartConfig'
2
+ import type { ViewPort } from '@cdc/core/types/ViewPort'
3
3
 
4
4
  export const AXIS_LABEL_FONT_SIZE = 18
5
5
  export const AXIS_LABEL_FONT_SIZE_SMALL = 14
6
6
 
7
- export const getAxisLabelFontSize = (vizViewport: ViewportSize) =>
7
+ export const getAxisLabelFontSize = (vizViewport: ViewPort) =>
8
8
  isMobileFontViewport(vizViewport) ? AXIS_LABEL_FONT_SIZE_SMALL : AXIS_LABEL_FONT_SIZE
@@ -0,0 +1,60 @@
1
+ import * as d3 from 'd3-array'
2
+ import { sortByNumber, toSortableNumber } from '@cdc/core/helpers/sorting'
3
+
4
+ export type BoxPlotStats = {
5
+ deviation: number | undefined
6
+ iqr: number
7
+ lowerBound: number
8
+ mean: number | undefined
9
+ median: number | undefined
10
+ nonOutliers: number[]
11
+ outliers: number[]
12
+ q1: number
13
+ q3: number
14
+ upperBound: number
15
+ values: number[]
16
+ whiskerMax: number
17
+ whiskerMin: number
18
+ }
19
+
20
+ export const getSortedBoxPlotValues = (values: unknown[] = []): number[] => {
21
+ const numericValues = values.reduce<number[]>((result, value) => {
22
+ if (value === null || value === undefined || value === '') return result
23
+
24
+ const numericValue = toSortableNumber(value)
25
+ if (Number.isFinite(numericValue)) result.push(numericValue)
26
+
27
+ return result
28
+ }, [])
29
+
30
+ return sortByNumber(numericValues)
31
+ }
32
+
33
+ export const calculateBoxPlotStats = (values: unknown[] = []): BoxPlotStats | null => {
34
+ const sortedValues = getSortedBoxPlotValues(values)
35
+ if (!sortedValues.length) return null
36
+
37
+ const q1 = d3.quantile(sortedValues, 0.25) ?? 0
38
+ const q3 = d3.quantile(sortedValues, 0.75) ?? 0
39
+ const iqr = q3 - q1
40
+ const lowerBound = q1 - 1.5 * iqr
41
+ const upperBound = q3 + 1.5 * iqr
42
+ const nonOutliers = sortedValues.filter(value => value >= lowerBound && value <= upperBound)
43
+ const outliers = sortedValues.filter(value => value < lowerBound || value > upperBound)
44
+
45
+ return {
46
+ deviation: d3.deviation(sortedValues),
47
+ iqr,
48
+ lowerBound,
49
+ mean: d3.mean(sortedValues),
50
+ median: d3.median(sortedValues),
51
+ nonOutliers,
52
+ outliers,
53
+ q1,
54
+ q3,
55
+ upperBound,
56
+ values: sortedValues,
57
+ whiskerMax: nonOutliers[nonOutliers.length - 1] ?? q3,
58
+ whiskerMin: nonOutliers[0] ?? q1
59
+ }
60
+ }
@@ -2,6 +2,7 @@ import { isDateScale } from '@cdc/core/helpers/cove/date'
2
2
  import { buildTooltipListHtml, getTooltipSeriesMarker } from './tooltipHelpers'
3
3
  import { type ChartConfig } from '../types/ChartConfig'
4
4
  import { type ColorScale } from '../types/ChartContext'
5
+ import { getSeriesValueLabel } from '@cdc/core/helpers/getSeriesName'
5
6
 
6
7
  type TooltipDateHelpers = {
7
8
  formatDate: (date: Date) => string
@@ -35,7 +36,7 @@ export const buildBumpChartTooltipHtml = ({ config, colorScale, dataRow, series,
35
36
  const xAxisLabel = config.runtime?.xAxis?.label || config.xAxis.dataKey
36
37
  const heading = `${xAxisLabel ? `${xAxisLabel}: ` : ''}${formattedXAxisValue ?? ''}`
37
38
 
38
- const seriesName = series.name || config.runtime?.seriesLabels?.[series.dataKey] || series.dataKey
39
+ const seriesName = getSeriesValueLabel(series.dataKey, { ...config, series: [series] })
39
40
  const marker = getTooltipSeriesMarker(config, colorScale, series.dataKey)
40
41
  const bodyRows = [
41
42
  {
@@ -0,0 +1,37 @@
1
+ import { getTextWidth } from '@cdc/core/helpers/getTextWidth'
2
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
3
+ import { calculateHorizontalBarCategoryLabelWidth } from './calculateHorizontalBarCategoryLabelWidth'
4
+
5
+ vi.mock('@cdc/core/helpers/getTextWidth', () => ({
6
+ getTextWidth: vi.fn()
7
+ }))
8
+
9
+ const mockedGetTextWidth = vi.mocked(getTextWidth)
10
+
11
+ const calculateWidth = (categoryValues: string[], chartWidth = 500) =>
12
+ calculateHorizontalBarCategoryLabelWidth({
13
+ yScale: { domain: () => categoryValues },
14
+ chartWidth,
15
+ formatDate: vi.fn(),
16
+ parseDate: vi.fn(),
17
+ tickLabelFont: 'normal 16px Nunito, sans-serif',
18
+ labelPlacement: 'On Date/Category Axis'
19
+ })
20
+
21
+ describe('calculateHorizontalBarCategoryLabelWidth', () => {
22
+ beforeEach(() => {
23
+ mockedGetTextWidth.mockImplementation(label => label.length * 10)
24
+ })
25
+
26
+ it('keeps at least ten pixels between short labels and the chart area', () => {
27
+ expect(calculateWidth(['A', 'B'])).toBe(20)
28
+ })
29
+
30
+ it('retains proportional padding for longer labels', () => {
31
+ expect(calculateWidth(['abcdefghij'])).toBe(115)
32
+ })
33
+
34
+ it('still caps category label space at thirty percent of the chart width', () => {
35
+ expect(calculateWidth(['abcdefghij'], 300)).toBe(90)
36
+ })
37
+ })
@@ -47,8 +47,9 @@ export const calculateHorizontalBarCategoryLabelWidth = ({
47
47
  const labelWidths = formattedLabels.map(label => getTextWidth(label, tickLabelFont))
48
48
  const maxLabelWidth = Math.max(...labelWidths)
49
49
 
50
- // We need some extra padding or visx will wrap labels too early
51
- const paddedWidth = maxLabelWidth + Math.ceil(maxLabelWidth * 0.15)
50
+ // We need some extra padding or visx will wrap labels too early. Keep a
51
+ // minimum gap so short labels do not sit too close to the chart area.
52
+ const paddedWidth = maxLabelWidth + Math.max(10, Math.ceil(maxLabelWidth * 0.15))
52
53
 
53
54
  // Allocate at most 30% of chart width to category labels
54
55
  const maxAllowedWidth = chartWidth * 0.3
@@ -0,0 +1,60 @@
1
+ import { getTextWidth } from '@cdc/core/helpers/getTextWidth'
2
+ import { DEFAULT_TICK_LENGTH, TICK_LABEL_MARGIN_RIGHT } from '../components/Axis/axis.constants'
3
+
4
+ type CalculateRightYAxisWidthProps = {
5
+ axisLabelFontSize: number
6
+ config: any
7
+ formatNumber: (value: any, axis?: string) => string
8
+ tickLabelFont: string
9
+ tickValues?: number[]
10
+ yScaleRight: any
11
+ }
12
+
13
+ const AXIS_LABEL_PADDING = 5
14
+
15
+ const getRightTickValues = ({ config, tickValues, yScaleRight }) => {
16
+ if (tickValues) return tickValues
17
+
18
+ if (typeof yScaleRight?.ticks === 'function') {
19
+ return yScaleRight.ticks(config.runtime?.yAxis?.rightNumTicks || undefined)
20
+ }
21
+
22
+ if (typeof yScaleRight?.domain === 'function') {
23
+ return yScaleRight.domain()
24
+ }
25
+
26
+ return []
27
+ }
28
+
29
+ const measureWidestLabel = (labels: string[], tickLabelFont: string) => {
30
+ return labels.length ? Math.max(...labels.map(label => getTextWidth(label, tickLabelFont))) : 0
31
+ }
32
+
33
+ const getSideTitleSpace = ({ config, axisLabelFontSize, tickContentSpace }) => {
34
+ const rightTitle = config.runtime?.yAxis?.rightLabel ?? config.yAxis?.rightLabel
35
+
36
+ if (config.yAxis?.rightTitlePlacement === 'top' || !rightTitle) return 0
37
+
38
+ return tickContentSpace + axisLabelFontSize + AXIS_LABEL_PADDING
39
+ }
40
+
41
+ export const calculateRightYAxisWidth = ({
42
+ axisLabelFontSize,
43
+ config,
44
+ formatNumber,
45
+ tickLabelFont,
46
+ tickValues,
47
+ yScaleRight
48
+ }: CalculateRightYAxisWidthProps): number => {
49
+ const measuredTickValues = getRightTickValues({ config, tickValues, yScaleRight })
50
+ const formattedTicks = measuredTickValues.map(tick => String(formatNumber(tick, 'right') ?? ''))
51
+ const tickLabelWidth = config.yAxis?.rightHideLabel ? 0 : measureWidestLabel(formattedTicks, tickLabelFont)
52
+ const tickLabelSpace = tickLabelWidth ? tickLabelWidth + DEFAULT_TICK_LENGTH + TICK_LABEL_MARGIN_RIGHT : 0
53
+ const tickMarkSpace = config.runtime?.yAxis?.rightHideTicks ? 0 : DEFAULT_TICK_LENGTH
54
+ const tickContentSpace = Math.max(tickLabelSpace, tickMarkSpace)
55
+ const sideTitleSpace = getSideTitleSpace({ config, axisLabelFontSize, tickContentSpace })
56
+
57
+ return Math.ceil(Math.max(tickContentSpace, sideTitleSpace))
58
+ }
59
+
60
+ export default calculateRightYAxisWidth
@@ -0,0 +1,60 @@
1
+ import { ChartConfig } from '../types/ChartConfig'
2
+
3
+ type DataRow = Record<string, any>
4
+
5
+ export const isCustomCategoryOrderActive = (config: Pick<ChartConfig, 'xAxis'>) => {
6
+ return (
7
+ config.xAxis?.type === 'categorical' &&
8
+ config.xAxis?.categoryOrderType === 'custom' &&
9
+ Array.isArray(config.xAxis?.categoryOrder) &&
10
+ config.xAxis.categoryOrder.length > 0 &&
11
+ Boolean(config.xAxis?.dataKey)
12
+ )
13
+ }
14
+
15
+ export const getCategoryValues = (data: DataRow[] = [], dataKey?: string): string[] => {
16
+ if (!dataKey || !Array.isArray(data)) return []
17
+
18
+ const values: string[] = []
19
+ for (const row of data) {
20
+ const value = String(row?.[dataKey] ?? '')
21
+ if (value !== '') values.push(value)
22
+ }
23
+
24
+ return Array.from(new Set(values))
25
+ }
26
+
27
+ export const getOrderedCategoryValues = (
28
+ data: DataRow[] = [],
29
+ dataKey?: string,
30
+ categoryOrder: string[] = []
31
+ ): string[] => {
32
+ const values = getCategoryValues(data, dataKey)
33
+ if (!categoryOrder?.length) return values
34
+
35
+ const configuredValues = categoryOrder.map(String)
36
+ const configuredValueSet = new Set(configuredValues)
37
+ const valueSet = new Set(values)
38
+ const extras = values.filter(value => !configuredValueSet.has(value))
39
+
40
+ return [...configuredValues.filter(value => valueSet.has(value)), ...extras]
41
+ }
42
+
43
+ export const sortByCategoryOrder = (data: DataRow[] = [], config: Pick<ChartConfig, 'xAxis'>): DataRow[] => {
44
+ if (!Array.isArray(data) || !isCustomCategoryOrderActive(config)) return data
45
+
46
+ const dataKey = config.xAxis.dataKey
47
+ const categoryOrder = Array.from(new Set((config.xAxis.categoryOrder || []).map(String)))
48
+ const indexByValue = new Map(categoryOrder.map((value, index) => [value, index]))
49
+ return data
50
+ .map((row, originalIndex) => ({ row, originalIndex }))
51
+ .sort((a, b) => {
52
+ const indexA = indexByValue.get(String(a.row?.[dataKey] ?? ''))
53
+ const indexB = indexByValue.get(String(b.row?.[dataKey] ?? ''))
54
+ const rankA = indexA ?? Number.MAX_SAFE_INTEGER
55
+ const rankB = indexB ?? Number.MAX_SAFE_INTEGER
56
+
57
+ return rankA === rankB ? a.originalIndex - b.originalIndex : rankA - rankB
58
+ })
59
+ .map(({ row }) => row)
60
+ }
@@ -1,4 +1,5 @@
1
1
  import { type ChartConfig, type VisualizationType } from '../types/ChartConfig'
2
+ import { getSeriesName } from '@cdc/core/helpers/getSeriesName'
2
3
 
3
4
  export type SeriesColorAssignment = {
4
5
  key: string
@@ -45,8 +46,7 @@ export const hasSeriesColorAssignmentOverrides = (config: ChartConfig): boolean
45
46
  }
46
47
 
47
48
  export const getSeriesDisplayLabel = (config: ChartConfig, key: string): string => {
48
- const series = config.series?.find(item => item?.dataKey === key)
49
- return String(config.runtime?.seriesLabels?.[key] || series?.name || (series as any)?.label || key)
49
+ return getSeriesName(key, config)
50
50
  }
51
51
 
52
52
  export const getSeriesColorAssignmentItems = (config: ChartConfig): SeriesColorAssignmentItem[] => {
@@ -0,0 +1,56 @@
1
+ import cloneDeep from 'lodash/cloneDeep'
2
+ import mergeWith from 'lodash/mergeWith'
3
+
4
+ import defaults from '../data/initial-state'
5
+ import { ChartConfig } from '../types/ChartConfig'
6
+ import { getChartTypeDefaultPalette } from './getChartTypeDefaultPalette'
7
+ import { CURRENT_COVE_CONFIG_VERSION } from '@cdc/core/helpers/coveUpdateWorker'
8
+ import { applyChartTypeContract } from './applyChartTypeContract'
9
+
10
+ type CreateNewChartConfigOptions = {
11
+ isDashboard?: boolean
12
+ }
13
+
14
+ /**
15
+ * Creates a complete config for a brand-new chart using current defaults.
16
+ * Existing and legacy configs must continue through the normal migration and
17
+ * backfill paths instead of using this helper.
18
+ */
19
+ export const createNewChartConfig = (
20
+ starterConfig: Partial<ChartConfig> & Record<string, any>,
21
+ { isDashboard = false }: CreateNewChartConfigOptions = {}
22
+ ): ChartConfig => {
23
+ const currentDefaults = cloneDeep(defaults)
24
+ const defaultPalette = getChartTypeDefaultPalette(starterConfig.visualizationType)
25
+
26
+ if (defaultPalette && !starterConfig.general?.palette) {
27
+ currentDefaults.general.palette = cloneDeep(defaultPalette)
28
+ }
29
+
30
+ const config = applyChartTypeContract(
31
+ mergeWith(currentDefaults, cloneDeep(starterConfig), (_defaultValue, starterValue) =>
32
+ Array.isArray(starterValue) ? starterValue : undefined
33
+ ) as ChartConfig
34
+ )
35
+
36
+ if (config.orientation === 'horizontal') {
37
+ config.xAxis.hideAxis = starterConfig.xAxis?.hideAxis ?? true
38
+ config.xAxis.hideTicks = starterConfig.xAxis?.hideTicks ?? true
39
+ config.yAxis.hideAxis = starterConfig.yAxis?.hideAxis ?? false
40
+ config.yAxis.hideTicks = starterConfig.yAxis?.hideTicks ?? false
41
+ }
42
+
43
+ config.table.show = starterConfig.table?.show ?? !isDashboard
44
+ config.table.download = starterConfig.table?.download ?? !isDashboard
45
+ config.legend.unified = starterConfig.legend?.unified ?? true
46
+ config.legend.expandForecastConfidenceIntervals = starterConfig.legend?.expandForecastConfidenceIntervals ?? true
47
+
48
+ if (starterConfig.visualizationType === 'HeatMap') {
49
+ config.xAxis.manual = starterConfig.xAxis?.manual ?? false
50
+ config.xAxis.numTicks = starterConfig.xAxis?.numTicks
51
+ config.xAxis.viewportNumTicks = starterConfig.xAxis?.viewportNumTicks ?? {}
52
+ }
53
+
54
+ config.version = CURRENT_COVE_CONFIG_VERSION
55
+ return config
56
+ }
@@ -0,0 +1,18 @@
1
+ import { AllChartsConfig } from '../types/ChartConfig'
2
+ import { getDynamicYAxisCategories } from './getDynamicYAxisCategories'
3
+
4
+ type DataDrivenYAxisConfig = Pick<AllChartsConfig, 'yAxis'>
5
+
6
+ export const isDataDrivenYAxis = (config: DataDrivenYAxisConfig) =>
7
+ config.yAxis.type === 'categorical' &&
8
+ (config.yAxis.categoryMode === 'data-driven' ||
9
+ (config.yAxis.categoryMode === undefined && !!config.yAxis.dataDrivenCategories))
10
+
11
+ export const getDataDrivenYAxisCategories = (config: DataDrivenYAxisConfig, data: Record<string, any>[]) => {
12
+ if (!isDataDrivenYAxis(config) || !config.yAxis.dataDrivenCategories) return null
13
+
14
+ return getDynamicYAxisCategories({
15
+ config: config.yAxis.dataDrivenCategories,
16
+ data
17
+ })
18
+ }