@cdc/waffle-chart 4.25.2-25 → 4.25.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/cdcwafflechart.js +7247 -6959
- package/package.json +3 -3
- package/src/components/EditorPanel.jsx +272 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/waffle-chart",
|
|
3
|
-
"version": "4.25.
|
|
3
|
+
"version": "4.25.3",
|
|
4
4
|
"description": "React component for displaying a single piece of data in a card module",
|
|
5
5
|
"moduleName": "CdcWaffleChart",
|
|
6
6
|
"main": "dist/cdcwafflechart",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "Apache-2.0",
|
|
28
28
|
"homepage": "https://github.com/CDCgov/cdc-open-viz#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@cdc/core": "^4.25.
|
|
30
|
+
"@cdc/core": "^4.25.3",
|
|
31
31
|
"@visx/group": "^3.0.0",
|
|
32
32
|
"@visx/scale": "^3.0.0",
|
|
33
33
|
"@visx/shape": "^3.0.0",
|
|
@@ -42,5 +42,5 @@
|
|
|
42
42
|
"react": "^18.2.0",
|
|
43
43
|
"react-dom": "^18.2.0"
|
|
44
44
|
},
|
|
45
|
-
"gitHead": "
|
|
45
|
+
"gitHead": "b09566f5a7d57c8d0109e5f407257729d6b36846"
|
|
46
46
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect, memo, useContext } from 'react'
|
|
2
2
|
|
|
3
|
+
import _ from 'lodash'
|
|
3
4
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
4
5
|
|
|
5
6
|
import ConfigContext from '../ConfigContext'
|
|
@@ -19,23 +20,37 @@ import WarningImage from '../images/warning.svg'
|
|
|
19
20
|
|
|
20
21
|
import { DATA_OPERATORS, DATA_FUNCTIONS } from '../CdcWaffleChart'
|
|
21
22
|
|
|
22
|
-
const headerColors = [
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
const headerColors = [
|
|
24
|
+
'theme-blue',
|
|
25
|
+
'theme-purple',
|
|
26
|
+
'theme-brown',
|
|
27
|
+
'theme-teal',
|
|
28
|
+
'theme-pink',
|
|
29
|
+
'theme-orange',
|
|
30
|
+
'theme-slate',
|
|
31
|
+
'theme-indigo',
|
|
32
|
+
'theme-cyan',
|
|
33
|
+
'theme-green',
|
|
34
|
+
'theme-amber'
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
const CheckBox = memo(
|
|
38
|
+
({ label, value, fieldName, section = null, subsection = null, tooltip, updateField, ...attributes }) => (
|
|
39
|
+
<label className='checkbox'>
|
|
40
|
+
<input
|
|
41
|
+
type='checkbox'
|
|
42
|
+
name={fieldName}
|
|
43
|
+
checked={value}
|
|
44
|
+
onChange={() => {
|
|
45
|
+
updateField(section, subsection, fieldName, !value)
|
|
46
|
+
}}
|
|
47
|
+
{...attributes}
|
|
48
|
+
/>
|
|
49
|
+
<span className='edit-label column-heading'>{label}</span>
|
|
50
|
+
<span className='cove-icon'>{tooltip}</span>
|
|
51
|
+
</label>
|
|
52
|
+
)
|
|
53
|
+
)
|
|
39
54
|
|
|
40
55
|
const EditorPanel = memo(props => {
|
|
41
56
|
const { config, updateConfig, loading, data, setParentConfig, isDashboard } = useContext(ConfigContext)
|
|
@@ -93,7 +108,7 @@ const EditorPanel = memo(props => {
|
|
|
93
108
|
}
|
|
94
109
|
|
|
95
110
|
const convertStateToConfig = () => {
|
|
96
|
-
let strippedState =
|
|
111
|
+
let strippedState = _.cloneDeep(config)
|
|
97
112
|
delete strippedState.newViz
|
|
98
113
|
delete strippedState.runtime
|
|
99
114
|
|
|
@@ -148,11 +163,33 @@ const EditorPanel = memo(props => {
|
|
|
148
163
|
<Accordion.Section title='General'>
|
|
149
164
|
<div className='cove-accordion__panel-section'>
|
|
150
165
|
<div style={{ width: '100%', display: 'block' }} className='cove-input-group'>
|
|
151
|
-
<InputSelect
|
|
152
|
-
|
|
166
|
+
<InputSelect
|
|
167
|
+
value={config.visualizationType}
|
|
168
|
+
fieldName='visualizationType'
|
|
169
|
+
label='Chart Type'
|
|
170
|
+
updateField={updateField}
|
|
171
|
+
options={approvedWaffleChartOptions}
|
|
172
|
+
className='cove-input'
|
|
173
|
+
/>
|
|
174
|
+
{config.visualizationType === 'Gauge' && (
|
|
175
|
+
<InputSelect
|
|
176
|
+
value={config.visualizationSubType}
|
|
177
|
+
fieldName='visualizationSubType'
|
|
178
|
+
label='Chart Subtype'
|
|
179
|
+
updateField={updateField}
|
|
180
|
+
options={['Linear']}
|
|
181
|
+
className='cove-input'
|
|
182
|
+
/>
|
|
183
|
+
)}
|
|
153
184
|
</div>
|
|
154
185
|
</div>
|
|
155
|
-
<InputText
|
|
186
|
+
<InputText
|
|
187
|
+
value={config.title}
|
|
188
|
+
fieldName='title'
|
|
189
|
+
label='Title'
|
|
190
|
+
placeholder='Chart Title'
|
|
191
|
+
updateField={updateField}
|
|
192
|
+
/>
|
|
156
193
|
<InputText
|
|
157
194
|
type='textarea'
|
|
158
195
|
value={config.content}
|
|
@@ -165,7 +202,10 @@ const EditorPanel = memo(props => {
|
|
|
165
202
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
166
203
|
</Tooltip.Target>
|
|
167
204
|
<Tooltip.Content>
|
|
168
|
-
<p>
|
|
205
|
+
<p>
|
|
206
|
+
Enter the message text for the visualization. The following HTML tags are supported: strong, em, sup,
|
|
207
|
+
and sub.
|
|
208
|
+
</p>
|
|
169
209
|
</Tooltip.Content>
|
|
170
210
|
</Tooltip>
|
|
171
211
|
}
|
|
@@ -183,22 +223,46 @@ const EditorPanel = memo(props => {
|
|
|
183
223
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
184
224
|
</Tooltip.Target>
|
|
185
225
|
<Tooltip.Content>
|
|
186
|
-
<p>
|
|
226
|
+
<p>
|
|
227
|
+
Enter supporting text to display below the data visualization, if applicable. The following HTML tags
|
|
228
|
+
are supported: strong, em, sup, and sub.
|
|
229
|
+
</p>
|
|
187
230
|
</Tooltip.Content>
|
|
188
231
|
</Tooltip>
|
|
189
232
|
}
|
|
190
233
|
/>
|
|
191
234
|
</Accordion.Section>
|
|
192
235
|
|
|
193
|
-
<Accordion.Section
|
|
236
|
+
<Accordion.Section
|
|
237
|
+
icon={!config.dataColumn || !config.dataFunction ? <WarningImage width='15' className='warning-icon' /> : ''}
|
|
238
|
+
title='Data'
|
|
239
|
+
>
|
|
194
240
|
<h4 style={{ fontWeight: '600' }}>Numerator</h4>
|
|
195
241
|
<div className='cove-accordion__panel-section'>
|
|
196
242
|
<div className='cove-input-group'>
|
|
197
|
-
<InputSelect
|
|
243
|
+
<InputSelect
|
|
244
|
+
style={inputSelectStyle(!config.dataColumn)}
|
|
245
|
+
value={config.dataColumn || ''}
|
|
246
|
+
fieldName='dataColumn'
|
|
247
|
+
label='Data Column'
|
|
248
|
+
updateField={updateField}
|
|
249
|
+
initial='Select'
|
|
250
|
+
options={getColumns()}
|
|
251
|
+
className='cove-input'
|
|
252
|
+
/>
|
|
198
253
|
</div>
|
|
199
254
|
|
|
200
255
|
<div className='cove-input-group'>
|
|
201
|
-
<InputSelect
|
|
256
|
+
<InputSelect
|
|
257
|
+
style={inputSelectStyle(!config.dataFunction)}
|
|
258
|
+
value={config.dataFunction || ''}
|
|
259
|
+
fieldName='dataFunction'
|
|
260
|
+
label='Data Function'
|
|
261
|
+
updateField={updateField}
|
|
262
|
+
initial='Select'
|
|
263
|
+
options={DATA_FUNCTIONS}
|
|
264
|
+
className='cove-input'
|
|
265
|
+
/>
|
|
202
266
|
</div>
|
|
203
267
|
|
|
204
268
|
<div className='cove-input-group'>
|
|
@@ -207,18 +271,42 @@ const EditorPanel = memo(props => {
|
|
|
207
271
|
</label>
|
|
208
272
|
<div className='cove-accordion__panel-row cove-accordion__small-inputs'>
|
|
209
273
|
<div className='cove-accordion__panel-col'>
|
|
210
|
-
<InputSelect
|
|
274
|
+
<InputSelect
|
|
275
|
+
value={config.dataConditionalColumn || ''}
|
|
276
|
+
fieldName='dataConditionalColumn'
|
|
277
|
+
updateField={updateField}
|
|
278
|
+
initial='Select'
|
|
279
|
+
options={getColumns()}
|
|
280
|
+
className='cove-input'
|
|
281
|
+
/>
|
|
211
282
|
</div>
|
|
212
283
|
<div className='cove-accordion__panel-col'>
|
|
213
|
-
<InputSelect
|
|
284
|
+
<InputSelect
|
|
285
|
+
value={config.dataConditionalOperator || ''}
|
|
286
|
+
fieldName='dataConditionalOperator'
|
|
287
|
+
updateField={updateField}
|
|
288
|
+
initial='Select'
|
|
289
|
+
options={DATA_OPERATORS}
|
|
290
|
+
className='cove-input'
|
|
291
|
+
/>
|
|
214
292
|
</div>
|
|
215
293
|
<div className='cove-accordion__panel-col'>
|
|
216
|
-
<InputText
|
|
294
|
+
<InputText
|
|
295
|
+
value={config.dataConditionalComparate}
|
|
296
|
+
fieldName={'dataConditionalComparate'}
|
|
297
|
+
updateField={updateField}
|
|
298
|
+
className={config.invalidComparate ? 'cove-accordion__input-error' : ''}
|
|
299
|
+
style={{ minHeight: '2rem' }}
|
|
300
|
+
/>
|
|
217
301
|
</div>
|
|
218
302
|
</div>
|
|
219
303
|
</div>
|
|
220
304
|
|
|
221
|
-
{config.invalidComparate &&
|
|
305
|
+
{config.invalidComparate && (
|
|
306
|
+
<div className='cove-accordion__panel-error'>
|
|
307
|
+
Non-numerical comparate values can only be used with = or ≠.
|
|
308
|
+
</div>
|
|
309
|
+
)}
|
|
222
310
|
</div>
|
|
223
311
|
<div className='cove-accordion__panel-row align-center'>
|
|
224
312
|
<div className='cove-accordion__panel-col'>
|
|
@@ -227,7 +315,12 @@ const EditorPanel = memo(props => {
|
|
|
227
315
|
<div className='cove-accordion__panel-col'>
|
|
228
316
|
<div style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
229
317
|
<label className='cove-accordion__panel-label--inline'>Select from data</label>
|
|
230
|
-
<InputCheckbox
|
|
318
|
+
<InputCheckbox
|
|
319
|
+
size='small'
|
|
320
|
+
value={config.customDenom}
|
|
321
|
+
fieldName='customDenom'
|
|
322
|
+
updateField={updateField}
|
|
323
|
+
/>
|
|
231
324
|
</div>
|
|
232
325
|
</div>
|
|
233
326
|
</div>
|
|
@@ -244,8 +337,22 @@ const EditorPanel = memo(props => {
|
|
|
244
337
|
)}
|
|
245
338
|
{config.customDenom && (
|
|
246
339
|
<>
|
|
247
|
-
<InputSelect
|
|
248
|
-
|
|
340
|
+
<InputSelect
|
|
341
|
+
value={config.dataDenomColumn || ''}
|
|
342
|
+
fieldName='dataDenomColumn'
|
|
343
|
+
label='Data Column'
|
|
344
|
+
updateField={updateField}
|
|
345
|
+
initial='Select'
|
|
346
|
+
options={getColumns()}
|
|
347
|
+
/>
|
|
348
|
+
<InputSelect
|
|
349
|
+
value={config.dataDenomFunction || ''}
|
|
350
|
+
fieldName='dataDenomFunction'
|
|
351
|
+
label='Data Function'
|
|
352
|
+
updateField={updateField}
|
|
353
|
+
initial='Select'
|
|
354
|
+
options={DATA_FUNCTIONS}
|
|
355
|
+
/>
|
|
249
356
|
</>
|
|
250
357
|
)}
|
|
251
358
|
</div>
|
|
@@ -258,7 +365,13 @@ const EditorPanel = memo(props => {
|
|
|
258
365
|
<InputText value={config.suffix} fieldName='suffix' label='Suffix' updateField={updateField} />
|
|
259
366
|
</div>
|
|
260
367
|
<div>
|
|
261
|
-
<InputText
|
|
368
|
+
<InputText
|
|
369
|
+
type='number'
|
|
370
|
+
value={config.roundToPlace}
|
|
371
|
+
fieldName='roundToPlace'
|
|
372
|
+
label='Round'
|
|
373
|
+
updateField={updateField}
|
|
374
|
+
/>
|
|
262
375
|
</div>
|
|
263
376
|
</li>
|
|
264
377
|
</ul>
|
|
@@ -266,9 +379,30 @@ const EditorPanel = memo(props => {
|
|
|
266
379
|
<>
|
|
267
380
|
<hr className='cove-accordion__divider' />
|
|
268
381
|
<div className='cove-accordion__panel-section reverse-labels'>
|
|
269
|
-
<InputText
|
|
270
|
-
|
|
271
|
-
|
|
382
|
+
<InputText
|
|
383
|
+
inline
|
|
384
|
+
size='small'
|
|
385
|
+
value={config.valueDescription}
|
|
386
|
+
label='Value Descriptor'
|
|
387
|
+
fieldName='valueDescription'
|
|
388
|
+
updateField={updateField}
|
|
389
|
+
/>
|
|
390
|
+
<InputCheckbox
|
|
391
|
+
inline
|
|
392
|
+
size='small'
|
|
393
|
+
value={config.showPercent}
|
|
394
|
+
label='Show Percentage'
|
|
395
|
+
fieldName='showPercent'
|
|
396
|
+
updateField={updateField}
|
|
397
|
+
/>
|
|
398
|
+
<InputCheckbox
|
|
399
|
+
inline
|
|
400
|
+
size='small'
|
|
401
|
+
label='Show Denominator'
|
|
402
|
+
value={config.showDenominator}
|
|
403
|
+
fieldName='showDenominator'
|
|
404
|
+
updateField={updateField}
|
|
405
|
+
/>
|
|
272
406
|
</div>
|
|
273
407
|
</>
|
|
274
408
|
)}
|
|
@@ -279,7 +413,10 @@ const EditorPanel = memo(props => {
|
|
|
279
413
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
280
414
|
</Tooltip.Target>
|
|
281
415
|
<Tooltip.Content>
|
|
282
|
-
<p>
|
|
416
|
+
<p>
|
|
417
|
+
To refine the highlighted data point, specify one or more filters (e.g., "Male" and "Female" for a
|
|
418
|
+
column called "Sex").
|
|
419
|
+
</p>
|
|
283
420
|
</Tooltip.Content>
|
|
284
421
|
</Tooltip>
|
|
285
422
|
</label>
|
|
@@ -338,19 +475,54 @@ const EditorPanel = memo(props => {
|
|
|
338
475
|
</Button>
|
|
339
476
|
</Accordion.Section>
|
|
340
477
|
<Accordion.Section title='Visual'>
|
|
341
|
-
{config.visualizationType !== 'Gauge' && <InputSelect value={config.shape} fieldName='shape' label='Shape' updateField={updateField} options={['circle', 'square', 'person']} className='cove-input' />}
|
|
342
478
|
{config.visualizationType !== 'Gauge' && (
|
|
343
|
-
<
|
|
479
|
+
<InputSelect
|
|
480
|
+
value={config.shape}
|
|
481
|
+
fieldName='shape'
|
|
482
|
+
label='Shape'
|
|
483
|
+
updateField={updateField}
|
|
484
|
+
options={['circle', 'square', 'person']}
|
|
485
|
+
className='cove-input'
|
|
486
|
+
/>
|
|
487
|
+
)}
|
|
488
|
+
{config.visualizationType !== 'Gauge' && (
|
|
489
|
+
<div
|
|
490
|
+
className='cove-accordion__panel-row cove-accordion__small-inputs'
|
|
491
|
+
style={{ marginTop: '1rem', marginBottom: '1rem' }}
|
|
492
|
+
>
|
|
344
493
|
<div className='cove-accordion__panel-col'>
|
|
345
|
-
<InputText
|
|
494
|
+
<InputText
|
|
495
|
+
type='number'
|
|
496
|
+
value={config.nodeWidth}
|
|
497
|
+
fieldName='nodeWidth'
|
|
498
|
+
label='Width'
|
|
499
|
+
updateField={updateField}
|
|
500
|
+
/>
|
|
346
501
|
</div>
|
|
347
502
|
<div className='cove-accordion__panel-col'>
|
|
348
|
-
<InputText
|
|
503
|
+
<InputText
|
|
504
|
+
type='number'
|
|
505
|
+
value={config.nodeSpacer}
|
|
506
|
+
fieldName='nodeSpacer'
|
|
507
|
+
label='Spacer'
|
|
508
|
+
updateField={updateField}
|
|
509
|
+
/>
|
|
349
510
|
</div>
|
|
350
511
|
</div>
|
|
351
512
|
)}
|
|
352
513
|
|
|
353
|
-
<div className='cove-input-group'>
|
|
514
|
+
<div className='cove-input-group'>
|
|
515
|
+
{config.visualizationType !== 'Gauge' && (
|
|
516
|
+
<InputSelect
|
|
517
|
+
value={config.orientation}
|
|
518
|
+
fieldName='orientation'
|
|
519
|
+
label='Layout'
|
|
520
|
+
updateField={updateField}
|
|
521
|
+
className='cove-input'
|
|
522
|
+
options={['horizontal', 'vertical']}
|
|
523
|
+
/>
|
|
524
|
+
)}
|
|
525
|
+
</div>
|
|
354
526
|
|
|
355
527
|
<div className='cove-input-group'>
|
|
356
528
|
<label>
|
|
@@ -366,7 +538,14 @@ const EditorPanel = memo(props => {
|
|
|
366
538
|
</div>
|
|
367
539
|
</div>
|
|
368
540
|
|
|
369
|
-
<InputSelect
|
|
541
|
+
<InputSelect
|
|
542
|
+
value={config.overallFontSize}
|
|
543
|
+
fieldName='overallFontSize'
|
|
544
|
+
label='Overall Font Size'
|
|
545
|
+
updateField={updateField}
|
|
546
|
+
options={['small', 'medium', 'large']}
|
|
547
|
+
className='cove-input'
|
|
548
|
+
/>
|
|
370
549
|
|
|
371
550
|
<label>
|
|
372
551
|
<span className='edit-label cove-input__label'>Theme</span>
|
|
@@ -385,11 +564,48 @@ const EditorPanel = memo(props => {
|
|
|
385
564
|
</label>
|
|
386
565
|
|
|
387
566
|
<div className='cove-accordion__panel-section reverse-labels'>
|
|
388
|
-
<InputCheckbox
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
567
|
+
<InputCheckbox
|
|
568
|
+
inline
|
|
569
|
+
size='small'
|
|
570
|
+
value={config.visual.border}
|
|
571
|
+
section='visual'
|
|
572
|
+
fieldName='border'
|
|
573
|
+
label='Display Border'
|
|
574
|
+
updateField={updateField}
|
|
575
|
+
/>
|
|
576
|
+
<InputCheckbox
|
|
577
|
+
inline
|
|
578
|
+
size='small'
|
|
579
|
+
value={config.visual.borderColorTheme}
|
|
580
|
+
section='visual'
|
|
581
|
+
fieldName='borderColorTheme'
|
|
582
|
+
label='Use theme border color'
|
|
583
|
+
updateField={updateField}
|
|
584
|
+
/>
|
|
585
|
+
<InputCheckbox
|
|
586
|
+
size='small'
|
|
587
|
+
value={config.visual.accent}
|
|
588
|
+
section='visual'
|
|
589
|
+
fieldName='accent'
|
|
590
|
+
label='Use Accent Style'
|
|
591
|
+
updateField={updateField}
|
|
592
|
+
/>
|
|
593
|
+
<InputCheckbox
|
|
594
|
+
size='small'
|
|
595
|
+
value={config.visual.background}
|
|
596
|
+
section='visual'
|
|
597
|
+
fieldName='background'
|
|
598
|
+
label='Use Theme Background Color'
|
|
599
|
+
updateField={updateField}
|
|
600
|
+
/>
|
|
601
|
+
<InputCheckbox
|
|
602
|
+
size='small'
|
|
603
|
+
value={config.visual.hideBackgroundColor}
|
|
604
|
+
section='visual'
|
|
605
|
+
fieldName='hideBackgroundColor'
|
|
606
|
+
label='Hide Background Color'
|
|
607
|
+
updateField={updateField}
|
|
608
|
+
/>
|
|
393
609
|
</div>
|
|
394
610
|
</Accordion.Section>
|
|
395
611
|
</Accordion>
|
|
@@ -400,7 +616,13 @@ const EditorPanel = memo(props => {
|
|
|
400
616
|
return (
|
|
401
617
|
<ErrorBoundary component='EditorPanel'>
|
|
402
618
|
<>
|
|
403
|
-
<Layout.Sidebar
|
|
619
|
+
<Layout.Sidebar
|
|
620
|
+
displayPanel={displayPanel}
|
|
621
|
+
onBackClick={onBackClick}
|
|
622
|
+
isDashboard={isDashboard}
|
|
623
|
+
title='Configure Waffle Chart'
|
|
624
|
+
showEditorPanel={displayPanel}
|
|
625
|
+
>
|
|
404
626
|
{editorContent}
|
|
405
627
|
</Layout.Sidebar>
|
|
406
628
|
{props.children}
|