@cdc/core 4.26.1 → 4.26.3
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/.claude/agents/qa-test-developer.md +126 -0
- package/CLAUDE.local.md +67 -0
- package/LICENSE +201 -0
- package/_stories/Gallery.Charts.stories.tsx +35 -42
- package/_stories/Gallery.DataBite.stories.tsx +15 -8
- package/_stories/Gallery.Maps.stories.tsx +37 -28
- package/_stories/Gallery.WaffleChart.stories.tsx +1 -1
- package/_stories/PageART.stories.tsx +5 -4
- package/_stories/PageBRFSS.stories.tsx +21 -16
- package/_stories/PageCancerRegistries.stories.tsx +15 -15
- package/_stories/PageEasternEquineEncephalitis.stories.tsx +33 -19
- package/_stories/PageExcessiveAlcoholUse.stories.tsx +148 -143
- package/_stories/PageMaternalMortality.stories.tsx +5 -4
- package/_stories/PageOralHealth.stories.tsx +15 -10
- package/_stories/PageRespiratory.stories.tsx +4 -4
- package/_stories/PageSmokingTobacco.stories.tsx +15 -10
- package/_stories/PageStateDiabetesProfiles.stories.tsx +15 -10
- package/_stories/PageWastewater.stories.tsx +44 -30
- package/_stories/VegaImport.stories.tsx +401 -0
- package/_stories/vega-fixtures/bars-with-line.json +444 -0
- package/_stories/vega-fixtures/bars.json +58 -0
- package/_stories/vega-fixtures/combo-bar-rolling-mean.json +88 -0
- package/_stories/vega-fixtures/combo.json +68 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars.json +83 -0
- package/_stories/vega-fixtures/grouped-horizontal-bars2.json +231 -0
- package/_stories/vega-fixtures/horizontal-bar.json +427 -0
- package/_stories/vega-fixtures/horizontal-bars-with-bad-colors.json +197 -0
- package/_stories/vega-fixtures/horizontal-bars2.json +58 -0
- package/_stories/vega-fixtures/lines.json +227 -0
- package/_stories/vega-fixtures/measles-bars.json +348 -0
- package/_stories/vega-fixtures/measles-map.json +11101 -0
- package/_stories/vega-fixtures/measles-stacked-bars.json +2147 -0
- package/_stories/vega-fixtures/multi-dataset.json +255 -0
- package/_stories/vega-fixtures/no-data.json +14 -0
- package/_stories/vega-fixtures/pie-chart.json +94 -0
- package/_stories/vega-fixtures/repeat-spec.json +47 -0
- package/_stories/vega-fixtures/stacked-area.json +222 -0
- package/_stories/vega-fixtures/stacked-bar-with-rect.json +3412 -0
- package/_stories/vega-fixtures/stacked-bars-with-line.json +364 -0
- package/_stories/vega-fixtures/stacked-bars.json +212 -0
- package/_stories/vega-fixtures/stacked-horizontal-bars.json +140 -0
- package/_stories/vega-fixtures/warning-combo.json +59 -0
- package/_stories/vega-fixtures/warning-scatter-and-line.json +1182 -0
- package/assets/callout-flag.svg +7 -0
- package/assets/icon-chart-area.svg +1 -0
- package/assets/icon-chart-radar.svg +23 -0
- package/assets/logo2.svg +31 -0
- package/components/AdvancedEditor/EmbedEditor.tsx +270 -38
- package/components/Alert/components/Alert.styles.css +2 -2
- package/components/ComboBox/combobox.styles.css +48 -48
- package/components/CustomColorsEditor/CustomColorsEditor.css +53 -53
- package/components/CustomColorsEditor/CustomColorsEditor.tsx +3 -10
- package/components/DataTable/DataTable.tsx +46 -18
- package/components/DataTable/DataTableStandAlone.tsx +1 -0
- package/components/DataTable/components/ChartHeader.tsx +21 -12
- package/components/DataTable/components/MapHeader.tsx +34 -28
- package/components/DataTable/components/SortIcon/sort-icon.css +5 -5
- package/components/DataTable/data-table.css +50 -52
- package/components/DataTable/helpers/applyCustomOrder.ts +17 -0
- package/components/DataTable/helpers/getChartCellValue.ts +10 -7
- package/components/DataTable/helpers/getMapDataTableColumnKeys.ts +22 -0
- package/components/DataTable/helpers/getSeriesName.ts +6 -0
- package/components/DataTable/helpers/mapCellMatrix.tsx +33 -23
- package/components/DataTable/helpers/tests/mapCellMatrix.test.ts +33 -0
- package/components/DownloadButton.tsx +14 -6
- package/components/EditorPanel/ColumnsEditor.tsx +38 -31
- package/components/EditorPanel/CustomSortOrder.tsx +94 -0
- package/components/EditorPanel/DataTableEditor.tsx +139 -23
- package/components/EditorPanel/EditorPanel.styles.css +71 -71
- package/components/EditorPanel/EditorPanel.tsx +3 -8
- package/components/EditorPanel/EditorPanelDispatch.tsx +4 -4
- package/components/EditorPanel/FootnotesEditor.tsx +2 -2
- package/components/EditorPanel/VizFilterEditor/NestedDropdownEditor.tsx +21 -12
- package/components/EditorPanel/VizFilterEditor/VizFilterEditor.tsx +16 -10
- package/components/EditorPanel/VizFilterEditor/components/FilterOrder.tsx +33 -29
- package/components/EditorPanel/components/MarkupVariablesEditor.tsx +160 -106
- package/components/EditorPanel/components/PanelMarkup.tsx +5 -1
- package/{styles/v2/components → components/EditorPanel}/editor.scss +76 -22
- package/components/EditorPanel/sections/StyleTreatmentSection.tsx +99 -0
- package/components/EditorPanel/sections/VisualSection.tsx +11 -0
- package/components/EditorWrapper/editor-wrapper.style.css +1 -1
- package/components/Filters/Filters.tsx +3 -5
- package/components/Filters/components/Tabs.tsx +19 -7
- package/{styles → components/Filters}/filters.scss +3 -3
- package/components/Footnotes/FootnotesStandAlone.tsx +4 -2
- package/components/HeaderThemeSelector/HeaderThemeSelector.css +61 -5
- package/components/Layout/components/Responsive.tsx +14 -6
- package/components/Layout/components/Sidebar/components/Sidebar.tsx +1 -1
- package/components/Layout/components/Sidebar/components/sidebar.styles.scss +14 -20
- package/components/Layout/components/Visualization/index.tsx +50 -38
- package/components/Layout/components/Visualization/visualizations.scss +232 -15
- package/components/Layout/components/VisualizationContainer.test.tsx +67 -0
- package/components/Layout/components/VisualizationContainer.tsx +37 -0
- package/components/Layout/components/VisualizationContent.test.tsx +182 -0
- package/components/Layout/components/VisualizationContent.tsx +75 -0
- package/components/Layout/index.tsx +5 -5
- package/components/Layout/styles/editor-utils.scss +3 -3
- package/components/Layout/styles/editor.scss +4 -4
- package/components/Legend/Legend.Gradient.tsx +7 -1
- package/components/Loader/loader.styles.css +2 -2
- package/components/Loading.jsx +1 -1
- package/components/MediaControls.tsx +10 -3
- package/components/MultiSelect/multiselect.styles.css +19 -19
- package/components/NestedDropdown/nesteddropdown.styles.css +15 -15
- package/components/PaletteSelector/PaletteSelector.css +15 -15
- package/components/RichTooltip/richTooltip.css +6 -6
- package/components/Table/table.styles.css +2 -2
- package/components/Waiting.tsx +1 -1
- package/components/_stories/CustomColorsEditor.stories.tsx +37 -0
- package/components/_stories/DataTable.stories.tsx +1 -0
- package/components/_stories/Filters.stories.tsx +1 -1
- package/components/_stories/styles.scss +0 -1
- package/components/elements/Button.jsx +1 -1
- package/components/elements/Card.jsx +1 -1
- package/{styles/v2/components → components/elements}/button.scss +9 -8
- package/components/inputs/InputCheckbox.jsx +1 -1
- package/components/inputs/InputSelect.tsx +1 -1
- package/components/inputs/InputText.jsx +1 -1
- package/components/inputs/InputToggle.tsx +1 -1
- package/{styles/v2/components/input → components/inputs}/_input-check-radio.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input-group.scss +3 -3
- package/{styles/v2/components/input → components/inputs}/_input-slider.scss +2 -2
- package/{styles/v2/components/input → components/inputs}/_input.scss +5 -5
- package/{styles/v2/components/input → components/inputs}/index.scss +2 -2
- package/{styles → components}/loading.scss +1 -1
- package/components/managers/DataDesigner.tsx +1 -1
- package/{styles/v2/components → components/managers}/data-designer.scss +6 -7
- package/components/ui/Accordion.jsx +1 -1
- package/components/ui/Icon.tsx +1 -1
- package/components/ui/LoadSpin.jsx +1 -1
- package/components/ui/Modal.jsx +1 -1
- package/components/ui/Overlay.jsx +1 -1
- package/components/ui/Title/index.test.tsx +34 -0
- package/components/ui/Title/index.tsx +24 -7
- package/components/ui/Title/title.styles.css +119 -25
- package/components/ui/Tooltip.tsx +1 -1
- package/components/ui/_stories/Title.stories.tsx +1 -1
- package/{styles/v2/components → components/ui}/accordion.scss +3 -3
- package/components/ui/accordion.styles.css +11 -11
- package/{styles/v2/components → components/ui}/modal.scss +2 -2
- package/{styles/v2/components → components/ui}/overlay.scss +6 -6
- package/{styles/v2/components → components}/ui/tooltip.scss +1 -1
- package/{styles → components}/waiting.scss +9 -3
- package/data/colorPalettes.ts +18 -5
- package/data/mapColorPalettes.ts +10 -0
- package/devTemplate/dev.js +285 -0
- package/devTemplate/index.html +30 -0
- package/devTemplate/preview.html +1503 -0
- package/devTemplate/sidebar.css +151 -0
- package/dist/cove-main.css +2530 -3901
- package/dist/cove-main.css.map +1 -1
- package/generateViteConfig.js +111 -2
- package/helpers/DataTransform.ts +1 -5
- package/helpers/backfillDefaults.ts +35 -0
- package/helpers/constants.ts +12 -0
- package/helpers/cove/date.ts +64 -3
- package/helpers/cove/number.ts +29 -15
- package/helpers/cove/string.ts +29 -0
- package/helpers/coveUpdateWorker.ts +14 -8
- package/helpers/displayDataAsText.ts +1 -1
- package/helpers/embed/embedCodeGenerator.ts +80 -0
- package/helpers/embed/embedHelper.js +169 -0
- package/helpers/embed/filterUtils.ts +121 -0
- package/helpers/embed/index.ts +17 -0
- package/helpers/embed/urlValidation.ts +119 -0
- package/helpers/extractDataAndMetadata.ts +20 -0
- package/helpers/fetchRemoteData.ts +14 -8
- package/helpers/filterVizData.ts +6 -1
- package/helpers/getFileExtension.ts +0 -6
- package/helpers/labelHash.ts +9 -0
- package/helpers/markupProcessor.ts +56 -38
- package/helpers/metrics/types.ts +3 -0
- package/helpers/palettes/colorDistributions.ts +1 -1
- package/helpers/palettes/utils.ts +12 -12
- package/helpers/parseCsvWithQuotes.ts +15 -14
- package/helpers/prepareScreenshot.ts +33 -10
- package/helpers/testing.ts +44 -0
- package/helpers/tests/DataTransform.test.ts +125 -0
- package/helpers/tests/abbreviateNumber.test.ts +59 -0
- package/helpers/tests/backfillDefaults.test.ts +253 -0
- package/helpers/tests/date.test.ts +110 -0
- package/helpers/tests/extractDataAndMetadata.test.ts +93 -0
- package/helpers/tests/markupProcessor.test.ts +315 -124
- package/helpers/tests/number.test.ts +42 -0
- package/helpers/tests/prepareScreenshot.test.ts +28 -28
- package/helpers/tests/testStandaloneBuild.ts +36 -26
- package/helpers/tests/useDataVizClasses.test.ts +66 -0
- package/helpers/tests/visualizationWrapperUsage.test.ts +57 -0
- package/helpers/useDataVizClasses.ts +13 -7
- package/helpers/vegaConfig.ts +1 -1
- package/helpers/vegaConfigImport.ts +160 -0
- package/helpers/ver/4.24.4.ts +24 -0
- package/helpers/ver/4.26.1.ts +1 -1
- package/helpers/ver/4.26.2.ts +84 -0
- package/helpers/ver/4.26.3.ts +44 -0
- package/helpers/ver/4.26.4.ts +31 -0
- package/helpers/ver/tests/4.26.1.test.ts +105 -0
- package/helpers/ver/tests/4.26.2.test.ts +298 -0
- package/helpers/ver/tests/4.26.3.test.ts +168 -0
- package/helpers/ver/tests/4.26.4.test.ts +88 -0
- package/helpers/ver/tests/coveUpdateWorker.test.ts +57 -0
- package/helpers/viewports.ts +2 -0
- package/package.json +27 -32
- package/styles/_global.scss +7 -7
- package/styles/_reset.scss +2 -2
- package/styles/{v2/base → base}/_file-selector.scss +4 -4
- package/styles/{v2/base → base}/_general.scss +2 -4
- package/styles/{v2/base → base}/index.scss +1 -1
- package/styles/base.scss +107 -165
- package/styles/cove-main.scss +3 -6
- package/styles/layout/_component.scss +110 -0
- package/styles/{v2/layout → layout}/_data-table.scss +7 -7
- package/styles/layout/_wrapper-padding.scss +27 -0
- package/styles/{v2/main.scss → main.scss} +3 -1
- package/styles/{v2/themes → themes}/_color-definitions.scss +46 -41
- package/styles/{_accessibility.scss → utils/_accessibility.scss} +1 -1
- package/styles/{v2/utils → utils}/_grid.scss +8 -3
- package/styles/{_global-variables.scss → utils/_properties.scss} +133 -112
- package/styles/{v2/utils → utils}/index.scss +2 -1
- package/types/Annotation.ts +10 -11
- package/types/Axis.ts +2 -0
- package/types/ComponentStyles.ts +1 -0
- package/types/ConfigureData.ts +1 -0
- package/types/General.ts +2 -0
- package/types/MarkupInclude.ts +1 -0
- package/types/MarkupVariable.ts +2 -1
- package/types/Palette.ts +22 -0
- package/types/Table.ts +9 -0
- package/types/Visualization.ts +7 -0
- package/_stories/StoryRenderingTests.stories.tsx +0 -164
- package/helpers/embedCodeGenerator.ts +0 -109
- package/styles/_common-components.css +0 -73
- package/styles/_variables.scss +0 -63
- package/styles/v2/layout/_component.scss +0 -21
- package/styles/v2/utils/_variables.scss +0 -9
- package/{styles/v2/components/card.scss → components/elements/card.css} +2 -2
- /package/{styles/v2/components → components/ui}/icon.scss +0 -0
- /package/{styles/v2/components → components/ui}/loadspin.scss +0 -0
- /package/styles/{v2/base → base}/_heading.scss +0 -0
- /package/styles/{v2/base → base}/_reset.scss +0 -0
- /package/styles/{v2/layout → layout}/_alert.scss +0 -0
- /package/styles/{v2/layout → layout}/_progression.scss +0 -0
- /package/styles/{v2/layout → layout}/_tooltip.scss +0 -0
- /package/styles/{v2/layout → layout}/index.scss +0 -0
- /package/styles/{v2/themes → themes}/index.scss +0 -0
- /package/styles/{v2/utils → utils}/_align.scss +0 -0
- /package/styles/{v2/utils → utils}/_animations.scss +0 -0
- /package/styles/{v2/utils → utils}/_breakpoints.scss +0 -0
- /package/styles/{v2/utils → utils}/_mixins.scss +0 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { CheckBox, Select } from '../Inputs'
|
|
2
|
+
|
|
3
|
+
type StyleTreatmentValue = 'legacy' | 'tp5'
|
|
4
|
+
|
|
5
|
+
type StyleTreatmentSectionProps = {
|
|
6
|
+
styleTreatment: StyleTreatmentValue
|
|
7
|
+
onStyleTreatmentChange: (value: StyleTreatmentValue) => void
|
|
8
|
+
showStyleTreatment?: boolean
|
|
9
|
+
showLegacyControls?: boolean
|
|
10
|
+
border?: boolean
|
|
11
|
+
borderColorTheme?: boolean
|
|
12
|
+
accent?: boolean
|
|
13
|
+
background?: boolean
|
|
14
|
+
hideBackgroundColor?: boolean
|
|
15
|
+
showBackground?: boolean
|
|
16
|
+
showHideBackgroundColor?: boolean
|
|
17
|
+
updateField: Function
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const StyleTreatmentSection = ({
|
|
21
|
+
styleTreatment,
|
|
22
|
+
onStyleTreatmentChange,
|
|
23
|
+
showStyleTreatment = true,
|
|
24
|
+
showLegacyControls = true,
|
|
25
|
+
border,
|
|
26
|
+
borderColorTheme,
|
|
27
|
+
accent,
|
|
28
|
+
background,
|
|
29
|
+
hideBackgroundColor,
|
|
30
|
+
showBackground = false,
|
|
31
|
+
showHideBackgroundColor = false,
|
|
32
|
+
updateField
|
|
33
|
+
}: StyleTreatmentSectionProps) => {
|
|
34
|
+
const hasContent = showStyleTreatment || (showLegacyControls && styleTreatment === 'legacy')
|
|
35
|
+
if (!hasContent) return null
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<div className='cove-accordion__panel-section checkbox-group'>
|
|
39
|
+
{showStyleTreatment && (
|
|
40
|
+
<Select
|
|
41
|
+
label='Style Treatment'
|
|
42
|
+
fieldName='styleTreatment'
|
|
43
|
+
value={styleTreatment}
|
|
44
|
+
style={{ width: '100%' }}
|
|
45
|
+
options={[
|
|
46
|
+
{ label: 'Legacy', value: 'legacy' },
|
|
47
|
+
{ label: 'TP5', value: 'tp5' }
|
|
48
|
+
]}
|
|
49
|
+
onChange={event => onStyleTreatmentChange(event.target.value as StyleTreatmentValue)}
|
|
50
|
+
/>
|
|
51
|
+
)}
|
|
52
|
+
{showLegacyControls && styleTreatment === 'legacy' && (
|
|
53
|
+
<>
|
|
54
|
+
<CheckBox
|
|
55
|
+
value={border}
|
|
56
|
+
section='visual'
|
|
57
|
+
fieldName='border'
|
|
58
|
+
label='Display Border'
|
|
59
|
+
updateField={updateField}
|
|
60
|
+
/>
|
|
61
|
+
<CheckBox
|
|
62
|
+
value={borderColorTheme}
|
|
63
|
+
section='visual'
|
|
64
|
+
fieldName='borderColorTheme'
|
|
65
|
+
label='Use Border Color Theme'
|
|
66
|
+
updateField={updateField}
|
|
67
|
+
/>
|
|
68
|
+
<CheckBox
|
|
69
|
+
value={accent}
|
|
70
|
+
section='visual'
|
|
71
|
+
fieldName='accent'
|
|
72
|
+
label='Use Accent Style'
|
|
73
|
+
updateField={updateField}
|
|
74
|
+
/>
|
|
75
|
+
{showBackground && (
|
|
76
|
+
<CheckBox
|
|
77
|
+
value={background}
|
|
78
|
+
section='visual'
|
|
79
|
+
fieldName='background'
|
|
80
|
+
label='Use Theme Background Color'
|
|
81
|
+
updateField={updateField}
|
|
82
|
+
/>
|
|
83
|
+
)}
|
|
84
|
+
{showHideBackgroundColor && (
|
|
85
|
+
<CheckBox
|
|
86
|
+
value={hideBackgroundColor}
|
|
87
|
+
section='visual'
|
|
88
|
+
fieldName='hideBackgroundColor'
|
|
89
|
+
label='Hide Background Color'
|
|
90
|
+
updateField={updateField}
|
|
91
|
+
/>
|
|
92
|
+
)}
|
|
93
|
+
</>
|
|
94
|
+
)}
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export default StyleTreatmentSection
|
|
@@ -2,6 +2,7 @@ import { ReactNode } from 'react'
|
|
|
2
2
|
import { CheckBox } from '../Inputs'
|
|
3
3
|
import { HeaderThemeSelector } from '../../HeaderThemeSelector'
|
|
4
4
|
import { UpdateFieldFunc } from '../../../types/UpdateFieldFunc'
|
|
5
|
+
import { isCoveDeveloperMode } from '../../../helpers/queryStringUtils'
|
|
5
6
|
|
|
6
7
|
export interface VisualSectionConfig {
|
|
7
8
|
visual?: {
|
|
@@ -10,6 +11,7 @@ export interface VisualSectionConfig {
|
|
|
10
11
|
accent?: boolean
|
|
11
12
|
background?: boolean
|
|
12
13
|
hideBackgroundColor?: boolean
|
|
14
|
+
highlightWrappers?: boolean
|
|
13
15
|
}
|
|
14
16
|
theme?: string
|
|
15
17
|
}
|
|
@@ -154,6 +156,15 @@ export const VisualSection = <TConfig extends VisualSectionConfig = VisualSectio
|
|
|
154
156
|
updateField={updateField}
|
|
155
157
|
/>
|
|
156
158
|
)}
|
|
159
|
+
{isCoveDeveloperMode() && (
|
|
160
|
+
<CheckBox
|
|
161
|
+
value={visual.highlightWrappers}
|
|
162
|
+
section='visual'
|
|
163
|
+
fieldName='highlightWrappers'
|
|
164
|
+
label='Highlight Layout Wrappers'
|
|
165
|
+
updateField={updateField}
|
|
166
|
+
/>
|
|
167
|
+
)}
|
|
157
168
|
</div>
|
|
158
169
|
)
|
|
159
170
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useState, useEffect, useMemo, useRef, useId } from 'react'
|
|
2
|
+
import './filters.scss'
|
|
2
3
|
import _ from 'lodash'
|
|
3
4
|
import parse from 'html-react-parser'
|
|
4
5
|
|
|
@@ -210,12 +211,9 @@ const Filters: React.FC<FilterProps> = ({
|
|
|
210
211
|
if (!hasVisibleFilters) return <></>
|
|
211
212
|
|
|
212
213
|
const getClasses = () => {
|
|
213
|
-
const {
|
|
214
|
-
const baseClass = 'filters-section'
|
|
215
|
-
const conditionalClass = standaloneMap ? general.headerColor : visualizationType === 'Spark Line' ? null : theme
|
|
214
|
+
const { legend } = visualizationConfig || {}
|
|
216
215
|
const legendClass = legend && !legend.hide && legend.position === 'top' ? 'mb-0' : null
|
|
217
|
-
|
|
218
|
-
return [baseClass, conditionalClass, legendClass, 'w-100'].filter(Boolean)
|
|
216
|
+
return ['filters-section', legendClass, 'w-100'].filter(Boolean)
|
|
219
217
|
}
|
|
220
218
|
|
|
221
219
|
const getNestedGroup = (singleFilter: VizFilter): string[] => {
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
import { useEffect, useId, useState } from 'react'
|
|
2
2
|
import { VizFilter } from '../../../types/VizFilter'
|
|
3
3
|
|
|
4
|
+
type TabCompatibleFilter = {
|
|
5
|
+
filterStyle: string
|
|
6
|
+
values: string[]
|
|
7
|
+
active?: string | string[]
|
|
8
|
+
queuedActive?: string | string[]
|
|
9
|
+
labels?: Record<string, string>
|
|
10
|
+
}
|
|
11
|
+
|
|
4
12
|
type TabsProps = {
|
|
5
|
-
filter: VizFilter
|
|
13
|
+
filter: VizFilter | TabCompatibleFilter
|
|
6
14
|
index: number
|
|
7
15
|
changeFilterActive: Function
|
|
8
|
-
theme
|
|
16
|
+
theme?: string
|
|
17
|
+
loading?: boolean
|
|
9
18
|
}
|
|
10
19
|
|
|
11
|
-
const Tabs: React.FC<TabsProps> = ({ filter, index: outerIndex, changeFilterActive,
|
|
20
|
+
const Tabs: React.FC<TabsProps> = ({ filter, index: outerIndex, changeFilterActive, loading }) => {
|
|
12
21
|
const [selectedFilter, setSelectedFilter] = useState<EventTarget>(null)
|
|
13
22
|
|
|
14
23
|
const id = useId()
|
|
@@ -21,18 +30,19 @@ const Tabs: React.FC<TabsProps> = ({ filter, index: outerIndex, changeFilterActi
|
|
|
21
30
|
}, [selectedFilter])
|
|
22
31
|
|
|
23
32
|
const getClassList = value => {
|
|
24
|
-
const
|
|
33
|
+
const activeValue = filter.queuedActive || filter.active
|
|
34
|
+
const isActive = activeValue === value
|
|
25
35
|
let classList = []
|
|
26
36
|
switch (filter.filterStyle) {
|
|
27
37
|
case 'tab bar':
|
|
28
38
|
classList = ['button__tab-bar', isActive && 'button__tab-bar--active']
|
|
29
39
|
break
|
|
30
40
|
case 'pill':
|
|
31
|
-
classList = ['pill', isActive && 'pill--active'
|
|
41
|
+
classList = ['pill', isActive && 'pill--active']
|
|
32
42
|
break
|
|
33
43
|
default:
|
|
34
44
|
const tabSimple = filter.filterStyle === 'tab-simple' && 'tab--simple'
|
|
35
|
-
classList = ['tab', isActive && 'tab--active',
|
|
45
|
+
classList = ['tab', isActive && 'tab--active', tabSimple]
|
|
36
46
|
break
|
|
37
47
|
}
|
|
38
48
|
return classList.filter(Boolean).join(' ')
|
|
@@ -41,9 +51,11 @@ const Tabs: React.FC<TabsProps> = ({ filter, index: outerIndex, changeFilterActi
|
|
|
41
51
|
const Tabs = filter.values.map((value, index) => {
|
|
42
52
|
return (
|
|
43
53
|
<button
|
|
54
|
+
type='button'
|
|
44
55
|
key={`${value}-${outerIndex}-${index}-${id}`}
|
|
45
56
|
id={`${value}-${outerIndex}-${index}-${id}`}
|
|
46
57
|
className={getClassList(value)}
|
|
58
|
+
disabled={loading}
|
|
47
59
|
onClick={e => {
|
|
48
60
|
changeFilterActive(outerIndex, value)
|
|
49
61
|
setSelectedFilter(e.target)
|
|
@@ -55,7 +67,7 @@ const Tabs: React.FC<TabsProps> = ({ filter, index: outerIndex, changeFilterActi
|
|
|
55
67
|
}
|
|
56
68
|
}}
|
|
57
69
|
>
|
|
58
|
-
{value}
|
|
70
|
+
{filter.labels?.[value] || value}
|
|
59
71
|
</button>
|
|
60
72
|
)
|
|
61
73
|
})
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
@import '
|
|
1
|
+
@import '../../styles/utils/breakpoints';
|
|
2
2
|
|
|
3
3
|
.filters-section {
|
|
4
4
|
&__wrapper {
|
|
5
5
|
flex-wrap: wrap;
|
|
6
6
|
display: flex;
|
|
7
7
|
gap: 1rem 1.5rem;
|
|
8
|
-
margin-bottom: 2rem;
|
|
9
8
|
|
|
10
9
|
label {
|
|
11
10
|
display: inherit;
|
|
@@ -107,7 +106,7 @@ div.single-filters {
|
|
|
107
106
|
}
|
|
108
107
|
}
|
|
109
108
|
|
|
110
|
-
.
|
|
109
|
+
.cove-visualization {
|
|
111
110
|
@include breakpointClass(xs) {
|
|
112
111
|
.single-filters--tab-simple .tab-simple-container .tab.tab--simple {
|
|
113
112
|
font-size: 0.778em;
|
|
@@ -152,6 +151,7 @@ div.single-filters {
|
|
|
152
151
|
flex: 1 1 0px;
|
|
153
152
|
padding: 10px;
|
|
154
153
|
background: none;
|
|
154
|
+
border: none;
|
|
155
155
|
transition: background 2s;
|
|
156
156
|
|
|
157
157
|
&--active {
|
|
@@ -13,9 +13,10 @@ type StandAloneProps = {
|
|
|
13
13
|
markupVariables?: MarkupVariable[]
|
|
14
14
|
enableMarkupVariables?: boolean
|
|
15
15
|
data?: Object[]
|
|
16
|
+
dataMetadata?: Record<string, string>
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
const FootnotesStandAlone: React.FC<StandAloneProps> = ({ config, filters, markupVariables = [], enableMarkupVariables = false, data = [] }) => {
|
|
19
|
+
const FootnotesStandAlone: React.FC<StandAloneProps> = ({ config, filters, markupVariables = [], enableMarkupVariables = false, data = [], dataMetadata }) => {
|
|
19
20
|
if (!config) return null
|
|
20
21
|
|
|
21
22
|
// Helper function to process markup variables in footnote text
|
|
@@ -33,7 +34,8 @@ const FootnotesStandAlone: React.FC<StandAloneProps> = ({ config, filters, marku
|
|
|
33
34
|
markupVariables,
|
|
34
35
|
{
|
|
35
36
|
filters,
|
|
36
|
-
isEditor: false
|
|
37
|
+
isEditor: false,
|
|
38
|
+
dataMetadata
|
|
37
39
|
}
|
|
38
40
|
)
|
|
39
41
|
|
|
@@ -1,3 +1,59 @@
|
|
|
1
|
+
/* Scoped theme color classes for header theme selector circles */
|
|
2
|
+
.header .color-palette button.theme-purple {
|
|
3
|
+
background: #712177;
|
|
4
|
+
border-bottom-color: #b890bb;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.header .color-palette button.theme-brown {
|
|
8
|
+
background: #705043;
|
|
9
|
+
border-bottom-color: #ad907b;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.header .color-palette button.theme-teal {
|
|
13
|
+
background: #00695c;
|
|
14
|
+
border-bottom-color: #4ebaaa;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.header .color-palette button.theme-pink {
|
|
18
|
+
background: #af4448;
|
|
19
|
+
border-bottom-color: #e57373;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.header .color-palette button.theme-orange {
|
|
23
|
+
background: #bb4d00;
|
|
24
|
+
border-bottom-color: #ffad42;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.header .color-palette button.theme-slate {
|
|
28
|
+
background: #29434e;
|
|
29
|
+
border-bottom-color: #7e9ba5;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.header .color-palette button.theme-indigo {
|
|
33
|
+
background: #26418f;
|
|
34
|
+
border-bottom-color: #92a6dd;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.header .color-palette button.theme-cyan {
|
|
38
|
+
background: #007b91;
|
|
39
|
+
border-bottom-color: #65b0bd;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.header .color-palette button.theme-green {
|
|
43
|
+
background: #4b830d;
|
|
44
|
+
border-bottom-color: #84bc49;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.header .color-palette button.theme-amber {
|
|
48
|
+
background: #fbab18;
|
|
49
|
+
border-bottom-color: #ffd54f;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.header .color-palette button.theme-blue {
|
|
53
|
+
background: #005eaa;
|
|
54
|
+
border-bottom-color: #88c3ea;
|
|
55
|
+
}
|
|
56
|
+
|
|
1
57
|
/* HeaderThemeSelector component styles */
|
|
2
58
|
|
|
3
59
|
.header {
|
|
@@ -6,8 +62,8 @@
|
|
|
6
62
|
|
|
7
63
|
.header .edit-label {
|
|
8
64
|
display: block;
|
|
9
|
-
margin-bottom: 0.5rem;
|
|
10
65
|
font-weight: 500;
|
|
66
|
+
margin-bottom: 0.5rem;
|
|
11
67
|
}
|
|
12
68
|
|
|
13
69
|
.header .color-palette {
|
|
@@ -20,13 +76,13 @@
|
|
|
20
76
|
}
|
|
21
77
|
|
|
22
78
|
.header .color-palette button {
|
|
23
|
-
width: 30px;
|
|
24
|
-
height: 30px;
|
|
25
|
-
border-radius: 50%;
|
|
26
79
|
border: 2px solid transparent;
|
|
80
|
+
border-radius: 50%;
|
|
27
81
|
cursor: pointer;
|
|
28
|
-
|
|
82
|
+
height: 30px;
|
|
29
83
|
outline: none;
|
|
84
|
+
transition: all 0.2s ease;
|
|
85
|
+
width: 30px;
|
|
30
86
|
}
|
|
31
87
|
|
|
32
88
|
.header .color-palette button:hover {
|
|
@@ -13,11 +13,17 @@ const breakpoints = [
|
|
|
13
13
|
'1280' // xl
|
|
14
14
|
]
|
|
15
15
|
|
|
16
|
-
const
|
|
17
|
-
|
|
16
|
+
const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : ''
|
|
17
|
+
const os = userAgent.indexOf('Win') !== -1 ? 'Win' : userAgent.indexOf('Mac') !== -1 ? 'MacOS' : null
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
type ResponsiveProps = {
|
|
20
|
+
children: React.ReactNode
|
|
21
|
+
isEditor: boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const Responsive = ({ children, isEditor }: ResponsiveProps) => {
|
|
20
25
|
const [displayPanel, setDisplayPanel] = useState(false)
|
|
26
|
+
const togglePanel = () => setDisplayPanel(p => !p)
|
|
21
27
|
const [displayGrid, setDisplayGrid] = useState(false)
|
|
22
28
|
const [viewportPreview, setViewportPreview] = useState(null)
|
|
23
29
|
const [rotateAnimation, setRotateAnimation] = useState(false)
|
|
@@ -37,7 +43,7 @@ const Responsive = ({ children, isEditor }) => {
|
|
|
37
43
|
|
|
38
44
|
const onKeypress = key => {
|
|
39
45
|
if (!isEditor) return key
|
|
40
|
-
if (key.code === 'KeyL' && key.ctrlKey)
|
|
46
|
+
if (key.code === 'KeyL' && key.ctrlKey) togglePanel()
|
|
41
47
|
const viewportCommandKey = os === 'MacOS' ? key.metaKey : key.altKey
|
|
42
48
|
if (viewportCommandKey) {
|
|
43
49
|
let keyIndex = key.key
|
|
@@ -109,9 +115,11 @@ const Responsive = ({ children, isEditor }) => {
|
|
|
109
115
|
}
|
|
110
116
|
})
|
|
111
117
|
|
|
112
|
-
const onBackClick = () =>
|
|
118
|
+
const onBackClick = () => togglePanel()
|
|
113
119
|
|
|
114
|
-
if (!isEditor || !displayPanel)
|
|
120
|
+
if (!isEditor || !displayPanel) {
|
|
121
|
+
return <div className='cove-visualization__outer'>{children}</div>
|
|
122
|
+
}
|
|
115
123
|
|
|
116
124
|
return (
|
|
117
125
|
<div className='cove-editor__content' data-grid={displayGrid || null}>
|
|
@@ -40,7 +40,7 @@ const Sidebar: React.FC<SidebarProps> = props => {
|
|
|
40
40
|
return (
|
|
41
41
|
<>
|
|
42
42
|
{/* mimic the editor panel title to keep the button visible. */}
|
|
43
|
-
<section className='editor-panel__toggle-wrapper
|
|
43
|
+
<section className='editor-panel__toggle-wrapper' style={{ height: '49.75px', width: '350px' }}>
|
|
44
44
|
<button className={getButtonClasses()} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick}></button>
|
|
45
45
|
</section>
|
|
46
46
|
<section className={getSectionClasses()}>
|
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
top: 0;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
.cdc-editor .configure .editor-heading + .
|
|
5
|
+
.cdc-editor .configure .editor-heading + .cove-visualization .editor-panel__toggle {
|
|
6
6
|
top: 12px;
|
|
7
7
|
position: relative;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.cdc-editor .configure .
|
|
10
|
+
.cdc-editor .configure .cove-visualization:not(.type-dashboard) .editor-panel__toggle {
|
|
11
11
|
position: absolute;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
.cdc-editor .configure .
|
|
14
|
+
.cdc-editor .configure .cove-visualization:not(.type-dashboard) .sidebar {
|
|
15
15
|
position: relative;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
.
|
|
18
|
+
.cove-visualization {
|
|
19
19
|
.waiting {
|
|
20
20
|
padding-top: 0 !important;
|
|
21
21
|
padding-left: 0 !important;
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
height: 100%; // take up the whole container
|
|
27
27
|
top: 0;
|
|
28
28
|
max-width: 350px;
|
|
29
|
-
width:
|
|
29
|
+
min-width: 0;
|
|
30
30
|
background-color: var(--white);
|
|
31
31
|
grid-area: panel;
|
|
32
32
|
|
|
@@ -440,6 +440,11 @@
|
|
|
440
440
|
|
|
441
441
|
&.checkbox {
|
|
442
442
|
display: flex;
|
|
443
|
+
align-items: center;
|
|
444
|
+
|
|
445
|
+
span.edit-label {
|
|
446
|
+
margin-bottom: 0;
|
|
447
|
+
}
|
|
443
448
|
|
|
444
449
|
input {
|
|
445
450
|
margin-left: 0;
|
|
@@ -626,9 +631,9 @@
|
|
|
626
631
|
|
|
627
632
|
.sort-list {
|
|
628
633
|
list-style: none;
|
|
634
|
+
padding: 0;
|
|
629
635
|
|
|
630
636
|
> li {
|
|
631
|
-
margin-right: 0.3em;
|
|
632
637
|
margin-bottom: 0.3em;
|
|
633
638
|
}
|
|
634
639
|
}
|
|
@@ -641,8 +646,8 @@
|
|
|
641
646
|
background: #f1f1f1;
|
|
642
647
|
padding: 0.4em 0.6em;
|
|
643
648
|
font-size: 0.8em;
|
|
644
|
-
margin-bottom: 0.3em;
|
|
645
649
|
cursor: move;
|
|
650
|
+
width: 100%;
|
|
646
651
|
}
|
|
647
652
|
|
|
648
653
|
.info {
|
|
@@ -799,12 +804,6 @@
|
|
|
799
804
|
font-size: 0.75rem;
|
|
800
805
|
}
|
|
801
806
|
|
|
802
|
-
.cove-accordion__button .cove-tooltip {
|
|
803
|
-
// display: inline-flex;
|
|
804
|
-
// right: 1.5rem;
|
|
805
|
-
// line-height: inherit;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
807
|
.cove-list-group__item .cove-tooltip {
|
|
809
808
|
width: 100%;
|
|
810
809
|
display: block;
|
|
@@ -929,15 +928,10 @@
|
|
|
929
928
|
}
|
|
930
929
|
}
|
|
931
930
|
|
|
932
|
-
&.type-dashboard {
|
|
933
|
-
.editor-panel__toggle {
|
|
934
|
-
top: 64px;
|
|
935
|
-
}
|
|
936
|
-
}
|
|
937
|
-
|
|
938
931
|
.editor-panel__toggle-wrapper {
|
|
939
932
|
position: absolute;
|
|
940
933
|
top: 0;
|
|
934
|
+
left: 0;
|
|
941
935
|
}
|
|
942
936
|
|
|
943
937
|
.editor-panel__toggle {
|
|
@@ -952,7 +946,7 @@
|
|
|
952
946
|
cursor: pointer;
|
|
953
947
|
width: 25px;
|
|
954
948
|
height: 25px;
|
|
955
|
-
|
|
949
|
+
left: calc(100% - 35px);
|
|
956
950
|
top: 50%;
|
|
957
951
|
transform: translateY(-50%);
|
|
958
952
|
box-shadow: rgba(0, 0, 0, 0.5) 0 1px 2px;
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
// main visualization wrapper
|
|
2
|
-
import { ChartConfig } from '@cdc/chart/src/types/ChartConfig'
|
|
3
2
|
import React, { forwardRef } from 'react'
|
|
4
|
-
import { Config as DataBiteConfig } from '@cdc/data-bite/src/types/Config'
|
|
5
|
-
import { Config as DataTableConfig } from '@cdc/data-table/src/types/Config'
|
|
6
3
|
import './visualizations.scss'
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
import type { AnyVisualization } from '@cdc/core/types/Visualization'
|
|
5
|
+
|
|
6
|
+
export type VisualizationShellConfig = Partial<AnyVisualization> & {
|
|
7
|
+
type?: AnyVisualization['type'] | 'dashboard'
|
|
8
|
+
theme?: string
|
|
9
|
+
visual?: {
|
|
10
|
+
highlightWrappers?: boolean
|
|
11
|
+
whiteBackground?: boolean
|
|
12
|
+
}
|
|
13
|
+
}
|
|
11
14
|
|
|
12
15
|
type VisualizationWrapper = {
|
|
13
16
|
children: React.ReactNode
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
| DataBiteConfig
|
|
17
|
-
| WaffleChartConfig
|
|
18
|
-
| MarkupIncludeConfig
|
|
19
|
-
| DashboardFilters
|
|
20
|
-
| MapConfig
|
|
21
|
-
| DataTableConfig
|
|
17
|
+
className?: string
|
|
18
|
+
config: VisualizationShellConfig
|
|
22
19
|
currentViewport?: string
|
|
23
20
|
imageId?: string
|
|
24
21
|
isEditor: boolean
|
|
@@ -35,15 +32,17 @@ const Visualization = forwardRef<HTMLDivElement, VisualizationWrapper>((props, r
|
|
|
35
32
|
className
|
|
36
33
|
} = props
|
|
37
34
|
|
|
35
|
+
const themeClass = config.type === 'map' ? config?.general?.headerColor || config?.theme : config?.theme
|
|
36
|
+
|
|
38
37
|
const getWrappingClasses = () => {
|
|
39
|
-
let classes = ['cdc-open-viz-module', `${currentViewport}`, `${
|
|
38
|
+
let classes = ['cove-visualization', 'cdc-open-viz-module', `${currentViewport}`, `${themeClass}`]
|
|
40
39
|
|
|
41
40
|
if (className) {
|
|
42
41
|
classes.push(className)
|
|
43
42
|
}
|
|
44
43
|
|
|
45
44
|
isEditor && classes.push('spacing-wrapper')
|
|
46
|
-
isEditor && classes.push('
|
|
45
|
+
isEditor && classes.push('is-editor')
|
|
47
46
|
|
|
48
47
|
if (isEditor && showEditorPanel) {
|
|
49
48
|
classes = classes.filter(item => item !== 'editor-panel--hidden')
|
|
@@ -55,9 +54,18 @@ const Visualization = forwardRef<HTMLDivElement, VisualizationWrapper>((props, r
|
|
|
55
54
|
classes.push('editor-panel--hidden')
|
|
56
55
|
}
|
|
57
56
|
|
|
57
|
+
if (isEditor && config.visual?.highlightWrappers) {
|
|
58
|
+
classes.push('cove-highlight-wrappers')
|
|
59
|
+
}
|
|
60
|
+
|
|
58
61
|
if (config.type === 'filtered-text') {
|
|
59
62
|
classes.push('type-filtered-text', `font-${config.fontSize}`)
|
|
60
|
-
classes = classes.filter(item => item !== 'cove-
|
|
63
|
+
classes = classes.filter(item => item !== 'cove-visualization__body')
|
|
64
|
+
return classes
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (config.type === 'dashboard') {
|
|
68
|
+
classes.push('type-dashboard')
|
|
61
69
|
return classes
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -66,37 +74,31 @@ const Visualization = forwardRef<HTMLDivElement, VisualizationWrapper>((props, r
|
|
|
66
74
|
config?.visualizationType === 'Spark Line' && classes.push(`type-sparkline`)
|
|
67
75
|
return classes
|
|
68
76
|
}
|
|
77
|
+
|
|
69
78
|
if (config.type === 'map') {
|
|
70
79
|
classes.push(`type-map`)
|
|
71
|
-
if (config?.runtime?.editorErrorMessage
|
|
80
|
+
if (config?.runtime?.editorErrorMessage?.length) classes.push('type-map--has-error')
|
|
81
|
+
return classes
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (config.type === 'table') {
|
|
85
|
+
classes.push('type-data-table')
|
|
86
|
+
return classes
|
|
72
87
|
}
|
|
73
88
|
|
|
74
89
|
if (config.type === 'data-bite') {
|
|
75
|
-
classes.push('
|
|
76
|
-
|
|
77
|
-
classes.push('is-editor')
|
|
78
|
-
}
|
|
90
|
+
classes.push('type-data-bite', `font-${config.fontSize}`)
|
|
91
|
+
return classes
|
|
79
92
|
}
|
|
80
93
|
|
|
81
94
|
if (config.type === 'markup-include') {
|
|
82
|
-
classes.push('markup-include'
|
|
95
|
+
classes.push('type-markup-include')
|
|
96
|
+
return classes
|
|
83
97
|
}
|
|
84
98
|
|
|
85
99
|
if (config.type === 'waffle-chart') {
|
|
86
|
-
classes.push(
|
|
87
|
-
'cove',
|
|
88
|
-
'cdc-open-viz-module',
|
|
89
|
-
'type-waffle-chart',
|
|
90
|
-
currentViewport,
|
|
91
|
-
config.theme,
|
|
92
|
-
'font-' + config.overallFontSize
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
if (isEditor) {
|
|
96
|
-
classes.push('is-editor')
|
|
97
|
-
}
|
|
100
|
+
classes.push('type-waffle-chart', 'font-' + config.overallFontSize)
|
|
98
101
|
|
|
99
|
-
// Add TP5 style classes
|
|
100
102
|
if (config.visualizationType === 'TP5 Waffle') {
|
|
101
103
|
classes.push('waffle__style--tp5')
|
|
102
104
|
if (config.visual?.whiteBackground) {
|
|
@@ -104,8 +106,16 @@ const Visualization = forwardRef<HTMLDivElement, VisualizationWrapper>((props, r
|
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
if (config.visualizationType === 'TP5 Gauge') {
|
|
110
|
+
classes.push('gauge__style--tp5')
|
|
111
|
+
if (config.visual?.whiteBackground) {
|
|
112
|
+
classes.push('white-background-style')
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return classes
|
|
108
117
|
}
|
|
118
|
+
|
|
109
119
|
return classes
|
|
110
120
|
}
|
|
111
121
|
|
|
@@ -121,4 +131,6 @@ const Visualization = forwardRef<HTMLDivElement, VisualizationWrapper>((props, r
|
|
|
121
131
|
)
|
|
122
132
|
})
|
|
123
133
|
|
|
134
|
+
Visualization.displayName = 'Visualization'
|
|
135
|
+
|
|
124
136
|
export default Visualization
|