@cdc/core 4.24.3 → 4.24.5

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 (72) hide show
  1. package/assets/icon-command.svg +3 -0
  2. package/assets/icon-rotate-left.svg +3 -0
  3. package/components/AdvancedEditor.jsx +9 -0
  4. package/components/DataTable/DataTable.tsx +20 -15
  5. package/components/DataTable/DataTableStandAlone.tsx +51 -4
  6. package/components/DataTable/components/ChartHeader.tsx +3 -2
  7. package/components/DataTable/components/DataTableEditorPanel.tsx +20 -3
  8. package/components/DataTable/components/ExpandCollapse.tsx +22 -16
  9. package/components/DataTable/helpers/chartCellMatrix.tsx +3 -2
  10. package/components/DataTable/helpers/getChartCellValue.ts +21 -1
  11. package/components/DataTable/helpers/getDataSeriesColumns.ts +37 -16
  12. package/components/DataTable/helpers/getSeriesName.ts +2 -1
  13. package/components/DataTable/helpers/mapCellMatrix.tsx +2 -2
  14. package/components/DataTable/helpers/{customColumns.ts → removeNullColumns.ts} +3 -3
  15. package/components/DataTable/types/TableConfig.ts +11 -21
  16. package/components/EditorPanel/ColumnsEditor.tsx +304 -260
  17. package/components/EditorPanel/DataTableEditor.tsx +119 -48
  18. package/components/EditorPanel/VizFilterEditor.tsx +234 -0
  19. package/components/EditorWrapper/EditorWrapper.tsx +48 -0
  20. package/components/EditorWrapper/editor-wrapper.style.css +14 -0
  21. package/components/Filters.jsx +78 -61
  22. package/components/Layout/components/Responsive.tsx +184 -0
  23. package/components/Layout/components/Sidebar/components/Sidebar.tsx +47 -0
  24. package/components/Layout/components/Sidebar/components/sidebar.styles.scss +902 -0
  25. package/components/Layout/components/Sidebar/index.tsx +3 -0
  26. package/components/Layout/components/Visualization/index.tsx +81 -0
  27. package/components/Layout/components/Visualization/visualizations.scss +33 -0
  28. package/components/Layout/index.tsx +11 -0
  29. package/components/Layout/styles/editor-grid-view.scss +156 -0
  30. package/components/Layout/styles/editor-utils.scss +197 -0
  31. package/components/Layout/styles/editor.scss +144 -0
  32. package/components/LegendCircle.jsx +4 -3
  33. package/components/MediaControls.jsx +1 -1
  34. package/components/Table/Table.tsx +7 -5
  35. package/components/Table/components/Row.tsx +6 -2
  36. package/components/Table/types/RowType.ts +3 -0
  37. package/components/Waiting.jsx +11 -1
  38. package/components/_stories/DataTable.stories.tsx +1 -2
  39. package/components/_stories/EditorPanel.stories.tsx +1 -0
  40. package/components/createBarElement.jsx +37 -34
  41. package/components/elements/SkipTo.tsx +37 -5
  42. package/components/managers/DataDesigner.tsx +18 -18
  43. package/components/ui/Icon.tsx +5 -1
  44. package/helpers/DataTransform.ts +9 -32
  45. package/helpers/coveUpdateWorker.ts +21 -0
  46. package/helpers/footnoteSymbols.ts +11 -0
  47. package/helpers/useDataVizClasses.js +1 -5
  48. package/helpers/ver/4.23.4.ts +27 -0
  49. package/helpers/ver/4.24.3.ts +56 -0
  50. package/helpers/ver/4.24.5.ts +32 -0
  51. package/package.json +2 -2
  52. package/styles/_data-table.scss +8 -0
  53. package/styles/_global.scss +7 -4
  54. package/styles/_reset.scss +7 -6
  55. package/styles/_variables.scss +3 -0
  56. package/styles/base.scss +0 -18
  57. package/styles/v2/base/index.scss +1 -1
  58. package/styles/v2/components/ui/tooltip.scss +0 -21
  59. package/types/Axis.ts +4 -0
  60. package/types/Column.ts +1 -0
  61. package/types/ConfigureData.ts +8 -0
  62. package/types/DataDescription.ts +9 -0
  63. package/types/Legend.ts +1 -0
  64. package/types/MarkupInclude.ts +26 -0
  65. package/types/Runtime.ts +1 -0
  66. package/types/Series.ts +1 -1
  67. package/types/Table.ts +15 -13
  68. package/types/Visualization.ts +14 -10
  69. package/types/VizFilter.ts +13 -0
  70. package/helpers/coveUpdateWorker.js +0 -19
  71. package/helpers/ver/4.23.js +0 -10
  72. package/helpers/ver/4.24.3.js +0 -25
@@ -7,15 +7,19 @@ type RowProps = {
7
7
  wrapColumns: boolean
8
8
  isTotal?: boolean
9
9
  cellMinWidth?: number
10
+ fontSize: 'small' | 'medium' | 'large'
11
+ viewport: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
10
12
  }
11
13
 
12
- const Row = ({ childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal }: RowProps) => {
14
+ const Row = ({ childRow, rowKey, wrapColumns, cellMinWidth = 0, isTotal, fontSize, viewport }: RowProps) => {
13
15
  const whiteSpace = wrapColumns ? 'unset' : 'nowrap'
14
16
  const minWidth = cellMinWidth + 'px'
17
+ const fontSizes = { small: 16, medium: 18, large: 20 }
18
+ const cellFontSize = ['sm', 'xs', 'xxs'].includes(viewport) ? '11px' : `${fontSizes[fontSize]}px`
15
19
  return (
16
20
  <tr>
17
21
  {childRow.map((child, i) => (
18
- <Cell key={rowKey + '__' + i} style={{ whiteSpace, minWidth }} isBold={isTotal}>
22
+ <Cell key={rowKey + '__' + i} style={{ whiteSpace, minWidth, fontSize: cellFontSize }} isBold={isTotal}>
19
23
  {child}
20
24
  </Cell>
21
25
  ))}
@@ -3,3 +3,6 @@ export enum RowType {
3
3
  total = 'total',
4
4
  row_group_total = 'row_group_total'
5
5
  }
6
+
7
+ // The only distinction between total and row_group_total is the way the UI renders it.
8
+ // They function otherwise the same a regular row.
@@ -1,8 +1,18 @@
1
1
  import React from 'react'
2
2
  import '../styles/waiting.scss'
3
3
 
4
+ const styles = {
5
+ position: 'relative',
6
+ height: '100vh',
7
+ width: '100%',
8
+ display: 'flex',
9
+ justifyContent: 'center',
10
+ alignItems: 'center',
11
+ gridArea: 'content'
12
+ }
13
+
4
14
  export default ({ requiredColumns, className }) => (
5
- <section className={className}>
15
+ <section className={className} style={styles}>
6
16
  <section className='waiting-container'>
7
17
  <h3>Configuration Required</h3>
8
18
  <p>
@@ -51,13 +51,12 @@ export const CityState: Story = {
51
51
 
52
52
  export const Grouped: Story = {
53
53
  args: {
54
- config: Example_1,
54
+ config: { ...Example_1, table: { ...Example_1.table, groupBy: 'TimeZone' } },
55
55
  dataConfig: Example_1.datasets[datasetKey],
56
56
  rawData: Example_1.datasets[datasetKey].data,
57
57
  runtimeData: Example_1.datasets[datasetKey].data,
58
58
  expandDataTable: true,
59
59
  tableTitle: 'COVE DataTable',
60
- groupBy: 'TimeZone',
61
60
  viewport: 'lg',
62
61
  tabbingId: datasetKey
63
62
  }
@@ -46,6 +46,7 @@ export const Primary: Story = {
46
46
  label: 'Data Table',
47
47
  show: true
48
48
  },
49
+ columns: {},
49
50
  visualizationType: 'Pie'
50
51
  },
51
52
  isDashboard: true
@@ -1,6 +1,9 @@
1
1
  export default function createBarElement(props) {
2
2
  const { config, index, id, className, background, borderColor, borderWidth, width, height, x, y, onMouseOver, onMouseLeave, onClick, tooltipHtml, tooltipId, styleOverrides, seriesHighlight } = props
3
3
 
4
+ const adjustedWidth = Math.max(0, width);
5
+ const adjustedHeight = Math.max(0, height);
6
+
4
7
  const isHorizontal = config.orientation === 'horizontal'
5
8
  const isRounded = config.barStyle === 'rounded'
6
9
  const isStacked = config.visualizationSubType === 'stacked'
@@ -11,67 +14,67 @@ export default function createBarElement(props) {
11
14
  const stackCount = comboBarSeriesCount ? comboBarSeriesCount : isolateSeriesCount ? isolateSeriesCount : barSeriesCount
12
15
 
13
16
  let radius = config.roundingStyle === 'standard' ? 8 : config.roundingStyle === 'shallow' ? 5 : config.roundingStyle === 'finger' ? 15 : 0
14
- if (radius > width / 2 || radius > height / 2) {
15
- radius = Math.min(width / 2, height / 2)
17
+ if (radius > adjustedWidth / 2 || radius > adjustedHeight / 2) {
18
+ radius = Math.min(adjustedWidth / 2, adjustedHeight / 2)
16
19
  }
17
20
 
18
21
  const roundTop = () => {
19
- return `M${x},${y + height}
22
+ return `M${x},${y + adjustedHeight}
20
23
  L${x},${y + radius}
21
24
  Q${x},${y} ${x + radius},${y}
22
- L${x + width - radius},${y}
23
- Q${x + width},${y} ${x + width},${y + radius}
24
- L${x + width},${y + height}
25
- L${x},${y + height}`
25
+ L${x + adjustedWidth - radius},${y}
26
+ Q${x + adjustedWidth},${y} ${x + adjustedWidth},${y + radius}
27
+ L${x + adjustedWidth},${y + adjustedHeight}
28
+ L${x},${y + adjustedHeight}`
26
29
  }
27
30
 
28
31
  const roundRight = () => {
29
- return `M${x},${y + height}
32
+ return `M${x},${y + adjustedHeight}
30
33
  L${x},${y}
31
- L${x + width - radius},${y}
32
- Q${x + width},${y} ${x + width},${y + radius}
33
- L${x + width},${y + height - radius}
34
- Q${x + width},${y + height} ${x + width - radius},${y + height}
35
- L${x},${y + height}`
34
+ L${x + adjustedWidth - radius},${y}
35
+ Q${x + adjustedWidth},${y} ${x + adjustedWidth},${y + radius}
36
+ L${x + adjustedWidth},${y + adjustedHeight - radius}
37
+ Q${x + adjustedWidth},${y + adjustedHeight} ${x + adjustedWidth - radius},${y + adjustedHeight}
38
+ L${x},${y + adjustedHeight}`
36
39
  }
37
40
 
38
41
  const roundBottom = () => {
39
- return `M${x + radius},${y + height}
40
- Q${x},${y + height} ${x},${y + height - radius}
42
+ return `M${x + radius},${y + adjustedHeight}
43
+ Q${x},${y + adjustedHeight} ${x},${y + adjustedHeight - radius}
41
44
  L${x},${y}
42
- L${x + width},${y}
43
- L${x + width},${y + height - radius}
44
- Q${x + width},${y + height} ${x + width - radius},${y + height}
45
- L${x + radius},${y + height}`
45
+ L${x + adjustedWidth},${y}
46
+ L${x + adjustedWidth},${y + adjustedHeight - radius}
47
+ Q${x + adjustedWidth},${y + adjustedHeight} ${x + adjustedWidth - radius},${y + adjustedHeight}
48
+ L${x + radius},${y + adjustedHeight}`
46
49
  }
47
50
 
48
51
  const roundLeft = () => {
49
- return `M${x + radius},${y + height}
50
- Q${x},${y + height} ${x},${y + height - radius}
52
+ return `M${x + radius},${y + adjustedHeight}
53
+ Q${x},${y + adjustedHeight} ${x},${y + adjustedHeight - radius}
51
54
  L${x},${y + radius}
52
55
  Q${x},${y} ${x + radius},${y}
53
- L${x + width},${y}
54
- L${x + width},${y + height}
55
- L${x + radius},${y + height}`
56
+ L${x + adjustedWidth},${y}
57
+ L${x + adjustedWidth},${y + adjustedHeight}
58
+ L${x + radius},${y + adjustedHeight}`
56
59
  }
57
60
 
58
61
  const roundFull = () => {
59
- return `M${x + radius},${y + height}
60
- Q${x},${y + height} ${x},${y + height - radius}
62
+ return `M${x + radius},${y + adjustedHeight}
63
+ Q${x},${y + adjustedHeight} ${x},${y + adjustedHeight - radius}
61
64
  L${x},${y + radius}
62
65
  Q${x},${y} ${x + radius},${y}
63
- L${x + width - radius},${y}
64
- Q${x + width},${y} ${x + width},${y + radius}
65
- L${x + width},${y + height - radius}
66
- Q${x + width},${y + height} ${x + width - radius},${y + height}
67
- L${x + radius},${y + height}`
66
+ L${x + adjustedWidth - radius},${y}
67
+ Q${x + adjustedWidth},${y} ${x + adjustedWidth},${y + radius}
68
+ L${x + adjustedWidth},${y + adjustedHeight - radius}
69
+ Q${x + adjustedWidth},${y + adjustedHeight} ${x + adjustedWidth - radius},${y + adjustedHeight}
70
+ L${x + radius},${y + adjustedHeight}`
68
71
  }
69
72
 
70
73
  const nonRounded = () => {
71
74
  return `M${x},${y}
72
- L${x + width},${y}
73
- L${x + width},${y + height}
74
- L${x},${y + height}
75
+ L${x + adjustedWidth},${y}
76
+ L${x + adjustedWidth},${y + adjustedHeight}
77
+ L${x},${y + adjustedHeight}
75
78
  L${x},${y}`
76
79
  }
77
80
 
@@ -1,3 +1,5 @@
1
+ import { useId } from 'react'
2
+
1
3
  type SkipToProps = {
2
4
  // id to skip to
3
5
  skipId: string
@@ -5,10 +7,40 @@ type SkipToProps = {
5
7
  skipMessage: string
6
8
  }
7
9
 
8
- const SkipTo: React.FC<SkipToProps> = ({ skipId, skipMessage }) => (
9
- <a id='skip-nav' className='cdcdataviz-sr-only-focusable' href={`#${skipId}`}>
10
- {skipMessage}
11
- </a>
12
- )
10
+ const SkipTo: React.FC<SkipToProps> = ({ skipId, skipMessage }) => {
11
+ const accessibleId = useId()
12
+ const handleOnClick = () => {
13
+ // Navigate to the specific part of the page
14
+ const targetElement = document.getElementById(skipId)
15
+ if (targetElement) {
16
+ targetElement.scrollIntoView()
17
+ targetElement.setAttribute('tabIndex', '-1')
18
+ targetElement.focus()
19
+ // Setup to remove tabIndex on blur to maintain document flow
20
+ const blurListener = () => {
21
+ targetElement.removeAttribute('tabIndex')
22
+ targetElement.removeEventListener('blur', blurListener)
23
+ }
24
+ targetElement.addEventListener('blur', blurListener)
25
+ }
26
+ }
27
+ return (
28
+ <div
29
+ tabIndex={0}
30
+ id={`skip-nav--${accessibleId}`}
31
+ className='cdcdataviz-sr-only-focusable'
32
+ onClick={handleOnClick}
33
+ onKeyDown={e => {
34
+ if (e.key === 'Enter' || e.key === ' ') {
35
+ handleOnClick()
36
+ }
37
+ }}
38
+ role='link'
39
+ aria-label={skipMessage}
40
+ >
41
+ {skipMessage}
42
+ </div>
43
+ )
44
+ }
13
45
 
14
46
  export default SkipTo
@@ -5,18 +5,18 @@ import Card from '../elements/Card'
5
5
 
6
6
  import { DATA_TABLE_VERTICAL, DATA_TABLE_HORIZONTAL, DATA_TABLE_SINGLE_ROW, DATA_TABLE_MULTI_ROW } from '../../templates/dataDesignerTables'
7
7
  import '../../styles/v2/components/data-designer.scss'
8
+ import { ConfigureData } from '../../types/ConfigureData'
8
9
 
9
10
  type DataDesignerProps = {
10
- configureData?: any // todo: add description here when understood better
11
- updateDescriptionProp?: (vizKey: string, dataKey: string, propName: string, value: any) => void // used to update data description fields
12
- visualizationKey?: any // todo: add description here when understood better
13
- dataKey?: string // appears to be the data file name, ie valid-data.csv
11
+ configureData?: ConfigureData
12
+ updateDescriptionProp: (propName: string, value: any) => void // used to update data description fields
13
+ visualizationKey: string
14
14
  config?: any // can be one of many different types of chart configs that aren't fully established yet
15
15
  setConfig?: (newConfig: any) => void
16
16
  }
17
17
 
18
18
  const DataDesigner = (props: DataDesignerProps) => {
19
- const { configureData, updateDescriptionProp, visualizationKey, dataKey, config, setConfig } = props
19
+ const { configureData, updateDescriptionProp, config, setConfig } = props
20
20
  const hasDataOrientation = config?.visualizationType !== 'Forest Plot'
21
21
  const hasMultipleSeries = config?.visualizationType !== 'Forest Plot'
22
22
  const hasRowSelection = config?.visualizationType !== 'Forest Plot'
@@ -47,7 +47,7 @@ const DataDesigner = (props: DataDesignerProps) => {
47
47
  <button
48
48
  className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === false ? ' active' : '')}
49
49
  onClick={() => {
50
- updateDescriptionProp(visualizationKey, dataKey, 'horizontal', false)
50
+ updateDescriptionProp('horizontal', false)
51
51
  }}
52
52
  >
53
53
  <Card>
@@ -63,7 +63,7 @@ const DataDesigner = (props: DataDesignerProps) => {
63
63
  <button
64
64
  className={'cove-data-designer__button' + (configureData.dataDescription && configureData.dataDescription.horizontal === true ? ' active' : '')}
65
65
  onClick={() => {
66
- updateDescriptionProp(visualizationKey, dataKey, 'horizontal', true)
66
+ updateDescriptionProp('horizontal', true)
67
67
  }}
68
68
  >
69
69
  <Card>
@@ -90,7 +90,7 @@ const DataDesigner = (props: DataDesignerProps) => {
90
90
  hoverStyle={{ backgroundColor: '#015daa' }}
91
91
  className='mr-1'
92
92
  onClick={() => {
93
- updateDescriptionProp(visualizationKey, dataKey, 'series', true)
93
+ updateDescriptionProp('series', true)
94
94
  }}
95
95
  active={configureData.dataDescription.series === true}
96
96
  >
@@ -100,7 +100,7 @@ const DataDesigner = (props: DataDesignerProps) => {
100
100
  style={{ backgroundColor: '#00345d' }}
101
101
  hoverStyle={{ backgroundColor: '#015daa' }}
102
102
  onClick={() => {
103
- updateDescriptionProp(visualizationKey, dataKey, 'series', false)
103
+ updateDescriptionProp('series', false)
104
104
  }}
105
105
  active={configureData.dataDescription.series === false}
106
106
  >
@@ -114,7 +114,7 @@ const DataDesigner = (props: DataDesignerProps) => {
114
114
  <div className='mb-1'>Which property in the dataset represents which series the row is describing?</div>
115
115
  <select
116
116
  onChange={e => {
117
- updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
117
+ updateDescriptionProp('seriesKey', e.target.value)
118
118
  }}
119
119
  defaultValue={configureData.dataDescription.seriesKey}
120
120
  >
@@ -136,7 +136,7 @@ const DataDesigner = (props: DataDesignerProps) => {
136
136
  <button
137
137
  className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === true ? ' active' : '')}
138
138
  onClick={() => {
139
- updateDescriptionProp(visualizationKey, dataKey, 'singleRow', true)
139
+ updateDescriptionProp('singleRow', true)
140
140
  }}
141
141
  >
142
142
  <Card>
@@ -150,7 +150,7 @@ const DataDesigner = (props: DataDesignerProps) => {
150
150
  <button
151
151
  className={'cove-data-designer__button' + (configureData.dataDescription.singleRow === false ? ' active' : '')}
152
152
  onClick={() => {
153
- updateDescriptionProp(visualizationKey, dataKey, 'singleRow', false)
153
+ updateDescriptionProp('singleRow', false)
154
154
  }}
155
155
  >
156
156
  <Card>
@@ -168,7 +168,7 @@ const DataDesigner = (props: DataDesignerProps) => {
168
168
  <div className='mb-1'>Which property in the dataset represents which series the row is describing?</div>
169
169
  <select
170
170
  onChange={e => {
171
- updateDescriptionProp(visualizationKey, dataKey, 'seriesKey', e.target.value)
171
+ updateDescriptionProp('seriesKey', e.target.value)
172
172
  }}
173
173
  defaultValue={configureData.dataDescription.seriesKey}
174
174
  >
@@ -184,7 +184,7 @@ const DataDesigner = (props: DataDesignerProps) => {
184
184
  <div className='mb-1'>Which property in the dataset represents the values for the category/date axis or map geography?</div>
185
185
  <select
186
186
  onChange={e => {
187
- updateDescriptionProp(visualizationKey, dataKey, 'xKey', e.target.value)
187
+ updateDescriptionProp('xKey', e.target.value)
188
188
  }}
189
189
  defaultValue={configureData.dataDescription.xKey}
190
190
  >
@@ -207,7 +207,7 @@ const DataDesigner = (props: DataDesignerProps) => {
207
207
  onClick={() => {
208
208
  let newValueKeys = configureData.dataDescription.valueKeysTallSupport
209
209
  newValueKeys.splice(index, 1)
210
- updateDescriptionProp(visualizationKey, dataKey, 'valueKeysTallSupport', newValueKeys)
210
+ updateDescriptionProp('valueKeysTallSupport', newValueKeys)
211
211
  }}
212
212
  >
213
213
  X
@@ -219,7 +219,7 @@ const DataDesigner = (props: DataDesignerProps) => {
219
219
  <select
220
220
  onChange={e => {
221
221
  if (e.target.value && (!configureData.dataDescription.valueKeysTallSupport || configureData.dataDescription.valueKeysTallSupport.indexOf(e.target.value) === -1)) {
222
- updateDescriptionProp(visualizationKey, dataKey, 'valueKeysTallSupport', [...(configureData.dataDescription.valueKeysTallSupport || []), e.target.value])
222
+ updateDescriptionProp('valueKeysTallSupport', [...(configureData.dataDescription.valueKeysTallSupport || []), e.target.value])
223
223
  }
224
224
  }}
225
225
  >
@@ -244,7 +244,7 @@ const DataDesigner = (props: DataDesignerProps) => {
244
244
  onClick={() => {
245
245
  let newIgnoredKeys = configureData.dataDescription.ignoredKeys
246
246
  newIgnoredKeys.splice(index, 1)
247
- updateDescriptionProp(visualizationKey, dataKey, 'ignoredKeys', newIgnoredKeys)
247
+ updateDescriptionProp('ignoredKeys', newIgnoredKeys)
248
248
  }}
249
249
  >
250
250
  X
@@ -256,7 +256,7 @@ const DataDesigner = (props: DataDesignerProps) => {
256
256
  <select
257
257
  onChange={e => {
258
258
  if (e.target.value) {
259
- updateDescriptionProp(visualizationKey, dataKey, 'ignoredKeys', [...(configureData.dataDescription.ignoredKeys || []), e.target.value])
259
+ updateDescriptionProp('ignoredKeys', [...(configureData.dataDescription.ignoredKeys || []), e.target.value])
260
260
  }
261
261
  e.target.value = ''
262
262
  }}
@@ -33,6 +33,8 @@ import iconPlus from '../../assets/icon-plus.svg'
33
33
  import iconMinus from '../../assets/icon-minus.svg'
34
34
  import iconTable from '../../assets/icon-table.svg'
35
35
  import iconSankey from '../../assets/icon-sankey.svg'
36
+ import iconRotateLeft from '../../assets/icon-rotate-left.svg'
37
+ import iconCommand from '../../assets/icon-command.svg'
36
38
 
37
39
  import '../../styles/v2/components/icon.scss'
38
40
 
@@ -68,7 +70,9 @@ const iconHash = {
68
70
  'filtered-text': iconText,
69
71
  'filter-dropdowns': iconDropdowns,
70
72
  table: iconTable,
71
- sankey: iconSankey
73
+ sankey: iconSankey,
74
+ rotateLeft: iconRotateLeft,
75
+ command: iconCommand
72
76
  }
73
77
 
74
78
  export const ICON_TYPES = Object.keys(iconHash)
@@ -134,27 +134,27 @@ export class DataTransform {
134
134
  let standardized: string[] = []
135
135
 
136
136
  data.forEach(row => {
137
- let uniqueKey = row[description.xKey];
137
+ let uniqueKey = row[description.xKey]
138
138
  Object.keys(row).forEach(key => {
139
- if(key !== description.xKey && key !== description.seriesKey && description.valueKeysTallSupport.indexOf(key) === -1 && (!description.ignoredKeys || description.ignoredKeys.indexOf(key) === -1)){
140
- uniqueKey += "|" + row[key];
139
+ if (key !== description.xKey && key !== description.seriesKey && description.valueKeysTallSupport.indexOf(key) === -1 && (!description.ignoredKeys || description.ignoredKeys.indexOf(key) === -1)) {
140
+ uniqueKey += '|' + row[key]
141
141
  }
142
142
  })
143
143
 
144
- if(!standardizedMapped[uniqueKey]){
145
- standardizedMapped[uniqueKey] = {[description.xKey]: row[description.xKey]}
144
+ if (!standardizedMapped[uniqueKey]) {
145
+ standardizedMapped[uniqueKey] = { [description.xKey]: row[description.xKey] }
146
146
  }
147
147
  Object.keys(row).forEach(key => {
148
- if(key !== description.xKey && key !== description.seriesKey && description.valueKeysTallSupport.indexOf(key) === -1 && (!description.ignoredKeys || description.ignoredKeys.indexOf(key) === -1)){
149
- standardizedMapped[uniqueKey][key] = row[key];
148
+ if (key !== description.xKey && key !== description.seriesKey && description.valueKeysTallSupport.indexOf(key) === -1 && (!description.ignoredKeys || description.ignoredKeys.indexOf(key) === -1)) {
149
+ standardizedMapped[uniqueKey][key] = row[key]
150
150
  }
151
151
  })
152
152
  description.valueKeysTallSupport.forEach(valueKey => {
153
- standardizedMapped[uniqueKey][row[description.seriesKey] + '-' + valueKey] = row[valueKey];
153
+ standardizedMapped[uniqueKey][row[description.seriesKey] + '-' + valueKey] = row[valueKey]
154
154
  })
155
155
  })
156
156
 
157
- standardized = Object.keys(standardizedMapped).map(key => standardizedMapped[key]);
157
+ standardized = Object.keys(standardizedMapped).map(key => standardizedMapped[key])
158
158
 
159
159
  return standardized
160
160
  } else if (description.valueKeys !== undefined) {
@@ -291,29 +291,6 @@ export class DataTransform {
291
291
  return cleanedupData
292
292
  }
293
293
 
294
- applySuppression = (data, suppressedData) => {
295
- if (!suppressedData || suppressedData.length === 0) return data
296
-
297
- // Create a new array to store the result without modifying the original data
298
- const result = data.map(item => {
299
- // Create a new object to store the updated item without modifying the original item
300
- const newItem = { ...item }
301
-
302
- // For each suppressedData item
303
- for (let i = 0; i < suppressedData.length; i++) {
304
- // If the object contains the column and its value matches the suppressed one
305
- if (newItem[suppressedData[i].column] && newItem[suppressedData[i].column] === suppressedData[i].value) {
306
- // Replace the value with the label in the new object
307
- newItem[suppressedData[i].column] = suppressedData[i].label
308
- }
309
- }
310
-
311
- return newItem
312
- })
313
-
314
- return result
315
- }
316
-
317
294
  // clean out %, $, commas from numbers when needing to do sorting!
318
295
  cleanDataPoint(data, testing = false) {
319
296
  if (testing) console.log('clean', data)
@@ -0,0 +1,21 @@
1
+ // If config key names or position in the config have been changed with a version change,
2
+ // process those config entries and format old values into new
3
+ import update_4_24_4 from './ver/4.23.4'
4
+ import update_4_24_3 from './ver/4.24.3'
5
+ import update_4_24_5 from './ver/4.24.5'
6
+
7
+ export const coveUpdateWorker = config => {
8
+ let genConfig = config
9
+
10
+ genConfig = update_4_24_3(genConfig)
11
+ genConfig = update_4_24_4(genConfig)
12
+ genConfig = update_4_24_5(genConfig)
13
+
14
+ return genConfig
15
+ }
16
+
17
+ const asyncWorker = async config => {
18
+ return await coveUpdateWorker(config)
19
+ }
20
+
21
+ export default asyncWorker
@@ -0,0 +1,11 @@
1
+ import _ from 'lodash'
2
+
3
+ const symbols = [
4
+ ['*', 'Asterisk'],
5
+ ['†', 'Dagger'],
6
+ ['§', 'Section Symbol'],
7
+ ['¶', 'Paragraph Symbol']
8
+ ]
9
+
10
+ export const footnotesSymbols = symbols.concat(symbols.map(([symbol, name]) => [symbol + symbol, 'Double ' + name]))
11
+ export const adjustedSymbols = _.fromPairs(_.map(footnotesSymbols, ([symbol, name]) => [name, symbol]))
@@ -1,7 +1,6 @@
1
1
  export default function useDataVizClasses(config, viewport = null) {
2
2
  const { legend } = config
3
3
  let lineDatapointClass = ''
4
- let barBorderClass = ''
5
4
 
6
5
  if (config.lineDatapointStyle === 'hover') {
7
6
  lineDatapointClass = ' chart-line--hover'
@@ -9,9 +8,6 @@ export default function useDataVizClasses(config, viewport = null) {
9
8
  if (config.lineDatapointStyle === 'always show') {
10
9
  lineDatapointClass = ' chart-line--always'
11
10
  }
12
- if (config.barHasBorder === 'false') {
13
- barBorderClass = ' chart-bar--no-border'
14
- }
15
11
 
16
12
  let innerContainerClasses = ['cove-component__inner']
17
13
  let contentClasses = ['cove-component__content']
@@ -69,5 +65,5 @@ export default function useDataVizClasses(config, viewport = null) {
69
65
  div: [legend?.position === 'bottom' && legend?.singleRow ? 'shape-container single-row' : 'shape-container']
70
66
  }
71
67
 
72
- return { innerContainerClasses, contentClasses, barBorderClass, lineDatapointClass, sparkLineStyles, legendClasses }
68
+ return { innerContainerClasses, contentClasses, lineDatapointClass, sparkLineStyles, legendClasses }
73
69
  }
@@ -0,0 +1,27 @@
1
+ import _ from 'lodash'
2
+
3
+ const addFiltersToTables = config => {
4
+ if (config.type === 'dashboard') {
5
+ Object.keys(config.visualizations).forEach(vizKey => {
6
+ const viz = config.visualizations[vizKey]
7
+ if (viz.type === 'table') {
8
+ if (!viz.filters) {
9
+ viz.filters = []
10
+ viz.filterBehavior = 'Filter Change'
11
+ }
12
+ }
13
+ })
14
+ }
15
+ }
16
+
17
+ const update_4_24_4 = config => {
18
+ const ver = '4.24.4'
19
+
20
+ const newConfig = _.cloneDeep(config)
21
+ addFiltersToTables(newConfig)
22
+
23
+ newConfig.version = ver
24
+ return newConfig
25
+ }
26
+
27
+ export default update_4_24_4
@@ -0,0 +1,56 @@
1
+ import { ConfigRow } from '@cdc/dashboard/src/types/ConfigRow'
2
+ import _ from 'lodash'
3
+
4
+ const remapDashboardRows = config => {
5
+ if (config.type === 'dashboard') {
6
+ config.rows = config.rows.map(row => {
7
+ let newRow = undefined
8
+ if (row.columns === undefined) {
9
+ newRow = {} as ConfigRow
10
+ const newColumns = row.map(column => {
11
+ newRow.uuid = column.uuid
12
+ newRow.toggle = column.toggle
13
+ newRow.equalHeight = column.equalHeight
14
+ return _.pick(column, 'equalHeight', 'width', 'hide', 'widget', 'uuid')
15
+ })
16
+ newRow.columns = newColumns
17
+ }
18
+ return newRow ?? row
19
+ })
20
+ }
21
+ }
22
+
23
+ const chartUpdates = newConfig => {
24
+ if (newConfig.type === 'chart') {
25
+ if (newConfig.xAxis.sortDates) {
26
+ newConfig.xAxis.type = 'date-time'
27
+ }
28
+ newConfig.table.download = true
29
+
30
+ delete newConfig.xAxis.sortDates
31
+ }
32
+ }
33
+
34
+ const mapUpdates = newConfig => {
35
+ if (newConfig.type === 'map') {
36
+ newConfig.table.download = true
37
+ newConfig.general.showDownloadButton = true
38
+ // expandDataTable should be removed in the future....
39
+ newConfig.general.expandDataTable = newConfig.table.expanded
40
+ }
41
+ }
42
+
43
+ const update_4_24_3 = config => {
44
+ const ver = '4.24.3'
45
+
46
+ const newConfig = _.cloneDeep(config)
47
+
48
+ remapDashboardRows(newConfig)
49
+ chartUpdates(newConfig)
50
+ mapUpdates(newConfig)
51
+
52
+ newConfig.version = ver
53
+ return newConfig
54
+ }
55
+
56
+ export default update_4_24_3
@@ -0,0 +1,32 @@
1
+ import _ from 'lodash'
2
+
3
+ const migrateMarkupInclude = newConfig => {
4
+ if (newConfig.type === 'markup-include') {
5
+ if (!newConfig.contentEditor) {
6
+ newConfig.contentEditor = {
7
+ title: newConfig.title,
8
+ showHeader: newConfig.showHeader,
9
+ srcUrl: newConfig.srcUrl
10
+ }
11
+ delete newConfig.title
12
+ delete newConfig.showHeader
13
+ delete newConfig.srcUrl
14
+ }
15
+ if (!newConfig.visual) {
16
+ newConfig.visual = {}
17
+ }
18
+ }
19
+ }
20
+
21
+ const update_4_24_4 = config => {
22
+ const ver = '4.24.4'
23
+
24
+ const newConfig = _.cloneDeep(config)
25
+
26
+ migrateMarkupInclude(newConfig)
27
+
28
+ newConfig.version = ver
29
+ return newConfig
30
+ }
31
+
32
+ export default update_4_24_4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/core",
3
- "version": "4.24.3",
3
+ "version": "4.24.5",
4
4
  "description": "Core components, styles, hooks, and helpers, for the CDC Open Visualization project",
5
5
  "moduleName": "CdcCore",
6
6
  "main": "dist/cdccore",
@@ -31,5 +31,5 @@
31
31
  "react": "^18.2.0",
32
32
  "react-dom": "^18.2.0"
33
33
  },
34
- "gitHead": "9c7ef7ca74f2d2a1e04d923b133fe0fc557a62bf"
34
+ "gitHead": "def85aaf4cd9dc1983e80f2900199f35de82af95"
35
35
  }