@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,262 @@
1
+ import { useEffect, useMemo, useRef } from 'react'
2
+ import cloneConfig from '@cdc/core/helpers/cloneConfig'
3
+ import { Select } from '@cdc/core/components/EditorPanel/Inputs'
4
+ import Tooltip from '@cdc/core/components/ui/Tooltip'
5
+ import Icon from '@cdc/core/components/ui/Icon'
6
+ import { DataColorSelector } from '@cdc/core/components/DataColorSelector'
7
+ import { getColorPaletteVersion } from '@cdc/core/helpers/getColorPaletteVersion'
8
+ import { getCurrentPaletteName, migratePaletteWithMap } from '@cdc/core/helpers/palettes/utils'
9
+ import { paletteMigrationMap } from '@cdc/core/helpers/palettes/migratePaletteName'
10
+ import { getColorScale } from '../../../../helpers/getColorScale'
11
+ import { ChartConfig } from '../../../../types/ChartConfig'
12
+ import {
13
+ getSeriesColorAssignmentItems,
14
+ getSeriesColorAssignments,
15
+ isSeriesColorAssignmentModeByValue,
16
+ supportsSeriesColorAssignments,
17
+ type SeriesColorAssignment,
18
+ type SeriesColorAssignmentItem
19
+ } from '../../../../helpers/colorAssignmentHelpers'
20
+
21
+ type SeriesColorAssignmentsProps = {
22
+ config: ChartConfig
23
+ updateConfig: (config: ChartConfig) => void
24
+ colorPalettes: Record<string, any>
25
+ }
26
+
27
+ const SeriesColorAssignments = ({ config, updateConfig, colorPalettes }: SeriesColorAssignmentsProps) => {
28
+ const seriesColorAssignmentItems = useMemo(() => getSeriesColorAssignmentItems(config), [config])
29
+ const seriesColorAssignments = getSeriesColorAssignments(config)
30
+ const seriesColorAssignmentMap = useMemo(
31
+ () => new Map(seriesColorAssignments.map(assignment => [assignment.key, assignment.color])),
32
+ [seriesColorAssignments]
33
+ )
34
+ const seriesColorAssignmentItemsFingerprint = seriesColorAssignmentItems
35
+ .map(({ key, label }) => `${key}:${label}`)
36
+ .join('|')
37
+ const seriesColorAssignmentsFingerprint = seriesColorAssignments.map(({ key, color }) => `${key}:${color}`).join('|')
38
+ const seriesColorAssignmentSupported = supportsSeriesColorAssignments(config)
39
+ const seriesColorAssignmentMode = config.general?.palette?.colorAssignmentMode || 'ordered'
40
+ const isSeriesColorAssignmentByValue = isSeriesColorAssignmentModeByValue(config)
41
+ const currentPaletteName = getCurrentPaletteName(config)
42
+ const customColors = config.general?.palette?.customColorsOrdered || config.general?.palette?.customColors
43
+ const hasCustomColors = Array.isArray(customColors) && customColors.length > 0
44
+
45
+ const getOrderedColorScaleConfig = () => ({
46
+ ...config,
47
+ general: {
48
+ ...config.general,
49
+ palette: {
50
+ ...config.general?.palette,
51
+ colorAssignmentMode: 'ordered' as const
52
+ }
53
+ }
54
+ })
55
+
56
+ const orderedColorScaleConfig = useMemo(getOrderedColorScaleConfig, [config])
57
+ const orderedColorScale = useMemo(() => getColorScale(orderedColorScaleConfig), [orderedColorScaleConfig])
58
+ const distributedPaletteColorOptions = useMemo(() => {
59
+ const colors = (orderedColorScale as any)?.range?.() || []
60
+ return Array.from(new Set(colors.filter(Boolean)))
61
+ }, [orderedColorScale])
62
+ const paletteColorOptions = useMemo(() => {
63
+ if (hasCustomColors) {
64
+ return Array.from(new Set(customColors.filter(Boolean)))
65
+ }
66
+
67
+ const version = getColorPaletteVersion(config)
68
+ const versionedPalettes = colorPalettes?.[`v${version}`] || colorPalettes?.v2 || colorPalettes || {}
69
+ const paletteName = migratePaletteWithMap(currentPaletteName, paletteMigrationMap, false)
70
+ const colors =
71
+ versionedPalettes[paletteName] || versionedPalettes[currentPaletteName] || distributedPaletteColorOptions
72
+
73
+ return Array.from(new Set(colors.filter(Boolean)))
74
+ }, [colorPalettes, config, customColors, hasCustomColors, currentPaletteName, distributedPaletteColorOptions])
75
+ const paletteSourceFingerprint = hasCustomColors
76
+ ? 'custom-colors'
77
+ : `${currentPaletteName}|${paletteColorOptions.join('|')}`
78
+ const previousPaletteSource = useRef<{ hasCustomColors: boolean; fingerprint: string } | null>(null)
79
+
80
+ const getColorForAssignmentItem = ({ label }: SeriesColorAssignmentItem, index: number): string => {
81
+ const orderedColor = orderedColorScale(label)
82
+ return paletteColorOptions.includes(orderedColor)
83
+ ? orderedColor
84
+ : distributedPaletteColorOptions[index % distributedPaletteColorOptions.length] ||
85
+ paletteColorOptions[index % paletteColorOptions.length] ||
86
+ '#000000'
87
+ }
88
+
89
+ const getAssignmentsFromCurrentColors = (): SeriesColorAssignment[] =>
90
+ seriesColorAssignmentItems.map((item, index) => ({
91
+ key: item.key,
92
+ color: getColorForAssignmentItem(item, index)
93
+ }))
94
+
95
+ const getAssignmentsWithMissingCurrentColors = (): SeriesColorAssignment[] | null => {
96
+ const assignments = [...seriesColorAssignments]
97
+ let hasMissingAssignment = false
98
+
99
+ seriesColorAssignmentItems.forEach((item, index) => {
100
+ const existingIndex = assignments.findIndex(assignment => assignment.key === item.key)
101
+ const nextAssignment = { key: item.key, color: getColorForAssignmentItem(item, index) }
102
+
103
+ if (existingIndex === -1) {
104
+ assignments.push(nextAssignment)
105
+ hasMissingAssignment = true
106
+ } else if (!assignments[existingIndex]?.color) {
107
+ assignments[existingIndex] = nextAssignment
108
+ hasMissingAssignment = true
109
+ }
110
+ })
111
+
112
+ return hasMissingAssignment ? assignments : null
113
+ }
114
+
115
+ const updateSeriesColorAssignmentMode = (mode: 'ordered' | 'by-value') => {
116
+ const _state = cloneConfig(config)
117
+ if (!_state.general.palette) {
118
+ _state.general.palette = {}
119
+ }
120
+
121
+ _state.general.palette.colorAssignmentMode = mode
122
+ if (mode === 'by-value') {
123
+ _state.general.palette.colorAssignments = getAssignmentsFromCurrentColors()
124
+ }
125
+
126
+ updateConfig(_state)
127
+ }
128
+
129
+ const resetSeriesColorAssignmentsToCurrentColors = () => {
130
+ const _state = cloneConfig(config)
131
+ if (!_state.general.palette) {
132
+ _state.general.palette = {}
133
+ }
134
+
135
+ _state.general.palette.colorAssignmentMode = 'by-value'
136
+ _state.general.palette.colorAssignments = getAssignmentsFromCurrentColors()
137
+ updateConfig(_state)
138
+ }
139
+
140
+ const updateSeriesColorAssignment = (key: string, color: string) => {
141
+ const _state = cloneConfig(config)
142
+ if (!_state.general.palette) {
143
+ _state.general.palette = {}
144
+ }
145
+
146
+ const currentSeriesKeys = new Set(seriesColorAssignmentItems.map(({ key }) => key))
147
+ const assignments = seriesColorAssignments.filter(assignment => currentSeriesKeys.has(assignment.key))
148
+ const existingIndex = assignments.findIndex(assignment => assignment.key === key)
149
+ if (existingIndex === -1) {
150
+ assignments.push({ key, color })
151
+ } else {
152
+ assignments[existingIndex] = { key, color }
153
+ }
154
+
155
+ _state.general.palette.colorAssignmentMode = 'by-value'
156
+ _state.general.palette.colorAssignments = assignments
157
+ updateConfig(_state)
158
+ }
159
+
160
+ useEffect(() => {
161
+ const currentSource = { hasCustomColors, fingerprint: paletteSourceFingerprint }
162
+
163
+ if (!seriesColorAssignmentSupported || !isSeriesColorAssignmentByValue) {
164
+ previousPaletteSource.current = currentSource
165
+ return
166
+ }
167
+
168
+ const shouldResetFromPalette =
169
+ previousPaletteSource.current !== null &&
170
+ !hasCustomColors &&
171
+ paletteColorOptions.length > 0 &&
172
+ (previousPaletteSource.current.hasCustomColors ||
173
+ previousPaletteSource.current.fingerprint !== paletteSourceFingerprint)
174
+
175
+ previousPaletteSource.current = currentSource
176
+
177
+ if (shouldResetFromPalette) {
178
+ resetSeriesColorAssignmentsToCurrentColors()
179
+ return
180
+ }
181
+
182
+ const assignmentsWithMissingCurrentColors = getAssignmentsWithMissingCurrentColors()
183
+ if (assignmentsWithMissingCurrentColors) {
184
+ const _state = cloneConfig(config)
185
+ if (!_state.general.palette) {
186
+ _state.general.palette = {}
187
+ }
188
+
189
+ _state.general.palette.colorAssignmentMode = 'by-value'
190
+ _state.general.palette.colorAssignments = assignmentsWithMissingCurrentColors
191
+ updateConfig(_state)
192
+ }
193
+ }, [
194
+ hasCustomColors,
195
+ isSeriesColorAssignmentByValue,
196
+ paletteSourceFingerprint,
197
+ seriesColorAssignmentItemsFingerprint,
198
+ seriesColorAssignmentsFingerprint,
199
+ seriesColorAssignmentSupported
200
+ ])
201
+
202
+ if (!seriesColorAssignmentSupported) return null
203
+
204
+ return (
205
+ <fieldset className='series-color-assignments'>
206
+ <Select
207
+ value={seriesColorAssignmentMode}
208
+ label='Color Assignment Mode'
209
+ tooltip={
210
+ <Tooltip style={{ textTransform: 'none' }}>
211
+ <Tooltip.Target>
212
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
213
+ </Tooltip.Target>
214
+ <Tooltip.Content>
215
+ <p>
216
+ Toggling this determines how colors in the palette are assigned. Colors can be assigned in order or can
217
+ be associated with specific series.
218
+ </p>
219
+ </Tooltip.Content>
220
+ </Tooltip>
221
+ }
222
+ fieldName='colorAssignmentMode'
223
+ section='general'
224
+ subsection='palette'
225
+ updateField={(_section, _subsection, _fieldName, value) => {
226
+ updateSeriesColorAssignmentMode(value as 'ordered' | 'by-value')
227
+ }}
228
+ options={[
229
+ { label: 'Use palette order', value: 'ordered' },
230
+ { label: 'Assign colors to series', value: 'by-value' }
231
+ ]}
232
+ />
233
+ {isSeriesColorAssignmentByValue && (
234
+ <div className='series-color-assignments__rows'>
235
+ {seriesColorAssignmentItems.map(({ key, label }) => {
236
+ const assignedColor = seriesColorAssignmentMap.get(key)
237
+ const color = assignedColor || orderedColorScale(label) || paletteColorOptions[0] || '#000000'
238
+
239
+ return (
240
+ <div className='series-color-assignments__row' key={key}>
241
+ <label className='series-color-assignments__label' title={`Series key: ${key}`}>
242
+ {label}
243
+ </label>
244
+ <DataColorSelector
245
+ aria-label={`Color for ${label}`}
246
+ value={color}
247
+ colors={paletteColorOptions}
248
+ allowNone={false}
249
+ allowCustom={false}
250
+ showCustomValue={false}
251
+ onChange={nextColor => updateSeriesColorAssignment(key, nextColor)}
252
+ />
253
+ </div>
254
+ )
255
+ })}
256
+ </div>
257
+ )}
258
+ </fieldset>
259
+ )
260
+ }
261
+
262
+ export default SeriesColorAssignments
@@ -0,0 +1,32 @@
1
+ .series-color-assignments {
2
+ border: 1px solid #d6d7d9;
3
+ border-radius: 4px;
4
+ margin-top: 1rem;
5
+ padding: 0.875rem;
6
+ }
7
+
8
+ .series-color-assignments__rows {
9
+ display: grid;
10
+ gap: 0.5rem;
11
+ margin-top: 0.75rem;
12
+ }
13
+
14
+ .series-color-assignments__row {
15
+ align-items: center;
16
+ display: grid;
17
+ gap: 0.5rem;
18
+ grid-template-columns: minmax(0, 1fr) auto;
19
+ }
20
+
21
+ .series-color-assignments__label {
22
+ color: #222;
23
+ display: block;
24
+ font-size: 0.875rem;
25
+ overflow: hidden;
26
+ text-overflow: ellipsis;
27
+ white-space: nowrap;
28
+ }
29
+
30
+ .series-color-assignments__row .data-color-selector__trigger {
31
+ justify-self: end;
32
+ }
@@ -83,3 +83,13 @@
83
83
  .annotation-group {
84
84
  border: 1px solid black;
85
85
  }
86
+
87
+ .small-multiples-color-assignment-warning {
88
+ background: #fff7e6;
89
+ border-left: 3px solid #a65f00;
90
+ color: #3d2a00;
91
+ font-size: 0.875rem;
92
+ line-height: 1.4;
93
+ margin: 0.75rem 0 1rem;
94
+ padding: 0.5rem 0.75rem;
95
+ }
@@ -1,4 +1,51 @@
1
1
  .cove-visualization.type-chart {
2
+ .axis-domain-group {
3
+ border: 1px solid var(--lightGray);
4
+ border-radius: 4px;
5
+ margin-top: 1em;
6
+ padding: 0.75em;
7
+
8
+ > label,
9
+ > .checkbox {
10
+ margin-top: 0.9em;
11
+ }
12
+ }
13
+
14
+ .axis-domain-group__title {
15
+ display: block;
16
+ font-size: 0.85em;
17
+ font-weight: 700;
18
+ margin-bottom: 0.75em;
19
+ text-transform: uppercase;
20
+ }
21
+
22
+ .axis-domain-group__row {
23
+ display: flex;
24
+ gap: 0.75em;
25
+ }
26
+
27
+ .axis-domain-group__field {
28
+ flex: 1 1 0;
29
+ min-width: 0;
30
+
31
+ > label {
32
+ margin-top: 0 !important;
33
+ }
34
+ }
35
+
36
+ .axis-domain-number {
37
+ max-width: 96px;
38
+ min-width: auto;
39
+ width: 100%;
40
+ }
41
+
42
+ .axis-domain-warning {
43
+ color: red;
44
+ display: block;
45
+ font-size: 0.85em;
46
+ margin-top: 0.25em;
47
+ }
48
+
2
49
  .viewport-overrides {
3
50
  button {
4
51
  width: 100%;
@@ -22,7 +22,11 @@ export const getVisualizationTypeConfigUpdate = (
22
22
  return {
23
23
  ...config,
24
24
  visualizationType,
25
- series: [],
25
+ series: (config.series || []).map(series => ({
26
+ ...series,
27
+ type: 'HeatMap',
28
+ axis: 'Left'
29
+ })),
26
30
  yAxis: {
27
31
  ...config.yAxis,
28
32
  type: 'categorical',
@@ -40,7 +44,7 @@ export const getVisualizationTypeConfigUpdate = (
40
44
  ...config.legend,
41
45
  position: 'top',
42
46
  style: 'gradient',
43
- subStyle: 'smooth'
47
+ subStyle: 'linear blocks'
44
48
  },
45
49
  general: {
46
50
  ...config.general,
@@ -40,17 +40,35 @@ describe('getVisualizationTypeConfigUpdate', () => {
40
40
  const updatedConfig = getVisualizationTypeConfigUpdate(buildConfig(), 'HeatMap')
41
41
 
42
42
  expect(updatedConfig?.visualizationType).toBe('HeatMap')
43
- expect(updatedConfig?.series).toEqual([])
43
+ expect(updatedConfig?.series).toEqual([{ dataKey: 'Value', type: 'HeatMap', axis: 'Left' }])
44
44
  expect(updatedConfig?.yAxis.type).toBe('categorical')
45
45
  expect(updatedConfig?.yAxis.titlePlacement).toBe('side')
46
46
  expect(updatedConfig?.heatmap).toEqual(HEATMAP_CONFIG_DEFAULTS)
47
47
  expect(updatedConfig?.legend.position).toBe('top')
48
48
  expect(updatedConfig?.legend.style).toBe('gradient')
49
- expect(updatedConfig?.legend.subStyle).toBe('smooth')
49
+ expect(updatedConfig?.legend.subStyle).toBe('linear blocks')
50
50
  expect(updatedConfig?.general.palette).toEqual({
51
51
  isReversed: false,
52
52
  version: '2.0',
53
53
  name: 'sequential_blue'
54
54
  })
55
55
  })
56
+
57
+ it('preserves selected rows when switching back to HeatMap from another chart type', () => {
58
+ const updatedConfig = getVisualizationTypeConfigUpdate(
59
+ buildConfig({
60
+ visualizationType: 'Bar',
61
+ series: [
62
+ { dataKey: 'North', name: 'North', type: 'Bar', axis: 'Left', tooltip: true },
63
+ { dataKey: 'South', name: 'South', type: 'Bar', axis: 'Left', tooltip: true }
64
+ ]
65
+ }),
66
+ 'HeatMap'
67
+ )
68
+
69
+ expect(updatedConfig?.series).toEqual([
70
+ { dataKey: 'North', name: 'North', type: 'HeatMap', axis: 'Left', tooltip: true },
71
+ { dataKey: 'South', name: 'South', type: 'HeatMap', axis: 'Left', tooltip: true }
72
+ ])
73
+ })
56
74
  })
@@ -1,7 +1,7 @@
1
1
  import DataTransform from '@cdc/core/helpers/DataTransform'
2
2
  import { ChartConfig } from '../../../types/ChartConfig'
3
3
  import cloneConfig from '@cdc/core/helpers/cloneConfig'
4
- import _ from 'lodash'
4
+ import get from 'lodash/get'
5
5
 
6
6
  const transform = new DataTransform()
7
7
 
@@ -31,8 +31,8 @@ export const updateFieldRankByValue = (
31
31
  newConfig.rankByValue = newValue
32
32
 
33
33
  if (config.rankByValue && !newValue) {
34
- const CIkeys: string[] = Object.values(_.get(config, 'confidenceKeys', {})) as string[]
35
- const seriesKeys: string[] = _.get(config, 'series', []).map((s: any) => s.dataKey)
34
+ const CIkeys: string[] = Object.values(get(config, 'confidenceKeys', {})) as string[]
35
+ const seriesKeys: string[] = get(config, 'series', []).map((s: any) => s.dataKey)
36
36
  const keysToClean: string[] = [...(seriesKeys ?? []), ...(CIkeys ?? [])]
37
37
 
38
38
  const cleanData = config?.xAxis?.dataKey