@cdc/chart 4.26.5 → 4.26.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/CONFIG.md +20 -14
  2. package/dist/{cdcchart-DQ00cQCm.es.js → cdcchart-BWVIUcAF.es.js} +5 -55
  3. package/dist/cdcchart.js +36554 -34320
  4. package/examples/feature/heatmap/average-age-categorical.json +1 -1
  5. package/examples/feature/heatmap/calendar-heatmap.json +1 -1
  6. package/examples/feature/heatmap/sparse-aggregation.json +1 -1
  7. package/examples/private/bad-y-axis.json +543 -0
  8. package/examples/private/bar-chart-negative-value.json +455 -0
  9. package/examples/private/flueview.json +22051 -0
  10. package/package.json +3 -11
  11. package/src/CdcChart.tsx +7 -6
  12. package/src/CdcChartComponent.tsx +71 -18
  13. package/src/_stories/Chart.PieLabels.stories.tsx +47 -0
  14. package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +183 -0
  15. package/src/_stories/Chart.YAxisAutoMaxStrategy.stories.tsx +52 -0
  16. package/src/_stories/Chart.YAxisFilterDomain.stories.tsx +90 -0
  17. package/src/_stories/Chart.smoke.stories.tsx +14 -1
  18. package/src/_stories/ChartAnnotation.smoke.stories.tsx +10 -0
  19. package/src/_stories/ChartPrefixSuffix.smoke.stories.tsx +28 -1
  20. package/src/_stories/_mock/annotation_event-line_mock.json +1064 -0
  21. package/src/_stories/_mock/heatmap-average-age-categorical.json +1 -1
  22. package/src/_stories/_mock/heatmap.json +1 -1
  23. package/src/components/Annotations/components/AnnotationDraggable.styles.css +22 -1
  24. package/src/components/Annotations/components/AnnotationDraggable.tsx +219 -119
  25. package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +198 -0
  26. package/src/components/Axis/LeftAxis.tsx +3 -0
  27. package/src/components/Axis/LeftAxisGridlines.tsx +8 -1
  28. package/src/components/Axis/RightAxis.tsx +3 -0
  29. package/src/components/Axis/tests/AxisTickValues.test.tsx +86 -0
  30. package/src/components/BarChart/components/BarChart.Horizontal.tsx +1 -2
  31. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +1 -1
  32. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +1 -1
  33. package/src/components/BarChart/components/BarChart.Vertical.tsx +1 -2
  34. package/src/components/BarChart/helpers/getBarData.ts +28 -28
  35. package/src/components/BarChart/helpers/getBarHeights.ts +2 -2
  36. package/src/components/BarChart/helpers/tests/useBarChart.test.tsx +98 -0
  37. package/src/components/BarChart/helpers/useBarChart.ts +4 -5
  38. package/src/components/BoxPlot/BoxPlot.Horizontal.tsx +7 -6
  39. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +9 -7
  40. package/src/components/BoxPlot/helpers/index.ts +4 -3
  41. package/src/components/Brush/BrushSelector.tsx +1 -1
  42. package/src/components/EditorPanel/EditorPanel.tsx +457 -165
  43. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +101 -52
  44. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +16 -7
  45. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +3 -3
  46. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +19 -4
  47. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.test.tsx +98 -0
  48. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +10 -0
  49. package/src/components/EditorPanel/components/Panels/Panel.Visual.test.tsx +484 -0
  50. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +3 -0
  51. package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +262 -0
  52. package/src/components/EditorPanel/components/Panels/panelVisual.styles.css +32 -0
  53. package/src/components/EditorPanel/components/panels.scss +10 -0
  54. package/src/components/EditorPanel/editor-panel.scss +47 -0
  55. package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +6 -2
  56. package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +20 -2
  57. package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +3 -3
  58. package/src/components/EditorPanel/useEditorPermissions.test.tsx +288 -11
  59. package/src/components/EditorPanel/useEditorPermissions.ts +46 -6
  60. package/src/components/Forecasting/Forecasting.tsx +1 -1
  61. package/src/components/HeatMap/components/HeatMap.tsx +22 -17
  62. package/src/components/HeatMap/components/HeatMapGradientLegend.tsx +29 -15
  63. package/src/components/HeatMap/heatmap.css +15 -1
  64. package/src/components/HeatMap/tests/HeatMap.test.tsx +39 -7
  65. package/src/components/Legend/Legend.Component.tsx +56 -61
  66. package/src/components/Legend/Legend.Suppression.tsx +3 -3
  67. package/src/components/Legend/LegendGroup/LegendGroup.tsx +0 -1
  68. package/src/components/Legend/helpers/createFormatLabels.test.ts +88 -0
  69. package/src/components/Legend/helpers/createFormatLabels.tsx +6 -1
  70. package/src/components/LineChart/helpers.test.ts +230 -1
  71. package/src/components/LineChart/helpers.ts +25 -14
  72. package/src/components/LineChart/index.tsx +23 -7
  73. package/src/components/LinearChart/tests/LinearChart.test.tsx +30 -0
  74. package/src/components/LinearChart.tsx +51 -15
  75. package/src/components/PieChart/PieChart.tsx +117 -10
  76. package/src/components/PieChart/helpers/labelPlacement.test.ts +88 -0
  77. package/src/components/PieChart/helpers/labelPlacement.ts +95 -0
  78. package/src/components/ScatterPlot/ScatterPlot.jsx +5 -13
  79. package/src/components/SmallMultiples/SmallMultipleTile.tsx +3 -0
  80. package/src/components/SmallMultiples/SmallMultiples.tsx +38 -9
  81. package/src/components/SmallMultiples/tests/SmallMultiples.test.tsx +170 -0
  82. package/src/data/initial-state.js +3 -0
  83. package/src/helpers/calculateLeftYAxisWidth.ts +9 -3
  84. package/src/helpers/categoryOrder.ts +60 -0
  85. package/src/helpers/colorAssignmentHelpers.ts +102 -0
  86. package/src/helpers/dataHelpers.ts +11 -1
  87. package/src/helpers/getAxisMaxOverride.ts +16 -0
  88. package/src/helpers/getBoxPlotConfig.ts +19 -12
  89. package/src/helpers/getCleanTopTickMax.ts +64 -0
  90. package/src/helpers/getColorScale.ts +18 -9
  91. package/src/helpers/getComboChartConfig.ts +0 -1
  92. package/src/helpers/getExcludedData.ts +0 -1
  93. package/src/helpers/getHasBoundarySuppression.ts +27 -0
  94. package/src/helpers/getMinMax.ts +25 -22
  95. package/src/helpers/getNewRuntime.ts +0 -2
  96. package/src/helpers/getPiePercent.ts +3 -3
  97. package/src/helpers/getYAxisDomainData.ts +38 -0
  98. package/src/helpers/getYAxisFinalizationEligibility.ts +40 -0
  99. package/src/helpers/hasSpacedInlineLabel.ts +10 -0
  100. package/src/helpers/isConvertLineToBarGraph.ts +2 -2
  101. package/src/helpers/seriesColumnSettings.ts +26 -7
  102. package/src/helpers/sizeHelpers.ts +0 -2
  103. package/src/helpers/smallMultiplesHelpers.ts +5 -0
  104. package/src/helpers/tests/calculateLeftYAxisWidth.test.ts +38 -0
  105. package/src/helpers/tests/categoryOrder.test.ts +57 -0
  106. package/src/helpers/tests/dataHelpers.test.ts +135 -0
  107. package/src/helpers/tests/getAxisMaxOverride.test.ts +36 -0
  108. package/src/helpers/tests/getCleanTopTickMax.test.ts +165 -0
  109. package/src/helpers/tests/getColorScale.test.ts +197 -0
  110. package/src/helpers/tests/getMinMax.test.ts +211 -0
  111. package/src/helpers/tests/getYAxisDomainData.test.ts +119 -0
  112. package/src/helpers/tests/getYAxisFinalizationEligibility.test.ts +185 -0
  113. package/src/helpers/tests/{getYAxisAutoPaddingMode.test.ts → hasSpacedInlineLabel.test.ts} +17 -32
  114. package/src/helpers/tests/seriesColumnSettings.test.ts +76 -2
  115. package/src/helpers/tests/smallMultiplesHelpers.test.ts +99 -0
  116. package/src/hooks/tests/useRightAxis.test.tsx +268 -0
  117. package/src/hooks/tests/useScales.test.tsx +302 -27
  118. package/src/hooks/tests/useTooltip.test.tsx +132 -0
  119. package/src/hooks/useRightAxis.ts +35 -25
  120. package/src/hooks/useScales.ts +45 -28
  121. package/src/hooks/useTooltip.tsx +17 -11
  122. package/src/store/chart.reducer.ts +0 -1
  123. package/src/test/CdcChart.dataTable.test.tsx +216 -0
  124. package/src/types/ChartConfig.ts +6 -1
  125. package/src/types/ChartContext.ts +3 -0
  126. package/src/helpers/getYAxisAutoPadding.ts +0 -55
  127. package/src/helpers/getYAxisAutoPaddingMode.ts +0 -17
  128. package/src/helpers/tests/getYAxisAutoPadding.test.ts +0 -37
@@ -0,0 +1,90 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { expect, within } from 'storybook/test'
3
+ import Chart from '../CdcChartComponent'
4
+ import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
5
+ import smallestLeftAxisMaxConfig from './_mock/smallest_left_axis_max.json'
6
+ import horizontalBarConfig from './_mock/horizontal_bar.json'
7
+ import { assertVisualizationRendered, openAccordion, waitForEditor } from '@cdc/core/helpers/testing'
8
+
9
+ const meta: Meta<typeof Chart> = {
10
+ title: 'Components/Templates/Chart/Y Axis Filter Domain',
11
+ component: Chart
12
+ }
13
+
14
+ type Story = StoryObj<typeof Chart>
15
+
16
+ const baseConfig = editConfigKeys(smallestLeftAxisMaxConfig, [
17
+ { path: ['yAxis', 'smallestLeftAxisMax'], value: undefined },
18
+ { path: ['yAxis', 'numTicks'], value: 4 }
19
+ ])
20
+
21
+ export const Dynamic_Filter_Domain: Story = {
22
+ args: {
23
+ config: editConfigKeys(baseConfig, [{ path: ['yAxis', 'filterDomainBehavior'], value: 'dynamic' }])
24
+ },
25
+ play: async ({ canvasElement }) => {
26
+ await assertVisualizationRendered(canvasElement)
27
+ }
28
+ }
29
+
30
+ export const Stable_Filter_Domain: Story = {
31
+ args: {
32
+ config: editConfigKeys(baseConfig, [{ path: ['yAxis', 'filterDomainBehavior'], value: 'stable' }])
33
+ },
34
+ play: async ({ canvasElement }) => {
35
+ await assertVisualizationRendered(canvasElement)
36
+ }
37
+ }
38
+
39
+ export const Editor_Control: Story = {
40
+ args: {
41
+ config: editConfigKeys(baseConfig, [
42
+ { path: ['yAxis', 'filterDomainBehavior'], value: 'stable' },
43
+ { path: ['yAxis', 'autoMaxStrategy'], value: 'clean-top-tick' }
44
+ ]),
45
+ isEditor: true
46
+ },
47
+ play: async ({ canvasElement }) => {
48
+ const canvas = within(canvasElement)
49
+ await waitForEditor(canvas)
50
+ await openAccordion(canvas, 'Left Value Axis')
51
+
52
+ const filterDomainSelect = (await canvas.findByLabelText(/Filter Domain Behavior/i)) as HTMLSelectElement
53
+ expect(filterDomainSelect.value).toBe('stable')
54
+ expect(Array.from(filterDomainSelect.options).map(option => option.text)).toEqual(['Dynamic', 'Stable'])
55
+
56
+ const autoMaxStrategySelect = (await canvas.findByLabelText(/Automatic max strategy/i)) as HTMLSelectElement
57
+ expect(autoMaxStrategySelect.value).toBe('clean-top-tick')
58
+ expect(Array.from(autoMaxStrategySelect.options).map(option => option.text)).toEqual(['Default', 'Clean top tick'])
59
+ }
60
+ }
61
+
62
+ export const Horizontal_Editor_Control: Story = {
63
+ args: {
64
+ config: editConfigKeys(horizontalBarConfig, [
65
+ { path: ['filters'], value: [{ columnName: 'Race', active: 'AI/AN, Non-Hispanic', showDropdown: true }] },
66
+ { path: ['xAxis', 'max'], value: '' },
67
+ { path: ['yAxis', 'type'], value: 'linear' },
68
+ { path: ['yAxis', 'smallestLeftAxisMax'], value: 5 },
69
+ { path: ['yAxis', 'filterDomainBehavior'], value: 'stable' },
70
+ { path: ['yAxis', 'autoMaxStrategy'], value: 'clean-top-tick' }
71
+ ]),
72
+ isEditor: true
73
+ },
74
+ play: async ({ canvasElement }) => {
75
+ const canvas = within(canvasElement)
76
+ await waitForEditor(canvas)
77
+ await openAccordion(canvas, 'Value Axis')
78
+
79
+ const smallestAxisMaxInput = (await canvas.findByLabelText(/Smallest axis maximum/i)) as HTMLInputElement
80
+ expect(smallestAxisMaxInput.value).toBe('5')
81
+
82
+ const filterDomainSelect = (await canvas.findByLabelText(/Filter Domain Behavior/i)) as HTMLSelectElement
83
+ expect(filterDomainSelect.value).toBe('stable')
84
+
85
+ const autoMaxStrategySelect = (await canvas.findByLabelText(/Automatic max strategy/i)) as HTMLSelectElement
86
+ expect(autoMaxStrategySelect.value).toBe('clean-top-tick')
87
+ }
88
+ }
89
+
90
+ export default meta
@@ -26,6 +26,19 @@ const meta: Meta<typeof Chart> = {
26
26
 
27
27
  type Story = StoryObj<typeof Chart>
28
28
 
29
+ const multipleLinesStoryData = [
30
+ { week_end: '2024-01-06', Adults: 45.1, Children: 29.3, pathogen: 'COVID-19' },
31
+ { week_end: '2024-01-13', Adults: 46.7, Children: 30.2, pathogen: 'COVID-19' },
32
+ { week_end: '2024-01-20', Adults: 48.0, Children: 31.0, pathogen: 'COVID-19' }
33
+ ]
34
+
35
+ const multipleLinesConfig = editConfigKeys(multipleLines, [
36
+ { path: ['tooltips', 'dateDisplayFormat'], value: '%b. %d %Y' },
37
+ { path: ['formattedData'], value: multipleLinesStoryData },
38
+ { path: ['dataUrl'], value: undefined },
39
+ { path: ['runtimeDataUrl'], value: undefined }
40
+ ])
41
+
29
42
  export const line_Chart_Two_Points_Regression_Test: Story = {
30
43
  args: {
31
44
  config: lineChartTwoPointsRegressionTest,
@@ -47,7 +60,7 @@ export const line_Chart_Two_Points_New_Chart: Story = {
47
60
 
48
61
  export const multiple_lines: Story = {
49
62
  args: {
50
- config: editConfigKeys(multipleLines, [{ path: ['tooltips', 'dateDisplayFormat'], value: '%b. %d %Y' }])
63
+ config: multipleLinesConfig
51
64
  },
52
65
  play: async ({ canvasElement }) => {
53
66
  await assertVisualizationRendered(canvasElement)
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
2
2
  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
+ import annotationConfigEventLine from './_mock/annotation_event-line_mock.json'
5
6
  import Chart from '../CdcChartComponent'
6
7
  import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
7
8
 
@@ -42,4 +43,13 @@ export const Chart_Annotation_Date_Time: Story = {
42
43
  }
43
44
  }
44
45
 
46
+ export const Chart_Annotation_Event_Line: Story = {
47
+ args: {
48
+ config: annotationConfigEventLine
49
+ },
50
+ play: async ({ canvasElement }) => {
51
+ await assertVisualizationRendered(canvasElement)
52
+ }
53
+ }
54
+
45
55
  export default meta
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import { expect } from 'storybook/test'
2
3
  import barConfig from './_mock/line_chart_two_points_new_chart.json'
3
4
  import annotationConfig from './_mock/annotation_category_mock.json'
4
5
  import areaPrefix from './_mock/annotation_category_mock.json'
@@ -7,7 +8,7 @@ import scatterPlotConfig from './_mock/scatterplot_mock.json'
7
8
 
8
9
  import Chart from '../CdcChartComponent'
9
10
  import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
10
- import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
11
+ import { assertVisualizationRendered, waitForPresence } from '@cdc/core/helpers/testing'
11
12
 
12
13
  const meta: Meta<typeof Chart> = {
13
14
  title: 'Components/Templates/Chart/Prefix Suffix',
@@ -16,6 +17,11 @@ const meta: Meta<typeof Chart> = {
16
17
 
17
18
  type Story = StoryObj<typeof Chart>
18
19
 
20
+ const getSvgTextValues = (root: ParentNode | null, selector: string = 'text') => {
21
+ if (!root) return []
22
+ return Array.from(root.querySelectorAll(selector)).map(node => node.textContent?.trim() || '')
23
+ }
24
+
19
25
  export const Inline_Label: Story = {
20
26
  args: {
21
27
  config: editConfigKeys(barConfig, [
@@ -198,4 +204,25 @@ export const ScatterPlot_Bottom_Commas: Story = {
198
204
  }
199
205
  }
200
206
 
207
+ export const ScatterPlot_Bottom_Commas_And_Abbreviated: Story = {
208
+ args: {
209
+ config: editConfigKeys(scatterPlotConfig, [
210
+ { path: ['dataFormat', 'bottomCommas'], value: true },
211
+ { path: ['dataFormat', 'bottomAbbreviated'], value: true },
212
+ { path: ['dataFormat', 'bottomPrefix'], value: '$' },
213
+ { path: ['dataFormat', 'commas'], value: false },
214
+ { path: ['dataFormat', 'abbreviated'], value: false }
215
+ ])
216
+ },
217
+ play: async ({ canvasElement }) => {
218
+ await assertVisualizationRendered(canvasElement)
219
+ await waitForPresence('svg g.bottom-axis', canvasElement)
220
+
221
+ const svgText = getSvgTextValues(canvasElement, 'svg g.bottom-axis text')
222
+ const hasBottomAxisCurrencyAbbreviation = svgText.some(text => /^\$\d+(\.\d+)?K$/.test(text))
223
+
224
+ expect(hasBottomAxisCurrencyAbbreviation).toBe(true)
225
+ }
226
+ }
227
+
201
228
  export default meta