@cdc/core 4.24.4 → 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.
- package/components/DataTable/DataTable.tsx +13 -14
- package/components/DataTable/DataTableStandAlone.tsx +51 -4
- package/components/DataTable/components/ChartHeader.tsx +3 -2
- package/components/DataTable/components/DataTableEditorPanel.tsx +20 -3
- package/components/DataTable/helpers/chartCellMatrix.tsx +2 -1
- package/components/DataTable/helpers/getChartCellValue.ts +21 -1
- package/components/DataTable/helpers/getDataSeriesColumns.ts +37 -16
- package/components/DataTable/helpers/getSeriesName.ts +2 -1
- package/components/DataTable/helpers/{customColumns.ts → removeNullColumns.ts} +3 -3
- package/components/DataTable/types/TableConfig.ts +11 -22
- package/components/EditorPanel/ColumnsEditor.tsx +304 -261
- package/components/EditorPanel/DataTableEditor.tsx +119 -64
- package/components/EditorPanel/VizFilterEditor.tsx +234 -0
- package/components/EditorWrapper/EditorWrapper.tsx +48 -0
- package/components/EditorWrapper/editor-wrapper.style.css +14 -0
- package/components/Filters.jsx +70 -54
- package/components/Layout/components/Visualization/index.tsx +5 -3
- package/components/MediaControls.jsx +1 -1
- package/components/_stories/DataTable.stories.tsx +1 -2
- package/components/_stories/EditorPanel.stories.tsx +1 -0
- package/components/_stories/styles.scss +0 -1
- package/helpers/DataTransform.ts +9 -32
- package/helpers/coveUpdateWorker.ts +4 -2
- package/helpers/footnoteSymbols.ts +11 -0
- package/helpers/useDataVizClasses.js +0 -4
- package/helpers/ver/4.23.4.ts +27 -0
- package/helpers/ver/4.24.5.ts +32 -0
- package/package.json +2 -2
- package/styles/_reset.scss +7 -6
- package/types/Axis.ts +2 -0
- package/types/Column.ts +1 -0
- package/types/Legend.ts +1 -0
- package/types/MarkupInclude.ts +26 -0
- package/types/Runtime.ts +1 -0
- package/types/Series.ts +1 -1
- package/types/Table.ts +15 -14
- package/types/Visualization.ts +11 -4
- package/types/VizFilter.ts +13 -0
package/components/Filters.jsx
CHANGED
|
@@ -8,30 +8,57 @@ import { getQueryParams, updateQueryString } from '@cdc/core/helpers/queryString
|
|
|
8
8
|
// Third Party
|
|
9
9
|
import PropTypes from 'prop-types'
|
|
10
10
|
|
|
11
|
+
export const filterStyleOptions = ['dropdown', 'pill', 'tab', 'tab bar']
|
|
12
|
+
|
|
13
|
+
export const filterOrderOptions = [
|
|
14
|
+
{
|
|
15
|
+
label: 'Ascending Alphanumeric',
|
|
16
|
+
value: 'asc'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
label: 'Descending Alphanumeric',
|
|
20
|
+
value: 'desc'
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: 'Custom',
|
|
24
|
+
value: 'cust'
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
export const handleSorting = singleFilter => {
|
|
29
|
+
const { order } = singleFilter
|
|
30
|
+
|
|
31
|
+
const sortAsc = (a, b) => {
|
|
32
|
+
return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const sortDesc = (a, b) => {
|
|
36
|
+
return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!order || order === '') {
|
|
40
|
+
singleFilter.order = 'asc'
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (order === 'desc') {
|
|
44
|
+
singleFilter.values = singleFilter.values.sort(sortDesc)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (order === 'asc') {
|
|
48
|
+
singleFilter.values = singleFilter.values.sort(sortAsc)
|
|
49
|
+
}
|
|
50
|
+
return singleFilter
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const hasStandardFilterBehavior = ['chart', 'table']
|
|
54
|
+
|
|
11
55
|
export const useFilters = props => {
|
|
12
56
|
const [showApplyButton, setShowApplyButton] = useState(false)
|
|
13
57
|
|
|
14
58
|
// Desconstructing: notice, adding more descriptive visualizationConfig name over config
|
|
15
59
|
// visualizationConfig feels more robust for all vis types so that its not confused with config/state/etc.
|
|
16
|
-
const { config: visualizationConfig, setConfig, filteredData, setFilteredData, excludedData, filterData } = props
|
|
17
|
-
const { type,
|
|
18
|
-
|
|
19
|
-
const filterStyleOptions = ['dropdown', 'pill', 'tab', 'tab bar']
|
|
20
|
-
|
|
21
|
-
const filterOrderOptions = [
|
|
22
|
-
{
|
|
23
|
-
label: 'Ascending Alphanumeric',
|
|
24
|
-
value: 'asc'
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
label: 'Descending Alphanumeric',
|
|
28
|
-
value: 'desc'
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
label: 'Custom',
|
|
32
|
-
value: 'cust'
|
|
33
|
-
}
|
|
34
|
-
]
|
|
60
|
+
const { config: visualizationConfig, setConfig, filteredData, setFilteredData, excludedData, filterData, getUniqueValues } = props
|
|
61
|
+
const { type, data } = visualizationConfig
|
|
35
62
|
|
|
36
63
|
/**
|
|
37
64
|
* Re-orders a filter based on two indices and updates the runtime filters array and filters state
|
|
@@ -51,7 +78,7 @@ export const useFilters = props => {
|
|
|
51
78
|
const [movedItem] = updatedValues.splice(idx1, 1)
|
|
52
79
|
updatedValues.splice(idx2, 0, movedItem)
|
|
53
80
|
|
|
54
|
-
const filtersCopy = visualizationConfig.type
|
|
81
|
+
const filtersCopy = hasStandardFilterBehavior.includes(visualizationConfig.type) ? [...visualizationConfig.filters] : [...filteredData]
|
|
55
82
|
const filterItem = { ...filtersCopy[filterIndex] }
|
|
56
83
|
|
|
57
84
|
// Overwrite filterItem.values since thats what we map through in the editor panel
|
|
@@ -99,7 +126,7 @@ export const useFilters = props => {
|
|
|
99
126
|
}
|
|
100
127
|
|
|
101
128
|
// If we're on a chart and not using the apply button
|
|
102
|
-
if (visualizationConfig.type
|
|
129
|
+
if (hasStandardFilterBehavior.includes(visualizationConfig.type) && visualizationConfig.filterBehavior === 'Filter Change') {
|
|
103
130
|
setFilteredData(filterData(newFilters, excludedData))
|
|
104
131
|
}
|
|
105
132
|
}
|
|
@@ -127,7 +154,7 @@ export const useFilters = props => {
|
|
|
127
154
|
setFilteredData(newFilters, excludedData)
|
|
128
155
|
}
|
|
129
156
|
|
|
130
|
-
if (type
|
|
157
|
+
if (hasStandardFilterBehavior.includes(visualizationConfig.type)) {
|
|
131
158
|
setFilteredData(filterData(newFilters, excludedData))
|
|
132
159
|
}
|
|
133
160
|
|
|
@@ -139,19 +166,33 @@ export const useFilters = props => {
|
|
|
139
166
|
e.preventDefault()
|
|
140
167
|
|
|
141
168
|
// reset to first item in values array.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
169
|
+
let needsQueryUpdate = false
|
|
170
|
+
const queryParams = getQueryParams()
|
|
171
|
+
newFilters.forEach((filter, i) => {
|
|
172
|
+
if(!filter.values || filter.values.length === 0){
|
|
173
|
+
filter.values = getUniqueValues(data, filter.columnName)
|
|
174
|
+
}
|
|
175
|
+
newFilters[i].active = handleSorting(filter).values[0]
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
if (filter.setByQueryParameter && queryParams[filter.setByQueryParameter] !== filter.active) {
|
|
179
|
+
queryParams[filter.setByQueryParameter] = filter.active
|
|
180
|
+
needsQueryUpdate = true
|
|
181
|
+
}
|
|
146
182
|
})
|
|
147
183
|
|
|
184
|
+
if (needsQueryUpdate) {
|
|
185
|
+
updateQueryString(queryParams)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
setConfig({ ...visualizationConfig, filters: newFilters })
|
|
189
|
+
|
|
148
190
|
if (type === 'map') {
|
|
149
191
|
setFilteredData(newFilters, excludedData)
|
|
150
192
|
} else {
|
|
151
193
|
setFilteredData(filterData(newFilters, excludedData))
|
|
152
194
|
}
|
|
153
195
|
|
|
154
|
-
setConfig({ ...visualizationConfig, filters: newFilters })
|
|
155
196
|
}
|
|
156
197
|
|
|
157
198
|
const filterConstants = {
|
|
@@ -161,31 +202,6 @@ export const useFilters = props => {
|
|
|
161
202
|
applyText: 'Select the apply button to update the visualization information.'
|
|
162
203
|
}
|
|
163
204
|
|
|
164
|
-
const handleSorting = singleFilter => {
|
|
165
|
-
const { order } = singleFilter
|
|
166
|
-
|
|
167
|
-
const sortAsc = (a, b) => {
|
|
168
|
-
return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const sortDesc = (a, b) => {
|
|
172
|
-
return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (!order || order === '') {
|
|
176
|
-
singleFilter.order = 'asc'
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (order === 'desc') {
|
|
180
|
-
singleFilter.values = singleFilter.values.sort(sortDesc)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
if (order === 'asc') {
|
|
184
|
-
singleFilter.values = singleFilter.values.sort(sortAsc)
|
|
185
|
-
}
|
|
186
|
-
return singleFilter
|
|
187
|
-
}
|
|
188
|
-
|
|
189
205
|
// prettier-ignore
|
|
190
206
|
return {
|
|
191
207
|
handleApplyButton,
|
|
@@ -202,8 +218,8 @@ export const useFilters = props => {
|
|
|
202
218
|
}
|
|
203
219
|
|
|
204
220
|
const Filters = props => {
|
|
205
|
-
const { config: visualizationConfig, filteredData, dimensions } = props
|
|
206
|
-
const { filters, type, general, theme, filterBehavior } = visualizationConfig
|
|
221
|
+
const { config: visualizationConfig, filteredData, dimensions, getUniqueValues } = props
|
|
222
|
+
const { filters, type, general, theme, filterBehavior, data } = visualizationConfig
|
|
207
223
|
const [mobileFilterStyle, setMobileFilterStyle] = useState(false)
|
|
208
224
|
const [selectedFilter, setSelectedFilter] = useState('')
|
|
209
225
|
const id = useId()
|
|
@@ -4,13 +4,15 @@ import React, { forwardRef, useRef } from 'react'
|
|
|
4
4
|
import { Config as DataBiteConfig } from '@cdc/data-bite/src/types/Config'
|
|
5
5
|
import './visualizations.scss'
|
|
6
6
|
import { Config as WaffleChartConfig } from '@cdc/waffle-chart/src/types/Config'
|
|
7
|
+
import { MarkupIncludeConfig } from '@cdc/core/types/MarkupInclude'
|
|
7
8
|
|
|
8
9
|
type VisualizationWrapper = {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
children: React.ReactNode
|
|
11
|
+
config: ChartConfig | DataBiteConfig | WaffleChartConfig | MarkupIncludeConfig
|
|
11
12
|
currentViewport: string
|
|
12
13
|
imageId: string
|
|
13
|
-
|
|
14
|
+
isEditor: boolean
|
|
15
|
+
showEditorPanel: boolean
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
const Visualization: React.FC<VisualizationWrapper> = forwardRef((props, ref) => {
|
|
@@ -59,7 +59,7 @@ const generateMedia = (state, type, elementToCapture) => {
|
|
|
59
59
|
|
|
60
60
|
switch (type) {
|
|
61
61
|
case 'image':
|
|
62
|
-
html2canvas(baseSvg).then(canvas => {
|
|
62
|
+
html2canvas(baseSvg, {ignoreElements: el => el.className?.indexOf && el.className.search(/download-buttons|download-links|data-table-container/) !== -1}).then(canvas => {
|
|
63
63
|
saveImageAs(canvas.toDataURL(), filename + '.png')
|
|
64
64
|
})
|
|
65
65
|
return
|
|
@@ -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
|
}
|
package/helpers/DataTransform.ts
CHANGED
|
@@ -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 +=
|
|
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)
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// If config key names or position in the config have been changed with a version change,
|
|
2
2
|
// process those config entries and format old values into new
|
|
3
|
+
import update_4_24_4 from './ver/4.23.4'
|
|
3
4
|
import update_4_24_3 from './ver/4.24.3'
|
|
5
|
+
import update_4_24_5 from './ver/4.24.5'
|
|
4
6
|
|
|
5
|
-
// 4.23.6 ------------------------------------------------------
|
|
6
7
|
export const coveUpdateWorker = config => {
|
|
7
8
|
let genConfig = config
|
|
8
9
|
|
|
9
|
-
// v4.24.3
|
|
10
10
|
genConfig = update_4_24_3(genConfig)
|
|
11
|
+
genConfig = update_4_24_4(genConfig)
|
|
12
|
+
genConfig = update_4_24_5(genConfig)
|
|
11
13
|
|
|
12
14
|
return genConfig
|
|
13
15
|
}
|
|
@@ -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]))
|
|
@@ -18,10 +18,6 @@ export default function useDataVizClasses(config, viewport = null) {
|
|
|
18
18
|
if (title && showTitle) contentClasses.push('component--has-title')
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
if (config.type === 'markup-include') {
|
|
22
|
-
contentClasses = contentClasses.filter(item => item !== 'cove-component__content')
|
|
23
|
-
}
|
|
24
|
-
|
|
25
21
|
config.showTitle && contentClasses.push('component--has-title')
|
|
26
22
|
config.title && config.visualizationType !== 'chart' && config.visualizationType !== 'Spark Line' && contentClasses.push('component--has-title')
|
|
27
23
|
config.subtext && innerContainerClasses.push('component--has-subtext')
|
|
@@ -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,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
|
+
"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": "
|
|
34
|
+
"gitHead": "def85aaf4cd9dc1983e80f2900199f35de82af95"
|
|
35
35
|
}
|
package/styles/_reset.scss
CHANGED
|
@@ -141,15 +141,16 @@
|
|
|
141
141
|
top: -0.5em;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
header sup {
|
|
145
|
-
/* Allow line breaks using html in the header. */
|
|
146
|
-
top: initial;
|
|
147
|
-
line-height: initial;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
144
|
sub {
|
|
151
145
|
/* Move the subscripted text down, but only
|
|
152
146
|
half as far down as the superscript moved up */
|
|
153
147
|
bottom: -0.25em;
|
|
154
148
|
}
|
|
149
|
+
|
|
150
|
+
ul > li:first-child {
|
|
151
|
+
margin-top: auto;
|
|
152
|
+
}
|
|
153
|
+
ul > li:last-of-type {
|
|
154
|
+
margin-bottom: auto;
|
|
155
|
+
}
|
|
155
156
|
}
|
package/types/Axis.ts
CHANGED
package/types/Column.ts
CHANGED
package/types/Legend.ts
CHANGED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Runtime } from '@cdc/core/types/Runtime'
|
|
2
|
+
import { Variable } from '@cdc/markup-include/src/types/Variable'
|
|
3
|
+
import { Visualization } from './Visualization'
|
|
4
|
+
|
|
5
|
+
export type MarkupIncludeConfig = Visualization & {
|
|
6
|
+
contentEditor: {
|
|
7
|
+
// Changing the base config object creates an infinite loop, nesting it is a workaround
|
|
8
|
+
inlineHTML: string
|
|
9
|
+
markupVariables: Variable[]
|
|
10
|
+
showHeader: boolean
|
|
11
|
+
srcUrl: string
|
|
12
|
+
title: string
|
|
13
|
+
useInlineHTML: boolean
|
|
14
|
+
}
|
|
15
|
+
data?: Object[]
|
|
16
|
+
formattedData: {}
|
|
17
|
+
newViz?: boolean
|
|
18
|
+
runtime?: Runtime
|
|
19
|
+
visual: {
|
|
20
|
+
border: boolean
|
|
21
|
+
accent: boolean
|
|
22
|
+
background: boolean
|
|
23
|
+
hideBackgroundColor: boolean
|
|
24
|
+
borderColorTheme: boolean
|
|
25
|
+
}
|
|
26
|
+
}
|
package/types/Runtime.ts
CHANGED
package/types/Series.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type Series = { dataKey: string; name: string; axis: string; type: string }[]
|
|
1
|
+
export type Series = { dataKey: string; name: string; axis: string; type: string; tooltip: boolean }[]
|
package/types/Table.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
export type Table = {
|
|
2
|
+
caption?: string
|
|
2
3
|
cellMinWidth?: number
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
collapsible?: boolean
|
|
5
|
+
dateDisplayFormat?: string
|
|
6
|
+
download?: boolean
|
|
7
|
+
downloadImageButton?: boolean
|
|
8
|
+
downloadPdfButton?: boolean
|
|
9
|
+
excludeColumns?: string[]
|
|
10
|
+
expanded?: boolean
|
|
11
|
+
fontSize: 'small' | 'medium' | 'large'
|
|
12
|
+
groupBy?: string
|
|
13
|
+
height?: number
|
|
6
14
|
indexLabel?: string
|
|
7
|
-
|
|
15
|
+
label?: string
|
|
8
16
|
limitHeight?: boolean
|
|
9
|
-
|
|
10
|
-
expanded?: boolean
|
|
17
|
+
show?: boolean
|
|
11
18
|
showDataTableLink?: boolean
|
|
12
|
-
showDownloadUrl?: boolean
|
|
13
|
-
download?: boolean
|
|
14
|
-
customTableConfig?: boolean
|
|
15
|
-
excludeColumns?: string[]
|
|
16
19
|
showDownloadImgButton?: boolean
|
|
17
20
|
showDownloadPdfButton?: boolean
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
dateDisplayFormat?: string
|
|
21
|
-
fontSize: 'small' | 'medium' | 'large'
|
|
21
|
+
showDownloadUrl?: boolean
|
|
22
|
+
showVertical?: boolean
|
|
22
23
|
}
|
package/types/Visualization.ts
CHANGED
|
@@ -6,31 +6,38 @@ import { Table } from './Table'
|
|
|
6
6
|
import { ConfidenceInterval } from './ConfidenceInterval'
|
|
7
7
|
import { BaseVisualizationType } from './BaseVisualizationType'
|
|
8
8
|
import { ConfigureData } from './ConfigureData'
|
|
9
|
+
import { VizFilter } from './VizFilter'
|
|
10
|
+
import { FilterBehavior } from './FilterBehavior'
|
|
11
|
+
import { General } from './General'
|
|
9
12
|
|
|
10
13
|
export type Visualization = ConfigureData & {
|
|
11
14
|
autoLoad: boolean
|
|
12
|
-
columns: Record<string, Column
|
|
15
|
+
columns: Record<string, Partial<Column>>
|
|
13
16
|
confidenceKeys: ConfidenceInterval
|
|
14
17
|
dataFileName: string
|
|
15
18
|
dataFileSourceType: string
|
|
16
19
|
dataFormat: any
|
|
17
20
|
datasets: Record<string, any>
|
|
18
21
|
editing: boolean
|
|
19
|
-
|
|
22
|
+
filterBehavior: FilterBehavior
|
|
23
|
+
filters: VizFilter[]
|
|
24
|
+
general: General
|
|
20
25
|
hide: any[]
|
|
21
26
|
legend: Legend
|
|
22
27
|
multiDashboards?: any[]
|
|
23
28
|
newViz: boolean
|
|
24
29
|
openModal: boolean
|
|
25
|
-
originalFormattedData: any
|
|
26
30
|
orientation: 'vertical' | 'horizontal'
|
|
31
|
+
originalFormattedData: any
|
|
27
32
|
series: Series
|
|
33
|
+
showEditorPanel: boolean
|
|
28
34
|
table: Table
|
|
35
|
+
theme: string
|
|
29
36
|
title: string
|
|
30
37
|
type: BaseVisualizationType
|
|
31
38
|
uid: string // this is the actual key of the visualization object
|
|
32
39
|
usesSharedFilter: any
|
|
33
|
-
visualizationType: string
|
|
34
40
|
visualizationSubType: string
|
|
41
|
+
visualizationType: string
|
|
35
42
|
xAxis: Axis
|
|
36
43
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type VizFilter = {
|
|
2
|
+
active: string
|
|
3
|
+
columnName: string
|
|
4
|
+
filterStyle: 'tab' | 'pill' | 'tab bar' | 'dropdown'
|
|
5
|
+
label: string
|
|
6
|
+
order: 'asc' | 'desc' | 'cust'
|
|
7
|
+
orderedValues?: string[]
|
|
8
|
+
queryParameter: string
|
|
9
|
+
setByQueryParameter: string
|
|
10
|
+
showDropdown: boolean
|
|
11
|
+
type: 'url'
|
|
12
|
+
values: string[]
|
|
13
|
+
}
|