@cdc/chart 4.24.1 → 4.24.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/dist/cdcchart.js +48948 -37923
- package/examples/{private/combo.json → chart-regression-1.json} +40 -31
- package/examples/chart-regression-2.json +2360 -0
- package/examples/feature/filters/url-filter.json +1076 -0
- package/examples/feature/line/line-chart-preliminary.json +84 -37
- package/examples/feature/line/line-chart.json +2 -1
- package/examples/feature/regions/index.json +55 -5
- package/examples/feature/sankey/sankey-example-data.json +1364 -0
- package/examples/feature/sankey/sankey_chart_data.csv +20 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +306 -19
- package/examples/sparkline.json +868 -0
- package/index.html +128 -121
- package/package.json +4 -2
- package/src/CdcChart.tsx +73 -38
- package/src/_stories/ChartEditor.stories.tsx +15 -4
- package/src/_stories/_mock/pie_config.json +4 -3
- package/src/_stories/_mock/url_filter.json +1076 -0
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +2 -1
- package/src/components/AreaChart/components/AreaChart.jsx +2 -25
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +39 -49
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +36 -56
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +36 -41
- package/src/components/BarChart/components/BarChart.Vertical.tsx +48 -64
- package/src/components/BoxPlot/BoxPlot.jsx +11 -9
- package/src/components/DeviationBar.jsx +3 -3
- package/src/components/EditorPanel/EditorPanel.tsx +1717 -1961
- package/src/components/EditorPanel/EditorPanelContext.ts +40 -0
- package/src/components/EditorPanel/components/Panels/Panel.BoxPlot.tsx +148 -0
- package/src/components/EditorPanel/components/{Panel.ForestPlotSettings.tsx → Panels/Panel.ForestPlotSettings.tsx} +16 -7
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +160 -0
- package/src/components/EditorPanel/components/{Panel.Regions.tsx → Panels/Panel.Regions.tsx} +6 -6
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +108 -0
- package/src/components/EditorPanel/components/{Panel.Series.tsx → Panels/Panel.Series.tsx} +50 -6
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +338 -0
- package/src/components/EditorPanel/components/Panels/index.tsx +19 -0
- package/src/components/EditorPanel/components/panels.scss +11 -0
- package/src/components/EditorPanel/editor-panel.scss +1 -13
- package/src/components/EditorPanel/useEditorPermissions.js +44 -13
- package/src/components/Legend/Legend.Component.tsx +207 -0
- package/src/components/Legend/Legend.tsx +8 -327
- package/src/components/Legend/helpers/createFormatLabels.tsx +140 -0
- package/src/components/LineChart/LineChartProps.ts +2 -1
- package/src/components/LineChart/components/LineChart.Circle.tsx +85 -52
- package/src/components/LineChart/helpers.ts +3 -3
- package/src/components/LineChart/index.tsx +99 -23
- package/src/components/LinearChart.jsx +12 -33
- package/src/components/PairedBarChart.jsx +10 -12
- package/src/components/PieChart/PieChart.tsx +80 -27
- package/src/components/Regions/components/Regions.tsx +120 -69
- package/src/components/Sankey/index.tsx +434 -0
- package/src/components/Sankey/sankey.scss +153 -0
- package/src/components/Sankey/types/index.ts +16 -0
- package/src/components/ScatterPlot/ScatterPlot.jsx +1 -0
- package/src/components/Sparkline/{SparkLine.jsx → components/SparkLine.tsx} +14 -30
- package/src/components/Sparkline/index.scss +3 -0
- package/src/components/Sparkline/index.tsx +1 -1
- package/src/components/ZoomBrush.tsx +2 -1
- package/src/data/initial-state.js +51 -4
- package/src/helpers/computeMarginBottom.ts +4 -3
- package/src/helpers/tests/computeMarginBottom.test.ts +2 -1
- package/src/hooks/useBarChart.js +5 -2
- package/src/hooks/useHighlightedBars.js +1 -1
- package/src/hooks/useMinMax.ts +3 -3
- package/src/hooks/useScales.ts +28 -18
- package/src/hooks/useTooltip.tsx +19 -14
- package/src/scss/main.scss +8 -96
- package/src/types/ChartConfig.ts +47 -20
- package/src/types/ChartContext.ts +17 -4
- package/src/types/Label.ts +7 -0
- package/examples/private/chart-t.json +0 -3740
- package/examples/private/epi-data.csv +0 -13
- package/examples/private/epi-data.json +0 -62
- package/examples/private/epi.json +0 -403
- package/examples/private/occupancy.json +0 -109283
- package/examples/private/prod-line-config.json +0 -401
- package/examples/private/region-data.json +0 -822
- package/examples/private/region-testing.json +0 -312
- package/examples/private/scaling.json +0 -45325
- package/examples/private/testing-data.json +0 -1739
- package/examples/private/testing.json +0 -816
- package/src/components/EditorPanel/components/Panel.DateHighlighting.tsx +0 -109
- package/src/components/EditorPanel/components/Panels.tsx +0 -13
package/src/CdcChart.tsx
CHANGED
|
@@ -15,8 +15,10 @@ import 'react-tooltip/dist/react-tooltip.css'
|
|
|
15
15
|
|
|
16
16
|
// Primary Components
|
|
17
17
|
import ConfigContext from './ConfigContext'
|
|
18
|
-
import PieChart from './components/PieChart
|
|
18
|
+
import PieChart from './components/PieChart'
|
|
19
|
+
import SankeyChart from './components/Sankey'
|
|
19
20
|
import LinearChart from './components/LinearChart'
|
|
21
|
+
import { isDateScale } from '@cdc/core/helpers/cove/date'
|
|
20
22
|
|
|
21
23
|
import { colorPalettesChart as colorPalettes, twoColorPalette } from '@cdc/core/data/colorPalettes'
|
|
22
24
|
|
|
@@ -46,22 +48,27 @@ import { DataTransform } from '@cdc/core/helpers/DataTransform'
|
|
|
46
48
|
import cacheBustingString from '@cdc/core/helpers/cacheBustingString'
|
|
47
49
|
import isNumber from '@cdc/core/helpers/isNumber'
|
|
48
50
|
import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
|
|
51
|
+
import { getQueryStringFilterValue } from '@cdc/core/helpers/queryStringUtils'
|
|
49
52
|
|
|
50
53
|
import './scss/main.scss'
|
|
51
54
|
// load both then config below determines which to use
|
|
52
55
|
import DataTable from '@cdc/core/components/DataTable'
|
|
53
56
|
import { getFileExtension } from '@cdc/core/helpers/getFileExtension'
|
|
54
57
|
import Title from '@cdc/core/components/ui/Title'
|
|
58
|
+
import { ChartConfig } from './types/ChartConfig'
|
|
59
|
+
import { Label } from './types/Label'
|
|
60
|
+
import { isSolrCsv, isSolrJson } from '@cdc/core/helpers/isSolr'
|
|
61
|
+
import SkipTo from '@cdc/core/components/elements/SkipTo'
|
|
55
62
|
|
|
56
63
|
export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
|
|
57
64
|
const transform = new DataTransform()
|
|
58
65
|
const [loading, setLoading] = useState(true)
|
|
59
66
|
const [colorScale, setColorScale] = useState(null)
|
|
60
|
-
const [config, setConfig] = useState<
|
|
67
|
+
const [config, setConfig] = useState<ChartConfig>({} as ChartConfig)
|
|
61
68
|
const [stateData, setStateData] = useState(config.data || [])
|
|
62
69
|
const [excludedData, setExcludedData] = useState<Record<string, number>[] | undefined>(undefined)
|
|
63
70
|
const [filteredData, setFilteredData] = useState<Record<string, any>[] | undefined>(undefined)
|
|
64
|
-
const [seriesHighlight, setSeriesHighlight] = useState<
|
|
71
|
+
const [seriesHighlight, setSeriesHighlight] = useState<string[]>(configObj && configObj?.legend?.seriesHighlight?.length ? [...configObj?.legend?.seriesHighlight] : [])
|
|
65
72
|
const [currentViewport, setCurrentViewport] = useState('lg')
|
|
66
73
|
const [dimensions, setDimensions] = useState<[number?, number?]>([])
|
|
67
74
|
const [externalFilters, setExternalFilters] = useState<any[]>()
|
|
@@ -72,6 +79,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
72
79
|
type Config = typeof config
|
|
73
80
|
let legendMemo = useRef(new Map()) // map collection
|
|
74
81
|
let innerContainerRef = useRef()
|
|
82
|
+
const legendRef = useRef(null)
|
|
75
83
|
|
|
76
84
|
if (isDebug) console.log('Chart config, isEditor', config, isEditor)
|
|
77
85
|
|
|
@@ -87,7 +95,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
87
95
|
|
|
88
96
|
const { barBorderClass, lineDatapointClass, contentClasses, sparkLineStyles } = useDataVizClasses(config)
|
|
89
97
|
|
|
90
|
-
const handleChartTabbing = config.
|
|
98
|
+
const handleChartTabbing = !config.legend?.hide ? `legend` : config?.title ? `dataTableSection__${config.title.replace(/\s/g, '')}` : `dataTableSection`
|
|
91
99
|
|
|
92
100
|
const reloadURLData = async () => {
|
|
93
101
|
if (config.dataUrl) {
|
|
@@ -95,7 +103,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
95
103
|
let qsParams = Object.fromEntries(new URLSearchParams(dataUrl.search))
|
|
96
104
|
|
|
97
105
|
let isUpdateNeeded = false
|
|
98
|
-
config.filters
|
|
106
|
+
config.filters?.forEach(filter => {
|
|
99
107
|
if (filter.type === 'url' && qsParams[filter.queryParameter] !== decodeURIComponent(filter.active)) {
|
|
100
108
|
qsParams[filter.queryParameter] = filter.active
|
|
101
109
|
isUpdateNeeded = true
|
|
@@ -117,7 +125,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
117
125
|
|
|
118
126
|
try {
|
|
119
127
|
const ext = getFileExtension(dataUrl.href)
|
|
120
|
-
if ('csv' === ext) {
|
|
128
|
+
if ('csv' === ext || isSolrCsv(dataUrlFinal)) {
|
|
121
129
|
data = await fetch(dataUrlFinal)
|
|
122
130
|
.then(response => response.text())
|
|
123
131
|
.then(responseText => {
|
|
@@ -128,7 +136,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
128
136
|
})
|
|
129
137
|
return parsedCsv.data
|
|
130
138
|
})
|
|
131
|
-
} else if ('json' === ext) {
|
|
139
|
+
} else if ('json' === ext || isSolrJson(dataUrlFinal)) {
|
|
132
140
|
data = await fetch(dataUrlFinal).then(response => response.json())
|
|
133
141
|
} else {
|
|
134
142
|
data = []
|
|
@@ -166,7 +174,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
166
174
|
if (response.dataUrl && !urlFilters) {
|
|
167
175
|
try {
|
|
168
176
|
const ext = getFileExtension(response.dataUrl)
|
|
169
|
-
if ('csv' === ext) {
|
|
177
|
+
if ('csv' === ext || isSolrCsv(response.dataUrl)) {
|
|
170
178
|
data = await fetch(response.dataUrl + `?v=${cacheBustingString()}`)
|
|
171
179
|
.then(response => response.text())
|
|
172
180
|
.then(responseText => {
|
|
@@ -189,7 +197,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
189
197
|
})
|
|
190
198
|
}
|
|
191
199
|
|
|
192
|
-
if ('json' === ext) {
|
|
200
|
+
if ('json' === ext || isSolrJson(response.dataUrl)) {
|
|
193
201
|
data = await fetch(response.dataUrl + `?v=${cacheBustingString()}`).then(response => response.json())
|
|
194
202
|
}
|
|
195
203
|
} catch {
|
|
@@ -216,6 +224,15 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
216
224
|
}
|
|
217
225
|
}
|
|
218
226
|
let newConfig = { ...defaults, ...response }
|
|
227
|
+
if (newConfig.filters) {
|
|
228
|
+
newConfig.filters.forEach((filter, index) => {
|
|
229
|
+
const queryStringFilterValue = getQueryStringFilterValue(filter)
|
|
230
|
+
if (queryStringFilterValue) {
|
|
231
|
+
newConfig.filters[index].active = queryStringFilterValue
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
|
|
219
236
|
if (newConfig.visualizationType === 'Box Plot') {
|
|
220
237
|
newConfig.legend.hide = true
|
|
221
238
|
}
|
|
@@ -250,7 +267,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
250
267
|
if (newConfig.exclusions && newConfig.exclusions.active) {
|
|
251
268
|
if (newConfig.xAxis.type === 'categorical' && newConfig.exclusions.keys?.length > 0) {
|
|
252
269
|
newExcludedData = data.filter(e => !newConfig.exclusions.keys.includes(e[newConfig.xAxis.dataKey]))
|
|
253
|
-
} else if (newConfig.xAxis
|
|
270
|
+
} else if (isDateScale(newConfig.xAxis) && (newConfig.exclusions.dateStart || newConfig.exclusions.dateEnd) && newConfig.xAxis.dateParseFormat) {
|
|
254
271
|
// Filter dates
|
|
255
272
|
const timestamp = e => new Date(e).getTime()
|
|
256
273
|
|
|
@@ -294,6 +311,12 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
294
311
|
setFilteredData(currentData)
|
|
295
312
|
}
|
|
296
313
|
|
|
314
|
+
if (newConfig.xAxis.type === 'date-time' && newConfig.barThickness > 0.1) {
|
|
315
|
+
newConfig.barThickness = 0.035
|
|
316
|
+
} else if (newConfig.xAxis.type !== 'date-time' && newConfig.barThickness < 0.1) {
|
|
317
|
+
newConfig.barThickness = 0.35
|
|
318
|
+
}
|
|
319
|
+
|
|
297
320
|
//Enforce default values that need to be calculated at runtime
|
|
298
321
|
newConfig.runtime = {}
|
|
299
322
|
newConfig.runtime.seriesLabels = {}
|
|
@@ -426,6 +449,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
426
449
|
if (series.type === 'Line' || series.type === 'dashed-sm' || series.type === 'dashed-md' || series.type === 'dashed-lg') {
|
|
427
450
|
newConfig.runtime.lineSeriesKeys.push(series.dataKey)
|
|
428
451
|
}
|
|
452
|
+
if (series.type === 'Combo') {
|
|
453
|
+
series.type = 'Bar'
|
|
454
|
+
}
|
|
429
455
|
})
|
|
430
456
|
}
|
|
431
457
|
|
|
@@ -448,8 +474,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
448
474
|
}
|
|
449
475
|
|
|
450
476
|
if ((newConfig.visualizationType === 'Bar' && newConfig.orientation === 'horizontal') || ['Deviation Bar', 'Paired Bar', 'Forest Plot'].includes(newConfig.visualizationType)) {
|
|
451
|
-
newConfig.runtime.xAxis = newConfig.yAxis
|
|
452
|
-
newConfig.runtime.yAxis = newConfig.xAxis
|
|
477
|
+
newConfig.runtime.xAxis = newConfig.yAxis['yAxis'] ? newConfig.yAxis['yAxis'] : newConfig.yAxis
|
|
478
|
+
newConfig.runtime.yAxis = newConfig.xAxis['xAxis'] ? newConfig.xAxis['xAxis'] : newConfig.xAxis
|
|
453
479
|
|
|
454
480
|
newConfig.runtime.horizontal = false
|
|
455
481
|
newConfig.orientation = 'horizontal'
|
|
@@ -463,9 +489,17 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
463
489
|
newConfig.runtime.yAxis = newConfig.yAxis
|
|
464
490
|
newConfig.runtime.horizontal = false
|
|
465
491
|
}
|
|
492
|
+
|
|
466
493
|
newConfig.runtime.uniqueId = Date.now()
|
|
467
494
|
newConfig.runtime.editorErrorMessage = newConfig.visualizationType === 'Pie' && !newConfig.yAxis.dataKey ? 'Data Key property in Y Axis section must be set for pie charts.' : ''
|
|
468
495
|
|
|
496
|
+
// Sankey Description box error message
|
|
497
|
+
newConfig.runtime.editorErrorMessage = newConfig.visualizationType === 'Sankey' && !newConfig.description ? 'SUBTEXT/CITATION field is empty: A description of the Sankey Diagram data must be inputted.' : ''
|
|
498
|
+
|
|
499
|
+
if (newConfig.legend.seriesHighlight?.length) {
|
|
500
|
+
setSeriesHighlight(newConfig.legend?.seriesHighlight)
|
|
501
|
+
}
|
|
502
|
+
|
|
469
503
|
setConfig(newConfig)
|
|
470
504
|
}
|
|
471
505
|
|
|
@@ -607,9 +641,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
607
641
|
|
|
608
642
|
// Generates color palette to pass to child chart component
|
|
609
643
|
useEffect(() => {
|
|
610
|
-
if (stateData && config.xAxis && config.runtime
|
|
611
|
-
const configPalette =
|
|
612
|
-
const allPalettes = { ...colorPalettes, ...twoColorPalette }
|
|
644
|
+
if (stateData && config.xAxis && config.runtime?.seriesKeys) {
|
|
645
|
+
const configPalette = ['Paired Bar', 'Deviation Bar'].includes(config.visualizationType) ? config.twoColor.palette : config.palette
|
|
646
|
+
const allPalettes: Record<string, string[]> = { ...colorPalettes, ...twoColorPalette }
|
|
613
647
|
let palette = config.customColors || allPalettes[configPalette]
|
|
614
648
|
let numberOfKeys = config.runtime.seriesKeys.length
|
|
615
649
|
let newColorScale
|
|
@@ -637,27 +671,22 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
637
671
|
}, [config, stateData]) // eslint-disable-line
|
|
638
672
|
|
|
639
673
|
// Called on legend click, highlights/unhighlights the data series with the given label
|
|
640
|
-
const highlight = label => {
|
|
641
|
-
const newSeriesHighlight: any[] = []
|
|
642
|
-
|
|
674
|
+
const highlight = (label: Label) => {
|
|
643
675
|
// If we're highlighting all the series, reset them
|
|
644
676
|
if (seriesHighlight.length + 1 === config.runtime.seriesKeys.length && config.visualizationType !== 'Forecasting') {
|
|
645
677
|
highlightReset()
|
|
646
678
|
return
|
|
647
679
|
}
|
|
648
680
|
|
|
649
|
-
|
|
650
|
-
newSeriesHighlight.push(value)
|
|
651
|
-
})
|
|
681
|
+
const newSeriesHighlight = [...seriesHighlight]
|
|
652
682
|
|
|
653
683
|
let newHighlight = label.datum
|
|
654
684
|
if (config.runtime.seriesLabels) {
|
|
655
|
-
|
|
656
|
-
if (config.runtime.seriesLabels[
|
|
657
|
-
newHighlight =
|
|
658
|
-
break
|
|
685
|
+
config.runtime.seriesKeys.forEach(key => {
|
|
686
|
+
if (config.runtime.seriesLabels[key] === label.datum) {
|
|
687
|
+
newHighlight = key
|
|
659
688
|
}
|
|
660
|
-
}
|
|
689
|
+
})
|
|
661
690
|
}
|
|
662
691
|
|
|
663
692
|
if (newSeriesHighlight.indexOf(newHighlight) !== -1) {
|
|
@@ -686,7 +715,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
686
715
|
// Called on reset button click, unhighlights all data series
|
|
687
716
|
const highlightReset = () => {
|
|
688
717
|
try {
|
|
689
|
-
const legend =
|
|
718
|
+
const legend = legendRef.current
|
|
690
719
|
if (!legend) throw new Error('No legend available to set previous focus on.')
|
|
691
720
|
legend.focus()
|
|
692
721
|
} catch (e) {
|
|
@@ -713,6 +742,10 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
713
742
|
return timeFormat(config.runtime[section].dateDisplayFormat)(date)
|
|
714
743
|
}
|
|
715
744
|
|
|
745
|
+
const formatTooltipsDate = date => {
|
|
746
|
+
return timeFormat(config.tooltips.dateDisplayFormat)(date)
|
|
747
|
+
}
|
|
748
|
+
|
|
716
749
|
// function calculates the width of given text and its font-size
|
|
717
750
|
function getTextWidth(text, font) {
|
|
718
751
|
const canvas = document.createElement('canvas')
|
|
@@ -887,6 +920,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
887
920
|
}
|
|
888
921
|
|
|
889
922
|
const missingRequiredSections = () => {
|
|
923
|
+
if (config.visualizationType === 'Sankey') return false // skip checks for now
|
|
890
924
|
if (config.visualizationType === 'Forecasting') return false // skip required checks for now.
|
|
891
925
|
if (config.visualizationType === 'Forest Plot') return false // skip required checks for now.
|
|
892
926
|
if (config.visualizationType === 'Pie') {
|
|
@@ -1018,14 +1052,12 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1018
1052
|
<>
|
|
1019
1053
|
{isEditor && <EditorPanel />}
|
|
1020
1054
|
{!missingRequiredSections() && !config.newViz && (
|
|
1021
|
-
<div className='cdc-chart-inner-container'>
|
|
1055
|
+
<div className='cdc-chart-inner-container' aria-label={handleChartAriaLabels(config)} tabIndex={0}>
|
|
1022
1056
|
<Title showTitle={config.showTitle} isDashboard={isDashboard} title={title} superTitle={config.superTitle} classes={['chart-title', `${config.theme}`, 'cove-component__header']} style={undefined} />
|
|
1057
|
+
<SkipTo skipId={handleChartTabbing} skipMessage='Skip Over Chart Container' />
|
|
1023
1058
|
|
|
1024
|
-
<a id='skip-chart-container' className='cdcdataviz-sr-only-focusable' href={handleChartTabbing}>
|
|
1025
|
-
Skip Over Chart Container
|
|
1026
|
-
</a>
|
|
1027
1059
|
{/* Filters */}
|
|
1028
|
-
{config.filters && !externalFilters && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
|
|
1060
|
+
{config.filters && !externalFilters && config.visualizationType !== 'Spark Line' && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
|
|
1029
1061
|
{/* Visualization */}
|
|
1030
1062
|
{config?.introText && config.visualizationType !== 'Spark Line' && <section className='introText'>{parse(config.introText)}</section>}
|
|
1031
1063
|
<div
|
|
@@ -1038,6 +1070,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1038
1070
|
{/* Sparkline */}
|
|
1039
1071
|
{config.visualizationType === 'Spark Line' && (
|
|
1040
1072
|
<>
|
|
1073
|
+
<Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />
|
|
1041
1074
|
{config?.introText && (
|
|
1042
1075
|
<section className='introText' style={{ padding: '0px 0 35px' }}>
|
|
1043
1076
|
{parse(config.introText)}
|
|
@@ -1053,7 +1086,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1053
1086
|
)}
|
|
1054
1087
|
</>
|
|
1055
1088
|
)}
|
|
1056
|
-
{
|
|
1089
|
+
{/* Sankey */}
|
|
1090
|
+
{config.visualizationType === 'Sankey' && <ParentSize aria-hidden='true'>{parent => <SankeyChart runtime={config.runtime} width={parent.width} height={parent.height} />}</ParentSize>}
|
|
1091
|
+
{!config.legend.hide && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Sankey' && <Legend ref={legendRef} />}
|
|
1057
1092
|
</div>
|
|
1058
1093
|
{/* Link */}
|
|
1059
1094
|
{isDashboard && config.table && config.table.show && config.table.showDataTableLink ? tableLink : link && link}
|
|
@@ -1068,11 +1103,11 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1068
1103
|
</MediaControls.Section>
|
|
1069
1104
|
|
|
1070
1105
|
{/* Data Table */}
|
|
1071
|
-
{config.xAxis.dataKey && config.table.show && config.visualizationType !== 'Spark Line' && (
|
|
1106
|
+
{((config.xAxis.dataKey && config.table.show && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Sankey') || (config.visualizationType === 'Sankey' && config.table.show)) && (
|
|
1072
1107
|
<DataTable
|
|
1073
1108
|
config={config}
|
|
1074
|
-
rawData={config.data}
|
|
1075
|
-
runtimeData={transform.applySuppression(filteredData || excludedData, config.suppressedData)}
|
|
1109
|
+
rawData={config.visualizationType === 'Sankey' ? config?.data?.[0]?.tableData : config.table.customTableConfig ? filterData(config.filters, config.data) : config.data}
|
|
1110
|
+
runtimeData={config.visualizationType === 'Sankey' ? config?.data?.[0]?.tableData : transform.applySuppression(filteredData || excludedData, config.suppressedData)}
|
|
1076
1111
|
expandDataTable={config.table.expanded}
|
|
1077
1112
|
columns={config.columns}
|
|
1078
1113
|
displayDataAsText={displayDataAsText}
|
|
@@ -1094,13 +1129,12 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1094
1129
|
)
|
|
1095
1130
|
}
|
|
1096
1131
|
|
|
1097
|
-
const getXAxisData = d => (config.runtime.xAxis
|
|
1132
|
+
const getXAxisData = d => (isDateScale(config.runtime.xAxis) ? parseDate(d[config.runtime.originalXAxis.dataKey]).getTime() : d[config.runtime.originalXAxis.dataKey])
|
|
1098
1133
|
const getYAxisData = (d, seriesKey) => d[seriesKey]
|
|
1099
1134
|
|
|
1100
1135
|
const capitalize = str => {
|
|
1101
1136
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
1102
1137
|
}
|
|
1103
|
-
|
|
1104
1138
|
const contextValues = {
|
|
1105
1139
|
capitalize,
|
|
1106
1140
|
computeMarginBottom,
|
|
@@ -1119,6 +1153,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1119
1153
|
currentViewport,
|
|
1120
1154
|
parseDate,
|
|
1121
1155
|
formatDate,
|
|
1156
|
+
formatTooltipsDate,
|
|
1122
1157
|
formatNumber,
|
|
1123
1158
|
loading,
|
|
1124
1159
|
updateConfig,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
-
|
|
2
|
+
import { userEvent, within } from '@storybook/testing-library'
|
|
3
3
|
import Chart from '../CdcChart'
|
|
4
|
-
|
|
5
4
|
import pieChartExample from './_mock/pie_config.json'
|
|
6
5
|
import pieData from './_mock/pie_data.json'
|
|
6
|
+
import urlFilterExample from './_mock/url_filter.json'
|
|
7
7
|
|
|
8
8
|
const meta: Meta<typeof Chart> = {
|
|
9
|
-
title: 'Components/Templates/Editor
|
|
9
|
+
title: 'Components/Templates/Chart/Editor',
|
|
10
10
|
component: Chart
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -14,7 +14,18 @@ type Story = StoryObj<typeof Chart>
|
|
|
14
14
|
|
|
15
15
|
export const Primary: Story = {
|
|
16
16
|
args: {
|
|
17
|
-
config: { ...pieChartExample, data: pieData },
|
|
17
|
+
config: { ...pieChartExample, data: pieData, columns: { someCol: { name: 'females', showInViz: true } } },
|
|
18
|
+
isEditor: true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const sleep = ms => {
|
|
23
|
+
return new Promise(r => setTimeout(r, ms))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const Url_Filter: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
config: urlFilterExample,
|
|
18
29
|
isEditor: true
|
|
19
30
|
}
|
|
20
31
|
}
|
|
@@ -97,11 +97,12 @@
|
|
|
97
97
|
"caption": "",
|
|
98
98
|
"showDownloadUrl": false,
|
|
99
99
|
"showDataTableLink": true,
|
|
100
|
-
"indexLabel": "",
|
|
100
|
+
"indexLabel": "Cause Type",
|
|
101
101
|
"download": false,
|
|
102
102
|
"showVertical": true,
|
|
103
103
|
"show": true,
|
|
104
|
-
"customTableConfig": true
|
|
104
|
+
"customTableConfig": true,
|
|
105
|
+
"excludeColumns": ["location", "age", "use", "data_group", "data_sub_group", "cause_category"]
|
|
105
106
|
},
|
|
106
107
|
"orientation": "vertical",
|
|
107
108
|
"color": "pinkpurple",
|
|
@@ -182,7 +183,7 @@
|
|
|
182
183
|
"filters": [
|
|
183
184
|
{
|
|
184
185
|
"values": ["age", "sex"],
|
|
185
|
-
"active": "
|
|
186
|
+
"active": "sex",
|
|
186
187
|
"filterStyle": "dropdown",
|
|
187
188
|
"order": "asc",
|
|
188
189
|
"columnName": "data_group"
|