@cdc/chart 4.24.9-1 → 4.24.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/dist/cdcchart.js +37673 -36530
- package/index.html +1 -1
- package/package.json +2 -2
- package/src/CdcChart.tsx +128 -106
- package/src/_stories/Chart.Legend.Gradient.stories.tsx +33 -0
- package/src/_stories/Chart.stories.tsx +28 -0
- package/src/_stories/ChartAxisLabels.stories.tsx +20 -0
- package/src/_stories/ChartAxisTitles.stories.tsx +53 -0
- package/src/_stories/ChartPrefixSuffix.stories.tsx +151 -0
- package/src/_stories/_mock/horizontal_bar.json +257 -0
- package/src/_stories/_mock/large_x_axis_labels.json +261 -0
- package/src/_stories/_mock/paired-bar.json +262 -0
- package/src/_stories/_mock/pie_with_data.json +255 -0
- package/src/_stories/_mock/simplified_line.json +1510 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +0 -3
- package/src/components/Annotations/components/AnnotationDropdown.tsx +1 -1
- package/src/components/Axis/Categorical.Axis.tsx +22 -4
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +95 -16
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +41 -17
- package/src/components/BarChart/components/BarChart.Vertical.tsx +78 -20
- package/src/components/BarChart/helpers/index.ts +23 -4
- package/src/components/BrushChart.tsx +3 -2
- package/src/components/DeviationBar.jsx +58 -8
- package/src/components/EditorPanel/EditorPanel.tsx +62 -39
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +6 -23
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +21 -4
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +297 -35
- package/src/components/EditorPanel/components/panels.scss +4 -6
- package/src/components/EditorPanel/editor-panel.scss +0 -8
- package/src/components/EditorPanel/helpers/tests/updateFieldRankByValue.test.ts +38 -0
- package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +42 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +1 -0
- package/src/components/ForestPlot/ForestPlot.tsx +2 -3
- package/src/components/ForestPlot/ForestPlotProps.ts +2 -0
- package/src/components/Legend/Legend.Component.tsx +16 -16
- package/src/components/Legend/Legend.Suppression.tsx +25 -20
- package/src/components/Legend/Legend.tsx +0 -2
- package/src/components/Legend/helpers/index.ts +16 -19
- package/src/components/LegendWrapper.tsx +3 -1
- package/src/components/LinearChart.tsx +740 -562
- package/src/components/PairedBarChart.jsx +50 -10
- package/src/components/PieChart/PieChart.tsx +1 -6
- package/src/components/Regions/components/Regions.tsx +33 -19
- package/src/components/ZoomBrush.tsx +25 -6
- package/src/coreStyles_chart.scss +3 -0
- package/src/data/initial-state.js +6 -2
- package/src/helpers/configHelpers.ts +28 -0
- package/src/helpers/handleRankByValue.ts +15 -0
- package/src/helpers/sizeHelpers.ts +25 -0
- package/src/helpers/tests/handleRankByValue.test.ts +37 -0
- package/src/helpers/tests/sizeHelpers.test.ts +80 -0
- package/src/hooks/useColorPalette.js +10 -2
- package/src/hooks/useLegendClasses.ts +4 -0
- package/src/hooks/useScales.ts +31 -3
- package/src/hooks/useTooltip.tsx +9 -5
- package/src/index.jsx +1 -0
- package/src/scss/DataTable.scss +5 -4
- package/src/scss/main.scss +57 -52
- package/src/types/ChartConfig.ts +38 -16
- package/src/types/ChartContext.ts +18 -14
- package/src/_stories/Chart.Legend.Gradient.tsx +0 -19
- package/src/_stories/ChartBrush.stories.tsx +0 -19
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { useContext, FC } from 'react'
|
|
2
2
|
|
|
3
3
|
// external libraries
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
AccordionItem,
|
|
6
|
+
AccordionItemHeading,
|
|
7
|
+
AccordionItemPanel,
|
|
8
|
+
AccordionItemButton
|
|
9
|
+
} from 'react-accessible-accordion'
|
|
5
10
|
|
|
6
11
|
// core
|
|
7
12
|
import { TextField, Select, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
@@ -22,9 +27,21 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
22
27
|
const { config, updateConfig, colorPalettes, twoColorPalette } = useContext<ChartContext>(ConfigContext)
|
|
23
28
|
const { visual } = config
|
|
24
29
|
const { setLollipopShape, updateField } = useEditorPanelContext()
|
|
25
|
-
const {
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
const {
|
|
31
|
+
visHasBarBorders,
|
|
32
|
+
visCanAnimate,
|
|
33
|
+
visSupportsNonSequentialPallete,
|
|
34
|
+
headerColors,
|
|
35
|
+
visSupportsTooltipOpacity,
|
|
36
|
+
visSupportsTooltipLines,
|
|
37
|
+
visSupportsBarSpace,
|
|
38
|
+
visSupportsBarThickness,
|
|
39
|
+
visHasDataCutoff,
|
|
40
|
+
visSupportsSequentialPallete,
|
|
41
|
+
visSupportsReverseColorPalette,
|
|
42
|
+
visHasSingleSeriesTooltip
|
|
43
|
+
} = useEditorPermissions()
|
|
44
|
+
const { twoColorPalettes, sequential, nonSequential, accessibleColors } = useColorPalette(config, updateConfig)
|
|
28
45
|
|
|
29
46
|
const updateColor = (property, _value) => {
|
|
30
47
|
console.log('value', _value)
|
|
@@ -76,26 +93,98 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
76
93
|
</label>
|
|
77
94
|
</div>
|
|
78
95
|
</fieldset>
|
|
79
|
-
<Select
|
|
80
|
-
|
|
96
|
+
<Select
|
|
97
|
+
value={config.lollipopColorStyle ? config.lollipopColorStyle : 'two-tone'}
|
|
98
|
+
fieldName='lollipopColorStyle'
|
|
99
|
+
label='Lollipop Color Style'
|
|
100
|
+
updateField={updateField}
|
|
101
|
+
options={['regular', 'two-tone']}
|
|
102
|
+
/>
|
|
103
|
+
<Select
|
|
104
|
+
value={config.lollipopSize ? config.lollipopSize : 'small'}
|
|
105
|
+
fieldName='lollipopSize'
|
|
106
|
+
label='Lollipop Size'
|
|
107
|
+
updateField={updateField}
|
|
108
|
+
options={['small', 'medium', 'large']}
|
|
109
|
+
/>
|
|
81
110
|
</>
|
|
82
111
|
)}
|
|
83
112
|
{config.visualizationType === 'Box Plot' && (
|
|
84
113
|
<fieldset className='fieldset fieldset--boxplot'>
|
|
85
114
|
<legend className=''>Box Plot Settings</legend>
|
|
86
|
-
<Select
|
|
87
|
-
|
|
88
|
-
|
|
115
|
+
<Select
|
|
116
|
+
value={config.boxplot.borders}
|
|
117
|
+
fieldName='borders'
|
|
118
|
+
section='boxplot'
|
|
119
|
+
label='Box Plot Borders'
|
|
120
|
+
updateField={updateField}
|
|
121
|
+
options={['true', 'false']}
|
|
122
|
+
/>
|
|
123
|
+
<CheckBox
|
|
124
|
+
value={config.boxplot.plotOutlierValues}
|
|
125
|
+
fieldName='plotOutlierValues'
|
|
126
|
+
section='boxplot'
|
|
127
|
+
label='Plot Outliers'
|
|
128
|
+
updateField={updateField}
|
|
129
|
+
/>
|
|
130
|
+
<CheckBox
|
|
131
|
+
value={config.boxplot.plotNonOutlierValues}
|
|
132
|
+
fieldName='plotNonOutlierValues'
|
|
133
|
+
section='boxplot'
|
|
134
|
+
label='Plot non-outlier values'
|
|
135
|
+
updateField={updateField}
|
|
136
|
+
/>
|
|
89
137
|
</fieldset>
|
|
90
138
|
)}
|
|
91
|
-
<Select
|
|
92
|
-
|
|
93
|
-
|
|
139
|
+
<Select
|
|
140
|
+
value={config.fontSize}
|
|
141
|
+
fieldName='fontSize'
|
|
142
|
+
label='Font Size'
|
|
143
|
+
updateField={updateField}
|
|
144
|
+
options={['small', 'medium', 'large']}
|
|
145
|
+
/>
|
|
146
|
+
{visHasBarBorders() && (
|
|
147
|
+
<Select
|
|
148
|
+
value={config.barHasBorder}
|
|
149
|
+
fieldName='barHasBorder'
|
|
150
|
+
label='Bar Borders'
|
|
151
|
+
updateField={updateField}
|
|
152
|
+
options={['true', 'false']}
|
|
153
|
+
/>
|
|
154
|
+
)}
|
|
155
|
+
{visCanAnimate() && (
|
|
156
|
+
<CheckBox
|
|
157
|
+
value={config.animate}
|
|
158
|
+
fieldName='animate'
|
|
159
|
+
label='Animate Visualization'
|
|
160
|
+
updateField={updateField}
|
|
161
|
+
/>
|
|
162
|
+
)}
|
|
94
163
|
{/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
|
|
95
|
-
{((config.series?.some(
|
|
164
|
+
{((config.series?.some(
|
|
165
|
+
series =>
|
|
166
|
+
series.type === 'Line' ||
|
|
167
|
+
series.type === 'dashed-lg' ||
|
|
168
|
+
series.type === 'dashed-sm' ||
|
|
169
|
+
series.type === 'dashed-md'
|
|
170
|
+
) &&
|
|
171
|
+
config.visualizationType === 'Combo') ||
|
|
172
|
+
config.visualizationType === 'Line') && (
|
|
96
173
|
<>
|
|
97
|
-
<Select
|
|
98
|
-
|
|
174
|
+
<Select
|
|
175
|
+
value={config.lineDatapointStyle}
|
|
176
|
+
fieldName='lineDatapointStyle'
|
|
177
|
+
label='Line Datapoint Style'
|
|
178
|
+
updateField={updateField}
|
|
179
|
+
options={['hidden', 'hover', 'always show']}
|
|
180
|
+
/>
|
|
181
|
+
<Select
|
|
182
|
+
value={config.lineDatapointColor}
|
|
183
|
+
fieldName='lineDatapointColor'
|
|
184
|
+
label='Line Datapoint Color'
|
|
185
|
+
updateField={updateField}
|
|
186
|
+
options={['Same as Line', 'Lighter than Line']}
|
|
187
|
+
/>
|
|
99
188
|
</>
|
|
100
189
|
)}
|
|
101
190
|
{/* eslint-disable */}
|
|
@@ -121,7 +210,15 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
121
210
|
<label>
|
|
122
211
|
<span className='edit-label'>Chart Color Palette</span>
|
|
123
212
|
</label>
|
|
124
|
-
{visSupportsReverseColorPalette() &&
|
|
213
|
+
{visSupportsReverseColorPalette() && (
|
|
214
|
+
<InputToggle
|
|
215
|
+
fieldName='isPaletteReversed'
|
|
216
|
+
size='small'
|
|
217
|
+
label='Use selected palette in reverse order'
|
|
218
|
+
updateField={updateField}
|
|
219
|
+
value={config.isPaletteReversed}
|
|
220
|
+
/>
|
|
221
|
+
)}
|
|
125
222
|
{visSupportsSequentialPallete() && (
|
|
126
223
|
<>
|
|
127
224
|
<span>Sequential</span>
|
|
@@ -175,6 +272,38 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
175
272
|
backgroundColor: colorPalettes[palette][6]
|
|
176
273
|
}
|
|
177
274
|
|
|
275
|
+
return (
|
|
276
|
+
<button
|
|
277
|
+
title={palette}
|
|
278
|
+
key={palette}
|
|
279
|
+
onClick={e => {
|
|
280
|
+
e.preventDefault()
|
|
281
|
+
updateConfig({ ...config, palette })
|
|
282
|
+
}}
|
|
283
|
+
className={config.palette === palette ? 'selected' : ''}
|
|
284
|
+
>
|
|
285
|
+
<span style={colorOne}></span>
|
|
286
|
+
<span style={colorTwo}></span>
|
|
287
|
+
<span style={colorThree}></span>
|
|
288
|
+
</button>
|
|
289
|
+
)
|
|
290
|
+
})}
|
|
291
|
+
</ul>
|
|
292
|
+
<span>Colorblind Safe</span>
|
|
293
|
+
<ul className='color-palette'>
|
|
294
|
+
{accessibleColors.map(palette => {
|
|
295
|
+
const colorOne = {
|
|
296
|
+
backgroundColor: colorPalettes[palette][2]
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const colorTwo = {
|
|
300
|
+
backgroundColor: colorPalettes[palette][3]
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const colorThree = {
|
|
304
|
+
backgroundColor: colorPalettes[palette][5]
|
|
305
|
+
}
|
|
306
|
+
|
|
178
307
|
return (
|
|
179
308
|
<button
|
|
180
309
|
title={palette}
|
|
@@ -199,22 +328,47 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
199
328
|
{config.visualizationType === 'Sankey' && (
|
|
200
329
|
<>
|
|
201
330
|
<span className='sankey__color-input'>
|
|
202
|
-
<input
|
|
331
|
+
<input
|
|
332
|
+
type='color'
|
|
333
|
+
value={config.sankey.nodeColor.default}
|
|
334
|
+
id='storyNodeColor'
|
|
335
|
+
name='storyNodeColor'
|
|
336
|
+
onChange={e => updateColor('nodeColor', e.target.value)}
|
|
337
|
+
/>
|
|
203
338
|
<label htmlFor='storyNodeColor'>Story Node Color</label>
|
|
204
339
|
</span>
|
|
205
340
|
<span className='sankey__color-input'>
|
|
206
|
-
<input
|
|
341
|
+
<input
|
|
342
|
+
type='color'
|
|
343
|
+
value={config.sankey.storyNodeFontColor || 'red'}
|
|
344
|
+
id='storyNodeFontColor'
|
|
345
|
+
name='storyNodeFontColor'
|
|
346
|
+
onChange={e => updateColor('storyNodeFontColor', e.target.value)}
|
|
347
|
+
/>
|
|
207
348
|
<label htmlFor='storyNodeFontColor'>Story Node Font Color</label>
|
|
208
349
|
</span>
|
|
209
350
|
<span className='sankey__color-input'>
|
|
210
|
-
<input
|
|
351
|
+
<input
|
|
352
|
+
type='color'
|
|
353
|
+
value={config.sankey.linkColor.default}
|
|
354
|
+
id='linkColor'
|
|
355
|
+
name='linkColor'
|
|
356
|
+
onChange={e => updateColor('linkColor', e.target.value)}
|
|
357
|
+
/>
|
|
211
358
|
<label htmlFor='linkColor'>Link Color</label>
|
|
212
359
|
</span>
|
|
213
360
|
</>
|
|
214
361
|
)}
|
|
215
362
|
{(config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') && (
|
|
216
363
|
<>
|
|
217
|
-
<InputToggle
|
|
364
|
+
<InputToggle
|
|
365
|
+
section='twoColor'
|
|
366
|
+
fieldName='isPaletteReversed'
|
|
367
|
+
size='small'
|
|
368
|
+
label='Use selected palette in reverse order'
|
|
369
|
+
updateField={updateField}
|
|
370
|
+
value={config.twoColor.isPaletteReversed}
|
|
371
|
+
/>
|
|
218
372
|
<ul className='color-palette'>
|
|
219
373
|
{twoColorPalettes.map(palette => {
|
|
220
374
|
const colorOne = {
|
|
@@ -258,32 +412,132 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
258
412
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
259
413
|
</Tooltip.Target>
|
|
260
414
|
<Tooltip.Content>
|
|
261
|
-
<p>
|
|
415
|
+
<p>
|
|
416
|
+
Any value below the cut-off value is included in a special "less than" category. This option
|
|
417
|
+
supports special conditions like suppressed data.
|
|
418
|
+
</p>
|
|
262
419
|
</Tooltip.Content>
|
|
263
420
|
</Tooltip>
|
|
264
421
|
}
|
|
265
422
|
/>
|
|
266
423
|
</>
|
|
267
424
|
)}
|
|
268
|
-
{visSupportsBarThickness() &&
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
425
|
+
{visSupportsBarThickness() &&
|
|
426
|
+
config.orientation === 'horizontal' &&
|
|
427
|
+
!config.isLollipopChart &&
|
|
428
|
+
config.yAxis.labelPlacement !== 'On Bar' && (
|
|
429
|
+
<TextField
|
|
430
|
+
type='number'
|
|
431
|
+
value={config.barHeight || '25'}
|
|
432
|
+
fieldName='barHeight'
|
|
433
|
+
label=' Bar Thickness'
|
|
434
|
+
updateField={updateField}
|
|
435
|
+
min={15}
|
|
436
|
+
/>
|
|
437
|
+
)}
|
|
438
|
+
{((config.visualizationType === 'Bar' && config.orientation !== 'horizontal') ||
|
|
439
|
+
config.visualizationType === 'Combo') && (
|
|
440
|
+
<TextField
|
|
441
|
+
value={config.barThickness}
|
|
442
|
+
type='number'
|
|
443
|
+
fieldName='barThickness'
|
|
444
|
+
label='Bar Thickness'
|
|
445
|
+
updateField={updateField}
|
|
446
|
+
/>
|
|
447
|
+
)}
|
|
448
|
+
{visSupportsBarSpace() && (
|
|
449
|
+
<TextField
|
|
450
|
+
type='number'
|
|
451
|
+
value={config.barSpace || '15'}
|
|
452
|
+
fieldName='barSpace'
|
|
453
|
+
label='Bar Space'
|
|
454
|
+
updateField={updateField}
|
|
455
|
+
min={0}
|
|
456
|
+
/>
|
|
457
|
+
)}
|
|
458
|
+
{(config.visualizationType === 'Bar' ||
|
|
459
|
+
config.visualizationType === 'Line' ||
|
|
460
|
+
config.visualizationType === 'Combo') && (
|
|
461
|
+
<CheckBox
|
|
462
|
+
value={config.topAxis.hasLine}
|
|
463
|
+
section='topAxis'
|
|
464
|
+
fieldName='hasLine'
|
|
465
|
+
label='Add Top Axis Line'
|
|
466
|
+
updateField={updateField}
|
|
467
|
+
/>
|
|
468
|
+
)}
|
|
272
469
|
{config.visualizationType === 'Spark Line' && (
|
|
273
470
|
<div className='cove-accordion__panel-section checkbox-group'>
|
|
274
|
-
<CheckBox
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
471
|
+
<CheckBox
|
|
472
|
+
value={visual?.border}
|
|
473
|
+
section='visual'
|
|
474
|
+
fieldName='border'
|
|
475
|
+
label='Show Border'
|
|
476
|
+
updateField={updateField}
|
|
477
|
+
/>
|
|
478
|
+
<CheckBox
|
|
479
|
+
value={visual?.borderColorTheme}
|
|
480
|
+
section='visual'
|
|
481
|
+
fieldName='borderColorTheme'
|
|
482
|
+
label='Use Border Color Theme'
|
|
483
|
+
updateField={updateField}
|
|
484
|
+
/>
|
|
485
|
+
<CheckBox
|
|
486
|
+
value={visual?.accent}
|
|
487
|
+
section='visual'
|
|
488
|
+
fieldName='accent'
|
|
489
|
+
label='Use Accent Style'
|
|
490
|
+
updateField={updateField}
|
|
491
|
+
/>
|
|
492
|
+
<CheckBox
|
|
493
|
+
value={visual?.background}
|
|
494
|
+
section='visual'
|
|
495
|
+
fieldName='background'
|
|
496
|
+
label='Use Theme Background Color'
|
|
497
|
+
updateField={updateField}
|
|
498
|
+
/>
|
|
499
|
+
<CheckBox
|
|
500
|
+
value={visual?.hideBackgroundColor}
|
|
501
|
+
section='visual'
|
|
502
|
+
fieldName='hideBackgroundColor'
|
|
503
|
+
label='Hide Background Color'
|
|
504
|
+
updateField={updateField}
|
|
505
|
+
/>
|
|
279
506
|
</div>
|
|
280
507
|
)}
|
|
281
|
-
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') &&
|
|
282
|
-
|
|
508
|
+
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && (
|
|
509
|
+
<CheckBox
|
|
510
|
+
value={config.showLineSeriesLabels}
|
|
511
|
+
fieldName='showLineSeriesLabels'
|
|
512
|
+
label='Append Series Name to End of Line Charts'
|
|
513
|
+
updateField={updateField}
|
|
514
|
+
/>
|
|
515
|
+
)}
|
|
516
|
+
{(config.visualizationType === 'Line' || config.visualizationType === 'Combo') &&
|
|
517
|
+
config.showLineSeriesLabels && (
|
|
518
|
+
<CheckBox
|
|
519
|
+
value={config.colorMatchLineSeriesLabels}
|
|
520
|
+
fieldName='colorMatchLineSeriesLabels'
|
|
521
|
+
label='Match Series Color to Name at End of Line Charts'
|
|
522
|
+
updateField={updateField}
|
|
523
|
+
/>
|
|
524
|
+
)}
|
|
283
525
|
{visSupportsTooltipLines() && (
|
|
284
526
|
<>
|
|
285
|
-
<CheckBox
|
|
286
|
-
|
|
527
|
+
<CheckBox
|
|
528
|
+
value={visual.verticalHoverLine}
|
|
529
|
+
fieldName='verticalHoverLine'
|
|
530
|
+
section='visual'
|
|
531
|
+
label='Vertical Hover Line'
|
|
532
|
+
updateField={updateField}
|
|
533
|
+
/>
|
|
534
|
+
<CheckBox
|
|
535
|
+
value={visual.horizontalHoverLine}
|
|
536
|
+
fieldName='horizontalHoverLine'
|
|
537
|
+
section='visual'
|
|
538
|
+
label='Horizontal Hover Line'
|
|
539
|
+
updateField={updateField}
|
|
540
|
+
/>
|
|
287
541
|
</>
|
|
288
542
|
)}
|
|
289
543
|
{visSupportsTooltipOpacity() && (
|
|
@@ -304,7 +558,15 @@ const PanelVisual: FC<PanelProps> = props => {
|
|
|
304
558
|
/>
|
|
305
559
|
</label>
|
|
306
560
|
)}
|
|
307
|
-
{visHasSingleSeriesTooltip() &&
|
|
561
|
+
{visHasSingleSeriesTooltip() && (
|
|
562
|
+
<CheckBox
|
|
563
|
+
value={config.tooltips.singleSeries}
|
|
564
|
+
fieldName='singleSeries'
|
|
565
|
+
section='tooltips'
|
|
566
|
+
label='SHOW HOVER FOR SINGLE DATA SERIES'
|
|
567
|
+
updateField={updateField}
|
|
568
|
+
/>
|
|
569
|
+
)}
|
|
308
570
|
<label>
|
|
309
571
|
<span className='edit-label column-heading'>No Data Message</span>
|
|
310
572
|
<input
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
@import '@cdc/core/styles/v2/themes/color-definitions';
|
|
2
|
-
|
|
3
1
|
.date-highlight {
|
|
4
2
|
select,
|
|
5
3
|
input {
|
|
6
|
-
background:
|
|
4
|
+
background: var(--lightestGray);
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
&__day-selection {
|
|
@@ -15,17 +13,17 @@
|
|
|
15
13
|
.week-button {
|
|
16
14
|
margin-bottom: 0;
|
|
17
15
|
border-radius: 50%;
|
|
18
|
-
color:
|
|
16
|
+
color: var(--darkGray);
|
|
19
17
|
width: 24px;
|
|
20
18
|
height: 24px;
|
|
21
19
|
display: flex;
|
|
22
20
|
align-items: center;
|
|
23
21
|
justify-content: center;
|
|
24
|
-
background:
|
|
22
|
+
background: var(--lightestGray);
|
|
25
23
|
margin: 5px 2px 0;
|
|
26
24
|
|
|
27
25
|
&--active {
|
|
28
|
-
background:
|
|
26
|
+
background: var(--primary);
|
|
29
27
|
color: white;
|
|
30
28
|
}
|
|
31
29
|
}
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
@import '@cdc/core/styles/base';
|
|
2
|
-
@import '@cdc/core/styles/v2/themes/color-definitions';
|
|
3
|
-
|
|
4
|
-
//TODO: Remove after COVE refactor
|
|
5
|
-
.cove {
|
|
6
|
-
@import '@cdc/core/styles/v2/layout/tooltip.scss';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
1
|
.cdc-open-viz-module.type-chart {
|
|
10
2
|
.viewport-overrides {
|
|
11
3
|
button {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { updateFieldRankByValue } from '../updateFieldRankByValue'
|
|
2
|
+
|
|
3
|
+
describe('updateFieldRankByValue', () => {
|
|
4
|
+
it('should update rankByValue to "asc" and return new config', () => {
|
|
5
|
+
const config = { rankByValue: undefined }
|
|
6
|
+
const newValue = 'asc'
|
|
7
|
+
const preTransformedData = [{ value: 3 }, { value: 1 }, { value: 2 }]
|
|
8
|
+
|
|
9
|
+
const [newConfig] = updateFieldRankByValue(config, newValue, preTransformedData)
|
|
10
|
+
|
|
11
|
+
expect(newConfig.rankByValue).toBe('asc')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('should return new config and sorted data when newValue is undefined and config.rankByValue is set', () => {
|
|
15
|
+
const config = {
|
|
16
|
+
rankByValue: 'asc',
|
|
17
|
+
data: [{ value: 1 }, { value: 2 }, { value: 3 }],
|
|
18
|
+
xAxis: { dataKey: 'value' }
|
|
19
|
+
}
|
|
20
|
+
const newValue = undefined
|
|
21
|
+
const preTransformedData = [{ value: 3 }, { value: 1 }, { value: 2 }]
|
|
22
|
+
|
|
23
|
+
const [newConfig, newData] = updateFieldRankByValue(config, newValue, preTransformedData)
|
|
24
|
+
|
|
25
|
+
expect(newConfig.rankByValue).toBeUndefined()
|
|
26
|
+
expect(newData).toEqual([{ value: 1 }, { value: 2 }, { value: 3 }])
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should return new config when newValue is undefined and config.rankByValue is not set', () => {
|
|
30
|
+
const config = { rankByValue: undefined }
|
|
31
|
+
const newValue = undefined
|
|
32
|
+
const preTransformedData = [{ value: 3 }, { value: 1 }, { value: 2 }]
|
|
33
|
+
|
|
34
|
+
const [newConfig] = updateFieldRankByValue(config, newValue, preTransformedData)
|
|
35
|
+
|
|
36
|
+
expect(newConfig.rankByValue).toBeUndefined()
|
|
37
|
+
})
|
|
38
|
+
})
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import DataTransform from '@cdc/core/helpers/DataTransform'
|
|
2
|
+
import { ChartConfig } from '../../../types/ChartConfig'
|
|
3
|
+
import _ from 'lodash'
|
|
4
|
+
|
|
5
|
+
const transform = new DataTransform()
|
|
6
|
+
|
|
7
|
+
const indexOfObj = (data, obj) => {
|
|
8
|
+
for (let i = 0; i < data.length; i++) {
|
|
9
|
+
let keys = Object.keys(data[i])
|
|
10
|
+
let equal = true
|
|
11
|
+
for (let j = 0; j < keys.length; j++) {
|
|
12
|
+
if (data[i][keys[j]] !== obj[keys[j]]) {
|
|
13
|
+
equal = false
|
|
14
|
+
break
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (equal) {
|
|
18
|
+
return i
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return -1
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const updateFieldRankByValue = (
|
|
25
|
+
config: ChartConfig,
|
|
26
|
+
newValue: 'asc' | 'desc' | undefined,
|
|
27
|
+
preTransformedData: Object[]
|
|
28
|
+
): [ChartConfig, Object[]?] => {
|
|
29
|
+
const newConfig = _.cloneDeep(config)
|
|
30
|
+
newConfig.rankByValue = newValue
|
|
31
|
+
|
|
32
|
+
if (config.rankByValue && !newValue) {
|
|
33
|
+
const cleanData = config?.xAxis?.dataKey ? transform.cleanData(config.data, config.xAxis.dataKey) : config.data
|
|
34
|
+
const newData = preTransformedData.sort((a, b) => {
|
|
35
|
+
const aIndex = indexOfObj(cleanData, a)
|
|
36
|
+
const bIndex = indexOfObj(cleanData, b)
|
|
37
|
+
return aIndex - bIndex
|
|
38
|
+
})
|
|
39
|
+
return [newConfig, newData]
|
|
40
|
+
}
|
|
41
|
+
return [newConfig]
|
|
42
|
+
}
|
|
@@ -337,6 +337,7 @@ export const useEditorPermissions = () => {
|
|
|
337
337
|
const visSupportsDateCategoryHeight = () => {
|
|
338
338
|
const disabledCharts = ['Spark Line', 'Sankey', 'Bump Chart']
|
|
339
339
|
if (disabledCharts.includes(visualizationType)) return false
|
|
340
|
+
if (config.orientation !== 'horizontal') return false
|
|
340
341
|
return true
|
|
341
342
|
}
|
|
342
343
|
|
|
@@ -16,9 +16,8 @@ import { type ChartContext } from '@cdc/chart/src/types/ChartContext'
|
|
|
16
16
|
import ConfigContext from '../../ConfigContext'
|
|
17
17
|
import { getFontSize } from '@cdc/core/helpers/cove/number'
|
|
18
18
|
|
|
19
|
-
const ForestPlot = (
|
|
19
|
+
const ForestPlot = ({ xScale, yScale, config, height, width, handleTooltipMouseOff, handleTooltipMouseOver, forestPlotRightLabelRef }: ForestPlotProps) => {
|
|
20
20
|
const { rawData: data, updateConfig } = useContext<ChartContext>(ConfigContext)
|
|
21
|
-
const { xScale, yScale, config, height, width, handleTooltipMouseOff, handleTooltipMouseOver } = props
|
|
22
21
|
const { forestPlot } = config as ChartConfig
|
|
23
22
|
const labelPosition = config.xAxis.tickWidthMax + 10
|
|
24
23
|
const [initialLogTicksSet, setInitialLogTicks] = useState(false)
|
|
@@ -243,7 +242,7 @@ const ForestPlot = (props: ForestPlotProps) => {
|
|
|
243
242
|
)}
|
|
244
243
|
|
|
245
244
|
{forestPlot.rightLabel && (
|
|
246
|
-
<Text className='forest-plot__right-label' x={forestPlot.type === 'Linear' ? xScale(0) + 25 : xScale(1) + 25} y={height + labelPosition} textAnchor='start' verticalAnchor='start'>
|
|
245
|
+
<Text innerRef={forestPlotRightLabelRef} className='forest-plot__right-label' x={forestPlot.type === 'Linear' ? xScale(0) + 25 : xScale(1) + 25} y={height + labelPosition} textAnchor='start' verticalAnchor='start'>
|
|
247
246
|
{forestPlot.rightLabel}
|
|
248
247
|
</Text>
|
|
249
248
|
)}
|
|
@@ -8,6 +8,8 @@ export type ForestPlotProps = {
|
|
|
8
8
|
/** config - standard chart config */
|
|
9
9
|
config: ChartConfig
|
|
10
10
|
/** height - height of chart */
|
|
11
|
+
/** forestPlotLeftLabelRef - ref for left label for resizing svg*/
|
|
12
|
+
forestPlotRightLabelRef: React.RefObject<SVGSVGElement>
|
|
11
13
|
height: number
|
|
12
14
|
/** width - width of chart */
|
|
13
15
|
width: number
|