@cdc/chart 4.26.4 → 4.26.6
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.
- package/CONFIG.md +353 -29
- package/LICENSE +201 -0
- package/dist/{cdcchart-DQ00cQCm.es.js → cdcchart-BWVIUcAF.es.js} +5 -55
- package/dist/cdcchart.js +37885 -35117
- package/examples/feature/heatmap/average-age-categorical.json +313 -0
- package/examples/feature/heatmap/calendar-heatmap.json +134 -0
- package/examples/feature/heatmap/cell-values-bottom-axis.json +181 -0
- package/examples/feature/heatmap/sparse-aggregation.json +158 -0
- package/examples/private/bad-y-axis.json +543 -0
- package/examples/private/bar-chart-negative-value.json +455 -0
- package/examples/private/bump-chart.json +1116 -0
- package/examples/private/test-123.json +624 -0
- package/package.json +4 -3
- package/src/CdcChart.tsx +5 -4
- package/src/CdcChartComponent.tsx +166 -62
- package/src/_stories/Chart.AltText.stories.tsx +136 -0
- package/src/_stories/Chart.HeatMap.stories.tsx +187 -0
- package/src/_stories/Chart.Sankey.smoke.stories.tsx +62 -0
- package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +183 -0
- package/src/_stories/Chart.SmallMultiples.smoke.stories.tsx +29 -0
- package/src/_stories/Chart.YAxisAutoMaxStrategy.stories.tsx +52 -0
- package/src/_stories/Chart.YAxisFilterDomain.stories.tsx +90 -0
- package/src/_stories/ChartAnnotation.smoke.stories.tsx +10 -0
- package/src/_stories/ChartAxisTitles.smoke.stories.tsx +13 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +63 -0
- package/src/_stories/ChartBrush.Interaction.stories.tsx +112 -0
- package/src/_stories/ChartBrush.smoke.stories.tsx +13 -4
- package/src/_stories/_mock/alt_text_metadata.json +38 -0
- package/src/_stories/_mock/annotation_event-line_mock.json +1064 -0
- package/src/_stories/_mock/heatmap-average-age-categorical.json +315 -0
- package/src/_stories/_mock/heatmap.json +156 -0
- package/src/_stories/_mock/reported_pertussis_cases.json +1643 -0
- package/src/_stories/_mock/sankey_mock.json +78 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +1 -1
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +22 -1
- package/src/components/Annotations/components/AnnotationDraggable.tsx +220 -120
- package/src/components/Annotations/components/AnnotationDropdown.tsx +5 -2
- package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +198 -0
- package/src/components/Axis/LeftAxis.tsx +17 -11
- package/src/components/Axis/LeftAxisGridlines.tsx +22 -12
- package/src/components/Axis/RightAxis.tsx +3 -0
- package/src/components/Axis/tests/AxisTickValues.test.tsx +86 -0
- package/src/components/Brush/BrushSelector.tsx +88 -187
- package/src/components/Brush/brushInteraction.ts +22 -0
- package/src/components/Brush/tests/brushInteraction.test.ts +38 -0
- package/src/components/EditorPanel/EditorPanel.tsx +677 -185
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +114 -52
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +105 -13
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +1 -0
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +5 -0
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +2 -2
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.test.tsx +98 -0
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +10 -0
- package/src/components/EditorPanel/components/Panels/Panel.Visual.test.tsx +484 -0
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +4 -1
- package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +262 -0
- package/src/components/EditorPanel/components/Panels/panelVisual.styles.css +32 -0
- package/src/components/EditorPanel/components/panels.scss +10 -0
- package/src/components/EditorPanel/editor-panel.scss +47 -0
- package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +61 -0
- package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +74 -0
- package/src/components/EditorPanel/useEditorPermissions.test.tsx +315 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +77 -21
- package/src/components/HeatMap/components/HeatMap.tsx +767 -0
- package/src/components/HeatMap/components/HeatMapGradientLegend.tsx +128 -0
- package/src/components/HeatMap/heatmap.constants.ts +13 -0
- package/src/components/HeatMap/heatmap.css +85 -0
- package/src/components/HeatMap/helpers/index.ts +261 -0
- package/src/components/HeatMap/index.tsx +5 -0
- package/src/components/HeatMap/tests/HeatMap.test.tsx +1072 -0
- package/src/components/HeatMap/tests/helpers.test.ts +167 -0
- package/src/components/Legend/Legend.Component.tsx +2 -2
- package/src/components/Legend/helpers/createFormatLabels.test.ts +88 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +6 -1
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +19 -22
- package/src/components/LineChart/helpers.test.ts +574 -0
- package/src/components/LineChart/helpers.ts +39 -16
- package/src/components/LineChart/index.tsx +28 -5
- package/src/components/LinearChart/tests/LinearChart.test.tsx +137 -33
- package/src/components/LinearChart/tests/mockConfigContext.ts +1 -0
- package/src/components/LinearChart.tsx +103 -47
- package/src/components/PieChart/PieChart.tsx +4 -1
- package/src/components/RadarChart/RadarChart.tsx +3 -1
- package/src/components/Regions/components/Regions.tsx +195 -41
- package/src/components/Sankey/components/Sankey.tsx +7 -3
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +7 -6
- package/src/components/ScatterPlot/ScatterPlot.jsx +3 -3
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +33 -3
- package/src/components/SmallMultiples/SmallMultiples.css +12 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +50 -15
- package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +152 -0
- package/src/components/SmallMultiples/tests/SmallMultiples.test.tsx +170 -0
- package/src/components/Sparkline/components/SparkLine.tsx +4 -9
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +1 -1
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +2 -2
- package/src/data/initial-state.js +12 -0
- package/src/helpers/axisLabelFontSize.ts +8 -0
- package/src/helpers/bumpChartTooltip.ts +54 -0
- package/src/helpers/calculateLeftYAxisWidth.ts +13 -3
- package/src/helpers/colorAssignmentHelpers.ts +102 -0
- package/src/helpers/dataHelpers.ts +11 -1
- package/src/helpers/ensureSpecialChartAxisTypes.ts +11 -0
- package/src/helpers/getAxisMaxOverride.ts +16 -0
- package/src/helpers/getCleanTopTickMax.ts +64 -0
- package/src/helpers/getColorScale.ts +18 -9
- package/src/helpers/getHasBoundarySuppression.ts +26 -0
- package/src/helpers/getMinMax.ts +26 -25
- package/src/helpers/getYAxisDomainData.ts +38 -0
- package/src/helpers/getYAxisFinalizationEligibility.ts +40 -0
- package/src/helpers/handleChartAriaLabels.ts +23 -10
- package/src/helpers/hasSpacedInlineLabel.ts +10 -0
- package/src/helpers/seriesColumnSettings.ts +5 -4
- package/src/helpers/seriesHighlight.ts +26 -0
- package/src/helpers/smallMultiplesHelpers.ts +5 -0
- package/src/helpers/tests/axisLabelFontSize.test.ts +15 -0
- package/src/helpers/tests/bumpChartTooltip.test.ts +75 -0
- package/src/helpers/tests/calculateLeftYAxisWidth.test.ts +38 -0
- package/src/helpers/tests/dataHelpers.test.ts +135 -0
- package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +30 -0
- package/src/helpers/tests/getAxisMaxOverride.test.ts +36 -0
- package/src/helpers/tests/getCleanTopTickMax.test.ts +165 -0
- package/src/helpers/tests/getColorScale.test.ts +197 -0
- package/src/helpers/tests/getMinMax.test.ts +211 -0
- package/src/helpers/tests/getYAxisDomainData.test.ts +119 -0
- package/src/helpers/tests/getYAxisFinalizationEligibility.test.ts +185 -0
- package/src/helpers/tests/handleChartAriaLabels.test.ts +71 -0
- package/src/helpers/tests/hasSpacedInlineLabel.test.ts +75 -0
- package/src/helpers/tests/seriesColumnSettings.test.ts +16 -2
- package/src/helpers/tests/seriesHighlight.test.ts +61 -0
- package/src/helpers/tests/smallMultiplesHelpers.test.ts +99 -0
- package/src/hooks/tests/useRightAxis.test.tsx +127 -0
- package/src/hooks/tests/useScales.test.tsx +383 -0
- package/src/hooks/useRightAxis.ts +30 -13
- package/src/hooks/useScales.ts +48 -21
- package/src/hooks/useTooltip.tsx +3 -1
- package/src/index.jsx +5 -2
- package/src/scss/main.scss +32 -49
- package/src/test/CdcChart.dataTable.test.tsx +122 -0
- package/src/types/ChartConfig.ts +24 -1
- package/src/types/ChartContext.ts +5 -0
- package/src/helpers/getYAxisAutoPadding.ts +0 -53
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { renderHook } from '@testing-library/react'
|
|
3
|
+
import { describe, expect, it } from 'vitest'
|
|
4
|
+
import ConfigContext from '../../ConfigContext'
|
|
5
|
+
import { useEditorPermissions } from './useEditorPermissions'
|
|
6
|
+
import { createMockChartContext, createMockConfig } from '../LinearChart/tests/mockConfigContext'
|
|
7
|
+
import { ChartConfig } from '../../types/ChartConfig'
|
|
8
|
+
|
|
9
|
+
const renderUseEditorPermissions = (
|
|
10
|
+
configOverrides: Partial<ChartConfig>,
|
|
11
|
+
contextOverrides: Partial<ReturnType<typeof createMockChartContext>> = {}
|
|
12
|
+
) => {
|
|
13
|
+
const config = createMockConfig(configOverrides)
|
|
14
|
+
const context = createMockChartContext(config, contextOverrides)
|
|
15
|
+
const wrapper = ({ children }: React.PropsWithChildren) => (
|
|
16
|
+
<ConfigContext.Provider value={context}>{children}</ConfigContext.Provider>
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
return renderHook(() => useEditorPermissions(), { wrapper })
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('useEditorPermissions', () => {
|
|
23
|
+
it('shows manual y-axis padding controls when there is no spaced inline label', () => {
|
|
24
|
+
const { result } = renderUseEditorPermissions({
|
|
25
|
+
yAxis: {
|
|
26
|
+
...createMockConfig().yAxis,
|
|
27
|
+
titlePlacement: 'side',
|
|
28
|
+
inlineLabel: 'Rate'
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
expect(result.current.visSupportsYPadding()).toBe(true)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('hides manual y-axis padding controls for spaced inline labels when renderer headroom applies', () => {
|
|
36
|
+
const { result } = renderUseEditorPermissions({
|
|
37
|
+
yAxis: {
|
|
38
|
+
...createMockConfig().yAxis,
|
|
39
|
+
titlePlacement: 'side',
|
|
40
|
+
inlineLabel: 'per 100k'
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
expect(result.current.visSupportsYPadding()).toBe(false)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('shows manual y-axis padding controls for horizontal charts with spaced inline labels', () => {
|
|
48
|
+
const { result } = renderUseEditorPermissions({
|
|
49
|
+
orientation: 'horizontal',
|
|
50
|
+
yAxis: {
|
|
51
|
+
...createMockConfig().yAxis,
|
|
52
|
+
titlePlacement: 'side',
|
|
53
|
+
inlineLabel: 'per 100k'
|
|
54
|
+
}
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
expect(result.current.visSupportsYPadding()).toBe(true)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('shows manual y-axis padding controls for Combo charts with spaced inline labels', () => {
|
|
61
|
+
const { result } = renderUseEditorPermissions({
|
|
62
|
+
visualizationType: 'Combo',
|
|
63
|
+
yAxis: {
|
|
64
|
+
...createMockConfig().yAxis,
|
|
65
|
+
titlePlacement: 'side',
|
|
66
|
+
inlineLabel: 'per 100k'
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
expect(result.current.visSupportsYPadding()).toBe(true)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('shows manual y-axis padding controls for top y-axis titles', () => {
|
|
74
|
+
const { result } = renderUseEditorPermissions({
|
|
75
|
+
yAxis: {
|
|
76
|
+
...createMockConfig().yAxis,
|
|
77
|
+
titlePlacement: 'top',
|
|
78
|
+
label: 'Y-Axis',
|
|
79
|
+
inlineLabel: ''
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
expect(result.current.visSupportsYPadding()).toBe(true)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it('supports series color assignments only for eligible authored-series charts', () => {
|
|
87
|
+
const supported = renderUseEditorPermissions({
|
|
88
|
+
visualizationType: 'Line',
|
|
89
|
+
series: [{ dataKey: 'cases', type: 'Line' }] as any
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
expect(supported.result.current.visSupportsSeriesColorAssignments()).toBe(true)
|
|
93
|
+
|
|
94
|
+
const unsupported = renderUseEditorPermissions({
|
|
95
|
+
visualizationType: 'Pie',
|
|
96
|
+
series: [{ dataKey: 'cases', type: 'Pie' }] as any
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
expect(unsupported.result.current.visSupportsSeriesColorAssignments()).toBe(false)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('shows filter-domain behavior when a standalone chart has visible filters and automatic max', () => {
|
|
103
|
+
const { result } = renderUseEditorPermissions({
|
|
104
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
105
|
+
yAxis: {
|
|
106
|
+
...createMockConfig().yAxis,
|
|
107
|
+
max: '',
|
|
108
|
+
type: 'linear'
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(true)
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
it('shows filter-domain behavior for horizontal bar charts when automatic max can respond to filters', () => {
|
|
116
|
+
const { result } = renderUseEditorPermissions({
|
|
117
|
+
visualizationType: 'Bar',
|
|
118
|
+
orientation: 'horizontal',
|
|
119
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
120
|
+
yAxis: {
|
|
121
|
+
...createMockConfig().yAxis,
|
|
122
|
+
max: '',
|
|
123
|
+
type: 'linear'
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(true)
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('shows filter-domain behavior for dashboard charts without local filters', () => {
|
|
131
|
+
const { result } = renderUseEditorPermissions(
|
|
132
|
+
{
|
|
133
|
+
filters: [],
|
|
134
|
+
yAxis: {
|
|
135
|
+
...createMockConfig().yAxis,
|
|
136
|
+
max: '',
|
|
137
|
+
type: 'linear'
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{ isDashboard: true }
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(true)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('hides filter-domain behavior when vertical value-axis max is explicit', () => {
|
|
147
|
+
const { result } = renderUseEditorPermissions(
|
|
148
|
+
{
|
|
149
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
150
|
+
yAxis: {
|
|
151
|
+
...createMockConfig().yAxis,
|
|
152
|
+
max: '100',
|
|
153
|
+
type: 'linear'
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
{ isDashboard: true }
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(false)
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('hides filter-domain behavior for horizontal charts when value-axis max is explicit', () => {
|
|
163
|
+
const { result } = renderUseEditorPermissions(
|
|
164
|
+
{
|
|
165
|
+
visualizationType: 'Bar',
|
|
166
|
+
orientation: 'horizontal',
|
|
167
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
168
|
+
xAxis: {
|
|
169
|
+
...createMockConfig().xAxis,
|
|
170
|
+
max: '100'
|
|
171
|
+
},
|
|
172
|
+
yAxis: {
|
|
173
|
+
...createMockConfig().yAxis,
|
|
174
|
+
max: '',
|
|
175
|
+
type: 'linear'
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
{ isDashboard: true }
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(false)
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('hides filter-domain behavior for unfiltered standalone charts', () => {
|
|
185
|
+
const { result } = renderUseEditorPermissions({
|
|
186
|
+
filters: [],
|
|
187
|
+
yAxis: {
|
|
188
|
+
...createMockConfig().yAxis,
|
|
189
|
+
max: '',
|
|
190
|
+
type: 'linear'
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(false)
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
it('hides filter-domain behavior for charts outside the value-axis allowlist', () => {
|
|
198
|
+
const { result } = renderUseEditorPermissions(
|
|
199
|
+
{
|
|
200
|
+
visualizationType: 'Bump Chart',
|
|
201
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
202
|
+
yAxis: {
|
|
203
|
+
...createMockConfig().yAxis,
|
|
204
|
+
max: '',
|
|
205
|
+
type: 'linear'
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
{ isDashboard: true }
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(false)
|
|
212
|
+
})
|
|
213
|
+
|
|
214
|
+
it('hides filter-domain behavior for chart types with specialized value scales', () => {
|
|
215
|
+
const { result } = renderUseEditorPermissions(
|
|
216
|
+
{
|
|
217
|
+
visualizationType: 'Paired Bar',
|
|
218
|
+
filters: [{ columnName: 'Region', showDropdown: true } as any],
|
|
219
|
+
yAxis: {
|
|
220
|
+
...createMockConfig().yAxis,
|
|
221
|
+
max: '',
|
|
222
|
+
type: 'linear'
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
{ isDashboard: true }
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
expect(result.current.visSupportsFilterDomainBehavior()).toBe(false)
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
it('shows automatic max strategy for automatic numeric value axes', () => {
|
|
232
|
+
const { result } = renderUseEditorPermissions({
|
|
233
|
+
yAxis: {
|
|
234
|
+
...createMockConfig().yAxis,
|
|
235
|
+
max: '',
|
|
236
|
+
type: 'linear'
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(true)
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
it('shows automatic max strategy for horizontal charts with automatic value axes', () => {
|
|
244
|
+
const { result } = renderUseEditorPermissions({
|
|
245
|
+
visualizationType: 'Bar',
|
|
246
|
+
orientation: 'horizontal',
|
|
247
|
+
xAxis: {
|
|
248
|
+
...createMockConfig().xAxis,
|
|
249
|
+
max: ''
|
|
250
|
+
},
|
|
251
|
+
yAxis: {
|
|
252
|
+
...createMockConfig().yAxis,
|
|
253
|
+
max: '',
|
|
254
|
+
type: 'linear'
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(true)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it('hides automatic max strategy when vertical value-axis max is explicit', () => {
|
|
262
|
+
const { result } = renderUseEditorPermissions({
|
|
263
|
+
yAxis: {
|
|
264
|
+
...createMockConfig().yAxis,
|
|
265
|
+
max: '100',
|
|
266
|
+
type: 'linear'
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(false)
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
it('hides automatic max strategy for horizontal charts when value-axis max is explicit', () => {
|
|
274
|
+
const { result } = renderUseEditorPermissions({
|
|
275
|
+
visualizationType: 'Bar',
|
|
276
|
+
orientation: 'horizontal',
|
|
277
|
+
xAxis: {
|
|
278
|
+
...createMockConfig().xAxis,
|
|
279
|
+
max: '100'
|
|
280
|
+
},
|
|
281
|
+
yAxis: {
|
|
282
|
+
...createMockConfig().yAxis,
|
|
283
|
+
max: '',
|
|
284
|
+
type: 'linear'
|
|
285
|
+
}
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(false)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
it('hides automatic max strategy for categorical value axes', () => {
|
|
292
|
+
const { result } = renderUseEditorPermissions({
|
|
293
|
+
yAxis: {
|
|
294
|
+
...createMockConfig().yAxis,
|
|
295
|
+
max: '',
|
|
296
|
+
type: 'categorical'
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(false)
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it('hides automatic max strategy for chart types with specialized value scales', () => {
|
|
304
|
+
const { result } = renderUseEditorPermissions({
|
|
305
|
+
visualizationType: 'Paired Bar',
|
|
306
|
+
yAxis: {
|
|
307
|
+
...createMockConfig().yAxis,
|
|
308
|
+
max: '',
|
|
309
|
+
type: 'linear'
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
expect(result.current.visSupportsAutoMaxStrategy()).toBe(false)
|
|
314
|
+
})
|
|
315
|
+
})
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import React, { useContext } from 'react'
|
|
2
2
|
import ConfigContext from '../../ConfigContext'
|
|
3
|
+
import { getYAxisFinalizationEligibility } from '../../helpers/getYAxisFinalizationEligibility'
|
|
4
|
+
import { hasSpacedInlineLabel } from '../../helpers/hasSpacedInlineLabel'
|
|
5
|
+
import { supportsSeriesColorAssignments } from '../../helpers/colorAssignmentHelpers'
|
|
6
|
+
import { hasVisibleVizFilters } from '@cdc/core/helpers/filterVisibility'
|
|
3
7
|
|
|
4
8
|
export const useEditorPermissions = () => {
|
|
5
|
-
const { config } = useContext(ConfigContext)
|
|
9
|
+
const { config, isDashboard } = useContext(ConfigContext)
|
|
6
10
|
const { visualizationType, series, orientation, visualizationSubType } = config
|
|
7
11
|
|
|
8
12
|
// Overall support for the chart types
|
|
@@ -16,6 +20,7 @@ export const useEditorPermissions = () => {
|
|
|
16
20
|
'Deviation Bar',
|
|
17
21
|
'Forecasting',
|
|
18
22
|
// 'Forest Plot',
|
|
23
|
+
'HeatMap',
|
|
19
24
|
'Horizon Chart',
|
|
20
25
|
'Line',
|
|
21
26
|
'Paired Bar',
|
|
@@ -58,7 +63,7 @@ export const useEditorPermissions = () => {
|
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
const visSupportsClickingLegend = () => {
|
|
61
|
-
const disabledCharts = ['Horizon Chart']
|
|
66
|
+
const disabledCharts = ['HeatMap', 'Horizon Chart']
|
|
62
67
|
if (disabledCharts.includes(visualizationType)) return false
|
|
63
68
|
return true
|
|
64
69
|
}
|
|
@@ -75,6 +80,7 @@ export const useEditorPermissions = () => {
|
|
|
75
80
|
'Box Plot',
|
|
76
81
|
'Bump Chart',
|
|
77
82
|
'Forest Plot',
|
|
83
|
+
'HeatMap',
|
|
78
84
|
'Horizon Chart',
|
|
79
85
|
'Pie',
|
|
80
86
|
'Radar',
|
|
@@ -93,6 +99,7 @@ export const useEditorPermissions = () => {
|
|
|
93
99
|
'Box Plot',
|
|
94
100
|
'Bump Chart',
|
|
95
101
|
'Forest Plot',
|
|
102
|
+
'HeatMap',
|
|
96
103
|
'Radar',
|
|
97
104
|
'Sankey',
|
|
98
105
|
'Scatter Plot',
|
|
@@ -109,6 +116,8 @@ export const useEditorPermissions = () => {
|
|
|
109
116
|
return true
|
|
110
117
|
case 'Forest Plot':
|
|
111
118
|
return false
|
|
119
|
+
case 'HeatMap':
|
|
120
|
+
return true
|
|
112
121
|
case 'Spark Line':
|
|
113
122
|
return false
|
|
114
123
|
case 'Sankey':
|
|
@@ -197,9 +206,13 @@ export const useEditorPermissions = () => {
|
|
|
197
206
|
}
|
|
198
207
|
}
|
|
199
208
|
|
|
200
|
-
const visHasSelectableLegendValues = ![
|
|
201
|
-
|
|
202
|
-
|
|
209
|
+
const visHasSelectableLegendValues = ![
|
|
210
|
+
'Box Plot',
|
|
211
|
+
'Forest Plot',
|
|
212
|
+
'HeatMap',
|
|
213
|
+
'Spark Line',
|
|
214
|
+
'Warming Stripes'
|
|
215
|
+
].includes(visualizationType)
|
|
203
216
|
const visHasLegendAxisAlign = () => {
|
|
204
217
|
return visualizationType === 'Bar' && visualizationSubType === 'stacked' && config.legend.behavior === 'isolate'
|
|
205
218
|
}
|
|
@@ -208,7 +221,7 @@ export const useEditorPermissions = () => {
|
|
|
208
221
|
}
|
|
209
222
|
|
|
210
223
|
const visSupportsTooltipOpacity = () => {
|
|
211
|
-
const disabledCharts = ['Spark Line', 'Sankey', 'Warming Stripes']
|
|
224
|
+
const disabledCharts = ['HeatMap', 'Spark Line', 'Sankey', 'Warming Stripes']
|
|
212
225
|
if (disabledCharts.includes(visualizationType)) return false
|
|
213
226
|
return true
|
|
214
227
|
}
|
|
@@ -226,7 +239,7 @@ export const useEditorPermissions = () => {
|
|
|
226
239
|
}
|
|
227
240
|
|
|
228
241
|
const visSupportsNonSequentialPallete = () => {
|
|
229
|
-
const disabledCharts = ['Paired Bar', 'Deviation Bar', 'Forest Plot', 'Forecasting', 'Sankey']
|
|
242
|
+
const disabledCharts = ['HeatMap', 'Paired Bar', 'Deviation Bar', 'Forest Plot', 'Forecasting', 'Sankey']
|
|
230
243
|
if (disabledCharts.includes(visualizationType)) return false
|
|
231
244
|
return true
|
|
232
245
|
}
|
|
@@ -238,7 +251,7 @@ export const useEditorPermissions = () => {
|
|
|
238
251
|
}
|
|
239
252
|
|
|
240
253
|
const visSupportsDateCategoryAxisLabel = () => {
|
|
241
|
-
const disabledCharts = ['Forest Plot', 'Spark Line', 'Bump Chart', 'Warming Stripes']
|
|
254
|
+
const disabledCharts = ['Forest Plot', 'HeatMap', 'Spark Line', 'Bump Chart', 'Warming Stripes']
|
|
242
255
|
if (disabledCharts.includes(visualizationType)) return false
|
|
243
256
|
return true
|
|
244
257
|
}
|
|
@@ -262,31 +275,41 @@ export const useEditorPermissions = () => {
|
|
|
262
275
|
}
|
|
263
276
|
|
|
264
277
|
const visSupportsDateCategoryNumTicks = () => {
|
|
265
|
-
const disabledCharts = ['Spark Line']
|
|
278
|
+
const disabledCharts = ['HeatMap', 'Spark Line']
|
|
266
279
|
if (disabledCharts.includes(visualizationType)) return false
|
|
267
280
|
return true
|
|
268
281
|
}
|
|
269
282
|
|
|
270
283
|
const visSupportsResponsiveTicks = () => {
|
|
271
|
-
const disabledCharts = ['Spark Line']
|
|
284
|
+
const disabledCharts = ['HeatMap', 'Spark Line']
|
|
272
285
|
if (disabledCharts.includes(visualizationType)) return false
|
|
273
286
|
return true
|
|
274
287
|
}
|
|
275
288
|
|
|
276
289
|
const visSupportsRegions = () => {
|
|
277
|
-
const disabledCharts = [
|
|
290
|
+
const disabledCharts = [
|
|
291
|
+
'Forest Plot',
|
|
292
|
+
'Horizon Chart',
|
|
293
|
+
'HeatMap',
|
|
294
|
+
'Pie',
|
|
295
|
+
'Paired Bar',
|
|
296
|
+
'Radar',
|
|
297
|
+
'Spark Line',
|
|
298
|
+
'Sankey',
|
|
299
|
+
'Warming Stripes'
|
|
300
|
+
]
|
|
278
301
|
if (disabledCharts.includes(visualizationType)) return false
|
|
279
302
|
return true
|
|
280
303
|
}
|
|
281
304
|
|
|
282
305
|
const visSupportsValueAxisMax = () => {
|
|
283
|
-
const disabledCharts = ['Forest Plot']
|
|
306
|
+
const disabledCharts = ['Forest Plot', 'HeatMap']
|
|
284
307
|
if (disabledCharts.includes(visualizationType)) return false
|
|
285
308
|
return true
|
|
286
309
|
}
|
|
287
310
|
|
|
288
311
|
const visSupportsValueAxisMin = () => {
|
|
289
|
-
const disabledCharts = ['Forest Plot']
|
|
312
|
+
const disabledCharts = ['Forest Plot', 'HeatMap']
|
|
290
313
|
if (disabledCharts.includes(visualizationType)) return false
|
|
291
314
|
return true
|
|
292
315
|
}
|
|
@@ -297,15 +320,36 @@ export const useEditorPermissions = () => {
|
|
|
297
320
|
return true
|
|
298
321
|
}
|
|
299
322
|
|
|
323
|
+
const hasExplicitValueAxisMax = () => {
|
|
324
|
+
const valueAxisMax = orientation === 'horizontal' ? config.xAxis?.max : config.yAxis?.max
|
|
325
|
+
return valueAxisMax !== undefined && valueAxisMax !== null && valueAxisMax !== ''
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const visSupportsAutomaticValueDomain = () => {
|
|
329
|
+
const enabledCharts = ['Area Chart', 'Bar', 'Combo', 'Deviation Bar', 'Forecasting', 'Line', 'Scatter Plot']
|
|
330
|
+
if (!enabledCharts.includes(visualizationType)) return false
|
|
331
|
+
if (config.yAxis?.type === 'categorical') return false
|
|
332
|
+
if (hasExplicitValueAxisMax()) return false
|
|
333
|
+
return true
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const visSupportsAutoMaxStrategy = () => {
|
|
337
|
+
return visSupportsAutomaticValueDomain()
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const visSupportsFilterDomainBehavior = () => {
|
|
341
|
+
return visSupportsAutomaticValueDomain() && Boolean(isDashboard || hasVisibleVizFilters(config.filters))
|
|
342
|
+
}
|
|
343
|
+
|
|
300
344
|
const visSupportsValueAxisGridLines = () => {
|
|
301
|
-
const disabledCharts = ['Forest Plot']
|
|
345
|
+
const disabledCharts = ['Forest Plot', 'HeatMap']
|
|
302
346
|
if (disabledCharts.includes(visualizationType)) return false
|
|
303
347
|
return true
|
|
304
348
|
}
|
|
305
349
|
|
|
306
350
|
// implement later
|
|
307
351
|
const visSupportsValueAxisTicks = () => {
|
|
308
|
-
const disabledCharts = ['Forest Plot']
|
|
352
|
+
const disabledCharts = ['Forest Plot', 'HeatMap']
|
|
309
353
|
if (disabledCharts.includes(visualizationType)) return false
|
|
310
354
|
return true
|
|
311
355
|
}
|
|
@@ -319,7 +363,7 @@ export const useEditorPermissions = () => {
|
|
|
319
363
|
|
|
320
364
|
// implement later
|
|
321
365
|
const visSupportsValueAxisLabels = () => {
|
|
322
|
-
const disabledCharts = ['Forest Plot', 'Bump Chart']
|
|
366
|
+
const disabledCharts = ['Forest Plot', 'HeatMap', 'Bump Chart']
|
|
323
367
|
if (disabledCharts.includes(visualizationType)) return false
|
|
324
368
|
return true
|
|
325
369
|
}
|
|
@@ -332,7 +376,7 @@ export const useEditorPermissions = () => {
|
|
|
332
376
|
}
|
|
333
377
|
|
|
334
378
|
const visSupportsBarThickness = () => {
|
|
335
|
-
const disabledCharts = ['Forest Plot', 'Warming Stripes']
|
|
379
|
+
const disabledCharts = ['Forest Plot', 'HeatMap', 'Warming Stripes']
|
|
336
380
|
if (disabledCharts.includes(visualizationType)) return false
|
|
337
381
|
return true
|
|
338
382
|
}
|
|
@@ -344,7 +388,7 @@ export const useEditorPermissions = () => {
|
|
|
344
388
|
}
|
|
345
389
|
const visSupportsMobileChartHeight = () => {
|
|
346
390
|
// TODO: this is a soft release. Support should eventually match visSupportsChartHeight
|
|
347
|
-
const enabledCharts = ['Bar', 'Line', 'Combo', 'Area Chart', 'Radar']
|
|
391
|
+
const enabledCharts = ['Bar', 'Line', 'Combo', 'Area Chart', 'HeatMap', 'Radar']
|
|
348
392
|
if (enabledCharts.includes(visualizationType)) return true
|
|
349
393
|
return false
|
|
350
394
|
}
|
|
@@ -356,13 +400,13 @@ export const useEditorPermissions = () => {
|
|
|
356
400
|
}
|
|
357
401
|
|
|
358
402
|
const visSupportsRankByValue = () => {
|
|
359
|
-
const disabledCharts = ['Spark Line']
|
|
403
|
+
const disabledCharts = ['HeatMap', 'Spark Line']
|
|
360
404
|
if (disabledCharts.includes(visualizationType)) return false
|
|
361
405
|
return true
|
|
362
406
|
}
|
|
363
407
|
|
|
364
408
|
const visSupportsDateCategoryHeight = () => {
|
|
365
|
-
const disabledCharts = ['Spark Line', 'Sankey', 'Bump Chart']
|
|
409
|
+
const disabledCharts = ['HeatMap', 'Spark Line', 'Sankey', 'Bump Chart']
|
|
366
410
|
if (disabledCharts.includes(visualizationType)) return false
|
|
367
411
|
if (config.orientation !== 'horizontal') return false
|
|
368
412
|
if (config.orientation === 'horizontal' && visualizationType === 'Bar' && !config.isLollipopChart) return false
|
|
@@ -406,8 +450,17 @@ export const useEditorPermissions = () => {
|
|
|
406
450
|
return false
|
|
407
451
|
}
|
|
408
452
|
|
|
453
|
+
const visSupportsSeriesColorAssignments = () => supportsSeriesColorAssignments(config)
|
|
454
|
+
|
|
409
455
|
const visSupportsYPadding = () => {
|
|
410
|
-
|
|
456
|
+
const { shouldUseInlineLabelHeadroom } = getYAxisFinalizationEligibility({
|
|
457
|
+
config,
|
|
458
|
+
hasSpacedInlineLabel: hasSpacedInlineLabel(config),
|
|
459
|
+
hasValidExplicitLeftMax: false,
|
|
460
|
+
isHorizontal: orientation === 'horizontal'
|
|
461
|
+
})
|
|
462
|
+
|
|
463
|
+
return !shouldUseInlineLabelHeadroom
|
|
411
464
|
}
|
|
412
465
|
|
|
413
466
|
const visHasSingleSeriesTooltip = () => {
|
|
@@ -466,6 +519,8 @@ export const useEditorPermissions = () => {
|
|
|
466
519
|
visSupportsDateCategoryTickRotation,
|
|
467
520
|
visSupportsDynamicSeries,
|
|
468
521
|
visSupportsFilters,
|
|
522
|
+
visSupportsAutoMaxStrategy,
|
|
523
|
+
visSupportsFilterDomainBehavior,
|
|
469
524
|
visSupportsFootnotes,
|
|
470
525
|
visSupportsLeftValueAxis,
|
|
471
526
|
visSupportsMobileChartHeight,
|
|
@@ -477,6 +532,7 @@ export const useEditorPermissions = () => {
|
|
|
477
532
|
visSupportsResponsiveTicks,
|
|
478
533
|
visSupportsReverseColorPalette,
|
|
479
534
|
visSupportsSequentialPallete,
|
|
535
|
+
visSupportsSeriesColorAssignments,
|
|
480
536
|
visSupportsSmallMultiples,
|
|
481
537
|
visSupportsSuperTitle,
|
|
482
538
|
visSupportsTooltipLines,
|