@cdc/chart 4.25.8 → 4.25.10
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/settings.local.json +9 -0
- package/dist/cdcchart.js +37524 -35243
- package/examples/feature/__data__/planet-example-data.json +0 -30
- package/examples/grouped-bar-test.json +400 -0
- package/examples/private/d.json +382 -0
- package/examples/private/example-2.json +49784 -0
- package/examples/private/f2.json +1 -0
- package/examples/private/f4.json +1577 -0
- package/examples/private/forecast.json +1180 -0
- package/examples/private/lollipop.json +468 -0
- package/examples/private/new.json +48756 -0
- package/examples/private/pie-chart-legend.json +904 -0
- package/examples/suppressed_tooltip.json +480 -0
- package/index.html +10 -22
- package/package.json +25 -7
- package/src/CdcChart.tsx +1 -2
- package/src/CdcChartComponent.tsx +174 -32
- package/src/_stories/Chart.Anchors.stories.tsx +2 -2
- package/src/_stories/Chart.BoxPlot.stories.tsx +1 -1
- package/src/_stories/Chart.CI.stories.tsx +1 -1
- package/src/_stories/Chart.CustomColors.stories.tsx +1 -1
- package/src/_stories/Chart.DynamicSeries.stories.tsx +2 -2
- package/src/_stories/Chart.Filters.stories.tsx +2 -2
- package/src/_stories/Chart.Legend.Gradient.stories.tsx +2 -2
- package/src/_stories/Chart.Patterns.stories.tsx +19 -0
- package/src/_stories/Chart.ScatterPlot.stories.tsx +1 -1
- package/src/_stories/Chart.stories.tsx +8 -5
- package/src/_stories/Chart.tooltip.stories.tsx +1 -1
- package/src/_stories/ChartAnnotation.stories.tsx +1 -1
- package/src/_stories/ChartAxisLabels.stories.tsx +2 -2
- package/src/_stories/ChartAxisTitles.stories.tsx +2 -2
- package/src/_stories/ChartEditor.stories.tsx +60 -60
- package/src/_stories/ChartLine.Suppression.stories.tsx +1 -1
- package/src/_stories/ChartLine.Symbols.stories.tsx +1 -1
- package/src/_stories/ChartPrefixSuffix.stories.tsx +2 -2
- package/src/_stories/_mock/stacked-pattern-test.json +520 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -0
- package/src/components/Annotations/components/AnnotationDropdown.tsx +1 -1
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +159 -20
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +138 -5
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +215 -73
- package/src/components/BarChart/components/BarChart.Vertical.tsx +153 -21
- package/src/components/BarChart/helpers/index.ts +43 -4
- package/src/components/BarChart/helpers/lollipopColors.ts +27 -0
- package/src/components/BarChart/helpers/useBarChart.ts +25 -3
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +2 -1
- package/src/components/DeviationBar.jsx +9 -6
- package/src/components/EditorPanel/EditorPanel.tsx +364 -39
- package/src/components/EditorPanel/EditorPanelContext.ts +3 -0
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +414 -0
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +28 -20
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +115 -120
- package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
- package/src/components/EditorPanel/components/Panels/panelVisual.styles.css +0 -8
- package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +49 -48
- package/src/components/Forecasting/Forecasting.tsx +36 -6
- package/src/components/ForestPlot/ForestPlot.tsx +11 -7
- package/src/components/ForestPlot/ForestPlotProps.ts +1 -1
- package/src/components/Legend/Legend.Component.tsx +106 -13
- package/src/components/Legend/helpers/createFormatLabels.tsx +230 -171
- package/src/components/LegendWrapper.tsx +1 -1
- package/src/components/LineChart/components/LineChart.Circle.tsx +2 -2
- package/src/components/LineChart/index.tsx +2 -2
- package/src/components/LinearChart.tsx +22 -5
- package/src/components/PairedBarChart.jsx +6 -4
- package/src/components/PieChart/PieChart.tsx +170 -54
- package/src/components/Sankey/components/Sankey.tsx +7 -1
- package/src/components/ScatterPlot/ScatterPlot.jsx +32 -4
- package/src/data/initial-state.js +315 -293
- package/src/helpers/buildForecastPaletteMappings.ts +112 -0
- package/src/helpers/buildForecastPaletteOptions.ts +109 -0
- package/src/helpers/getColorScale.ts +72 -8
- package/src/helpers/getNewRuntime.ts +1 -1
- package/src/helpers/getTransformedData.ts +1 -1
- package/src/hooks/useChartHoverAnalytics.tsx +44 -0
- package/src/hooks/useReduceData.ts +105 -70
- package/src/hooks/useTooltip.tsx +57 -15
- package/src/index.jsx +0 -2
- package/src/scss/main.scss +12 -0
- package/src/store/chart.reducer.ts +1 -1
- package/src/test/CdcChart.test.jsx +8 -3
- package/src/types/ChartConfig.ts +30 -6
- package/src/types/ChartContext.ts +1 -0
- package/vite.config.js +1 -1
- package/vitest.config.ts +16 -0
- package/src/coreStyles_chart.scss +0 -3
- package/src/helpers/configHelpers.ts +0 -28
- package/src/helpers/generateColorsArray.ts +0 -8
- package/src/hooks/useColorPalette.js +0 -76
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useEffect, useCallback, useRef, useId, useContext, useReducer } from 'react'
|
|
1
|
+
import React, { useState, useEffect, useCallback, useRef, useId, useContext, useReducer, useMemo } from 'react'
|
|
2
2
|
|
|
3
3
|
// IE11
|
|
4
4
|
import ResizeObserver from 'resize-observer-polyfill'
|
|
@@ -24,7 +24,6 @@ import { Label } from './types/Label'
|
|
|
24
24
|
import ParentSize from '@visx/responsive/lib/components/ParentSize'
|
|
25
25
|
import { timeParse, timeFormat } from 'd3-time-format'
|
|
26
26
|
import parse from 'html-react-parser'
|
|
27
|
-
import 'react-tooltip/dist/react-tooltip.css'
|
|
28
27
|
import _ from 'lodash'
|
|
29
28
|
// Primary Components
|
|
30
29
|
import ConfigContext, { ChartDispatchContext } from './ConfigContext'
|
|
@@ -33,7 +32,8 @@ import SankeyChart from './components/Sankey'
|
|
|
33
32
|
import LinearChart from './components/LinearChart'
|
|
34
33
|
import { isDateScale } from '@cdc/core/helpers/cove/date'
|
|
35
34
|
|
|
36
|
-
import {
|
|
35
|
+
import { twoColorPalette } from '@cdc/core/data/colorPalettes'
|
|
36
|
+
import { filterChartColorPalettes } from '@cdc/core/helpers/filterColorPalettes'
|
|
37
37
|
|
|
38
38
|
import SparkLine from './components/Sparkline'
|
|
39
39
|
import Legend from './components/Legend'
|
|
@@ -46,7 +46,8 @@ import { handleChartAriaLabels } from './helpers/handleChartAriaLabels'
|
|
|
46
46
|
import { lineOptions } from './helpers/lineOptions'
|
|
47
47
|
import { handleLineType } from './helpers/handleLineType'
|
|
48
48
|
import { handleRankByValue } from './helpers/handleRankByValue'
|
|
49
|
-
import { generateColorsArray } from '
|
|
49
|
+
import { generateColorsArray } from '@cdc/core/helpers/generateColorsArray'
|
|
50
|
+
import { processMarkupVariables } from '@cdc/core/helpers/markupProcessor'
|
|
50
51
|
import Loading from '@cdc/core/components/Loading'
|
|
51
52
|
import Filters from '@cdc/core/components/Filters'
|
|
52
53
|
import MediaControls from '@cdc/core/components/MediaControls'
|
|
@@ -63,7 +64,7 @@ import numberFromString from '@cdc/core/helpers/numberFromString'
|
|
|
63
64
|
import getViewport from '@cdc/core/helpers/getViewport'
|
|
64
65
|
import isNumber from '@cdc/core/helpers/isNumber'
|
|
65
66
|
import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
|
|
66
|
-
import EditorContext from '
|
|
67
|
+
import EditorContext from '@cdc/core/contexts/EditorContext'
|
|
67
68
|
import { EDITOR_WIDTH } from '@cdc/core/helpers/constants'
|
|
68
69
|
import { extractCoveData, updateVegaData } from '@cdc/core/helpers/vegaConfig'
|
|
69
70
|
// Local helpers
|
|
@@ -83,6 +84,8 @@ import { getNewRuntime } from './helpers/getNewRuntime'
|
|
|
83
84
|
import FootnotesStandAlone from '@cdc/core/components/Footnotes/FootnotesStandAlone'
|
|
84
85
|
import { Datasets } from '@cdc/core/types/DataSet'
|
|
85
86
|
import { publishAnalyticsEvent } from '@cdc/core/helpers/metrics/helpers'
|
|
87
|
+
import cloneConfig from '@cdc/core/helpers/cloneConfig'
|
|
88
|
+
import { getVizTitle, getVizSubType } from '@cdc/core/helpers/metrics/utils'
|
|
86
89
|
|
|
87
90
|
interface CdcChartProps {
|
|
88
91
|
config?: ChartConfig
|
|
@@ -152,6 +155,73 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
152
155
|
// Destructure items from config for more readable JSX
|
|
153
156
|
let { legend, title } = config
|
|
154
157
|
|
|
158
|
+
// Process markup variables for text fields (memoized to prevent re-processing on every render)
|
|
159
|
+
// Note: XSS Safety - The processed content is parsed using html-react-parser which sanitizes
|
|
160
|
+
// HTML input by default. The markup processor returns plain text with user data substituted.
|
|
161
|
+
const processedTextFields = useMemo(() => {
|
|
162
|
+
if (!config.enableMarkupVariables || !config.markupVariables?.length) {
|
|
163
|
+
return {
|
|
164
|
+
title,
|
|
165
|
+
superTitle: config.superTitle,
|
|
166
|
+
introText: config.introText,
|
|
167
|
+
legacyFootnotes: config.legacyFootnotes,
|
|
168
|
+
description: config.description
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
title: title
|
|
174
|
+
? processMarkupVariables(title, config.data || [], config.markupVariables, {
|
|
175
|
+
isEditor,
|
|
176
|
+
filters: config.filters || []
|
|
177
|
+
}).processedContent
|
|
178
|
+
: title,
|
|
179
|
+
superTitle: config.superTitle
|
|
180
|
+
? processMarkupVariables(config.superTitle, config.data || [], config.markupVariables, {
|
|
181
|
+
isEditor,
|
|
182
|
+
filters: config.filters || []
|
|
183
|
+
}).processedContent
|
|
184
|
+
: config.superTitle,
|
|
185
|
+
introText: config.introText
|
|
186
|
+
? processMarkupVariables(config.introText, config.data || [], config.markupVariables, {
|
|
187
|
+
isEditor,
|
|
188
|
+
filters: config.filters || []
|
|
189
|
+
}).processedContent
|
|
190
|
+
: config.introText,
|
|
191
|
+
legacyFootnotes: config.legacyFootnotes
|
|
192
|
+
? processMarkupVariables(config.legacyFootnotes, config.data || [], config.markupVariables, {
|
|
193
|
+
isEditor,
|
|
194
|
+
filters: config.filters || []
|
|
195
|
+
}).processedContent
|
|
196
|
+
: config.legacyFootnotes,
|
|
197
|
+
description: config.description
|
|
198
|
+
? processMarkupVariables(config.description, config.data || [], config.markupVariables, {
|
|
199
|
+
isEditor,
|
|
200
|
+
filters: config.filters || []
|
|
201
|
+
}).processedContent
|
|
202
|
+
: config.description
|
|
203
|
+
}
|
|
204
|
+
}, [
|
|
205
|
+
config.enableMarkupVariables,
|
|
206
|
+
config.markupVariables,
|
|
207
|
+
config.data,
|
|
208
|
+
config.filters,
|
|
209
|
+
title,
|
|
210
|
+
config.superTitle,
|
|
211
|
+
config.introText,
|
|
212
|
+
config.legacyFootnotes,
|
|
213
|
+
config.description,
|
|
214
|
+
isEditor
|
|
215
|
+
])
|
|
216
|
+
|
|
217
|
+
// Destructure processed values
|
|
218
|
+
title = processedTextFields.title
|
|
219
|
+
const processedSuperTitle = processedTextFields.superTitle
|
|
220
|
+
const processedIntroText = processedTextFields.introText
|
|
221
|
+
const processedLegacyFootnotes = processedTextFields.legacyFootnotes
|
|
222
|
+
const processedDescription = processedTextFields.description
|
|
223
|
+
// Note: Axis labels are processed within updateConfig to ensure they use the correct data
|
|
224
|
+
|
|
155
225
|
// set defaults on titles if blank AND only in editor
|
|
156
226
|
if (isEditor) {
|
|
157
227
|
if (!title || title === '') title = 'Chart Title'
|
|
@@ -169,7 +239,22 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
169
239
|
const convertLineToBarGraph = isConvertLineToBarGraph(config, filteredData)
|
|
170
240
|
|
|
171
241
|
const prepareConfig = (loadedConfig: ChartConfig) => {
|
|
172
|
-
|
|
242
|
+
// Create defaults without version to avoid overriding legacy configs
|
|
243
|
+
const defaultsWithoutPalette = { ...defaults }
|
|
244
|
+
|
|
245
|
+
// Only remove palette defaults for legacy (v1) configs
|
|
246
|
+
// New configs and v2 configs should get the v2 palette defaults
|
|
247
|
+
if (loadedConfig?.general?.palette || (!loadedConfig?.general && !loadedConfig?.color)) {
|
|
248
|
+
// Keep palette defaults for:
|
|
249
|
+
// 1. Configs that already have general.palette (v2 configs)
|
|
250
|
+
// 2. New configs (no general section and no legacy color property)
|
|
251
|
+
} else {
|
|
252
|
+
// Remove palette defaults for legacy configs that have color but no general.palette
|
|
253
|
+
delete defaultsWithoutPalette.general?.palette
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
let newConfig = { ...defaultsWithoutPalette, ...loadedConfig }
|
|
257
|
+
|
|
173
258
|
_.defaultsDeep(newConfig, {
|
|
174
259
|
table: { showVertical: false }
|
|
175
260
|
})
|
|
@@ -191,11 +276,30 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
191
276
|
}
|
|
192
277
|
|
|
193
278
|
const updateConfig = (_config: AllChartsConfig, dataOverride?: any[]) => {
|
|
194
|
-
const newConfig =
|
|
279
|
+
const newConfig = cloneConfig(_config)
|
|
195
280
|
let data = dataOverride || stateData
|
|
196
281
|
|
|
197
282
|
data = handleRankByValue(data, newConfig)
|
|
198
283
|
|
|
284
|
+
// Process axis labels for markup variables if enabled
|
|
285
|
+
let processedXAxis = newConfig.xAxis?.label
|
|
286
|
+
let processedYAxis = newConfig.yAxis?.label
|
|
287
|
+
|
|
288
|
+
if (newConfig.enableMarkupVariables && newConfig.markupVariables?.length) {
|
|
289
|
+
if (newConfig.xAxis?.label) {
|
|
290
|
+
processedXAxis = processMarkupVariables(newConfig.xAxis.label, data || [], newConfig.markupVariables, {
|
|
291
|
+
isEditor,
|
|
292
|
+
filters: newConfig.filters || []
|
|
293
|
+
}).processedContent
|
|
294
|
+
}
|
|
295
|
+
if (newConfig.yAxis?.label) {
|
|
296
|
+
processedYAxis = processMarkupVariables(newConfig.yAxis.label, data || [], newConfig.markupVariables, {
|
|
297
|
+
isEditor,
|
|
298
|
+
filters: newConfig.filters || []
|
|
299
|
+
}).processedContent
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
199
303
|
// Deeper copy
|
|
200
304
|
Object.keys(defaults).forEach(key => {
|
|
201
305
|
if (newConfig[key] && 'object' === typeof newConfig[key] && !Array.isArray(newConfig[key])) {
|
|
@@ -226,7 +330,9 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
226
330
|
newConfig.runtime.originalXAxis = newConfig.xAxis
|
|
227
331
|
|
|
228
332
|
if (newConfig.visualizationType === 'Pie') {
|
|
229
|
-
|
|
333
|
+
// Use the same data that will be passed to PieChart (after exclusions and filters)
|
|
334
|
+
const pieData = currentData.length > 0 ? currentData : newExcludedData
|
|
335
|
+
newConfig.runtime.seriesKeys = _.uniq(pieData.map(d => d[newConfig.xAxis.dataKey]))
|
|
230
336
|
newConfig.runtime.seriesLabelsAll = newConfig.runtime.seriesKeys
|
|
231
337
|
} else {
|
|
232
338
|
const finalData = dataOverride || newConfig.formattedData || newConfig.data
|
|
@@ -294,8 +400,15 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
294
400
|
newConfig.orientation === 'horizontal') ||
|
|
295
401
|
['Deviation Bar', 'Paired Bar', 'Forest Plot'].includes(newConfig.visualizationType)
|
|
296
402
|
) {
|
|
297
|
-
|
|
298
|
-
newConfig.runtime.
|
|
403
|
+
// For horizontal charts, axes are swapped, so processedYAxis goes to runtime.xAxis and vice versa
|
|
404
|
+
newConfig.runtime.xAxis = {
|
|
405
|
+
..._.cloneDeep(newConfig.yAxis.yAxis || newConfig.yAxis),
|
|
406
|
+
label: processedYAxis || (newConfig.yAxis.yAxis || newConfig.yAxis).label
|
|
407
|
+
}
|
|
408
|
+
newConfig.runtime.yAxis = {
|
|
409
|
+
..._.cloneDeep(newConfig.xAxis.xAxis || newConfig.xAxis),
|
|
410
|
+
label: processedXAxis || (newConfig.xAxis.xAxis || newConfig.xAxis).label
|
|
411
|
+
}
|
|
299
412
|
newConfig.runtime.yAxis.labelOffset *= -1
|
|
300
413
|
|
|
301
414
|
newConfig.runtime.horizontal = false
|
|
@@ -306,13 +419,13 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
306
419
|
['Scatter Plot', 'Area Chart', 'Line', 'Forecasting'].includes(newConfig.visualizationType) &&
|
|
307
420
|
!convertLineToBarGraph
|
|
308
421
|
) {
|
|
309
|
-
newConfig.runtime.xAxis = newConfig.xAxis
|
|
310
|
-
newConfig.runtime.yAxis = newConfig.yAxis
|
|
422
|
+
newConfig.runtime.xAxis = { ...newConfig.xAxis, label: processedXAxis || newConfig.xAxis.label }
|
|
423
|
+
newConfig.runtime.yAxis = { ...newConfig.yAxis, label: processedYAxis || newConfig.yAxis.label }
|
|
311
424
|
newConfig.runtime.horizontal = false
|
|
312
425
|
newConfig.orientation = 'vertical'
|
|
313
426
|
} else {
|
|
314
|
-
newConfig.runtime.xAxis = newConfig.xAxis
|
|
315
|
-
newConfig.runtime.yAxis = newConfig.yAxis
|
|
427
|
+
newConfig.runtime.xAxis = { ...newConfig.xAxis, label: processedXAxis || newConfig.xAxis.label }
|
|
428
|
+
newConfig.runtime.yAxis = { ...newConfig.yAxis, label: processedYAxis || newConfig.yAxis.label }
|
|
316
429
|
newConfig.runtime.horizontal = false
|
|
317
430
|
}
|
|
318
431
|
|
|
@@ -429,8 +542,16 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
429
542
|
} else if (newConfig.formattedData) {
|
|
430
543
|
newConfig.data = newConfig.formattedData
|
|
431
544
|
} else if (newConfig.dataDescription) {
|
|
432
|
-
|
|
433
|
-
|
|
545
|
+
// For dashboard contexts, get data from datasets if config.data is undefined
|
|
546
|
+
let dataToProcess = newConfig.data
|
|
547
|
+
if (!dataToProcess && isDashboard && datasets && newConfig.dataKey) {
|
|
548
|
+
dataToProcess = datasets[newConfig.dataKey]?.data
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
if (dataToProcess) {
|
|
552
|
+
newConfig.data = transform.autoStandardize(dataToProcess)
|
|
553
|
+
newConfig.data = transform.developerStandardize(newConfig.data, newConfig.dataDescription)
|
|
554
|
+
}
|
|
434
555
|
}
|
|
435
556
|
} catch (err) {
|
|
436
557
|
console.error('Error on prepareData function ', err)
|
|
@@ -468,7 +589,6 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
468
589
|
if (container && !isLoading && !_.isEmpty(config) && !coveLoadedEventRan) {
|
|
469
590
|
publish('cove_loaded', { config: config })
|
|
470
591
|
dispatch({ type: 'SET_LOADED_EVENT', payload: true })
|
|
471
|
-
publishAnalyticsEvent('chart_loaded', 'load', interactionLabel, 'chart')
|
|
472
592
|
}
|
|
473
593
|
}, [container, config, isLoading]) // eslint-disable-line
|
|
474
594
|
|
|
@@ -558,7 +678,17 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
558
678
|
} catch (e) {
|
|
559
679
|
console.error('COVE:', e.message)
|
|
560
680
|
}
|
|
561
|
-
publishAnalyticsEvent(
|
|
681
|
+
publishAnalyticsEvent({
|
|
682
|
+
vizType: config?.type,
|
|
683
|
+
vizSubType: getVizSubType(config),
|
|
684
|
+
eventType: 'chart_legend_reset',
|
|
685
|
+
eventAction: 'click',
|
|
686
|
+
eventLabel: interactionLabel,
|
|
687
|
+
vizTitle: getVizTitle(config),
|
|
688
|
+
...(config.visualizationType === 'Bar' && {
|
|
689
|
+
specifics: `orientation: ${config.orientation === 'horizontal' ? 'horizontal' : 'vertical'}`
|
|
690
|
+
})
|
|
691
|
+
})
|
|
562
692
|
dispatch({ type: 'SET_SERIES_HIGHLIGHT', payload: [] })
|
|
563
693
|
}
|
|
564
694
|
|
|
@@ -821,7 +951,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
821
951
|
}
|
|
822
952
|
|
|
823
953
|
const pivotDynamicSeries = (config: ChartConfig): TableConfig => {
|
|
824
|
-
const tableConfig: TableConfig =
|
|
954
|
+
const tableConfig: TableConfig = cloneConfig(config)
|
|
825
955
|
const dynamicSeries = tableConfig.series.find(series => !!series.dynamicCategory)
|
|
826
956
|
if (dynamicSeries) {
|
|
827
957
|
const pivot: Pivot = { columnName: dynamicSeries.dynamicCategory, valueColumns: [dynamicSeries.dataKey] }
|
|
@@ -893,16 +1023,17 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
893
1023
|
showTitle={config.showTitle}
|
|
894
1024
|
isDashboard={isDashboard}
|
|
895
1025
|
title={title}
|
|
896
|
-
superTitle={
|
|
1026
|
+
superTitle={processedSuperTitle}
|
|
897
1027
|
classes={['chart-title', `${config.theme}`, 'cove-component__header', 'mb-3']}
|
|
898
1028
|
style={undefined}
|
|
1029
|
+
config={config}
|
|
899
1030
|
/>
|
|
900
1031
|
|
|
901
1032
|
{/* Visualization Wrapper */}
|
|
902
1033
|
<div className={getChartWrapperClasses().join(' ')}>
|
|
903
1034
|
{/* Intro Text/Message */}
|
|
904
|
-
{
|
|
905
|
-
<section className={`introText mb-4`}>{parse(
|
|
1035
|
+
{processedIntroText && config.visualizationType !== 'Spark Line' && (
|
|
1036
|
+
<section className={`introText mb-4`}>{parse(processedIntroText)}</section>
|
|
906
1037
|
)}
|
|
907
1038
|
|
|
908
1039
|
{/* Filters */}
|
|
@@ -949,7 +1080,14 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
949
1080
|
|
|
950
1081
|
{config.visualizationType === 'Pie' && (
|
|
951
1082
|
<ParentSize className='justify-content-center d-flex' style={{ width: `100%` }}>
|
|
952
|
-
{parent =>
|
|
1083
|
+
{parent => (
|
|
1084
|
+
<PieChart
|
|
1085
|
+
ref={svgRef}
|
|
1086
|
+
parentWidth={parent.width}
|
|
1087
|
+
parentHeight={parent.height}
|
|
1088
|
+
interactionLabel={interactionLabel}
|
|
1089
|
+
/>
|
|
1090
|
+
)}
|
|
953
1091
|
</ParentSize>
|
|
954
1092
|
)}
|
|
955
1093
|
{/* Line Chart */}
|
|
@@ -993,9 +1131,9 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
993
1131
|
dimensions={dimensions}
|
|
994
1132
|
interactionLabel={interactionLabel}
|
|
995
1133
|
/>
|
|
996
|
-
{
|
|
1134
|
+
{processedIntroText && (
|
|
997
1135
|
<section className='introText mb-4' style={{ padding: '0px 0 35px' }}>
|
|
998
|
-
{parse(
|
|
1136
|
+
{parse(processedIntroText)}
|
|
999
1137
|
</section>
|
|
1000
1138
|
)}
|
|
1001
1139
|
<div style={{ height: `100px`, width: `100%`, ...sparkLineStyles }}>
|
|
@@ -1032,8 +1170,8 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1032
1170
|
: link && link}
|
|
1033
1171
|
{/* Description */}
|
|
1034
1172
|
|
|
1035
|
-
{
|
|
1036
|
-
<div className={getChartSubTextClasses().join(' ')}>{parse(
|
|
1173
|
+
{processedDescription && config.visualizationType !== 'Spark Line' && (
|
|
1174
|
+
<div className={getChartSubTextClasses().join(' ')}>{parse(processedDescription)}</div>
|
|
1037
1175
|
)}
|
|
1038
1176
|
|
|
1039
1177
|
{/* buttons */}
|
|
@@ -1067,7 +1205,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1067
1205
|
(config.visualizationType === 'Sankey' && config.table.show)) && (
|
|
1068
1206
|
<DataTable
|
|
1069
1207
|
/* changing the "key" will force the table to re-render
|
|
1070
|
-
|
|
1208
|
+
when the default sort changes while editing */
|
|
1071
1209
|
key={dataTableDefaultSortBy}
|
|
1072
1210
|
config={pivotDynamicSeries(config)}
|
|
1073
1211
|
rawData={
|
|
@@ -1094,8 +1232,8 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1094
1232
|
)}
|
|
1095
1233
|
{config?.annotations?.length > 0 && <Annotation.Dropdown />}
|
|
1096
1234
|
{/* show pdf or image button */}
|
|
1097
|
-
{
|
|
1098
|
-
<section className='footnotes pt-2 mt-4'>{parse(
|
|
1235
|
+
{processedLegacyFootnotes && (
|
|
1236
|
+
<section className='footnotes pt-2 mt-4'>{parse(processedLegacyFootnotes)}</section>
|
|
1099
1237
|
)}
|
|
1100
1238
|
</div>
|
|
1101
1239
|
<FootnotesStandAlone
|
|
@@ -1119,6 +1257,9 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1119
1257
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
1120
1258
|
}
|
|
1121
1259
|
|
|
1260
|
+
// Get version-specific color palettes based on current config
|
|
1261
|
+
const colorPalettes = filterChartColorPalettes(config)
|
|
1262
|
+
|
|
1122
1263
|
const contextValues = {
|
|
1123
1264
|
...state,
|
|
1124
1265
|
capitalize,
|
|
@@ -1137,6 +1278,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1137
1278
|
handleChartTabbing,
|
|
1138
1279
|
highlight,
|
|
1139
1280
|
handleShowAll,
|
|
1281
|
+
interactionLabel,
|
|
1140
1282
|
isDashboard,
|
|
1141
1283
|
isDebug,
|
|
1142
1284
|
handleDragStateChange,
|
|
@@ -1150,7 +1292,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1150
1292
|
outerContainerRef,
|
|
1151
1293
|
parentRef,
|
|
1152
1294
|
parseDate,
|
|
1153
|
-
rawData:
|
|
1295
|
+
rawData: stateData ?? {},
|
|
1154
1296
|
setConfig,
|
|
1155
1297
|
setEditing,
|
|
1156
1298
|
setParentConfig,
|
|
@@ -1160,7 +1302,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1160
1302
|
tableData: filteredData || excludedData,
|
|
1161
1303
|
transformedData: getTransformedData({ brushData: state.brushData, filteredData, excludedData, clean }),
|
|
1162
1304
|
twoColorPalette,
|
|
1163
|
-
unfilteredData:
|
|
1305
|
+
unfilteredData: stateData,
|
|
1164
1306
|
updateConfig
|
|
1165
1307
|
}
|
|
1166
1308
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { Meta, Story } from '@storybook/react'
|
|
2
|
+
import { Meta, Story } from '@storybook/react-vite'
|
|
3
3
|
import Chart from '../CdcChartComponent'
|
|
4
4
|
import exampleComboBarNonNumeric from './../../examples/feature/tests-date-exclusions/date-exclusions-config.json'
|
|
5
|
-
import { editConfigKeys } from '
|
|
5
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
6
|
|
|
7
7
|
export default {
|
|
8
8
|
title: 'Components/Templates/Chart/Anchors',
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import barChartCiLabels from './_mock/bar_chart_ci_labels.json'
|
|
3
3
|
import lineChartDynamicCI from './_mock/line_chart_dynamic_ci.json'
|
|
4
4
|
import lineChartNonDynamicCI from './_mock/line_chart_non_dynamic_ci.json'
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DynamicSeriesConfig from './_mock/dynamic_series_config.json'
|
|
2
2
|
import DynamicSeriesBarConfig from './_mock/dynamic_series_bar_config.json'
|
|
3
3
|
import DynamicSeriesSuppression from './_mock/dynamic_series_suppression_mock.json'
|
|
4
|
-
import { Meta, StoryObj } from '@storybook/react'
|
|
4
|
+
import { Meta, StoryObj } from '@storybook/react-vite'
|
|
5
5
|
import Chart from '../CdcChartComponent'
|
|
6
6
|
|
|
7
7
|
const meta: Meta<typeof Chart> = {
|
|
@@ -43,7 +43,7 @@ export const LineHoverPoints: Story = {
|
|
|
43
43
|
export const Bar_Vertical: Story = {
|
|
44
44
|
args: {
|
|
45
45
|
config: DynamicSeriesBarConfig,
|
|
46
|
-
isEditor:
|
|
46
|
+
isEditor: true
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import Chart from '../CdcChartComponent'
|
|
3
|
-
import { editConfigKeys } from '
|
|
3
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
4
4
|
import scatterPlotDownloadImage from './_mock/scatterplot-image-download.json'
|
|
5
5
|
|
|
6
6
|
const meta: Meta<typeof Chart> = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import chartGradientConfig from './_mock/legend.gradient_mock.json'
|
|
3
3
|
import chartGroupedLagend from './_mock/legend_groupBy_mock.json'
|
|
4
4
|
import SimplifiedLineConfig from './_mock/simplified_line.json'
|
|
5
5
|
|
|
6
6
|
import Chart from '../CdcChartComponent'
|
|
7
|
-
import { editConfigKeys } from '
|
|
7
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
8
8
|
|
|
9
9
|
const meta: Meta<typeof Chart> = {
|
|
10
10
|
title: 'Components/Templates/Chart/Legend',
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import StackedPattern from './_mock/stacked-pattern-test.json'
|
|
3
|
+
|
|
4
|
+
import Chart from '../CdcChartComponent'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Chart> = {
|
|
7
|
+
title: 'Components/Templates/Chart/Patterns',
|
|
8
|
+
component: Chart
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Story = StoryObj<typeof Chart>
|
|
12
|
+
|
|
13
|
+
export const Stacked_Bar_Pattern: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
config: StackedPattern
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default meta
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
|
|
3
3
|
import Chart from '../CdcChart'
|
|
4
4
|
import lineChartTwoPointsRegressionTest from './_mock/line_chart_two_points_regression_test.json'
|
|
@@ -12,7 +12,7 @@ import pieConfig from './_mock/pie_with_data.json'
|
|
|
12
12
|
import pieCalculatedArea from './_mock/pie_calculated_area.json'
|
|
13
13
|
import areaChartStacked from './_mock/area_chart_stacked.json'
|
|
14
14
|
import multipleLines from './_mock/short_dates.json'
|
|
15
|
-
import { editConfigKeys } from '
|
|
15
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
16
16
|
|
|
17
17
|
const meta: Meta<typeof Chart> = {
|
|
18
18
|
title: 'Components/Templates/Chart',
|
|
@@ -67,18 +67,21 @@ export const BarChart_Labels: Story = {
|
|
|
67
67
|
|
|
68
68
|
export const Pie: Story = {
|
|
69
69
|
args: {
|
|
70
|
-
config: pieConfig
|
|
70
|
+
config: pieConfig,
|
|
71
|
+
isEditor: true
|
|
71
72
|
}
|
|
72
73
|
}
|
|
73
74
|
export const Pie_Calculated_Area: Story = {
|
|
74
75
|
args: {
|
|
75
|
-
config: pieCalculatedArea
|
|
76
|
+
config: pieCalculatedArea,
|
|
77
|
+
isEditor: true
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export const Paired_Bar: Story = {
|
|
80
82
|
args: {
|
|
81
|
-
config: pairedBar
|
|
83
|
+
config: pairedBar,
|
|
84
|
+
isEditor: true
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import annotationConfig from './_mock/annotation_category_mock.json'
|
|
3
3
|
import annotationConfigDateLinear from './_mock/annotation_date-linear_mock.json'
|
|
4
4
|
import annotationConfigDateTime from './_mock/annotation_date-time_mock.json'
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import SimplifiedLineConfig from './_mock/simplified_line.json'
|
|
3
3
|
|
|
4
4
|
import Chart from '../CdcChartComponent'
|
|
5
|
-
import { editConfigKeys } from '
|
|
5
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
6
|
|
|
7
7
|
const meta: Meta<typeof Chart> = {
|
|
8
8
|
title: 'Components/Templates/Chart/Axis Labels',
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/react'
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import Chart from '../CdcChartComponent'
|
|
3
3
|
import longXLabelsConfig from './_mock/large_x_axis_labels.json'
|
|
4
4
|
import pairedBarConfig from './_mock/paired-bar.json'
|
|
5
|
-
import { editConfigKeys } from '
|
|
5
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
6
|
import { ChartConfig } from '../types/ChartConfig'
|
|
7
7
|
|
|
8
8
|
const meta: Meta<typeof Chart> = {
|