@cdc/chart 4.25.11 → 4.26.1

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 (77) hide show
  1. package/dist/cdcchart.js +38898 -40013
  2. package/examples/feature/pie/planet-pie-example-config.json +48 -2
  3. package/examples/private/DEV-12100.json +1303 -0
  4. package/examples/private/cat-y.json +1235 -0
  5. package/examples/private/data-points.json +228 -0
  6. package/examples/private/height.json +3915 -0
  7. package/examples/private/links.json +569 -0
  8. package/examples/private/quadrant.txt +30 -0
  9. package/examples/private/test-forecast.json +5510 -0
  10. package/examples/private/warming-stripe-test.json +2578 -0
  11. package/examples/private/warming-stripes.json +4763 -0
  12. package/examples/tech-adoption-with-links.json +560 -0
  13. package/index.html +15 -20
  14. package/package.json +5 -4
  15. package/preview.html +1616 -0
  16. package/src/CdcChartComponent.tsx +111 -75
  17. package/src/_stories/Chart.Regions.Categorical.stories.tsx +148 -0
  18. package/src/_stories/Chart.Regions.DateScale.stories.tsx +197 -0
  19. package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +297 -0
  20. package/src/_stories/Chart.stories.tsx +8 -0
  21. package/src/_stories/ChartBar.Editor.stories.tsx +11 -6
  22. package/src/_stories/ChartBrush.Editor.stories.tsx +295 -0
  23. package/src/_stories/ChartBrush.stories.tsx +50 -0
  24. package/src/_stories/ChartEditor.Editor.stories.tsx +3 -5
  25. package/src/_stories/TechAdoptionWithLinks.stories.tsx +27 -0
  26. package/src/_stories/_mock/brush_enabled.json +326 -0
  27. package/src/_stories/_mock/brush_mock.json +2 -69
  28. package/src/_stories/_mock/horizontal-bars-dynamic-y-axis.json +413 -0
  29. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +1 -2
  30. package/src/components/Axis/Categorical.Axis.tsx +6 -7
  31. package/src/components/BarChart/components/BarChart.Horizontal.tsx +178 -24
  32. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +3 -1
  33. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +1 -0
  34. package/src/components/BarChart/components/BarChart.Vertical.tsx +6 -8
  35. package/src/components/BarChart/components/context.tsx +1 -0
  36. package/src/components/BarChart/helpers/useBarChart.ts +14 -2
  37. package/src/components/Brush/BrushSelector.tsx +1258 -0
  38. package/src/components/Brush/MiniChartPreview.tsx +283 -0
  39. package/src/components/DeviationBar.jsx +9 -7
  40. package/src/components/EditorPanel/EditorPanel.tsx +2711 -2586
  41. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +56 -34
  42. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +57 -30
  43. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +2 -0
  44. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +30 -25
  45. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +21 -27
  46. package/src/components/EditorPanel/useEditorPermissions.ts +31 -18
  47. package/src/components/Legend/Legend.tsx +3 -2
  48. package/src/components/Legend/helpers/createFormatLabels.tsx +151 -2
  49. package/src/components/Legend/helpers/index.ts +10 -6
  50. package/src/components/LinearChart.tsx +495 -430
  51. package/src/components/PairedBarChart.jsx +20 -3
  52. package/src/components/Regions/components/Regions.tsx +365 -122
  53. package/src/components/ScatterPlot/ScatterPlot.jsx +2 -2
  54. package/src/components/SmallMultiples/SmallMultipleTile.tsx +5 -1
  55. package/src/components/WarmingStripes/WarmingStripes.tsx +160 -0
  56. package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +35 -0
  57. package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +104 -0
  58. package/src/components/WarmingStripes/index.tsx +3 -0
  59. package/src/data/initial-state.js +3 -1
  60. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +57 -0
  61. package/src/helpers/getMinMax.ts +12 -7
  62. package/src/helpers/sizeHelpers.ts +0 -20
  63. package/src/helpers/smallMultiplesHelpers.ts +1 -1
  64. package/src/hooks/useChartHoverAnalytics.tsx +10 -9
  65. package/src/hooks/useScales.ts +11 -1
  66. package/src/hooks/useTooltip.tsx +31 -10
  67. package/src/scss/DataTable.scss +0 -4
  68. package/src/scss/main.scss +17 -3
  69. package/src/test/CdcChart.test.jsx +1 -1
  70. package/src/types/ChartConfig.ts +3 -0
  71. package/src/types/Label.ts +1 -0
  72. package/src/utils/analyticsTracking.ts +19 -0
  73. package/LICENSE +0 -201
  74. package/src/components/Brush/BrushChart.tsx +0 -128
  75. package/src/components/Brush/BrushController.tsx +0 -71
  76. package/src/components/Brush/types.tsx +0 -8
  77. package/src/components/BrushChart.tsx +0 -223
@@ -8,18 +8,24 @@ import WarningImage from '../../../../images/warning.svg'
8
8
 
9
9
  // contexts
10
10
  import ConfigContext from '../../../../ConfigContext'
11
+ import { useEditorPanelContext } from '../../EditorPanelContext'
11
12
 
12
13
  // types
13
14
  import { type ChartContext } from '../../../../types/ChartContext'
14
15
  import { type PanelProps } from '../PanelProps'
15
16
 
16
- import { AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
17
+ import {
18
+ AccordionItem,
19
+ AccordionItemHeading,
20
+ AccordionItemPanel,
21
+ AccordionItemButton
22
+ } from 'react-accessible-accordion'
17
23
 
18
24
  const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
19
25
  const { config, rawData: unfilteredData, updateConfig } = useContext<ChartContext>(ConfigContext)
26
+ const { getColumns } = useEditorPanelContext()
20
27
  if (config.visualizationType !== 'Forest Plot') return
21
28
 
22
- // todo: get from editor context?
23
29
  const enforceRestrictions = updatedConfig => {
24
30
  if (updatedConfig.orientation === 'horizontal') {
25
31
  updatedConfig.labels = false
@@ -33,31 +39,6 @@ const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
33
39
  }
34
40
  }
35
41
 
36
- // todo: get from editor context?
37
- const getColumns = (filter = true) => {
38
- let columns = {}
39
- unfilteredData.forEach(row => {
40
- Object.keys(row).forEach(columnName => (columns[columnName] = true))
41
- })
42
-
43
- if (filter) {
44
- Object.keys(columns).forEach(key => {
45
- if (
46
- (config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
47
- (config.confidenceKeys && Object.keys(config.confidenceKeys).includes(key))
48
- /*
49
- TODO: Resolve errors when config keys exist, but have no value
50
- Proposal: (((confidenceUpper && confidenceLower) || confidenceUpper || confidenceLower) && Object.keys(config.confidenceKeys).includes(key))
51
- */
52
- ) {
53
- delete columns[key]
54
- }
55
- })
56
- }
57
-
58
- return Object.keys(columns)
59
- }
60
-
61
42
  // todo: editor context?
62
43
  const updateField = (section, subsection, fieldName, newValue) => {
63
44
  if (section === 'boxplot' && subsection === 'legend') {
@@ -151,7 +132,9 @@ const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
151
132
  <AccordionItemHeading>
152
133
  <AccordionItemButton>
153
134
  {name}
154
- {(!config.forestPlot.estimateField || !config.forestPlot.upper || !config.forestPlot.lower) && <WarningImage width='25' className='warning-icon' />}
135
+ {(!config.forestPlot.estimateField || !config.forestPlot.upper || !config.forestPlot.lower) && (
136
+ <WarningImage width='25' className='warning-icon' />
137
+ )}
155
138
  </AccordionItemButton>
156
139
  </AccordionItemHeading>
157
140
  <AccordionItemPanel>
@@ -201,14 +184,22 @@ const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
201
184
  <Tooltip.Content>
202
185
  <p>
203
186
  Linear - Typically used for continuous outcomes. Line of no effect is positioned on 0 (zero) <br />
204
- <br /> Logarithmic - Typically used for binary outcomes such as risk ratios and odds ratios. Line of no effect is positioned on 1.
187
+ <br /> Logarithmic - Typically used for binary outcomes such as risk ratios and odds ratios. Line of
188
+ no effect is positioned on 1.
205
189
  </p>
206
190
  </Tooltip.Content>
207
191
  </Tooltip>
208
192
  }
209
193
  />
210
194
 
211
- <TextField type='text' value={config.forestPlot?.title || ''} updateField={updateField} section='forestPlot' fieldName='title' label='Plot Title' />
195
+ <TextField
196
+ type='text'
197
+ value={config.forestPlot?.title || ''}
198
+ updateField={updateField}
199
+ section='forestPlot'
200
+ fieldName='title'
201
+ label='Plot Title'
202
+ />
212
203
 
213
204
  <br />
214
205
  <hr />
@@ -317,7 +308,14 @@ const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
317
308
  </span>
318
309
  </label>
319
310
 
320
- <CheckBox value={config.forestPlot?.lineOfNoEffect?.show || false} section='forestPlot' subsection='lineOfNoEffect' fieldName='show' label='Show Line of No Effect' updateField={updateField} />
311
+ <CheckBox
312
+ value={config.forestPlot?.lineOfNoEffect?.show || false}
313
+ section='forestPlot'
314
+ subsection='lineOfNoEffect'
315
+ fieldName='show'
316
+ label='Show Line of No Effect'
317
+ updateField={updateField}
318
+ />
321
319
 
322
320
  <br />
323
321
  <hr />
@@ -400,13 +398,37 @@ const ForestPlotSettings: FC<PanelProps> = ({ name }) => {
400
398
  />
401
399
  </label>
402
400
 
403
- <TextField type='number' min={20} max={45} value={config.forestPlot.rowHeight ? config.forestPlot.rowHeight : 10} updateField={updateField} section='forestPlot' fieldName='rowHeight' label='Row Height' placeholder='10' />
401
+ <TextField
402
+ type='number'
403
+ min={20}
404
+ max={45}
405
+ value={config.forestPlot.rowHeight ? config.forestPlot.rowHeight : 10}
406
+ updateField={updateField}
407
+ section='forestPlot'
408
+ fieldName='rowHeight'
409
+ label='Row Height'
410
+ placeholder='10'
411
+ />
404
412
  <br />
405
413
  <hr />
406
414
  <br />
407
415
  <h4>Labels Settings</h4>
408
- <TextField type='text' value={config.forestPlot?.leftLabel || ''} updateField={updateField} section='forestPlot' fieldName='leftLabel' label='Left Label' />
409
- <TextField type='text' value={config.forestPlot?.rightLabel || ''} updateField={updateField} section='forestPlot' fieldName='rightLabel' label='Right Label' />
416
+ <TextField
417
+ type='text'
418
+ value={config.forestPlot?.leftLabel || ''}
419
+ updateField={updateField}
420
+ section='forestPlot'
421
+ fieldName='leftLabel'
422
+ label='Left Label'
423
+ />
424
+ <TextField
425
+ type='text'
426
+ value={config.forestPlot?.rightLabel || ''}
427
+ updateField={updateField}
428
+ section='forestPlot'
429
+ fieldName='rightLabel'
430
+ label='Right Label'
431
+ />
410
432
 
411
433
  <br />
412
434
  <hr />
@@ -316,36 +316,37 @@ const PanelGeneral: FC<PanelProps> = props => {
316
316
  />
317
317
  </>
318
318
  )}
319
-
320
- <CheckBox
321
- tooltip={
322
- <Tooltip style={{ textTransform: 'none' }}>
323
- <Tooltip.Target>
324
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
325
- </Tooltip.Target>
326
- <Tooltip.Content>
327
- {config.visualizationSubType === 'stacked' && (
328
- <p>
329
- We do not recommend using stacked vertical/horizontal bar charts for missing data. If you choose to
330
- proceed, selecting this option will display 'N/A' in the tooltip hover and data table (e.g. nothing
331
- will display in chart).
332
- </p>
333
- )}
334
- {config.visualizationSubType !== 'stacked' && (
335
- <p>
336
- Selecting this option will display 'N/A' on the Date/Category Axis, in the tooltip hover, and in the
337
- data table to indicate missing or undefined data values.
338
- </p>
339
- )}
340
- </Tooltip.Content>
341
- </Tooltip>
342
- }
343
- value={config.general.showMissingDataLabel}
344
- section='general'
345
- fieldName='showMissingDataLabel'
346
- label='Display "Missing Data" Label'
347
- updateField={updateField}
348
- />
319
+ {config.visualizationType !== 'Warming Stripes' && (
320
+ <CheckBox
321
+ tooltip={
322
+ <Tooltip style={{ textTransform: 'none' }}>
323
+ <Tooltip.Target>
324
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
325
+ </Tooltip.Target>
326
+ <Tooltip.Content>
327
+ {config.visualizationSubType === 'stacked' && (
328
+ <p>
329
+ We do not recommend using stacked vertical/horizontal bar charts for missing data. If you choose
330
+ to proceed, selecting this option will display 'N/A' in the tooltip hover and data table (e.g.
331
+ nothing will display in chart).
332
+ </p>
333
+ )}
334
+ {config.visualizationSubType !== 'stacked' && (
335
+ <p>
336
+ Selecting this option will display 'N/A' on the Date/Category Axis, in the tooltip hover, and in
337
+ the data table to indicate missing or undefined data values.
338
+ </p>
339
+ )}
340
+ </Tooltip.Content>
341
+ </Tooltip>
342
+ }
343
+ value={config.general.showMissingDataLabel}
344
+ section='general'
345
+ fieldName='showMissingDataLabel'
346
+ label='Display "Missing Data" Label'
347
+ updateField={updateField}
348
+ />
349
+ )}
349
350
 
350
351
  {visualizationType === 'Pie' && (
351
352
  <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />
@@ -389,6 +390,32 @@ const PanelGeneral: FC<PanelProps> = props => {
389
390
  </Tooltip>
390
391
  }
391
392
  />
393
+
394
+ <Select
395
+ value={config.titleStyle}
396
+ fieldName='titleStyle'
397
+ label='Title Style'
398
+ updateField={updateField}
399
+ options={[
400
+ { value: 'small', label: 'Small (h3)' },
401
+ { value: 'large', label: 'Large (h2)' },
402
+ { value: 'legacy', label: 'Legacy' }
403
+ ]}
404
+ tooltip={
405
+ <Tooltip style={{ textTransform: 'none' }}>
406
+ <Tooltip.Target>
407
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
408
+ </Tooltip.Target>
409
+ <Tooltip.Content>
410
+ <p>
411
+ Choose the visual style for the title. Consider heading order on your page when selecting the title
412
+ style. For 508 reasons, ensure your page follows a proper heading order.
413
+ </p>
414
+ </Tooltip.Content>
415
+ </Tooltip>
416
+ }
417
+ />
418
+
392
419
  <CheckBox value={config.showTitle} fieldName='showTitle' label='Show Title' updateField={updateField} />
393
420
 
394
421
  {visSupportsSuperTitle() && (
@@ -311,6 +311,8 @@ const PanelPatternSettings: FC<PanelProps> = props => {
311
311
  updateConfig(updatedConfig)
312
312
  }
313
313
 
314
+ if (config.visualizationType === 'Warming Stripes') return
315
+
314
316
  return (
315
317
  <AccordionItem>
316
318
  <AccordionItemHeading>
@@ -1,4 +1,4 @@
1
- import { useContext, FC } from 'react'
1
+ import { useContext, FC, useMemo } from 'react'
2
2
  import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
3
3
  import {
4
4
  AccordionItem,
@@ -11,6 +11,7 @@ import {
11
11
  import { TextField, Select, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
12
12
  import Tooltip from '@cdc/core/components/ui/Tooltip'
13
13
  import Icon from '@cdc/core/components/ui/Icon'
14
+ import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
14
15
 
15
16
  // contexts
16
17
  import { ChartContext } from './../../../../types/ChartContext.js'
@@ -25,30 +26,30 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
25
26
  const { updateField } = useEditorPanelContext()
26
27
  const { visSupportsSmallMultiples } = useEditorPermissions()
27
28
 
28
- const getColumns = (filter = true) => {
29
- let columns = {}
30
- rawData?.forEach(row => {
31
- Object.keys(row).forEach(columnName => (columns[columnName] = true))
32
- })
33
-
34
- if (filter) {
35
- const { lower, upper } = config.confidenceKeys || {}
36
- Object.keys(columns).forEach(key => {
37
- if (
38
- (config.series && config.series.filter(series => series.dataKey === key).length > 0) ||
39
- (config.confidenceKeys &&
40
- Object.keys(config.confidenceKeys).includes(key) &&
41
- ((lower && upper) || lower || upper) &&
42
- key !== lower &&
43
- key !== upper)
44
- ) {
45
- delete columns[key]
46
- }
47
- })
48
- }
29
+ // Extract column names from data with memoization (replaces getColumns)
30
+ const allColumns = useDataColumns(rawData)
49
31
 
50
- return Object.keys(columns)
51
- }
32
+ // Filter out series columns and confidence key columns (except lower and upper)
33
+ const filteredColumns = useMemo(() => {
34
+ const { lower, upper } = config.confidenceKeys || {}
35
+ return allColumns.filter(key => {
36
+ // Filter out series columns
37
+ if (config.series && config.series.some(series => series.dataKey === key)) {
38
+ return false
39
+ }
40
+ // Filter out confidence key columns (except lower and upper)
41
+ if (
42
+ config.confidenceKeys &&
43
+ Object.keys(config.confidenceKeys).includes(key) &&
44
+ ((lower && upper) || lower || upper) &&
45
+ key !== lower &&
46
+ key !== upper
47
+ ) {
48
+ return false
49
+ }
50
+ return true
51
+ })
52
+ }, [allColumns, config.series, config.confidenceKeys])
52
53
 
53
54
  return (
54
55
  <>
@@ -91,7 +92,7 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
91
92
  label='Tile By Column'
92
93
  initial='Select Column'
93
94
  updateField={updateField}
94
- options={getColumns()}
95
+ options={filteredColumns}
95
96
  />
96
97
  )}
97
98
 
@@ -184,6 +185,8 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
184
185
  value={currentOrderType}
185
186
  options={tileOrderOptions}
186
187
  label='Tile Order'
188
+ fieldName='tileOrderType'
189
+ section='smallMultiples'
187
190
  updateField={(_section, _subsection, _fieldName, value) => {
188
191
  handleOrderTypeChange(value)
189
192
  }}
@@ -244,6 +247,8 @@ const PanelSmallMultiples: FC<PanelProps> = props => {
244
247
  }
245
248
  ]}
246
249
  label='Color Mode'
250
+ fieldName='colorMode'
251
+ section='smallMultiples'
247
252
  updateField={(_section, _subsection, _fieldName, value) => {
248
253
  updateConfig({
249
254
  ...config,
@@ -319,16 +319,21 @@ const PanelVisual: FC<PanelProps> = props => {
319
319
  colorIndices={[2, 4, 6]}
320
320
  className='color-palette'
321
321
  />
322
- <span>Colorblind Safe</span>
323
- <PaletteSelector
324
- palettes={accessibleColors}
325
- colorPalettes={colorPalettes}
326
- config={config}
327
- onPaletteSelect={handlePaletteSelection}
328
- selectedPalette={getCurrentPaletteName(config)}
329
- colorIndices={[2, 3, 5]}
330
- className='color-palette'
331
- />
322
+
323
+ {config.visualizationType !== 'Warming Stripes' && (
324
+ <>
325
+ <span>Colorblind Safe</span>
326
+ <PaletteSelector
327
+ palettes={accessibleColors}
328
+ colorPalettes={colorPalettes}
329
+ config={config}
330
+ onPaletteSelect={handlePaletteSelection}
331
+ selectedPalette={getCurrentPaletteName(config)}
332
+ colorIndices={[2, 3, 5]}
333
+ className='color-palette'
334
+ />
335
+ </>
336
+ )}
332
337
  </>
333
338
  )}
334
339
 
@@ -516,28 +521,17 @@ const PanelVisual: FC<PanelProps> = props => {
516
521
  />
517
522
  </>
518
523
  )}
519
- {visSupportsBarThickness() &&
520
- config.orientation === 'horizontal' &&
521
- !config.isLollipopChart &&
522
- config.yAxis.labelPlacement !== 'On Bar' && (
524
+
525
+ {(config.orientation !== 'horizontal' || config.visualizationType === 'Combo') &&
526
+ config.visualizationType !== 'Warming Stripes' && (
523
527
  <TextField
528
+ value={config.barThickness}
524
529
  type='number'
525
- value={config.barHeight || '25'}
526
- fieldName='barHeight'
527
- label=' Bar Thickness'
530
+ fieldName='barThickness'
531
+ label='Bar Thickness'
528
532
  updateField={updateField}
529
- min={15}
530
533
  />
531
534
  )}
532
- {(config.orientation !== 'horizontal' || config.visualizationType === 'Combo') && (
533
- <TextField
534
- value={config.barThickness}
535
- type='number'
536
- fieldName='barThickness'
537
- label='Bar Thickness'
538
- updateField={updateField}
539
- />
540
- )}
541
535
  {visSupportsBarSpace() && (
542
536
  <TextField
543
537
  type='number'
@@ -21,7 +21,8 @@ export const useEditorPermissions = () => {
21
21
  'Pie',
22
22
  'Scatter Plot',
23
23
  'Spark Line',
24
- 'Sankey'
24
+ 'Sankey',
25
+ 'Warming Stripes'
25
26
  ]
26
27
 
27
28
  const visSupportsDateCategoryAxis = () => {
@@ -63,7 +64,8 @@ export const useEditorPermissions = () => {
63
64
  'Forest Plot',
64
65
  'Spark Line',
65
66
  'Sankey',
66
- 'Bump Chart'
67
+ 'Bump Chart',
68
+ 'Warming Stripes'
67
69
  ]
68
70
  if (disabledCharts.includes(visualizationType)) return false
69
71
  return true
@@ -77,7 +79,8 @@ export const useEditorPermissions = () => {
77
79
  'Forest Plot',
78
80
  'Spark Line',
79
81
  'Sankey',
80
- 'Bump Chart'
82
+ 'Bump Chart',
83
+ 'Warming Stripes'
81
84
  ]
82
85
  if (disabledCharts.includes(visualizationType)) return false
83
86
  return true
@@ -93,6 +96,8 @@ export const useEditorPermissions = () => {
93
96
  return false
94
97
  case 'Sankey':
95
98
  return false
99
+ case 'Warming Stripes':
100
+ return true
96
101
  default:
97
102
  return true
98
103
  }
@@ -140,7 +145,11 @@ export const useEditorPermissions = () => {
140
145
  }
141
146
  const visHasBrushChart = () => {
142
147
  if (config.xAxis.type === 'categorical') return false
143
- return ['Line', 'Bar', 'Area Chart', 'Combo'].includes(visualizationType) && orientation === 'vertical'
148
+ // Allow Line charts, vertical Bar charts (both stacked and grouped), and vertical Area charts
149
+ if (visualizationType === 'Line' && orientation === 'vertical') return true
150
+ if (visualizationType === 'Bar' && orientation === 'vertical') return true
151
+ if (visualizationType === 'Area Chart' && orientation === 'vertical') return true
152
+ return false
144
153
  }
145
154
 
146
155
  const visHasBarBorders = () => {
@@ -153,6 +162,8 @@ export const useEditorPermissions = () => {
153
162
 
154
163
  const visHasDataCutoff = () => {
155
164
  switch (visualizationType) {
165
+ case 'Warming Stripes':
166
+ return false
156
167
  case 'Sankey':
157
168
  return false
158
169
  case 'Forest Plot':
@@ -168,7 +179,9 @@ export const useEditorPermissions = () => {
168
179
  }
169
180
  }
170
181
 
171
- const visHasSelectableLegendValues = !['Box Plot', 'Forest Plot', 'Spark Line'].includes(visualizationType)
182
+ const visHasSelectableLegendValues = !['Box Plot', 'Forest Plot', 'Spark Line', 'Warming Stripes'].includes(
183
+ visualizationType
184
+ )
172
185
  const visHasLegendAxisAlign = () => {
173
186
  return visualizationType === 'Bar' && visualizationSubType === 'stacked' && config.legend.behavior === 'isolate'
174
187
  }
@@ -177,7 +190,7 @@ export const useEditorPermissions = () => {
177
190
  }
178
191
 
179
192
  const visSupportsTooltipOpacity = () => {
180
- const disabledCharts = ['Spark Line', 'Sankey']
193
+ const disabledCharts = ['Spark Line', 'Sankey', 'Warming Stripes']
181
194
  if (disabledCharts.includes(visualizationType)) return false
182
195
  return true
183
196
  }
@@ -189,7 +202,7 @@ export const useEditorPermissions = () => {
189
202
  }
190
203
 
191
204
  const visSupportsSequentialPallete = () => {
192
- const disabledCharts = ['Paired Bar', 'Deviation Bar', 'Forest Plot', 'Forecasting', 'Sankey']
205
+ const disabledCharts = ['Line', 'Paired Bar', 'Deviation Bar', 'Forest Plot', 'Forecasting', 'Sankey']
193
206
  if (disabledCharts.includes(visualizationType)) return false
194
207
  return true
195
208
  }
@@ -207,19 +220,19 @@ export const useEditorPermissions = () => {
207
220
  }
208
221
 
209
222
  const visSupportsDateCategoryAxisLabel = () => {
210
- const disabledCharts = ['Forest Plot', 'Spark Line', 'Bump Chart']
223
+ const disabledCharts = ['Forest Plot', 'Spark Line', 'Bump Chart', 'Warming Stripes']
211
224
  if (disabledCharts.includes(visualizationType)) return false
212
225
  return true
213
226
  }
214
227
 
215
228
  const visSupportsDateCategoryAxisLine = () => {
216
- const disabledCharts = ['Forest Plot', 'Spark Line']
229
+ const disabledCharts = ['Forest Plot', 'Spark Line', 'Warming Stripes']
217
230
  if (disabledCharts.includes(visualizationType)) return false
218
231
  return true
219
232
  }
220
233
 
221
234
  const visSupportsDateCategoryAxisTicks = () => {
222
- const disabledCharts = ['Forest Plot', 'Spark Line']
235
+ const disabledCharts = ['Forest Plot', 'Spark Line', 'Warming Stripes']
223
236
  if (disabledCharts.includes(visualizationType)) return false
224
237
  return true
225
238
  }
@@ -243,7 +256,7 @@ export const useEditorPermissions = () => {
243
256
  }
244
257
 
245
258
  const visSupportsRegions = () => {
246
- const disabledCharts = ['Forest Plot', 'Pie', 'Paired Bar', 'Spark Line', 'Sankey']
259
+ const disabledCharts = ['Forest Plot', 'Pie', 'Paired Bar', 'Spark Line', 'Sankey', 'Warming Stripes']
247
260
  if (disabledCharts.includes(visualizationType)) return false
248
261
  return true
249
262
  }
@@ -261,14 +274,13 @@ export const useEditorPermissions = () => {
261
274
  }
262
275
 
263
276
  const visSupportsFilters = () => {
264
- const disabledCharts = ['Forest Plot', 'Sankey']
277
+ const disabledCharts = ['Forest Plot', 'Sankey', 'Warming Stripes']
265
278
  if (disabledCharts.includes(visualizationType)) return false
266
279
  return true
267
280
  }
268
281
 
269
282
  const visSupportsValueAxisGridLines = () => {
270
283
  const disabledCharts = ['Forest Plot']
271
- if (orientation === 'horizontal') return false
272
284
  if (disabledCharts.includes(visualizationType)) return false
273
285
  return true
274
286
  }
@@ -302,13 +314,13 @@ export const useEditorPermissions = () => {
302
314
  }
303
315
 
304
316
  const visSupportsBarThickness = () => {
305
- const disabledCharts = ['Forest Plot']
317
+ const disabledCharts = ['Forest Plot', 'Warming Stripes']
306
318
  if (disabledCharts.includes(visualizationType)) return false
307
319
  return true
308
320
  }
309
321
 
310
322
  const visSupportsChartHeight = () => {
311
- const disabledCharts = ['Spark Line']
323
+ const disabledCharts = ['Spark Line', 'Warming Stripes']
312
324
  if (disabledCharts.includes(visualizationType)) return false
313
325
  return true
314
326
  }
@@ -320,7 +332,7 @@ export const useEditorPermissions = () => {
320
332
  }
321
333
 
322
334
  const visSupportsLeftValueAxis = () => {
323
- const disabledCharts = ['Spark Line', 'Sankey']
335
+ const disabledCharts = ['Spark Line', 'Sankey', 'Warming Stripes']
324
336
  if (disabledCharts.includes(visualizationType)) return false
325
337
  return true
326
338
  }
@@ -335,6 +347,7 @@ export const useEditorPermissions = () => {
335
347
  const disabledCharts = ['Spark Line', 'Sankey', 'Bump Chart']
336
348
  if (disabledCharts.includes(visualizationType)) return false
337
349
  if (config.orientation !== 'horizontal') return false
350
+ if (config.orientation === 'horizontal' && visualizationType === 'Bar' && !config.isLollipopChart) return false
338
351
  return true
339
352
  }
340
353
 
@@ -370,8 +383,8 @@ export const useEditorPermissions = () => {
370
383
  }
371
384
 
372
385
  const visSupportsSmallMultiples = () => {
373
- const enabledCharts = ['Line', 'Bar', 'Area Chart', 'Combo', 'Box Plot', 'Scatter Plot']
374
- if (enabledCharts.includes(visualizationType)) return true
386
+ const enabledCharts = ['Line', 'Bar', 'Area Chart', 'Combo', 'Box Plot', 'Scatter Plot', 'Warming Stripes']
387
+ if (enabledCharts.includes(visualizationType) && config.orientation !== 'horizontal') return true
375
388
  return false
376
389
  }
377
390
 
@@ -18,13 +18,14 @@ const Legend = forwardRef((props, ref) => {
18
18
  currentViewport,
19
19
  dimensions,
20
20
  getTextWidth,
21
- transformedData
21
+ transformedData,
22
+ formatNumber
22
23
  } = useContext(ConfigContext)
23
24
  if (!config.legend) return null
24
25
  // create fn to reverse labels while legend is Bottom. Legend-right , legend-left works by default
25
26
  const { interactionLabel } = props
26
27
 
27
- const createLegendLabels = createFormatLabels(config, tableData, data, colorScale)
28
+ const createLegendLabels = createFormatLabels(config, tableData, data, colorScale, formatNumber)
28
29
 
29
30
  return (
30
31
  <Fragment>