@cdc/chart 4.25.10 → 4.26.1
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-1a1724a1.es.js → cdcchart-dgT_1dIT.es.js} +136 -151
- package/dist/cdcchart.js +44003 -43518
- package/examples/feature/__data__/planet-example-data.json +1 -1
- package/examples/feature/boxplot/valid-boxplot.csv +38 -17
- package/examples/feature/pie/planet-pie-example-config.json +48 -2
- package/examples/private/DEV-11825.json +573 -0
- package/examples/private/DEV-12100.json +1303 -0
- package/examples/private/cat-y.json +1235 -0
- package/examples/private/data-points.json +228 -0
- package/examples/private/height.json +3915 -0
- package/examples/private/links.json +569 -0
- package/examples/private/na.json +913 -0
- package/examples/private/quadrant.txt +30 -0
- package/examples/private/test-data.csv +28 -0
- package/examples/private/test-forecast.json +5510 -0
- package/examples/private/warming-stripe-test.json +2578 -0
- package/examples/private/warming-stripes.json +4763 -0
- package/examples/tech-adoption-with-links.json +560 -0
- package/index.html +16 -140
- package/package.json +6 -5
- package/preview.html +1616 -0
- package/src/CdcChart.tsx +8 -11
- package/src/CdcChartComponent.tsx +329 -124
- package/src/_stories/Chart.Combo.stories.tsx +18 -0
- package/src/_stories/Chart.Forecast.stories.tsx +36 -0
- package/src/_stories/Chart.HTMLInDataTable.stories.tsx +520 -0
- package/src/_stories/Chart.Patterns.stories.tsx +2 -1
- package/src/_stories/Chart.PreserveDecimals.stories.tsx +220 -0
- package/src/_stories/Chart.Regions.Categorical.stories.tsx +148 -0
- package/src/_stories/Chart.Regions.DateScale.stories.tsx +197 -0
- package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +297 -0
- package/src/_stories/Chart.SmallMultiples.stories.tsx +47 -0
- package/src/_stories/Chart.stories.tsx +8 -0
- package/src/_stories/ChartAnnotation.stories.tsx +6 -3
- package/src/_stories/ChartBar.Editor.stories.tsx +3585 -0
- package/src/_stories/ChartBrush.Editor.stories.tsx +295 -0
- package/src/_stories/ChartBrush.stories.tsx +50 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +656 -0
- package/src/_stories/ChartEditor.stories.tsx +1 -2
- package/src/_stories/TechAdoptionWithLinks.stories.tsx +27 -0
- package/src/_stories/_mock/brush_enabled.json +326 -0
- package/src/_stories/_mock/brush_mock.json +2 -69
- package/src/_stories/_mock/combo.json +451 -0
- package/src/_stories/_mock/editor-test-configs.json +376 -0
- package/src/_stories/_mock/editor-test-datasets.json +477 -0
- package/src/_stories/_mock/editor-tests/bar-chart-editor-test.json +255 -0
- package/src/_stories/_mock/editor-tests/bar-chart-general-test.json +267 -0
- package/src/_stories/_mock/editor-tests/bar-chart-test.json +237 -0
- package/src/_stories/_mock/forecast_combo_with_gaps.json +913 -0
- package/src/_stories/_mock/horizontal-bars-dynamic-y-axis.json +413 -0
- package/src/_stories/_mock/pie_config.json +257 -62
- package/src/_stories/_mock/small_multiples/small_multiples_bars.json +1944 -0
- package/src/_stories/_mock/small_multiples/small_multiples_big_data_bars.json +1114 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +2646 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines_colors.json +1305 -0
- package/src/_stories/_mock/small_multiples/small_multiples_stacked_bars.json +1936 -0
- package/src/components/Annotations/components/findNearestDatum.ts +6 -41
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -7
- package/src/components/AreaChart/index.tsx +1 -2
- package/src/components/Axis/Categorical.Axis.tsx +6 -7
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +181 -27
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +3 -1
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +1 -0
- package/src/components/BarChart/components/BarChart.Vertical.tsx +8 -9
- package/src/components/BarChart/components/context.tsx +1 -0
- package/src/components/BarChart/helpers/useBarChart.ts +14 -2
- package/src/components/BoxPlot/helpers/index.ts +3 -3
- package/src/components/Brush/BrushSelector.tsx +1258 -0
- package/src/components/Brush/MiniChartPreview.tsx +283 -0
- package/src/components/DeviationBar.jsx +9 -7
- package/src/components/EditorPanel/EditorPanel.tsx +2720 -2586
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +96 -111
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +56 -34
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +76 -31
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +104 -55
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +54 -49
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +427 -0
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +96 -48
- package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
- package/src/components/EditorPanel/editor-panel.scss +0 -20
- package/src/components/EditorPanel/useEditorPermissions.ts +36 -31
- package/src/components/Forecasting/Forecasting.tsx +139 -21
- package/src/components/Legend/Legend.Component.tsx +16 -9
- package/src/components/Legend/Legend.tsx +3 -2
- package/src/components/Legend/helpers/createFormatLabels.tsx +325 -176
- package/src/components/Legend/helpers/getLegendClasses.ts +0 -1
- package/src/components/Legend/helpers/index.ts +10 -6
- package/src/components/LineChart/LineChartProps.ts +0 -3
- package/src/components/LineChart/helpers.ts +1 -1
- package/src/components/LineChart/index.tsx +36 -13
- package/src/components/LinearChart.tsx +559 -499
- package/src/components/PairedBarChart.jsx +20 -3
- package/src/components/Regions/components/Regions.tsx +366 -144
- package/src/components/Sankey/types/index.ts +1 -1
- package/src/components/ScatterPlot/ScatterPlot.jsx +2 -2
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +202 -0
- package/src/components/SmallMultiples/SmallMultiples.css +32 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +271 -0
- package/src/components/SmallMultiples/index.ts +2 -0
- package/src/components/WarmingStripes/WarmingStripes.tsx +160 -0
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +35 -0
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +104 -0
- package/src/components/WarmingStripes/index.tsx +3 -0
- package/src/data/initial-state.js +16 -2
- package/src/helpers/buildForecastPaletteOptions.ts +0 -38
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +57 -0
- package/src/helpers/getColorScale.ts +10 -0
- package/src/{hooks/useMinMax.ts → helpers/getMinMax.ts} +26 -14
- package/src/helpers/getYAxisAutoPadding.ts +53 -0
- package/src/helpers/sizeHelpers.ts +0 -20
- package/src/helpers/smallMultiplesHelpers.ts +529 -0
- package/src/hooks/useChartHoverAnalytics.tsx +10 -9
- package/src/hooks/useProgrammaticTooltip.ts +96 -0
- package/src/hooks/useScales.ts +98 -34
- package/src/hooks/useSmallMultipleSynchronization.ts +59 -0
- package/src/hooks/useTooltip.tsx +91 -25
- package/src/scss/DataTable.scss +0 -4
- package/src/scss/main.scss +18 -83
- package/src/store/chart.actions.ts +2 -0
- package/src/store/chart.reducer.ts +4 -0
- package/src/test/CdcChart.test.jsx +1 -1
- package/src/types/ChartConfig.ts +27 -6
- package/src/types/ChartContext.ts +3 -0
- package/src/types/Label.ts +1 -0
- package/src/utils/analyticsTracking.ts +19 -0
- package/LICENSE +0 -201
- package/src/_stories/_mock/pie_data.json +0 -218
- package/src/components/AreaChart/components/AreaChart.jsx +0 -109
- package/src/components/Brush/BrushChart.tsx +0 -128
- package/src/components/Brush/BrushController.tsx +0 -71
- package/src/components/Brush/types.tsx +0 -8
- package/src/components/BrushChart.tsx +0 -223
- package/src/helpers/sort.ts +0 -7
- package/src/hooks/useActiveElement.js +0 -19
- package/src/hooks/useChartClasses.js +0 -41
|
@@ -10,6 +10,7 @@ import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
|
10
10
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
11
11
|
import Button from '@cdc/core/components/elements/Button'
|
|
12
12
|
import Alert from '@cdc/core/components/Alert'
|
|
13
|
+
import { Select } from '@cdc/core/components/EditorPanel/Inputs'
|
|
13
14
|
import ConfigContext from '../../../../ConfigContext'
|
|
14
15
|
import { ChartContext } from '../../../../types/ChartContext'
|
|
15
16
|
import { PanelProps } from '../PanelProps'
|
|
@@ -89,17 +90,22 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
// Checks contrast and logs warning if needed
|
|
92
|
-
const checkAndLogContrast = (
|
|
93
|
-
|
|
93
|
+
const checkAndLogContrast = (
|
|
94
|
+
patternColor: string,
|
|
95
|
+
backgroundColor: string,
|
|
96
|
+
dataValue: string,
|
|
97
|
+
dataKey: string
|
|
98
|
+
): boolean => {
|
|
99
|
+
if (!backgroundColor || !patternColor) return true // Default to true if colors are missing
|
|
94
100
|
|
|
95
|
-
const contrastCheck = checkColorContrast(
|
|
101
|
+
const contrastCheck = checkColorContrast(patternColor, backgroundColor)
|
|
96
102
|
|
|
97
103
|
if (!contrastCheck) {
|
|
98
104
|
console.error(
|
|
99
105
|
`COVE: pattern contrast check failed for ${dataValue} in ${dataKey} with:
|
|
100
106
|
pattern color: ${patternColor}
|
|
101
|
-
background color: ${
|
|
102
|
-
contrast: ${getColorContrast(
|
|
107
|
+
background color: ${backgroundColor}
|
|
108
|
+
contrast: ${getColorContrast(patternColor, backgroundColor)}`
|
|
103
109
|
)
|
|
104
110
|
}
|
|
105
111
|
|
|
@@ -108,7 +114,9 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
108
114
|
|
|
109
115
|
// Perform contrast check for a specific pattern against actual bar colors
|
|
110
116
|
const performContrastCheck = (patternKey: string, patternColor: string) => {
|
|
111
|
-
if (!patternColor || patternColor === '')
|
|
117
|
+
if (!patternColor || patternColor === '') {
|
|
118
|
+
return true
|
|
119
|
+
}
|
|
112
120
|
|
|
113
121
|
// Get the actual bar colors that the pattern will be overlaid on
|
|
114
122
|
let seriesColors: string[] = []
|
|
@@ -138,8 +146,8 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
138
146
|
const contrastResults: Array<{ color: string; passes: boolean; ratio: number | false }> = []
|
|
139
147
|
|
|
140
148
|
seriesColors.forEach((barColor, index) => {
|
|
141
|
-
const contrastPasses = checkAndLogContrast(
|
|
142
|
-
const contrastRatio = getColorContrast(
|
|
149
|
+
const contrastPasses = checkAndLogContrast(patternColor, barColor, patternKey, `series-${index}`)
|
|
150
|
+
const contrastRatio = getColorContrast(patternColor, barColor)
|
|
143
151
|
|
|
144
152
|
contrastResults.push({
|
|
145
153
|
color: barColor,
|
|
@@ -184,26 +192,48 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
184
192
|
}
|
|
185
193
|
}
|
|
186
194
|
|
|
187
|
-
|
|
195
|
+
const updatedConfig = {
|
|
188
196
|
...config,
|
|
189
197
|
legend: {
|
|
190
198
|
...(config.legend || {}),
|
|
191
199
|
patterns: newPatterns
|
|
200
|
+
},
|
|
201
|
+
runtime: {
|
|
202
|
+
...config.runtime
|
|
192
203
|
}
|
|
193
|
-
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Check if all patterns pass and set error message
|
|
207
|
+
const allPatternsPass = Object.values(newPatterns).every((p: any) => p.contrastCheck !== false)
|
|
208
|
+
updatedConfig.runtime.editorErrorMessage = allPatternsPass
|
|
209
|
+
? ''
|
|
210
|
+
: 'One or more patterns do not pass the WCAG 2.1 contrast ratio of 3:1.'
|
|
211
|
+
|
|
212
|
+
updateConfig(updatedConfig)
|
|
194
213
|
}
|
|
195
214
|
|
|
196
215
|
const handleRemovePattern = (patternKey: string) => {
|
|
197
216
|
const newPatterns = { ...(legendCfg.patterns || {}) }
|
|
198
217
|
delete newPatterns[patternKey]
|
|
199
218
|
|
|
200
|
-
|
|
219
|
+
const updatedConfig = {
|
|
201
220
|
...config,
|
|
202
221
|
legend: {
|
|
203
222
|
...(config.legend || {}),
|
|
204
223
|
patterns: newPatterns
|
|
224
|
+
},
|
|
225
|
+
runtime: {
|
|
226
|
+
...config.runtime
|
|
205
227
|
}
|
|
206
|
-
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Check if all remaining patterns pass and clear error message if needed
|
|
231
|
+
const allPatternsPass = Object.values(newPatterns).every((p: any) => p.contrastCheck !== false)
|
|
232
|
+
if (allPatternsPass || Object.keys(newPatterns).length === 0) {
|
|
233
|
+
updatedConfig.runtime.editorErrorMessage = ''
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
updateConfig(updatedConfig)
|
|
207
237
|
}
|
|
208
238
|
|
|
209
239
|
const handlePatternKeyChange = (oldKey: string, newKey: string) => {
|
|
@@ -228,15 +258,33 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
228
258
|
})
|
|
229
259
|
}
|
|
230
260
|
|
|
261
|
+
const reviewColorContrast = (updatedConfig: any, patternKey: string) => {
|
|
262
|
+
// Re-check the contrast for the updated pattern
|
|
263
|
+
const pattern = updatedConfig.legend.patterns[patternKey]
|
|
264
|
+
|
|
265
|
+
if (pattern?.color) {
|
|
266
|
+
pattern.contrastCheck = performContrastCheck(patternKey, pattern.color)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Update error message based on whether all patterns pass contrast checks
|
|
270
|
+
const allPatterns = Object.values(updatedConfig.legend.patterns || {})
|
|
271
|
+
|
|
272
|
+
const allPatternsPass = allPatterns.every((p: any) => p.contrastCheck !== false)
|
|
273
|
+
|
|
274
|
+
const errorMsg = allPatternsPass ? '' : 'One or more patterns do not pass the WCAG 2.1 contrast ratio of 3:1.'
|
|
275
|
+
// Set error message AFTER spreading runtime to avoid it being overwritten
|
|
276
|
+
updatedConfig.runtime.editorErrorMessage = errorMsg
|
|
277
|
+
}
|
|
278
|
+
|
|
231
279
|
const handlePatternUpdate = (patternKey: string, field: string, value: any) => {
|
|
232
280
|
const updatedPattern = {
|
|
233
281
|
...(legendCfg.patterns?.[patternKey] || {}),
|
|
234
282
|
[field]: value
|
|
235
283
|
}
|
|
236
284
|
|
|
237
|
-
//
|
|
238
|
-
if (field === '
|
|
239
|
-
updatedPattern.
|
|
285
|
+
// Clear dataValue if dataKey is being cleared or set to 'Select'
|
|
286
|
+
if (field === 'dataKey' && (value === 'Select' || value === '')) {
|
|
287
|
+
updatedPattern.dataValue = ''
|
|
240
288
|
}
|
|
241
289
|
|
|
242
290
|
const newPatterns = {
|
|
@@ -244,15 +292,27 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
244
292
|
[patternKey]: updatedPattern
|
|
245
293
|
}
|
|
246
294
|
|
|
247
|
-
|
|
295
|
+
const updatedConfig = {
|
|
248
296
|
...config,
|
|
249
297
|
legend: {
|
|
250
298
|
...(config.legend || {}),
|
|
251
299
|
patterns: newPatterns
|
|
300
|
+
},
|
|
301
|
+
runtime: {
|
|
302
|
+
...config.runtime
|
|
252
303
|
}
|
|
253
|
-
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Perform contrast check whenever color changes (even if cleared)
|
|
307
|
+
if (field === 'color') {
|
|
308
|
+
reviewColorContrast(updatedConfig, patternKey)
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
updateConfig(updatedConfig)
|
|
254
312
|
}
|
|
255
313
|
|
|
314
|
+
if (config.visualizationType === 'Warming Stripes') return
|
|
315
|
+
|
|
256
316
|
return (
|
|
257
317
|
<AccordionItem>
|
|
258
318
|
<AccordionItemHeading>
|
|
@@ -294,19 +354,16 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
294
354
|
/>
|
|
295
355
|
)}
|
|
296
356
|
|
|
297
|
-
<
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
</option>
|
|
308
|
-
))}
|
|
309
|
-
</select>
|
|
357
|
+
<Select
|
|
358
|
+
label='Data Key:'
|
|
359
|
+
value={p.dataKey || ''}
|
|
360
|
+
options={fieldOptions}
|
|
361
|
+
initial='Select Data Key'
|
|
362
|
+
fieldName={`pattern-datakey-${patternKey}`}
|
|
363
|
+
updateField={(section, subsection, fieldName, value) =>
|
|
364
|
+
handlePatternUpdate(patternKey, 'dataKey', value)
|
|
365
|
+
}
|
|
366
|
+
/>
|
|
310
367
|
|
|
311
368
|
{p.dataKey && (
|
|
312
369
|
<>
|
|
@@ -333,33 +390,25 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
333
390
|
/>
|
|
334
391
|
</label>
|
|
335
392
|
|
|
336
|
-
<
|
|
337
|
-
|
|
338
|
-
id={`pattern-type-${patternKey}`}
|
|
393
|
+
<Select
|
|
394
|
+
label='Pattern Type:'
|
|
339
395
|
value={p.shape || 'circles'}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
{
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
<label htmlFor={`pattern-size-${patternKey}`}>Pattern Size:</label>
|
|
350
|
-
<select
|
|
351
|
-
id={`pattern-size-${patternKey}`}
|
|
396
|
+
options={patternTypes}
|
|
397
|
+
fieldName={`pattern-type-${patternKey}`}
|
|
398
|
+
updateField={(section, subsection, fieldName, value) =>
|
|
399
|
+
handlePatternUpdate(patternKey, 'shape', value)
|
|
400
|
+
}
|
|
401
|
+
/>
|
|
402
|
+
|
|
403
|
+
<Select
|
|
404
|
+
label='Pattern Size:'
|
|
352
405
|
value={getPatternSizeText(p.patternSize || 8)}
|
|
353
|
-
|
|
354
|
-
|
|
406
|
+
options={patternSizes}
|
|
407
|
+
fieldName={`pattern-size-${patternKey}`}
|
|
408
|
+
updateField={(section, subsection, fieldName, value) =>
|
|
409
|
+
handlePatternUpdate(patternKey, 'patternSize', getPatternSizeNumeric(value))
|
|
355
410
|
}
|
|
356
|
-
|
|
357
|
-
{patternSizes.map((size, index) => (
|
|
358
|
-
<option value={size.value} key={index}>
|
|
359
|
-
{size.label}
|
|
360
|
-
</option>
|
|
361
|
-
))}
|
|
362
|
-
</select>
|
|
411
|
+
/>
|
|
363
412
|
|
|
364
413
|
<div className='mt-3'>
|
|
365
414
|
<label htmlFor={`pattern-color-${patternKey}`}>
|
|
@@ -380,7 +429,7 @@ const PanelPatternSettings: FC<PanelProps> = props => {
|
|
|
380
429
|
</Tooltip>
|
|
381
430
|
<input
|
|
382
431
|
type='text'
|
|
383
|
-
value={p.color || '
|
|
432
|
+
value={p.color || ''}
|
|
384
433
|
id={`pattern-color-${patternKey}`}
|
|
385
434
|
onChange={e => handlePatternUpdate(patternKey, 'color', e.target.value)}
|
|
386
435
|
placeholder='#666666'
|
|
@@ -2,7 +2,6 @@ import React, { useContext } from 'react'
|
|
|
2
2
|
import ConfigContext from '../../../../ConfigContext'
|
|
3
3
|
|
|
4
4
|
// Core
|
|
5
|
-
import InputSelect from '@cdc/core/components/inputs/InputSelect'
|
|
6
5
|
import Check from '@cdc/core/assets/icon-check.svg'
|
|
7
6
|
import { approvedCurveTypes } from '@cdc/core/helpers/lineChartHelpers'
|
|
8
7
|
import { colorPalettesChartV1, colorPalettesChartV2, sequentialPalettes } from '@cdc/core/data/colorPalettes'
|
|
@@ -98,12 +97,12 @@ const SeriesDropdownLineType = props => {
|
|
|
98
97
|
})
|
|
99
98
|
|
|
100
99
|
return (
|
|
101
|
-
<
|
|
100
|
+
<Select
|
|
102
101
|
initial='Select an option'
|
|
103
102
|
value={series.lineType ? series.lineType : 'curveLinear'}
|
|
104
103
|
label='Series Line Type'
|
|
105
|
-
|
|
106
|
-
changeLineType(index,
|
|
104
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
105
|
+
changeLineType(index, value)
|
|
107
106
|
}}
|
|
108
107
|
options={options}
|
|
109
108
|
/>
|
|
@@ -118,35 +117,35 @@ const SeriesDropdownSeriesType = props => {
|
|
|
118
117
|
|
|
119
118
|
const getOptions = () => {
|
|
120
119
|
if (config.visualizationType === 'Combo') {
|
|
121
|
-
return
|
|
122
|
-
Bar: 'Bar',
|
|
123
|
-
Line: 'Line',
|
|
124
|
-
'dashed-sm': 'Small Dashed',
|
|
125
|
-
'dashed-md': 'Medium Dashed',
|
|
126
|
-
'dashed-lg': 'Large Dashed',
|
|
127
|
-
'Area Chart': 'Area Chart',
|
|
128
|
-
Forecasting: 'Forecasting'
|
|
129
|
-
|
|
120
|
+
return [
|
|
121
|
+
{ value: 'Bar', label: 'Bar' },
|
|
122
|
+
{ value: 'Line', label: 'Line' },
|
|
123
|
+
{ value: 'dashed-sm', label: 'Small Dashed' },
|
|
124
|
+
{ value: 'dashed-md', label: 'Medium Dashed' },
|
|
125
|
+
{ value: 'dashed-lg', label: 'Large Dashed' },
|
|
126
|
+
{ value: 'Area Chart', label: 'Area Chart' },
|
|
127
|
+
{ value: 'Forecasting', label: 'Forecasting' }
|
|
128
|
+
]
|
|
130
129
|
}
|
|
131
130
|
if (config.visualizationType === 'Line' || config.visualizationType === 'Bump Chart') {
|
|
132
|
-
return
|
|
133
|
-
Line: 'Line',
|
|
134
|
-
'dashed-sm': 'Small Dashed',
|
|
135
|
-
'dashed-md': 'Medium Dashed',
|
|
136
|
-
'dashed-lg': 'Large Dashed'
|
|
137
|
-
|
|
131
|
+
return [
|
|
132
|
+
{ value: 'Line', label: 'Line' },
|
|
133
|
+
{ value: 'dashed-sm', label: 'Small Dashed' },
|
|
134
|
+
{ value: 'dashed-md', label: 'Medium Dashed' },
|
|
135
|
+
{ value: 'dashed-lg', label: 'Large Dashed' }
|
|
136
|
+
]
|
|
138
137
|
}
|
|
139
138
|
}
|
|
140
139
|
|
|
141
140
|
// Allowable changes
|
|
142
141
|
if (!['Line', 'Combo', 'Bump Chart'].includes(config.visualizationType)) return
|
|
143
142
|
return (
|
|
144
|
-
<
|
|
143
|
+
<Select
|
|
145
144
|
initial='Select an option'
|
|
146
145
|
value={series.type}
|
|
147
146
|
label='Series Type'
|
|
148
|
-
|
|
149
|
-
updateSeries(index,
|
|
147
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
148
|
+
updateSeries(index, value, 'type')
|
|
150
149
|
}}
|
|
151
150
|
options={getOptions()}
|
|
152
151
|
/>
|
|
@@ -162,13 +161,13 @@ const SeriesDropdownForecastingStage = props => {
|
|
|
162
161
|
// Only combo charts are allowed to have different options
|
|
163
162
|
|
|
164
163
|
return (
|
|
165
|
-
<
|
|
164
|
+
<Select
|
|
166
165
|
initial='Select an option'
|
|
167
166
|
value={series.stageColumn}
|
|
168
167
|
label='Add Forecasting Stages'
|
|
169
|
-
|
|
168
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
170
169
|
let stageObjects = []
|
|
171
|
-
let tempGroups = new Set(rawData?.map(item => item[
|
|
170
|
+
let tempGroups = new Set(rawData?.map(item => item[value])) // [estimate, forecast, etc.]
|
|
172
171
|
tempGroups = Array.from(tempGroups) // convert set to array
|
|
173
172
|
|
|
174
173
|
tempGroups = tempGroups.filter(group => group !== undefined) // removes undefined
|
|
@@ -176,7 +175,7 @@ const SeriesDropdownForecastingStage = props => {
|
|
|
176
175
|
tempGroups.forEach(group => stageObjects.push({ key: group }))
|
|
177
176
|
|
|
178
177
|
const copyOfSeries = [...config.series] // copy the entire series array
|
|
179
|
-
copyOfSeries[index] = { ...copyOfSeries[index], stages: stageObjects, stageColumn:
|
|
178
|
+
copyOfSeries[index] = { ...copyOfSeries[index], stages: stageObjects, stageColumn: value }
|
|
180
179
|
|
|
181
180
|
updateConfig({
|
|
182
181
|
...config,
|
|
@@ -200,19 +199,19 @@ const SeriesDropdownForecastingColumn = props => {
|
|
|
200
199
|
if (!series.stageColumn) return
|
|
201
200
|
|
|
202
201
|
let tempGroups = new Set(rawData.map(item => item[series.stageColumn])) // [estimate, forecast, etc.]
|
|
203
|
-
|
|
202
|
+
let tempGroupsArray = Array.from(tempGroups) // convert set to array
|
|
204
203
|
|
|
205
|
-
|
|
204
|
+
tempGroupsArray = tempGroupsArray.filter(group => group !== undefined) // removes undefined
|
|
206
205
|
|
|
207
206
|
return (
|
|
208
|
-
<
|
|
207
|
+
<Select
|
|
209
208
|
initial='Select an option'
|
|
210
209
|
value={series.stageItem}
|
|
211
210
|
label='Forecasting Item Column'
|
|
212
|
-
|
|
213
|
-
updateSeries(index,
|
|
211
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
212
|
+
updateSeries(index, value, 'stageItem')
|
|
214
213
|
}}
|
|
215
|
-
options={
|
|
214
|
+
options={tempGroupsArray}
|
|
216
215
|
/>
|
|
217
216
|
)
|
|
218
217
|
}
|
|
@@ -229,17 +228,17 @@ const SeriesDropdownAxisPosition = props => {
|
|
|
229
228
|
return
|
|
230
229
|
}
|
|
231
230
|
return (
|
|
232
|
-
<
|
|
231
|
+
<Select
|
|
233
232
|
initial='Select an option'
|
|
234
233
|
value={series.axis ? series.axis : 'Left'}
|
|
235
234
|
label='Series Axis'
|
|
236
|
-
|
|
237
|
-
updateSeries(index,
|
|
238
|
-
}}
|
|
239
|
-
options={{
|
|
240
|
-
['Left']: 'Left',
|
|
241
|
-
['Right']: 'Right'
|
|
235
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
236
|
+
updateSeries(index, value, 'axis')
|
|
242
237
|
}}
|
|
238
|
+
options={[
|
|
239
|
+
{ value: 'Left', label: 'Left' },
|
|
240
|
+
{ value: 'Right', label: 'Right' }
|
|
241
|
+
]}
|
|
243
242
|
/>
|
|
244
243
|
)
|
|
245
244
|
}
|
|
@@ -267,17 +266,23 @@ const SeriesDropdownForecastColor = props => {
|
|
|
267
266
|
|
|
268
267
|
// For dropdown options, only show version-specific palettes
|
|
269
268
|
const processedPalettes = updatePaletteNames(forecastPalettes)
|
|
270
|
-
const
|
|
269
|
+
const paletteOptionsObject = buildForecastPaletteOptions(processedPalettes, paletteVersion)
|
|
270
|
+
|
|
271
|
+
// Convert object to array format for Select component
|
|
272
|
+
const paletteOptions = Object.entries(paletteOptionsObject).map(([value, label]) => ({
|
|
273
|
+
value,
|
|
274
|
+
label
|
|
275
|
+
}))
|
|
271
276
|
|
|
272
277
|
return series?.stages?.map((stage, stageIndex) => (
|
|
273
|
-
<
|
|
278
|
+
<Select
|
|
274
279
|
key={`${stage}--${stageIndex}`}
|
|
275
280
|
initial='Select an option'
|
|
276
281
|
value={config.series?.[index].stages?.[stageIndex].color || 'Select'}
|
|
277
282
|
label={`${stage.key} Series Color`}
|
|
278
|
-
|
|
283
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
279
284
|
if (handleForecastPaletteSelection) {
|
|
280
|
-
handleForecastPaletteSelection(
|
|
285
|
+
handleForecastPaletteSelection(value, index, stageIndex)
|
|
281
286
|
}
|
|
282
287
|
}}
|
|
283
288
|
options={paletteOptions}
|
|
@@ -325,7 +330,7 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
325
330
|
</>
|
|
326
331
|
</AccordionItemHeading>
|
|
327
332
|
<AccordionItemPanel>
|
|
328
|
-
<
|
|
333
|
+
<Select
|
|
329
334
|
initial='Select an option'
|
|
330
335
|
value={
|
|
331
336
|
config.series[index].confidenceIntervals[ciIndex].low
|
|
@@ -333,9 +338,9 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
333
338
|
: 'Select'
|
|
334
339
|
}
|
|
335
340
|
label='Low Confidence Interval'
|
|
336
|
-
|
|
341
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
337
342
|
const copiedConfidenceArray = [...config.series[index].confidenceIntervals]
|
|
338
|
-
copiedConfidenceArray[ciIndex].low =
|
|
343
|
+
copiedConfidenceArray[ciIndex].low = value
|
|
339
344
|
const copyOfSeries = [...config.series] // copy the entire series array
|
|
340
345
|
copyOfSeries[index] = { ...copyOfSeries[index], confidenceIntervals: copiedConfidenceArray }
|
|
341
346
|
updateConfig({
|
|
@@ -345,7 +350,7 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
345
350
|
}}
|
|
346
351
|
options={getColumns()}
|
|
347
352
|
/>
|
|
348
|
-
<
|
|
353
|
+
<Select
|
|
349
354
|
initial='Select an option'
|
|
350
355
|
value={
|
|
351
356
|
config.series[index].confidenceIntervals[ciIndex].high
|
|
@@ -353,9 +358,9 @@ const SeriesDropdownConfidenceInterval = props => {
|
|
|
353
358
|
: 'Select'
|
|
354
359
|
}
|
|
355
360
|
label='High Confidence Interval'
|
|
356
|
-
|
|
361
|
+
updateField={(_section, _subsection, _fieldName, value) => {
|
|
357
362
|
const copiedConfidenceArray = [...config.series[index].confidenceIntervals]
|
|
358
|
-
copiedConfidenceArray[ciIndex].high =
|
|
363
|
+
copiedConfidenceArray[ciIndex].high = value
|
|
359
364
|
const copyOfSeries = [...config.series] // copy the entire series array
|
|
360
365
|
copyOfSeries[index] = { ...copyOfSeries[index], confidenceIntervals: copiedConfidenceArray }
|
|
361
366
|
updateConfig({
|