@cdc/chart 4.23.2 → 4.23.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.
Files changed (48) hide show
  1. package/dist/cdcchart.js +41198 -39447
  2. package/examples/area-chart.json +187 -0
  3. package/examples/big-small-test-bar.json +328 -0
  4. package/examples/big-small-test-line.json +328 -0
  5. package/examples/big-small-test-negative.json +328 -0
  6. package/examples/box-plot.json +0 -1
  7. package/examples/example-bar-chart.json +4 -1
  8. package/examples/example-sparkline.json +76 -0
  9. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +31 -172
  10. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json +1 -0
  11. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +96 -14
  12. package/examples/gallery/line/line.json +1 -0
  13. package/examples/horizontal-chart-max-increase.json +38 -0
  14. package/examples/line-chart-max-increase.json +32 -0
  15. package/examples/line-chart-nonnumeric.json +5 -5
  16. package/examples/line-chart.json +6 -6
  17. package/examples/planet-deviation-config.json +168 -0
  18. package/examples/planet-deviation-data.json +38 -0
  19. package/examples/planet-example-config.json +139 -20
  20. package/examples/planet-example-data-max-increase.json +56 -0
  21. package/examples/planet-example-data.json +10 -10
  22. package/examples/scatterplot-continuous.csv +3 -3
  23. package/examples/scatterplot.json +2 -2
  24. package/examples/sparkline-chart-nonnumeric.json +3 -3
  25. package/index.html +26 -9
  26. package/package.json +6 -3
  27. package/src/CdcChart.jsx +146 -92
  28. package/src/components/AreaChart.jsx +198 -0
  29. package/src/components/BarChart.jsx +58 -34
  30. package/src/components/BoxPlot.jsx +28 -15
  31. package/src/components/DataTable.jsx +21 -17
  32. package/src/components/DeviationBar.jsx +191 -0
  33. package/src/components/EditorPanel.jsx +473 -168
  34. package/src/components/Filters.jsx +3 -2
  35. package/src/components/Legend.jsx +59 -46
  36. package/src/components/LineChart.jsx +3 -21
  37. package/src/components/LinearChart.jsx +158 -55
  38. package/src/components/PairedBarChart.jsx +0 -1
  39. package/src/components/PieChart.jsx +11 -14
  40. package/src/components/ScatterPlot.jsx +19 -16
  41. package/src/components/SparkLine.jsx +87 -85
  42. package/src/components/useIntersectionObserver.jsx +1 -1
  43. package/src/data/initial-state.js +20 -4
  44. package/src/hooks/useColorPalette.js +58 -48
  45. package/src/hooks/useReduceData.js +3 -4
  46. package/src/index.jsx +1 -1
  47. package/src/scss/editor-panel.scss +5 -0
  48. package/src/test/CdcChart.test.jsx +6 -0
@@ -17,9 +17,9 @@ import Tooltip from '@cdc/core/components/ui/Tooltip'
17
17
  import Icon from '@cdc/core/components/ui/Icon'
18
18
  import useReduceData from '../hooks/useReduceData'
19
19
  import useRightAxis from '../hooks/useRightAxis'
20
+ import * as allCurves from '@visx/curve'
20
21
 
21
22
  /* eslint-disable react-hooks/rules-of-hooks */
22
-
23
23
  const TextField = memo(({ label, tooltip, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', i = null, min = null, ...attributes }) => {
24
24
  const [value, setValue] = useState(stateValue)
25
25
 
@@ -76,7 +76,7 @@ const CheckBox = memo(({ label, value, fieldName, section = null, subsection = n
76
76
  type='checkbox'
77
77
  name={fieldName}
78
78
  checked={value}
79
- onChange={() => {
79
+ onChange={e => {
80
80
  updateField(section, subsection, fieldName, !value)
81
81
  }}
82
82
  {...attributes}
@@ -206,17 +206,11 @@ const Regions = memo(({ config, updateConfig }) => {
206
206
  const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
207
207
 
208
208
  const EditorPanel = () => {
209
- const { config, updateConfig, transformedData: data, loading, colorPalettes, unfilteredData, excludedData, isDashboard, setParentConfig, missingRequiredSections } = useContext(ConfigContext)
209
+ const { config, updateConfig, transformedData: data, loading, colorPalettes, twoColorPalette, unfilteredData, excludedData, isDashboard, setParentConfig, missingRequiredSections } = useContext(ConfigContext)
210
210
 
211
211
  const { minValue, maxValue, existPositiveValue, isAllLine } = useReduceData(config, unfilteredData)
212
- const { paletteName, isPaletteReversed, filteredPallets, filteredQualitative, dispatch } = useColorPalette(colorPalettes, config)
213
- useEffect(() => {
214
- if (paletteName) updateConfig({ ...config, palette: paletteName })
215
- }, [paletteName]) // eslint-disable-line
216
212
 
217
- useEffect(() => {
218
- dispatch({ type: 'GET_PALETTE', payload: colorPalettes, paletteName: config.palette })
219
- }, [dispatch, config.palette]) // eslint-disable-line
213
+ const { twoColorPalettes, sequential, nonSequential } = useColorPalette(config, updateConfig)
220
214
 
221
215
  // when the visualization type changes we
222
216
  // have to update the individual series type & axis details
@@ -240,6 +234,19 @@ const EditorPanel = () => {
240
234
  })
241
235
  }, [config.visualizationType]) // eslint-disable-line
242
236
 
237
+ // Scatter Plots default date/category axis is 'continuous'
238
+ useEffect(() => {
239
+ if (config.visualizationType === 'Scatter Plot') {
240
+ updateConfig({
241
+ ...config,
242
+ xAxis: {
243
+ ...config.xAxis,
244
+ type: 'continuous'
245
+ }
246
+ })
247
+ }
248
+ }, [])
249
+
243
250
  const { hasRightAxis } = useRightAxis({ config: config, yMax: config.yAxis.size, data: config.data, updateConfig })
244
251
 
245
252
  const filterOptions = [
@@ -284,10 +291,13 @@ const EditorPanel = () => {
284
291
  if (updatedConfig.table.show === undefined) {
285
292
  updatedConfig.table.show = !isDashboard
286
293
  }
294
+ // DEV-3293 - Force combo to always be vertical
295
+ if (updatedConfig.visualizationType === 'Combo') {
296
+ updatedConfig.orientation = 'vertical'
297
+ }
287
298
  }
288
299
 
289
300
  const updateField = (section, subsection, fieldName, newValue) => {
290
-
291
301
  if (section === 'boxplot' && subsection === 'legend') {
292
302
  updateConfig({
293
303
  ...config,
@@ -315,7 +325,6 @@ const EditorPanel = () => {
315
325
  })
316
326
  return
317
327
  }
318
-
319
328
  if (null === section && null === subsection) {
320
329
  let updatedConfig = { ...config, [fieldName]: newValue }
321
330
  enforceRestrictions(updatedConfig)
@@ -327,8 +336,6 @@ const EditorPanel = () => {
327
336
 
328
337
  let sectionValue = isArray ? [...config[section], newValue] : { ...config[section], [fieldName]: newValue }
329
338
 
330
- console.log('section value', sectionValue)
331
-
332
339
  if (null !== subsection) {
333
340
  if (isArray) {
334
341
  sectionValue = [...config[section]]
@@ -353,6 +360,19 @@ const EditorPanel = () => {
353
360
  return null
354
361
  }
355
362
 
363
+ useEffect(() => {
364
+ if (!config.general?.boxplot) return
365
+ if (!config.general.boxplot.firstQuartilePercentage) {
366
+ updateConfig({
367
+ ...config,
368
+ boxplot: {
369
+ ...config.boxplot,
370
+ firstQuartilePercentage: 25
371
+ }
372
+ })
373
+ }
374
+ }, [config])
375
+
356
376
  const setLollipopShape = shape => {
357
377
  updateConfig({
358
378
  ...config,
@@ -386,7 +406,7 @@ const EditorPanel = () => {
386
406
 
387
407
  const addNewSeries = seriesKey => {
388
408
  let newSeries = config.series ? [...config.series] : []
389
- newSeries.push({ dataKey: seriesKey, type: 'Bar' })
409
+ newSeries.push({ dataKey: seriesKey, type: config.visualizationType })
390
410
  updateConfig({ ...config, series: newSeries }) // left axis series keys
391
411
  }
392
412
 
@@ -506,7 +526,7 @@ const EditorPanel = () => {
506
526
  }
507
527
 
508
528
  const showBarStyleOptions = () => {
509
- if (config.visualizationType === 'Bar' && config.visualizationSubType !== 'stacked' && (config.orientation === 'horizontal' || config.orientation === 'vertical')) {
529
+ if ((config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && config.visualizationSubType !== 'stacked' && (config.orientation === 'horizontal' || config.orientation === 'vertical')) {
510
530
  return ['flat', 'rounded', 'lollipop']
511
531
  } else {
512
532
  return ['flat', 'rounded']
@@ -590,6 +610,13 @@ const EditorPanel = () => {
590
610
  }
591
611
  }, [config.isLollipopChart, config.lollipopShape]) // eslint-disable-line
592
612
 
613
+ /// temporary force orientation untill we support Vartical deviaton bar
614
+ useEffect(() => {
615
+ if (config.visualizationType === 'Deviation Bar') {
616
+ updateConfig({ ...config, orientation: 'horizontal' })
617
+ }
618
+ }, [config.visualizationType])
619
+
593
620
  const ExclusionsList = useCallback(() => {
594
621
  const exclusions = [...config.exclusions.keys]
595
622
  return (
@@ -627,6 +654,63 @@ const EditorPanel = () => {
627
654
  updateConfig({ ...config, filters })
628
655
  }
629
656
 
657
+ const visHasLegend = () => {
658
+ const { visualizationType } = config
659
+
660
+ switch (visualizationType) {
661
+ case 'Box Plot':
662
+ return false
663
+ default:
664
+ return true
665
+ }
666
+ }
667
+
668
+ const visCanAnimate = () => {
669
+ const { visualizationType } = config
670
+ switch (visualizationType) {
671
+ case 'Scatter Plot':
672
+ return false
673
+ case 'Box Plot':
674
+ return false
675
+ default:
676
+ return true
677
+ }
678
+ }
679
+
680
+ const visHasDataCutoff = () => {
681
+ const { visualizationType } = config
682
+ switch (visualizationType) {
683
+ case 'Box Plot':
684
+ return false
685
+ case 'Pie':
686
+ return false
687
+ default:
688
+ return true
689
+ }
690
+ }
691
+
692
+ const visHasLabelOnData = () => {
693
+ const { visualizationType } = config
694
+ switch (visualizationType) {
695
+ case 'Box Plot':
696
+ return false
697
+ case 'Pie':
698
+ return false
699
+ case 'Scatter Plot':
700
+ return false
701
+ default:
702
+ return true
703
+ }
704
+ }
705
+
706
+ const visHasBarBorders = () => {
707
+ const { series, visualizationType } = config
708
+ if (visualizationType === 'Box Plot') return false
709
+ if (visualizationType === 'Scatter Plot') return false
710
+ if (visualizationType === 'Pie') return false
711
+ return series?.some(series => series.type === 'Bar' || series.type === 'Paired Bar' || series.type === 'Deviation Bar')
712
+ }
713
+
630
714
  const handleSeriesChange = (idx1, idx2) => {
631
715
  let seriesOrder = config.series
632
716
  let [movedItem] = seriesOrder.splice(idx1, 1)
@@ -676,7 +760,7 @@ const EditorPanel = () => {
676
760
  case config.visualizationType === 'Combo' && isAllLine && enteredValue && parseFloat(enteredValue) > minVal:
677
761
  message = 'Value must be less than ' + minValue
678
762
  break
679
- case (config.visualizationType === 'Bar' || (config.visualizationType === 'Combo' && !isAllLine)) && enteredValue && minVal > 0 && parseFloat(enteredValue) > 0:
763
+ case (config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar' || (config.visualizationType === 'Combo' && !isAllLine)) && enteredValue && minVal > 0 && parseFloat(enteredValue) > 0:
680
764
  message = 'Value must be less than or equal to 0'
681
765
  break
682
766
  case enteredValue && minVal < 0 && parseFloat(enteredValue) > minVal:
@@ -694,6 +778,19 @@ const EditorPanel = () => {
694
778
  validateMaxValue()
695
779
  }, [minValue, maxValue, config]) // eslint-disable-line
696
780
 
781
+ const enabledChartTypes = [
782
+ 'Pie',
783
+ 'Line',
784
+ 'Bar',
785
+ 'Combo',
786
+ 'Paired Bar',
787
+ 'Spark Line',
788
+ // 'Area Chart',
789
+ 'Scatter Plot',
790
+ 'Box Plot',
791
+ 'Deviation Bar'
792
+ ]
793
+
697
794
  return (
698
795
  <ErrorBoundary component='EditorPanel'>
699
796
  {config.newViz && <Confirm />}
@@ -713,22 +810,44 @@ const EditorPanel = () => {
713
810
  <AccordionItemButton>General</AccordionItemButton>
714
811
  </AccordionItemHeading>
715
812
  <AccordionItemPanel>
716
- <Select value={config.visualizationType} fieldName='visualizationType' label='Chart Type' updateField={updateField} options={['Pie', 'Line', 'Bar', 'Combo', 'Paired Bar', 'Spark Line']} />
717
-
813
+ <Select value={config.visualizationType} fieldName='visualizationType' label='Chart Type' updateField={updateField} options={enabledChartTypes} />
718
814
  {(config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && <Select value={config.visualizationSubType || 'Regular'} fieldName='visualizationSubType' label='Chart Subtype' updateField={updateField} options={['regular', 'stacked']} />}
719
815
  {config.visualizationType === 'Bar' && <Select value={config.orientation || 'vertical'} fieldName='orientation' label='Orientation' updateField={updateField} options={['vertical', 'horizontal']} />}
720
- {config.visualizationType === 'Bar' && <Select value={config.isLollipopChart ? 'lollipop' : config.barStyle || 'flat'} fieldName='barStyle' label='bar style' updateField={updateField} options={showBarStyleOptions()} />}
721
- {config.visualizationType === 'Bar' && config.barStyle === 'rounded' && <Select value={config.tipRounding || 'top'} fieldName='tipRounding' label='tip rounding' updateField={updateField} options={['top', 'full']} />}
722
- {config.visualizationType === 'Bar' && config.barStyle === 'rounded' && <Select value={config.roundingStyle || 'standard'} fieldName='roundingStyle' label='rounding style' updateField={updateField} options={['standard', 'shallow', 'finger']} />}
816
+ {config.visualizationType === 'Deviation Bar' && <Select label='Orientation' options={['horizontal']} />}
817
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && <Select value={config.isLollipopChart ? 'lollipop' : config.barStyle || 'flat'} fieldName='barStyle' label='bar style' updateField={updateField} options={showBarStyleOptions()} />}
818
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && config.barStyle === 'rounded' && <Select value={config.tipRounding || 'top'} fieldName='tipRounding' label='tip rounding' updateField={updateField} options={['top', 'full']} />}
819
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && config.barStyle === 'rounded' && (
820
+ <Select value={config.roundingStyle || 'standard'} fieldName='roundingStyle' label='rounding style' updateField={updateField} options={['standard', 'shallow', 'finger']} />
821
+ )}
723
822
  {config.visualizationType === 'Bar' && config.orientation === 'horizontal' && <Select value={config.yAxis.labelPlacement || 'Below Bar'} section='yAxis' fieldName='labelPlacement' label='Label Placement' updateField={updateField} options={['Below Bar', 'On Date/Category Axis']} />}
724
- {config.orientation === 'horizontal' && (config.yAxis.labelPlacement === 'Below Bar' || config.yAxis.labelPlacement === 'On Date/Category Axis' || config.visualizationType === 'Paired Bar') ? (
823
+ {config.orientation === 'horizontal' && (config.yAxis.labelPlacement === 'Below Bar' || config.yAxis.labelPlacement === 'On Date/Category Axis' || config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') ? (
725
824
  <CheckBox value={config.yAxis.displayNumbersOnBar} section='yAxis' fieldName='displayNumbersOnBar' label={config.isLollipopChart ? 'Display Numbers after Bar' : 'Display Numbers on Bar'} updateField={updateField} />
726
825
  ) : (
727
- config.visualizationType !== 'Pie' && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
826
+ visHasLabelOnData() && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
728
827
  )}
729
828
  {config.visualizationType === 'Pie' && <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />}
730
829
 
731
- <TextField value={config.title} fieldName='title' label='Title' updateField={updateField} />
830
+ <TextField
831
+ value={config.title || 'Chart Title'}
832
+ fieldName='title'
833
+ id='title'
834
+ label='Title'
835
+ placeholder='Chart Title'
836
+ //defaultValue='Chart Title'
837
+ updateField={updateField}
838
+ //onChange={handleTitleChange}
839
+ tooltip={
840
+ <Tooltip style={{ textTransform: 'none' }}>
841
+ <Tooltip.Target>
842
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
843
+ </Tooltip.Target>
844
+ <Tooltip.Content>
845
+ <p>Title is required to set the name of the download file but can be hidden using the option below.</p>
846
+ </Tooltip.Content>
847
+ </Tooltip>
848
+ }
849
+ />
850
+ <CheckBox value={config.showTitle} fieldName='showTitle' label='Show Title' updateField={updateField} />
732
851
  <TextField
733
852
  value={config.superTitle}
734
853
  updateField={updateField}
@@ -832,7 +951,7 @@ const EditorPanel = () => {
832
951
  {provided => (
833
952
  <ul {...provided.droppableProps} className='series-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
834
953
  {config.series.map((series, i) => {
835
- if (config.visualizationType === 'Combo') {
954
+ if (config.visualizationType === 'Combo' || 'Area Chart') {
836
955
  let changeType = (i, value) => {
837
956
  let series = [...config.series]
838
957
  series[i].type = value
@@ -842,6 +961,12 @@ const EditorPanel = () => {
842
961
  updateConfig({ ...config, series })
843
962
  }
844
963
 
964
+ let changeLineType = (i, value) => {
965
+ let series = [...config.series]
966
+ series[i].lineType = value
967
+ updateConfig({ ...config, series })
968
+ }
969
+
845
970
  let typeDropdown = (
846
971
  <select
847
972
  value={series.type}
@@ -849,33 +974,69 @@ const EditorPanel = () => {
849
974
  changeType(i, event.target.value)
850
975
  }}
851
976
  style={{ width: '100px', marginRight: '10px' }}
977
+ >
978
+ <option value='' default key='default'>
979
+ Select
980
+ </option>
981
+ {config.visualizationType === 'Combo' && <option value='Bar'>Bar</option>}
982
+ <option value='Line' key='Line'>
983
+ Solid Line
984
+ </option>
985
+ <option value='dashed-sm' key='dashed-sm'>
986
+ Small Dashed
987
+ </option>
988
+ <option value='dashed-md' key='dashed-md'>
989
+ Medium Dashed
990
+ </option>
991
+ <option value='dashed-lg' key='dashed-lg'>
992
+ Large Dashed
993
+ </option>
994
+ </select>
995
+ )
996
+
997
+ const lineType = (
998
+ <select
999
+ value={series.lineStyle}
1000
+ onChange={event => {
1001
+ changeLineType(i, event.target.value)
1002
+ }}
1003
+ style={{ width: '100px', marginRight: '10px' }}
1004
+ key='lineTypeSelection'
852
1005
  >
853
1006
  <option value='' default>
854
1007
  Select
855
1008
  </option>
856
- <option value='Bar'>Bar</option>
857
- <option value='Line'>Solid Line</option>
858
- <option value='dashed-sm'>Small Dashed</option>
859
- <option value='dashed-md'>Medium Dashed</option>
860
- <option value='dashed-lg'>Large Dashed</option>
1009
+
1010
+ {Object.keys(allCurves).map(curveName => (
1011
+ <option key={`curve-option-${curveName}`} value={curveName}>
1012
+ {curveName}
1013
+ </option>
1014
+ ))}
861
1015
  </select>
862
1016
  )
863
1017
 
864
1018
  return (
865
1019
  <Draggable key={series.dataKey} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
866
1020
  {(provided, snapshot) => (
867
- <li>
1021
+ <li key={i}>
868
1022
  <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
869
1023
  <div className={`series-list__name${series.dataKey.length > 15 ? ' series-list__name--truncate' : ''}`} data-title={series.dataKey}>
870
1024
  <div className='series-list__name-text'>{series.dataKey}</div>
871
1025
  </div>
872
1026
  <span>
873
- <span className='series-list__dropdown'>{typeDropdown}</span>
874
- {config.series && config.series.length > 1 && (
875
- <button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
876
- &#215;
877
- </button>
878
- )}
1027
+ <>
1028
+ {(config.visualizationType === 'Combo' || config.visualizationType === 'Area Chart') && (
1029
+ <>
1030
+ <span className='series-list__dropdown'>{typeDropdown}</span>
1031
+ {config.visualizationType === 'Area Chart' && <span className='series-list__dropdown series-list__dropdown--lineType'>{lineType}</span>}
1032
+ </>
1033
+ )}
1034
+ {config.series && config.series.length > 1 && (
1035
+ <button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
1036
+ &#215;
1037
+ </button>
1038
+ )}
1039
+ </>
879
1040
  </span>
880
1041
  </div>
881
1042
  </li>
@@ -885,7 +1046,7 @@ const EditorPanel = () => {
885
1046
  }
886
1047
 
887
1048
  return (
888
- <Draggable key={series.dataKey} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
1049
+ <Draggable key={`series.dataKey--${i}`} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
889
1050
  {(provided, snapshot) => (
890
1051
  <li
891
1052
  key={series.dataKey}
@@ -930,6 +1091,7 @@ const EditorPanel = () => {
930
1091
  }}
931
1092
  options={getColumns()}
932
1093
  />
1094
+
933
1095
  {config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
934
1096
  <>
935
1097
  <span className='divider-heading'>Confidence Keys</span>
@@ -949,7 +1111,7 @@ const EditorPanel = () => {
949
1111
  <AccordionItemButton>Measures</AccordionItemButton>
950
1112
  </AccordionItemHeading>
951
1113
  <AccordionItemPanel>
952
- <h4>Labels for 5-Number Summary</h4>
1114
+ <h4 style={{ fontSize: '18px' }}>Labels for 5-Number Summary</h4>
953
1115
 
954
1116
  {/* prettier-ignore */}
955
1117
  {/* max */}
@@ -1060,12 +1222,14 @@ const EditorPanel = () => {
1060
1222
  </Tooltip>
1061
1223
  }
1062
1224
  />
1225
+ <br />
1226
+ <h4 style={{ fontSize: '18px' }}>Labels for Additional Measures</h4>
1063
1227
 
1064
1228
  {/* iqr */}
1065
1229
  <TextField type='text' value={config.boxplot.labels.iqr} fieldName='iqr' section='boxplot' subsection='labels' label='Interquartile Range' updateField={updateField} />
1066
1230
 
1067
1231
  {/* count */}
1068
- <TextField type='text' value={config.boxplot.labels.count} fieldName='count' section='boxplot' subsection='labels' label='Count' updateField={updateField} />
1232
+ <TextField type='text' value={config.boxplot.labels.total} fieldName='total' section='boxplot' subsection='labels' label='Total' updateField={updateField} />
1069
1233
 
1070
1234
  {/* mean */}
1071
1235
  <TextField type='text' value={config.boxplot.labels.mean} fieldName='mean' section='boxplot' subsection='labels' label='Mean' updateField={updateField} />
@@ -1074,10 +1238,10 @@ const EditorPanel = () => {
1074
1238
  {/* values */}
1075
1239
  <TextField type='text' value={config.boxplot.labels.values} fieldName='values' section='boxplot' subsection='labels' label='Values' updateField={updateField} />
1076
1240
  <br />
1077
- <h4>Percentages for Quartiles</h4>
1241
+ <h4 style={{ fontSize: '18px' }}>Percentages for Quartiles</h4>
1078
1242
  <TextField
1079
1243
  type='number'
1080
- value={config.boxplot.firstQuartilePercentage}
1244
+ value={config.boxplot.firstQuartilePercentage ? config.boxplot.firstQuartilePercentage : 25}
1081
1245
  fieldName='firstQuartilePercentage'
1082
1246
  section='boxplot'
1083
1247
  label='Lower Quartile'
@@ -1097,7 +1261,7 @@ const EditorPanel = () => {
1097
1261
 
1098
1262
  <TextField
1099
1263
  type='number'
1100
- value={config.boxplot.thirdQuartilePercentage}
1264
+ value={config.boxplot.thirdQuartilePercentage ? config.boxplot.thirdQuartilePercentage : 75}
1101
1265
  fieldName='thirdQuartilePercentage'
1102
1266
  label='Upper Quartile'
1103
1267
  section='boxplot'
@@ -1157,10 +1321,12 @@ const EditorPanel = () => {
1157
1321
  }}
1158
1322
  style={{ width: '100px', marginRight: '10px' }}
1159
1323
  >
1160
- <option value='Left' default>
1324
+ <option value='Left' default key='left'>
1161
1325
  left
1162
1326
  </option>
1163
- <option value='Right'>right</option>
1327
+ <option value='Right' key='right'>
1328
+ right
1329
+ </option>
1164
1330
  </select>
1165
1331
  )
1166
1332
 
@@ -1215,7 +1381,7 @@ const EditorPanel = () => {
1215
1381
  {config.visualizationType !== 'Pie' && (
1216
1382
  <>
1217
1383
  <TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label' updateField={updateField} />
1218
- {config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && <CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />}
1384
+ {config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && config.visualizationType !== 'Box Plot' && <CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />}
1219
1385
  <TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1220
1386
  {config.visualizationType === 'Paired Bar' && <TextField value={config.yAxis.tickRotation || 0} type='number' min='0' section='yAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
1221
1387
  <TextField
@@ -1237,9 +1403,11 @@ const EditorPanel = () => {
1237
1403
  </Tooltip>
1238
1404
  }
1239
1405
  />
1240
- <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} />
1406
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1407
+ {/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1241
1408
  {config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
1242
1409
  {config.orientation !== 'horizontal' && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Display Gridlines' updateField={updateField} />}
1410
+ <CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
1243
1411
  </>
1244
1412
  )}
1245
1413
  <span className='divider-heading'>Number Formatting</span>
@@ -1306,8 +1474,17 @@ const EditorPanel = () => {
1306
1474
  <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1307
1475
  <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1308
1476
  <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1309
- <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='update max value' type='number' placeholder='Auto' updateField={updateField} />
1477
+ <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />
1310
1478
  <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1479
+ {config.visualizationType === 'Deviation Bar' && (
1480
+ <>
1481
+ <TextField value={config.xAxis.min} section='xAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1482
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1483
+ <TextField value={config.xAxis.target} section='xAxis' fieldName='target' type='number' label='Deviation point' placeholder='Auto' updateField={updateField} />
1484
+ <TextField value={config.xAxis.targetLabel || 'Target'} section='xAxis' fieldName='targetLabel' type='text' label='Deviation point Label' updateField={updateField} />
1485
+ <CheckBox value={config.xAxis.showTargetLabel} section='xAxis' fieldName='showTargetLabel' label='Display Deviation point label' updateField={updateField} />
1486
+ </>
1487
+ )}
1311
1488
  </>
1312
1489
  ) : (
1313
1490
  config.visualizationType !== 'Pie' && (
@@ -1315,9 +1492,9 @@ const EditorPanel = () => {
1315
1492
  <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1316
1493
  <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1317
1494
  <CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1318
- <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='update max value' placeholder='Auto' updateField={updateField} />
1495
+ <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='max value' placeholder='Auto' updateField={updateField} />
1319
1496
  <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1320
- <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='update min value' placeholder='Auto' updateField={updateField} />
1497
+ <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1321
1498
  <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1322
1499
  </>
1323
1500
  )
@@ -1396,7 +1573,7 @@ const EditorPanel = () => {
1396
1573
  <AccordionItemPanel>
1397
1574
  {config.visualizationType !== 'Pie' && (
1398
1575
  <>
1399
- <Select value={config.xAxis.type} section='xAxis' fieldName='type' label='Data Type' updateField={updateField} options={config.visualizationType !== 'Scatter Plot' ? ['categorical', 'date'] : ['categorical', 'date', 'continuous']} />
1576
+ <Select value={config.xAxis.type} section='xAxis' fieldName='type' label='Data Type' updateField={updateField} options={config.visualizationType !== 'Scatter Plot' ? ['categorical', 'date'] : ['categorical', 'continuous', 'date']} />
1400
1577
  <Select
1401
1578
  value={config.xAxis.dataKey || ''}
1402
1579
  section='xAxis'
@@ -1447,6 +1624,66 @@ const EditorPanel = () => {
1447
1624
  <>
1448
1625
  <TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
1449
1626
 
1627
+ {config.xAxis.type === 'continuous' && (
1628
+ <>
1629
+ <TextField
1630
+ value={config.dataFormat.bottomPrefix}
1631
+ section='dataFormat'
1632
+ fieldName='bottomPrefix'
1633
+ label='Prefix'
1634
+ updateField={updateField}
1635
+ tooltip={
1636
+ <Tooltip style={{ textTransform: 'none' }}>
1637
+ <Tooltip.Target>
1638
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1639
+ </Tooltip.Target>
1640
+ <Tooltip.Content>
1641
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1642
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1643
+ </Tooltip.Content>
1644
+ </Tooltip>
1645
+ }
1646
+ />
1647
+
1648
+ <TextField
1649
+ value={config.dataFormat.bottomSuffix}
1650
+ section='dataFormat'
1651
+ fieldName='bottomSuffix'
1652
+ label='Suffix'
1653
+ updateField={updateField}
1654
+ tooltip={
1655
+ <Tooltip style={{ textTransform: 'none' }}>
1656
+ <Tooltip.Target>
1657
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1658
+ </Tooltip.Target>
1659
+ <Tooltip.Content>
1660
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1661
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1662
+ </Tooltip.Content>
1663
+ </Tooltip>
1664
+ }
1665
+ />
1666
+
1667
+ <CheckBox
1668
+ value={config.dataFormat.bottomAbbreviated}
1669
+ section='dataFormat'
1670
+ fieldName='bottomAbbreviated'
1671
+ label='Abbreviate Axis Values'
1672
+ updateField={updateField}
1673
+ tooltip={
1674
+ <Tooltip style={{ textTransform: 'none' }}>
1675
+ <Tooltip.Target>
1676
+ <Icon display='question' />
1677
+ </Tooltip.Target>
1678
+ <Tooltip.Content>
1679
+ <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1680
+ </Tooltip.Content>
1681
+ </Tooltip>
1682
+ }
1683
+ />
1684
+ </>
1685
+ )}
1686
+
1450
1687
  {config.xAxis.type === 'date' && (
1451
1688
  <>
1452
1689
  <p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
@@ -1518,7 +1755,16 @@ const EditorPanel = () => {
1518
1755
  <TextField value={config.xAxis.numTicks} placeholder='Auto' type='number' min='1' section='xAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1519
1756
 
1520
1757
  <TextField value={config.xAxis.size} type='number' min='0' section='xAxis' fieldName='size' label={config.orientation === 'horizontal' ? 'Size (Width)' : 'Size (Height)'} className='number-narrow' updateField={updateField} />
1521
- <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} />
1758
+
1759
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1760
+ {/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1761
+
1762
+ {config.xAxis.type === 'continuous' && (
1763
+ <>
1764
+ <CheckBox value={config.dataFormat.bottomCommas} section='dataFormat' fieldName='bottomCommas' label='Add commas' updateField={updateField} />
1765
+ <TextField value={config.dataFormat.bottomRoundTo} type='number' section='dataFormat' fieldName='bottomRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1766
+ </>
1767
+ )}
1522
1768
 
1523
1769
  {config.yAxis.labelPlacement !== 'Below Bar' && <TextField value={config.xAxis.tickRotation} type='number' min='0' section='xAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
1524
1770
  {config.orientation === 'horizontal' ? (
@@ -1596,13 +1842,14 @@ const EditorPanel = () => {
1596
1842
  </AccordionItem>
1597
1843
  )}
1598
1844
 
1599
- <AccordionItem>
1600
- <AccordionItemHeading>
1601
- <AccordionItemButton>Legend</AccordionItemButton>
1602
- </AccordionItemHeading>
1603
- <AccordionItemPanel>
1604
- <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
1605
- {/* <fieldset className="checkbox-group">
1845
+ {visHasLegend() && (
1846
+ <AccordionItem>
1847
+ <AccordionItemHeading>
1848
+ <AccordionItemButton>Legend</AccordionItemButton>
1849
+ </AccordionItemHeading>
1850
+ <AccordionItemPanel>
1851
+ <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
1852
+ {/* <fieldset className="checkbox-group">
1606
1853
  <CheckBox value={config.legend.dynamicLegend} section="legend" fieldName="dynamicLegend" label="Dynamic Legend" updateField={updateField}/>
1607
1854
  {config.legend.dynamicLegend && (
1608
1855
  <>
@@ -1613,35 +1860,44 @@ const EditorPanel = () => {
1613
1860
  </>
1614
1861
  )}
1615
1862
  </fieldset> */}
1616
- <CheckBox
1617
- value={config.legend.hide}
1618
- section='legend'
1619
- fieldName='hide'
1620
- label='Hide Legend'
1621
- updateField={updateField}
1622
- tooltip={
1623
- <Tooltip style={{ textTransform: 'none' }}>
1624
- <Tooltip.Target>
1625
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1626
- </Tooltip.Target>
1627
- <Tooltip.Content>
1628
- <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
1629
- </Tooltip.Content>
1630
- </Tooltip>
1631
- }
1632
- />
1633
- <CheckBox value={config.legend.showLegendValuesTooltip} section='legend' fieldName='showLegendValuesTooltip' label='Show Legend Values in Tooltip' updateField={updateField} />
1863
+ <CheckBox
1864
+ value={config.legend.hide ? true : false}
1865
+ section='legend'
1866
+ fieldName='hide'
1867
+ label='Hide Legend'
1868
+ updateField={updateField}
1869
+ tooltip={
1870
+ <Tooltip style={{ textTransform: 'none' }}>
1871
+ <Tooltip.Target>
1872
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1873
+ </Tooltip.Target>
1874
+ <Tooltip.Content>
1875
+ <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
1876
+ </Tooltip.Content>
1877
+ </Tooltip>
1878
+ }
1879
+ />
1634
1880
 
1635
- {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
1636
- <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
1637
- )}
1638
- <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={updateField} options={['highlight', 'isolate']} />
1639
- <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
1640
- <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
1641
- {config.legend.position === 'bottom' && <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />}
1642
- <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
1643
- </AccordionItemPanel>
1644
- </AccordionItem>
1881
+ {/* {config.visualizationType === 'Box Plot' &&
1882
+ <>
1883
+ <CheckBox value={config.boxplot.legend.displayHowToReadText} fieldName='displayHowToReadText' section='boxplot' subsection='legend' label='Display How To Read Text' updateField={updateField} />
1884
+ <TextField type='textarea' value={config.boxplot.legend.howToReadText} updateField={updateField} fieldName='howToReadText' section='boxplot' subsection='legend' label='How to read text' />
1885
+ </>
1886
+ } */}
1887
+
1888
+ {config.visualizationType !== 'Box Plot' && <CheckBox value={config.legend.showLegendValuesTooltip ? true : false} section='legend' fieldName='showLegendValuesTooltip' label='Show Legend Values in Tooltip' updateField={updateField} />}
1889
+
1890
+ {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
1891
+ <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
1892
+ )}
1893
+ <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={updateField} options={['highlight', 'isolate']} />
1894
+ <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
1895
+ <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
1896
+ {config.legend.position === 'bottom' && <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />}
1897
+ <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
1898
+ </AccordionItemPanel>
1899
+ </AccordionItem>
1900
+ )}
1645
1901
 
1646
1902
  <AccordionItem>
1647
1903
  <AccordionItemHeading>
@@ -1765,21 +2021,18 @@ const EditorPanel = () => {
1765
2021
  </>
1766
2022
  )}
1767
2023
 
1768
- {config.visualizationType === 'Box Plot' &&
1769
- <fieldset fieldset className='fieldset fieldset--boxplot'>
2024
+ {config.visualizationType === 'Box Plot' && (
2025
+ <fieldset className='fieldset fieldset--boxplot'>
1770
2026
  <legend className=''>Box Plot Settings</legend>
1771
- {config.visualizationType === 'Box Plot' && <Select value={config.boxplot.borders} fieldName='borders' section='boxplot' label='Box Plot Borders' updateField={updateField} options={['true', 'false']} />}
1772
- {config.visualizationType === 'Box Plot' && <CheckBox value={config.boxplot.plotOutlierValues} fieldName='plotOutlierValues' section='boxplot' label='Plot Outliers' updateField={updateField} />}
1773
- {config.visualizationType === 'Box Plot' && <CheckBox value={config.boxplot.plotNonOutlierValues} fieldName='plotNonOutlierValues' section='boxplot' label='Plot non-outlier values' updateField={updateField} />}
1774
- {config.visualizationType === 'Box Plot' && <CheckBox value={config.boxplot.legend.displayHowToReadText} fieldName='displayHowToReadText' section='boxplot' subsection='legend' label='Display How To Read Text' updateField={updateField} />}
1775
- <TextField type='textarea' value={config.boxplot.legend.howToReadText} updateField={updateField} fieldName='howToReadText' section='boxplot' subsection='legend' label='How to read text' />
2027
+ <Select value={config.boxplot.borders} fieldName='borders' section='boxplot' label='Box Plot Borders' updateField={updateField} options={['true', 'false']} />
2028
+ <CheckBox value={config.boxplot.plotOutlierValues} fieldName='plotOutlierValues' section='boxplot' label='Plot Outliers' updateField={updateField} />
2029
+ <CheckBox value={config.boxplot.plotNonOutlierValues} fieldName='plotNonOutlierValues' section='boxplot' label='Plot non-outlier values' updateField={updateField} />
1776
2030
  </fieldset>
1777
- }
2031
+ )}
1778
2032
 
1779
2033
  <Select value={config.fontSize} fieldName='fontSize' label='Font Size' updateField={updateField} options={['small', 'medium', 'large']} />
1780
- {config.visualizationType !== 'Box Plot' && config.series?.some(series => series.type === 'Bar' || series.type === 'Paired Bar') && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
1781
-
1782
- <CheckBox value={config.animate} fieldName='animate' label='Animate Visualization' updateField={updateField} />
2034
+ {visHasBarBorders() && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
2035
+ {visCanAnimate() && <CheckBox value={config.animate} fieldName='animate' label='Animate Visualization' updateField={updateField} />}
1783
2036
 
1784
2037
  {/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
1785
2038
 
@@ -1808,74 +2061,108 @@ const EditorPanel = () => {
1808
2061
  <span className='edit-label'>Chart Color Palette</span>
1809
2062
  </label>
1810
2063
  {/* eslint-enable */}
1811
- {/* <InputCheckbox fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
1812
- <InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
1813
- <span>Sequential</span>
1814
- <ul className='color-palette'>
1815
- {filteredPallets.map(palette => {
1816
- const colorOne = {
1817
- backgroundColor: colorPalettes[palette][2]
1818
- }
1819
-
1820
- const colorTwo = {
1821
- backgroundColor: colorPalettes[palette][3]
1822
- }
1823
-
1824
- const colorThree = {
1825
- backgroundColor: colorPalettes[palette][5]
1826
- }
1827
-
1828
- return (
1829
- <button
1830
- title={palette}
1831
- key={palette}
1832
- onClick={e => {
1833
- e.preventDefault()
1834
- updateConfig({ ...config, palette })
1835
- }}
1836
- className={config.palette === palette ? 'selected' : ''}
1837
- >
1838
- <span style={colorOne}></span>
1839
- <span style={colorTwo}></span>
1840
- <span style={colorThree}></span>
1841
- </button>
1842
- )
1843
- })}
1844
- </ul>
1845
- <span>Non-Sequential</span>
1846
- <ul className='color-palette'>
1847
- {filteredQualitative.map(palette => {
1848
- const colorOne = {
1849
- backgroundColor: colorPalettes[palette][2]
1850
- }
1851
-
1852
- const colorTwo = {
1853
- backgroundColor: colorPalettes[palette][4]
1854
- }
1855
-
1856
- const colorThree = {
1857
- backgroundColor: colorPalettes[palette][6]
1858
- }
1859
-
1860
- return (
1861
- <button
1862
- title={palette}
1863
- key={palette}
1864
- onClick={e => {
1865
- e.preventDefault()
1866
- updateConfig({ ...config, palette })
1867
- }}
1868
- className={config.palette === palette ? 'selected' : ''}
1869
- >
1870
- <span style={colorOne}></span>
1871
- <span style={colorTwo}></span>
1872
- <span style={colorThree}></span>
1873
- </button>
1874
- )
1875
- })}
1876
- </ul>
2064
+ {config.visualizationType !== 'Paired Bar' && config.visualizationType !== 'Deviation Bar' && (
2065
+ <>
2066
+ <InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.isPaletteReversed} />
2067
+ <span>Sequential</span>
2068
+ <ul className='color-palette'>
2069
+ {sequential.map(palette => {
2070
+ const colorOne = {
2071
+ backgroundColor: colorPalettes[palette][2]
2072
+ }
2073
+
2074
+ const colorTwo = {
2075
+ backgroundColor: colorPalettes[palette][3]
2076
+ }
2077
+
2078
+ const colorThree = {
2079
+ backgroundColor: colorPalettes[palette][5]
2080
+ }
2081
+
2082
+ return (
2083
+ <button
2084
+ title={palette}
2085
+ key={palette}
2086
+ onClick={e => {
2087
+ e.preventDefault()
2088
+ updateConfig({ ...config, palette })
2089
+ }}
2090
+ className={config.palette === palette ? 'selected' : ''}
2091
+ >
2092
+ <span style={colorOne}></span>
2093
+ <span style={colorTwo}></span>
2094
+ <span style={colorThree}></span>
2095
+ </button>
2096
+ )
2097
+ })}
2098
+ </ul>
2099
+ <span>Non-Sequential</span>
2100
+ <ul className='color-palette'>
2101
+ {nonSequential.map(palette => {
2102
+ const colorOne = {
2103
+ backgroundColor: colorPalettes[palette][2]
2104
+ }
2105
+
2106
+ const colorTwo = {
2107
+ backgroundColor: colorPalettes[palette][4]
2108
+ }
2109
+
2110
+ const colorThree = {
2111
+ backgroundColor: colorPalettes[palette][6]
2112
+ }
2113
+
2114
+ return (
2115
+ <button
2116
+ title={palette}
2117
+ key={palette}
2118
+ onClick={e => {
2119
+ e.preventDefault()
2120
+ updateConfig({ ...config, palette })
2121
+ }}
2122
+ className={config.palette === palette ? 'selected' : ''}
2123
+ >
2124
+ <span style={colorOne}></span>
2125
+ <span style={colorTwo}></span>
2126
+ <span style={colorThree}></span>
2127
+ </button>
2128
+ )
2129
+ })}
2130
+ </ul>
2131
+ </>
2132
+ )}
2133
+ {(config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') && (
2134
+ <>
2135
+ <InputToggle section='twoColor' fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.twoColor.isPaletteReversed} />
2136
+ <ul className='color-palette'>
2137
+ {twoColorPalettes.map(palette => {
2138
+ const colorOne = {
2139
+ backgroundColor: twoColorPalette[palette][0]
2140
+ }
2141
+
2142
+ const colorTwo = {
2143
+ backgroundColor: twoColorPalette[palette][1]
2144
+ }
2145
+
2146
+ return (
2147
+ <button
2148
+ title={palette}
2149
+ key={palette}
2150
+ onClick={e => {
2151
+ e.preventDefault()
2152
+ updateConfig({ ...config, twoColor: { ...config.twoColor, palette } })
2153
+ }}
2154
+ className={config.twoColor.palette === palette ? 'selected' : ''}
2155
+ >
2156
+ <span className='two-color' style={colorOne}></span>
2157
+ <span className='two-color' style={colorTwo}></span>
2158
+ </button>
2159
+ )
2160
+ })}
2161
+ </ul>
2162
+ </>
2163
+ )}
1877
2164
 
1878
- {config.visualizationType !== 'Pie' && (
2165
+ {visHasDataCutoff() && (
1879
2166
  <>
1880
2167
  <TextField
1881
2168
  value={config.dataCutoff}
@@ -1924,6 +2211,25 @@ const EditorPanel = () => {
1924
2211
  <AccordionItemButton>Data Table</AccordionItemButton>
1925
2212
  </AccordionItemHeading>
1926
2213
  <AccordionItemPanel>
2214
+ <TextField
2215
+ value={config.table.label}
2216
+ updateField={updateField}
2217
+ section='table'
2218
+ fieldName='label'
2219
+ id='tableLabel'
2220
+ label='Data Table Title'
2221
+ placeholder='Data Table'
2222
+ tooltip={
2223
+ <Tooltip style={{ textTransform: 'none' }}>
2224
+ <Tooltip.Target>
2225
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2226
+ </Tooltip.Target>
2227
+ <Tooltip.Content>
2228
+ <p>Label is required for Data Table for 508 Compliance</p>
2229
+ </Tooltip.Content>
2230
+ </Tooltip>
2231
+ }
2232
+ />
1927
2233
  <CheckBox
1928
2234
  value={config.table.show}
1929
2235
  section='table'
@@ -1967,7 +2273,6 @@ const EditorPanel = () => {
1967
2273
  <CheckBox value={config.table.showDownloadUrl} section='table' fieldName='showDownloadUrl' label='Display Link to Dataset' updateField={updateField} />
1968
2274
  {/* <CheckBox value={config.table.showDownloadImgButton} section='table' fieldName='showDownloadImgButton' label='Display Image Button' updateField={updateField} /> */}
1969
2275
  {/* <CheckBox value={config.table.showDownloadPdfButton} section='table' fieldName='showDownloadPdfButton' label='Display PDF Button' updateField={updateField} /> */}
1970
- <TextField value={config.table.label} section='table' fieldName='label' label='Label' updateField={updateField} />
1971
2276
  {config.visualizationType !== 'Pie' && <TextField value={config.table.indexLabel} section='table' fieldName='indexLabel' label='Index Column Header' updateField={updateField} />}
1972
2277
  </AccordionItemPanel>
1973
2278
  </AccordionItem>
@@ -1976,7 +2281,7 @@ const EditorPanel = () => {
1976
2281
  {config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />}
1977
2282
  </section>
1978
2283
  </section>
1979
- </ErrorBoundary >
2284
+ </ErrorBoundary>
1980
2285
  )
1981
2286
  }
1982
2287