@cdc/chart 4.23.5 → 4.23.7

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.
@@ -18,6 +18,7 @@ import Icon from '@cdc/core/components/ui/Icon'
18
18
  import useReduceData from '../hooks/useReduceData'
19
19
  import useRightAxis from '../hooks/useRightAxis'
20
20
  import { useFilters } from '@cdc/core/components/Filters'
21
+ import Series from './Series'
21
22
  import { useHighlightedBars } from '../hooks/useHighlightedBars'
22
23
 
23
24
  /* eslint-disable react-hooks/rules-of-hooks */
@@ -207,7 +208,7 @@ const Regions = memo(({ config, updateConfig }) => {
207
208
  const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
208
209
 
209
210
  const EditorPanel = () => {
210
- const { config, updateConfig, transformedData: data, loading, colorPalettes, twoColorPalette, unfilteredData, excludedData, isDashboard, setParentConfig, missingRequiredSections, isDebug, setFilteredData, lineOptions } = useContext(ConfigContext)
211
+ const { config, updateConfig, transformedData: data, loading, colorPalettes, twoColorPalette, unfilteredData, excludedData, isDashboard, setParentConfig, missingRequiredSections, isDebug, setFilteredData, lineOptions, rawData } = useContext(ConfigContext)
211
212
 
212
213
  const { minValue, maxValue, existPositiveValue, isAllLine } = useReduceData(config, unfilteredData)
213
214
 
@@ -216,14 +217,6 @@ const EditorPanel = () => {
216
217
  // argument acts as props
217
218
  const { handleFilterOrder, filterOrderOptions, filterStyleOptions } = useFilters({ config, setConfig: updateConfig, filteredData: data, setFilteredData })
218
219
 
219
- const approvedCurveTypes = {
220
- Linear: 'curveLinear',
221
- Cardinal: 'curveCardinal',
222
- Natural: 'curveNatural',
223
- 'Monotone X': 'curveMonotoneX',
224
- Step: 'curveStep'
225
- }
226
-
227
220
  // when the visualization type changes we
228
221
  // have to update the individual series type & axis details
229
222
  // dataKey is unchanged here.
@@ -419,7 +412,18 @@ const EditorPanel = () => {
419
412
 
420
413
  const addNewSeries = seriesKey => {
421
414
  let newSeries = config.series ? [...config.series] : []
422
- newSeries.push({ dataKey: seriesKey, type: config.visualizationType })
415
+ let forecastingStages = Array.from(new Set(data.map(item => item[seriesKey])))
416
+ let forecastingStageArr = []
417
+
418
+ forecastingStages.forEach(stage => {
419
+ forecastingStageArr.push({ key: stage })
420
+ })
421
+
422
+ if (config.visualizationType === 'Forecasting') {
423
+ newSeries.push({ dataKey: seriesKey, type: config.visualizationType, stages: forecastingStageArr, stageColumn: seriesKey, axis: 'Left', tooltip: true })
424
+ } else {
425
+ newSeries.push({ dataKey: seriesKey, type: config.visualizationType, axis: 'Left', tooltip: true })
426
+ }
423
427
  updateConfig({ ...config, series: newSeries }) // left axis series keys
424
428
  }
425
429
 
@@ -631,16 +635,6 @@ const EditorPanel = () => {
631
635
  })
632
636
  }, [config.orientation])
633
637
 
634
- // Set paired bars to be horizontal, even though that option doesn't display
635
- useEffect(() => {
636
- if (config.visualizationType === 'Paired Bar') {
637
- updateConfig({
638
- ...config,
639
- orientation: 'horizontal'
640
- })
641
- }
642
- }, []) // eslint-disable-line
643
-
644
638
  useEffect(() => {
645
639
  if (config.orientation === 'horizontal') {
646
640
  updateConfig({
@@ -650,13 +644,6 @@ const EditorPanel = () => {
650
644
  }
651
645
  }, [config.isLollipopChart, config.lollipopShape]) // eslint-disable-line
652
646
 
653
- /// temporary force orientation untill we support Vartical deviaton bar
654
- useEffect(() => {
655
- if (config.visualizationType === 'Deviation Bar') {
656
- updateConfig({ ...config, orientation: 'horizontal' })
657
- }
658
- }, [config.visualizationType])
659
-
660
647
  const ExclusionsList = useCallback(() => {
661
648
  const exclusions = [...config.exclusions.keys]
662
649
  return (
@@ -677,6 +664,12 @@ const EditorPanel = () => {
677
664
  )
678
665
  }, [config]) // eslint-disable-line
679
666
 
667
+ const visSupportsTooltipLines = () => {
668
+ const chartsWithTooltipGuides = ['Combo', 'Forecasting', 'Area Chart', 'Line', 'Bar']
669
+ if (chartsWithTooltipGuides.includes(config.visualizationType)) return true
670
+ return false
671
+ }
672
+
680
673
  const visHasLegend = () => {
681
674
  const { visualizationType } = config
682
675
 
@@ -832,6 +825,7 @@ const EditorPanel = () => {
832
825
  'Box Plot',
833
826
  'Combo',
834
827
  'Deviation Bar',
828
+ 'Forecasting',
835
829
  'Line',
836
830
  'Paired Bar',
837
831
  'Pie',
@@ -849,15 +843,16 @@ const EditorPanel = () => {
849
843
  let datakeys = getColumns(false)
850
844
  if (datakeys.includes('Date')) return 'Date'
851
845
  if (datakeys.includes('Race')) return 'Race'
846
+ if (datakeys.includes('Month')) return 'Month'
852
847
  // add other known Category cols here to extend debug
853
848
  }
854
- return ''
849
+ return config?.xAxis?.dataKey || ''
855
850
  }
856
851
  const setDataColumn = () => {
857
852
  // only for debug mode
858
853
  if (undefined !== isDebug && isDebug && getColumns(false).length > 0) {
859
854
  // then try to set the x axis to appropriate value so we dont have to manually do it
860
- let datacols = getColumns(false).filter(x => x !== 'Date' && x !== 'Race')
855
+ let datacols = getColumns(false).filter(x => x !== setCategoryAxis())
861
856
  if (datacols.length > 0) {
862
857
  return datacols[0]
863
858
  }
@@ -871,7 +866,7 @@ const EditorPanel = () => {
871
866
  if (isDebug) console.log('### COVE DEBUG: Chart: Setting default datacol=', setdatacol) // eslint-disable-line
872
867
  }
873
868
 
874
- const chartsWithOptions = ['Area Chart', 'Combo', 'Line']
869
+ const chartsWithOptions = ['Area Chart', 'Combo', 'Line', 'Bar', 'Forecasting']
875
870
 
876
871
  const columnsOptions = [
877
872
  <option value='' key={'Select Option'}>
@@ -1027,94 +1022,274 @@ const EditorPanel = () => {
1027
1022
  Configure Chart
1028
1023
  </div>
1029
1024
  <section className='form-container'>
1030
- <form>
1031
- <Accordion allowZeroExpanded={true}>
1025
+ <Accordion allowZeroExpanded={true}>
1026
+ <AccordionItem>
1027
+ {' '}
1028
+ {/* General */}
1029
+ <AccordionItemHeading>
1030
+ <AccordionItemButton>General</AccordionItemButton>
1031
+ </AccordionItemHeading>
1032
+ <AccordionItemPanel>
1033
+ <Select value={config.visualizationType} fieldName='visualizationType' label='Chart Type' updateField={updateField} options={enabledChartTypes} />
1034
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && <Select value={config.visualizationSubType || 'Regular'} fieldName='visualizationSubType' label='Chart Subtype' updateField={updateField} options={['regular', 'stacked']} />}
1035
+ {config.visualizationType === 'Bar' && <Select value={config.orientation || 'vertical'} fieldName='orientation' label='Orientation' updateField={updateField} options={['vertical', 'horizontal']} />}
1036
+ {config.visualizationType === 'Deviation Bar' && <Select label='Orientation' options={['horizontal']} />}
1037
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && <Select value={config.isLollipopChart ? 'lollipop' : config.barStyle || 'flat'} fieldName='barStyle' label='bar style' updateField={updateField} options={showBarStyleOptions()} />}
1038
+ {(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']} />}
1039
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && config.barStyle === 'rounded' && (
1040
+ <Select value={config.roundingStyle || 'standard'} fieldName='roundingStyle' label='rounding style' updateField={updateField} options={['standard', 'shallow', 'finger']} />
1041
+ )}
1042
+ {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']} />}
1043
+ {config.orientation === 'horizontal' && (config.yAxis.labelPlacement === 'Below Bar' || config.yAxis.labelPlacement === 'On Date/Category Axis' || config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') ? (
1044
+ <CheckBox value={config.yAxis.displayNumbersOnBar} section='yAxis' fieldName='displayNumbersOnBar' label={config.isLollipopChart ? 'Display Numbers after Bar' : 'Display Numbers on Bar'} updateField={updateField} />
1045
+ ) : (
1046
+ visHasLabelOnData() && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
1047
+ )}
1048
+ {config.visualizationType === 'Pie' && <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />}
1049
+
1050
+ <TextField
1051
+ value={config.title || 'Chart Title'}
1052
+ fieldName='title'
1053
+ id='title'
1054
+ label='Title'
1055
+ placeholder='Chart Title'
1056
+ //defaultValue='Chart Title'
1057
+ updateField={updateField}
1058
+ //onChange={handleTitleChange}
1059
+ tooltip={
1060
+ <Tooltip style={{ textTransform: 'none' }}>
1061
+ <Tooltip.Target>
1062
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1063
+ </Tooltip.Target>
1064
+ <Tooltip.Content>
1065
+ <p>Title is required to set the name of the download file but can be hidden using the option below.</p>
1066
+ </Tooltip.Content>
1067
+ </Tooltip>
1068
+ }
1069
+ />
1070
+ <CheckBox value={config.showTitle} fieldName='showTitle' label='Show Title' updateField={updateField} />
1071
+ <TextField
1072
+ value={config.superTitle}
1073
+ updateField={updateField}
1074
+ fieldName='superTitle'
1075
+ label='Super Title'
1076
+ placeholder='Super Title'
1077
+ tooltip={
1078
+ <Tooltip style={{ textTransform: 'none' }}>
1079
+ <Tooltip.Target>
1080
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1081
+ </Tooltip.Target>
1082
+ <Tooltip.Content>
1083
+ <p>Super Title</p>
1084
+ </Tooltip.Content>
1085
+ </Tooltip>
1086
+ }
1087
+ />
1088
+
1089
+ <TextField
1090
+ type='textarea'
1091
+ value={config.introText}
1092
+ updateField={updateField}
1093
+ fieldName='introText'
1094
+ label='Intro Text'
1095
+ tooltip={
1096
+ <Tooltip style={{ textTransform: 'none' }}>
1097
+ <Tooltip.Target>
1098
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1099
+ </Tooltip.Target>
1100
+ <Tooltip.Content>
1101
+ <p>Intro Text</p>
1102
+ </Tooltip.Content>
1103
+ </Tooltip>
1104
+ }
1105
+ />
1106
+
1107
+ <TextField
1108
+ type='textarea'
1109
+ value={config.description}
1110
+ fieldName='description'
1111
+ label='Subtext'
1112
+ updateField={updateField}
1113
+ tooltip={
1114
+ <Tooltip style={{ textTransform: 'none' }}>
1115
+ <Tooltip.Target>
1116
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1117
+ </Tooltip.Target>
1118
+ <Tooltip.Content>
1119
+ <p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
1120
+ </Tooltip.Content>
1121
+ </Tooltip>
1122
+ }
1123
+ />
1124
+
1125
+ <TextField
1126
+ type='textarea'
1127
+ value={config.footnotes}
1128
+ updateField={updateField}
1129
+ fieldName='footnotes'
1130
+ label='Footnotes'
1131
+ tooltip={
1132
+ <Tooltip style={{ textTransform: 'none' }}>
1133
+ <Tooltip.Target>
1134
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1135
+ </Tooltip.Target>
1136
+ <Tooltip.Content>
1137
+ <p>Footnotes</p>
1138
+ </Tooltip.Content>
1139
+ </Tooltip>
1140
+ }
1141
+ />
1142
+
1143
+ {config.orientation === 'vertical' && <TextField type='number' value={config.heights.vertical} section='heights' fieldName='vertical' label='Chart Height' updateField={updateField} />}
1144
+ </AccordionItemPanel>
1145
+ </AccordionItem>
1146
+ {config.visualizationType !== 'Pie' && (
1032
1147
  <AccordionItem>
1033
- {' '}
1034
- {/* General */}
1035
1148
  <AccordionItemHeading>
1036
- <AccordionItemButton>General</AccordionItemButton>
1149
+ <AccordionItemButton>Data Series {(!config.series || config.series.length === 0 || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width='25' className='warning-icon' />}</AccordionItemButton>
1037
1150
  </AccordionItemHeading>
1038
1151
  <AccordionItemPanel>
1039
- <Select value={config.visualizationType} fieldName='visualizationType' label='Chart Type' updateField={updateField} options={enabledChartTypes} />
1040
- {(config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && <Select value={config.visualizationSubType || 'Regular'} fieldName='visualizationSubType' label='Chart Subtype' updateField={updateField} options={['regular', 'stacked']} />}
1041
- {config.visualizationType === 'Bar' && <Select value={config.orientation || 'vertical'} fieldName='orientation' label='Orientation' updateField={updateField} options={['vertical', 'horizontal']} />}
1042
- {config.visualizationType === 'Deviation Bar' && <Select label='Orientation' options={['horizontal']} />}
1043
- {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && <Select value={config.isLollipopChart ? 'lollipop' : config.barStyle || 'flat'} fieldName='barStyle' label='bar style' updateField={updateField} options={showBarStyleOptions()} />}
1044
- {(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']} />}
1045
- {(config.visualizationType === 'Bar' || config.visualizationType === 'Deviation Bar') && config.barStyle === 'rounded' && (
1046
- <Select value={config.roundingStyle || 'standard'} fieldName='roundingStyle' label='rounding style' updateField={updateField} options={['standard', 'shallow', 'finger']} />
1047
- )}
1048
- {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']} />}
1049
- {config.orientation === 'horizontal' && (config.yAxis.labelPlacement === 'Below Bar' || config.yAxis.labelPlacement === 'On Date/Category Axis' || config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') ? (
1050
- <CheckBox value={config.yAxis.displayNumbersOnBar} section='yAxis' fieldName='displayNumbersOnBar' label={config.isLollipopChart ? 'Display Numbers after Bar' : 'Display Numbers on Bar'} updateField={updateField} />
1051
- ) : (
1052
- visHasLabelOnData() && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
1152
+ {(!config.series || config.series.length === 0) && config.visualizationType !== 'Paired Bar' && <p className='warning'>At least one series is required</p>}
1153
+ {(!config.series || config.series.length === 0 || config.series.length < 2) && config.visualizationType === 'Paired Bar' && <p className='warning'>Select two data series for paired bar chart (e.g., Male and Female).</p>}
1154
+ <>
1155
+ <Select
1156
+ fieldName='visualizationType'
1157
+ label='Add Data Series'
1158
+ initial='Select'
1159
+ onChange={e => {
1160
+ if (e.target.value !== '' && e.target.value !== 'Select') {
1161
+ addNewSeries(e.target.value)
1162
+ }
1163
+ e.target.value = ''
1164
+ }}
1165
+ options={getColumns()}
1166
+ />
1167
+ {config.series && config.series.length !== 0 && (
1168
+ <Series.Wrapper getColumns={getColumns}>
1169
+ <fieldset>
1170
+ <legend className='edit-label float-left'>Displaying</legend>
1171
+ <Tooltip style={{ textTransform: 'none' }}>
1172
+ <Tooltip.Target>
1173
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1174
+ </Tooltip.Target>
1175
+ <Tooltip.Content>
1176
+ <p>A data series is a set of related data points plotted in a chart and typically represented in the chart legend.</p>
1177
+ </Tooltip.Content>
1178
+ </Tooltip>
1179
+ </fieldset>
1180
+
1181
+ <DragDropContext onDragEnd={({ source, destination }) => handleSeriesChange(source.index, destination.index)}>
1182
+ <Droppable droppableId='filter_order'>
1183
+ {/* prettier-ignore */}
1184
+ {provided => {
1185
+ return (
1186
+ <ul {...provided.droppableProps} className='series-list' ref={provided.innerRef}>
1187
+ <Series.List series={config.series} getItemStyle={getItemStyle} sortableItemStyles={sortableItemStyles} chartsWithOptions={chartsWithOptions} />
1188
+ {provided.placeholder}
1189
+ </ul>
1190
+ )
1191
+ }}
1192
+ </Droppable>
1193
+ </DragDropContext>
1194
+ </Series.Wrapper>
1195
+ )}
1196
+ </>
1197
+
1198
+ {config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
1199
+ <>
1200
+ <span className='divider-heading'>Confidence Keys</span>
1201
+ <Select value={config.confidenceKeys.upper || ''} section='confidenceKeys' fieldName='upper' label='Upper' updateField={updateField} initial='Select' options={getColumns()} />
1202
+ <Select value={config.confidenceKeys.lower || ''} section='confidenceKeys' fieldName='lower' label='Lower' updateField={updateField} initial='Select' options={getColumns()} />
1203
+ </>
1053
1204
  )}
1054
- {config.visualizationType === 'Pie' && <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />}
1055
1205
 
1206
+ {config.series && config.series.length === 1 && <Select fieldName='visualizationType' label='Rank by Value' initial='Select' onChange={e => sortSeries(e.target.value)} options={['asc', 'desc']} />}
1207
+ </AccordionItemPanel>
1208
+ </AccordionItem>
1209
+ )}
1210
+ {config.visualizationType === 'Box Plot' && (
1211
+ <AccordionItem>
1212
+ <AccordionItemHeading>
1213
+ <AccordionItemButton>Measures</AccordionItemButton>
1214
+ </AccordionItemHeading>
1215
+ <AccordionItemPanel>
1216
+ <h4 style={{ fontSize: '18px' }}>Labels for 5-Number Summary</h4>
1217
+
1218
+ {/* prettier-ignore */}
1219
+ {/* max */}
1056
1220
  <TextField
1057
- value={config.title || 'Chart Title'}
1058
- fieldName='title'
1059
- id='title'
1060
- label='Title'
1061
- placeholder='Chart Title'
1062
- //defaultValue='Chart Title'
1221
+ type='text'
1222
+ value={config.boxplot.labels.maximum}
1223
+ fieldName='maximum'
1224
+ section='boxplot'
1225
+ subsection='labels'
1226
+ label='Maximum'
1063
1227
  updateField={updateField}
1064
- //onChange={handleTitleChange}
1065
1228
  tooltip={
1066
1229
  <Tooltip style={{ textTransform: 'none' }}>
1067
1230
  <Tooltip.Target>
1068
1231
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1069
1232
  </Tooltip.Target>
1070
1233
  <Tooltip.Content>
1071
- <p>Title is required to set the name of the download file but can be hidden using the option below.</p>
1234
+ <p>Highest value, excluding outliers</p>
1072
1235
  </Tooltip.Content>
1073
1236
  </Tooltip>
1074
1237
  }
1075
1238
  />
1076
- <CheckBox value={config.showTitle} fieldName='showTitle' label='Show Title' updateField={updateField} />
1239
+
1240
+ {/* prettier-ignore */}
1241
+ {/* Q3 */}
1077
1242
  <TextField
1078
- value={config.superTitle}
1243
+ type='text'
1244
+ value={config.boxplot.labels.q3}
1245
+ fieldName='q3'
1246
+ section='boxplot'
1247
+ subsection='labels'
1248
+ label='Upper Quartile'
1079
1249
  updateField={updateField}
1080
- fieldName='superTitle'
1081
- label='Super Title'
1082
- placeholder='Super Title'
1083
1250
  tooltip={
1084
1251
  <Tooltip style={{ textTransform: 'none' }}>
1085
1252
  <Tooltip.Target>
1086
1253
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1087
1254
  </Tooltip.Target>
1088
1255
  <Tooltip.Content>
1089
- <p>Super Title</p>
1256
+ <p>Represented by top line of box. 25% of data are higher.</p>
1090
1257
  </Tooltip.Content>
1091
1258
  </Tooltip>
1092
1259
  }
1093
1260
  />
1094
1261
 
1262
+ {/* prettier-ignore */}
1263
+ {/* median */}
1095
1264
  <TextField
1096
- type='textarea'
1097
- value={config.introText}
1265
+ type='text'
1266
+ value={config.boxplot.labels.median}
1267
+ fieldName='median'
1268
+ section='boxplot'
1269
+ subsection='labels'
1270
+ label='Median'
1098
1271
  updateField={updateField}
1099
- fieldName='introText'
1100
- label='Intro Text'
1101
1272
  tooltip={
1102
1273
  <Tooltip style={{ textTransform: 'none' }}>
1103
1274
  <Tooltip.Target>
1104
1275
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1105
1276
  </Tooltip.Target>
1106
1277
  <Tooltip.Content>
1107
- <p>Intro Text</p>
1278
+ <p>Middle data point. Half of data are higher value.</p>
1108
1279
  </Tooltip.Content>
1109
1280
  </Tooltip>
1110
1281
  }
1111
1282
  />
1112
1283
 
1284
+ {/* prettier-ignore */}
1285
+ {/* q1 */}
1113
1286
  <TextField
1114
- type='textarea'
1115
- value={config.description}
1116
- fieldName='description'
1117
- label='Subtext'
1287
+ type='text'
1288
+ value={config.boxplot.labels.q1}
1289
+ fieldName='q1'
1290
+ section='boxplot'
1291
+ subsection='labels'
1292
+ label='Lower Quartile'
1118
1293
  updateField={updateField}
1119
1294
  tooltip={
1120
1295
  <Tooltip style={{ textTransform: 'none' }}>
@@ -1122,532 +1297,510 @@ const EditorPanel = () => {
1122
1297
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1123
1298
  </Tooltip.Target>
1124
1299
  <Tooltip.Content>
1125
- <p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
1300
+ <p>Represented by bottom line of box. 25% of data are lower.</p>
1126
1301
  </Tooltip.Content>
1127
1302
  </Tooltip>
1128
1303
  }
1129
1304
  />
1130
1305
 
1306
+ {/* prettier-ignore */}
1307
+ {/* minimum */}
1131
1308
  <TextField
1132
- type='textarea'
1133
- value={config.footnotes}
1309
+ type='text'
1310
+ value={config.boxplot.labels.minimum}
1311
+ fieldName='minimum'
1312
+ section='boxplot'
1313
+ subsection='labels'
1314
+ label='Minimum'
1134
1315
  updateField={updateField}
1135
- fieldName='footnotes'
1136
- label='Footnotes'
1137
1316
  tooltip={
1138
1317
  <Tooltip style={{ textTransform: 'none' }}>
1139
1318
  <Tooltip.Target>
1140
1319
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1141
1320
  </Tooltip.Target>
1142
1321
  <Tooltip.Content>
1143
- <p>Footnotes</p>
1322
+ <p>Lowest value, excluding outliers</p>
1144
1323
  </Tooltip.Content>
1145
1324
  </Tooltip>
1146
1325
  }
1147
1326
  />
1327
+ <br />
1328
+ <h4 style={{ fontSize: '18px' }}>Labels for Additional Measures</h4>
1148
1329
 
1149
- {config.orientation === 'vertical' && <TextField type='number' value={config.heights.vertical} section='heights' fieldName='vertical' label='Chart Height' updateField={updateField} />}
1150
- </AccordionItemPanel>
1151
- </AccordionItem>
1152
- {config.visualizationType !== 'Pie' && (
1153
- <AccordionItem>
1154
- <AccordionItemHeading>
1155
- <AccordionItemButton>Data Series {(!config.series || config.series.length === 0 || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width='25' className='warning-icon' />}</AccordionItemButton>
1156
- </AccordionItemHeading>
1157
- <AccordionItemPanel>
1158
- {(!config.series || config.series.length === 0) && config.visualizationType !== 'Paired Bar' && <p className='warning'>At least one series is required</p>}
1159
- {(!config.series || config.series.length === 0 || config.series.length < 2) && config.visualizationType === 'Paired Bar' && <p className='warning'>Select two data series for paired bar chart (e.g., Male and Female).</p>}
1160
- <Select
1161
- fieldName='visualizationType'
1162
- label='Add Data Series'
1163
- initial='Select'
1164
- onChange={e => {
1165
- if (e.target.value !== '' && e.target.value !== 'Select') {
1166
- addNewSeries(e.target.value)
1167
- }
1168
- e.target.value = ''
1169
- }}
1170
- options={getColumns()}
1171
- />
1172
- {config.series && config.series.length !== 0 && (
1173
- <>
1174
- <fieldset>
1175
- <legend className='edit-label float-left'>Displaying</legend>
1176
- <Tooltip style={{ textTransform: 'none' }}>
1177
- <Tooltip.Target>
1178
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1179
- </Tooltip.Target>
1180
- <Tooltip.Content>
1181
- <p>A data series is a set of related data points plotted in a chart and typically represented in the chart legend.</p>
1182
- </Tooltip.Content>
1183
- </Tooltip>
1184
- </fieldset>
1185
-
1186
- <DragDropContext onDragEnd={({ source, destination }) => handleSeriesChange(source.index, destination.index)}>
1187
- <Droppable droppableId='filter_order'>
1188
- {provided => (
1189
- <ul {...provided.droppableProps} className='series-list' ref={provided.innerRef}>
1190
- {config.series.map((series, i) => {
1191
- if (config.visualizationType === 'Combo' || 'Area Chart') {
1192
- let changeType = (i, value) => {
1193
- let series = [...config.series]
1194
- series[i].type = value
1195
-
1196
- series[i].axis = 'Left'
1197
-
1198
- updateConfig({ ...config, series })
1199
- }
1200
-
1201
- let changeLineType = (i, value) => {
1202
- let series = [...config.series]
1203
- series[i].lineType = value
1204
- updateConfig({ ...config, series })
1205
- }
1206
-
1207
- let typeDropdown = (
1208
- <>
1209
- <label htmlFor='type-dropdown'>Series Type</label>
1210
- <select
1211
- name='type-dropdown'
1212
- value={series.type}
1213
- onChange={event => {
1214
- changeType(i, event.target.value)
1215
- }}
1216
- >
1217
- <option value='' default key='default'>
1218
- Select
1219
- </option>
1220
- {config.visualizationType === 'Combo' && <option value='Bar'>Bar</option>}
1221
- <option value='Line' key='Line'>
1222
- Solid Line
1223
- </option>
1224
- <option value='dashed-sm' key='dashed-sm'>
1225
- Small Dashed
1226
- </option>
1227
- <option value='dashed-md' key='dashed-md'>
1228
- Medium Dashed
1229
- </option>
1230
- <option value='dashed-lg' key='dashed-lg'>
1231
- Large Dashed
1232
- </option>
1233
- <option value='Area Chart' key='Area Chart'>
1234
- Area
1235
- </option>
1236
- </select>
1237
- </>
1238
- )
1239
-
1240
- // used for assigning axis
1241
- let changeAxis = (i, value) => {
1242
- let series = [...config.series]
1243
- series[i].axis = value
1244
- updateConfig({ ...config, series })
1245
- }
1246
-
1247
- // assign an axis dropdown
1248
- let axisDropdown = (
1249
- <>
1250
- <label htmlFor='assign-axis'>Assign an axis</label>
1251
- <select
1252
- name='assign-axis'
1253
- value={series.axis}
1254
- onChange={event => {
1255
- changeAxis(i, event.target.value)
1256
- }}
1257
- >
1258
- <option value='Left' default key='left'>
1259
- left
1260
- </option>
1261
- <option value='Right' key='right'>
1262
- right
1263
- </option>
1264
- </select>
1265
- </>
1266
- )
1267
-
1268
- // line type dropdown
1269
- const lineType = (
1270
- <>
1271
- <label htmlFor='line-type'>Line Type</label>
1272
- <select
1273
- name='line-type'
1274
- value={series.lineStyle}
1275
- onChange={event => {
1276
- changeLineType(i, event.target.value)
1277
- }}
1278
- key='lineTypeSelection'
1279
- >
1280
- <option value='' default>
1281
- Select
1282
- </option>
1283
-
1284
- {Object.keys(approvedCurveTypes).map(curveName => {
1285
- return (
1286
- <option key={`curve-option-${approvedCurveTypes[curveName]}`} value={approvedCurveTypes[curveName]}>
1287
- {curveName}
1288
- </option>
1289
- )
1290
- })}
1291
- </select>
1292
- </>
1293
- )
1294
-
1295
- return (
1296
- <Draggable key={series.dataKey} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
1297
- {(provided, snapshot) => (
1298
- <>
1299
- <div key={i} className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
1300
- <div className={`series-list__name ${series.dataKey.length > 15 ? ' series-list__name--truncate' : ''}`} data-title={series.dataKey}></div>
1301
- <Accordion allowZeroExpanded>
1302
- <AccordionItem className='series-item series-item--chart'>
1303
- <AccordionItemHeading className='series-item__title'>
1304
- <AccordionItemButton className={chartsWithOptions.includes(config.visualizationType) ? 'accordion__button' : 'accordion__button hide-arrow'}>
1305
- <Icon display='move' size={15} style={{ cursor: 'default' }} />
1306
- {series.dataKey}
1307
- {config.series && config.series.length > 1 && (
1308
- <button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
1309
- Remove
1310
- </button>
1311
- )}
1312
- </AccordionItemButton>
1313
- </AccordionItemHeading>
1314
- {chartsWithOptions.includes(config.visualizationType) && (
1315
- <AccordionItemPanel>
1316
- <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
1317
- {config.visualizationType === 'Combo' && (
1318
- <>
1319
- <span className='series-list__dropdown series-item__dropdown'>{typeDropdown}</span>
1320
- {hasRightAxis && config.series && (series.type === 'Line' || series.type === 'dashed-sm' || series.type === 'dashed-md' || series.type === 'dashed-lg') && <span className='series-item__dropdown series-list__dropdown'>{axisDropdown}</span>}
1321
- </>
1322
- )}
1323
- {['Line', 'dashed-sm', 'dashed-md', 'dashed-lg', 'Area Chart'].some(item => item.includes(series.type)) && <span className='series-item__dropdown series-list__dropdown series-list__dropdown--lineType'>{lineType}</span>}
1324
- </div>
1325
- </AccordionItemPanel>
1326
- )}
1327
- </AccordionItem>
1328
- </Accordion>
1329
- </div>
1330
- </>
1331
- )}
1332
- </Draggable>
1333
- )
1334
- }
1335
-
1336
- return (
1337
- <Draggable key={`series.dataKey--${i}`} draggableId={`draggableFilter-${series.dataKey}`} index={i}>
1338
- {(provided, snapshot) => (
1339
- <li
1340
- key={series.dataKey}
1341
- className={snapshot.isDragging ? 'currently-dragging' : ''}
1342
- style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)}
1343
- ref={provided.innerRef}
1344
- {...provided.draggableProps}
1345
- {...provided.dragHandleProps}
1346
- >
1347
- {/*<div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>*/}
1348
- <div className='series-list__name' data-title={series.dataKey}>
1349
- <div className='series-list__name--text'>{series.dataKey}</div>
1350
- </div>
1351
- {config.series && config.series.length > 1 && (
1352
- <button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
1353
- &#215;
1354
- </button>
1355
- )}
1356
- {/*</div>*/}
1357
- </li>
1358
- )}
1359
- </Draggable>
1360
- )
1361
- })}
1362
- {provided.placeholder}
1363
- </ul>
1364
- )}
1365
- </Droppable>
1366
- </DragDropContext>
1367
- </>
1368
- )}
1369
-
1370
- {config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
1371
- <>
1372
- <span className='divider-heading'>Confidence Keys</span>
1373
- <Select value={config.confidenceKeys.upper || ''} section='confidenceKeys' fieldName='upper' label='Upper' updateField={updateField} initial='Select' options={getColumns()} />
1374
- <Select value={config.confidenceKeys.lower || ''} section='confidenceKeys' fieldName='lower' label='Lower' updateField={updateField} initial='Select' options={getColumns()} />
1375
- </>
1376
- )}
1377
-
1378
- {config.series && config.series.length === 1 && <Select fieldName='visualizationType' label='Rank by Value' initial='Select' onChange={e => sortSeries(e.target.value)} options={['asc', 'desc']} />}
1379
- </AccordionItemPanel>
1380
- </AccordionItem>
1381
- )}
1382
- {config.visualizationType === 'Box Plot' && (
1383
- <AccordionItem>
1384
- <AccordionItemHeading>
1385
- <AccordionItemButton>Measures</AccordionItemButton>
1386
- </AccordionItemHeading>
1387
- <AccordionItemPanel>
1388
- <h4 style={{ fontSize: '18px' }}>Labels for 5-Number Summary</h4>
1389
-
1390
- {/* prettier-ignore */}
1391
- {/* max */}
1392
- <TextField
1393
- type='text'
1394
- value={config.boxplot.labels.maximum}
1395
- fieldName='maximum'
1396
- section='boxplot'
1397
- subsection='labels'
1398
- label='Maximum'
1399
- updateField={updateField}
1400
- tooltip={
1401
- <Tooltip style={{ textTransform: 'none' }}>
1402
- <Tooltip.Target>
1403
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1404
- </Tooltip.Target>
1405
- <Tooltip.Content>
1406
- <p>Highest value, excluding outliers</p>
1407
- </Tooltip.Content>
1408
- </Tooltip>
1409
- }
1410
- />
1411
-
1412
- {/* prettier-ignore */}
1413
- {/* Q3 */}
1414
- <TextField
1415
- type='text'
1416
- value={config.boxplot.labels.q3}
1417
- fieldName='q3'
1418
- section='boxplot'
1419
- subsection='labels'
1420
- label='Upper Quartile'
1421
- updateField={updateField}
1422
- tooltip={
1423
- <Tooltip style={{ textTransform: 'none' }}>
1424
- <Tooltip.Target>
1425
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1426
- </Tooltip.Target>
1427
- <Tooltip.Content>
1428
- <p>Represented by top line of box. 25% of data are higher.</p>
1429
- </Tooltip.Content>
1430
- </Tooltip>
1431
- }
1432
- />
1433
-
1434
- {/* prettier-ignore */}
1435
- {/* median */}
1436
- <TextField
1437
- type='text'
1438
- value={config.boxplot.labels.median}
1439
- fieldName='median'
1440
- section='boxplot'
1441
- subsection='labels'
1442
- label='Median'
1443
- updateField={updateField}
1444
- tooltip={
1445
- <Tooltip style={{ textTransform: 'none' }}>
1446
- <Tooltip.Target>
1447
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1448
- </Tooltip.Target>
1449
- <Tooltip.Content>
1450
- <p>Middle data point. Half of data are higher value.</p>
1451
- </Tooltip.Content>
1452
- </Tooltip>
1453
- }
1454
- />
1455
-
1456
- {/* prettier-ignore */}
1457
- {/* q1 */}
1458
- <TextField
1459
- type='text'
1460
- value={config.boxplot.labels.q1}
1461
- fieldName='q1'
1462
- section='boxplot'
1463
- subsection='labels'
1464
- label='Lower Quartile'
1465
- updateField={updateField}
1466
- tooltip={
1467
- <Tooltip style={{ textTransform: 'none' }}>
1468
- <Tooltip.Target>
1469
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1470
- </Tooltip.Target>
1471
- <Tooltip.Content>
1472
- <p>Represented by bottom line of box. 25% of data are lower.</p>
1473
- </Tooltip.Content>
1474
- </Tooltip>
1475
- }
1476
- />
1477
-
1478
- {/* prettier-ignore */}
1479
- {/* minimum */}
1480
- <TextField
1481
- type='text'
1482
- value={config.boxplot.labels.minimum}
1483
- fieldName='minimum'
1484
- section='boxplot'
1485
- subsection='labels'
1486
- label='Minimum'
1487
- updateField={updateField}
1488
- tooltip={
1489
- <Tooltip style={{ textTransform: 'none' }}>
1490
- <Tooltip.Target>
1491
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1492
- </Tooltip.Target>
1493
- <Tooltip.Content>
1494
- <p>Lowest value, excluding outliers</p>
1495
- </Tooltip.Content>
1496
- </Tooltip>
1497
- }
1498
- />
1499
- <br />
1500
- <h4 style={{ fontSize: '18px' }}>Labels for Additional Measures</h4>
1501
-
1502
- {/* iqr */}
1503
- <TextField type='text' value={config.boxplot.labels.iqr} fieldName='iqr' section='boxplot' subsection='labels' label='Interquartile Range' updateField={updateField} />
1330
+ {/* iqr */}
1331
+ <TextField type='text' value={config.boxplot.labels.iqr} fieldName='iqr' section='boxplot' subsection='labels' label='Interquartile Range' updateField={updateField} />
1504
1332
 
1505
- {/* count */}
1506
- <TextField type='text' value={config.boxplot.labels.total} fieldName='total' section='boxplot' subsection='labels' label='Total' updateField={updateField} />
1507
-
1508
- {/* mean */}
1509
- <TextField type='text' value={config.boxplot.labels.mean} fieldName='mean' section='boxplot' subsection='labels' label='Mean' updateField={updateField} />
1510
- {/* outliers */}
1511
- <TextField type='text' value={config.boxplot.labels.outliers} fieldName='outliers' section='boxplot' subsection='labels' label='Outliers' updateField={updateField} />
1512
- {/* values */}
1513
- <TextField type='text' value={config.boxplot.labels.values} fieldName='values' section='boxplot' subsection='labels' label='Values' updateField={updateField} />
1514
- <br />
1515
- <h4 style={{ fontSize: '18px' }}>Percentages for Quartiles</h4>
1516
- <TextField
1517
- type='number'
1518
- value={config.boxplot.firstQuartilePercentage ? config.boxplot.firstQuartilePercentage : 25}
1519
- fieldName='firstQuartilePercentage'
1520
- section='boxplot'
1521
- label='Lower Quartile'
1522
- max={100}
1523
- updateField={updateField}
1524
- tooltip={
1525
- <Tooltip style={{ textTransform: 'none' }}>
1526
- <Tooltip.Target>
1527
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1528
- </Tooltip.Target>
1529
- <Tooltip.Content>
1530
- <p>Represented by bottom line of box. 25% of data are lower.</p>
1531
- </Tooltip.Content>
1532
- </Tooltip>
1533
- }
1534
- />
1333
+ {/* count */}
1334
+ <TextField type='text' value={config.boxplot.labels.total} fieldName='total' section='boxplot' subsection='labels' label='Total' updateField={updateField} />
1535
1335
 
1336
+ {/* mean */}
1337
+ <TextField type='text' value={config.boxplot.labels.mean} fieldName='mean' section='boxplot' subsection='labels' label='Mean' updateField={updateField} />
1338
+ {/* outliers */}
1339
+ <TextField type='text' value={config.boxplot.labels.outliers} fieldName='outliers' section='boxplot' subsection='labels' label='Outliers' updateField={updateField} />
1340
+ {/* values */}
1341
+ <TextField type='text' value={config.boxplot.labels.values} fieldName='values' section='boxplot' subsection='labels' label='Values' updateField={updateField} />
1342
+ </AccordionItemPanel>
1343
+ </AccordionItem>
1344
+ )}
1345
+ <AccordionItem>
1346
+ <AccordionItemHeading>
1347
+ <AccordionItemButton>
1348
+ {config.visualizationType !== 'Pie' ? (config.orientation !== 'horizontal' ? 'Left Value Axis' : 'Value Axis') : 'Data Format'}
1349
+ {config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1350
+ </AccordionItemButton>
1351
+ </AccordionItemHeading>
1352
+ <AccordionItemPanel>
1353
+ {config.visualizationType === 'Pie' && (
1354
+ <Select
1355
+ value={config.yAxis.dataKey || ''}
1356
+ section='yAxis'
1357
+ fieldName='dataKey'
1358
+ label='Data Column'
1359
+ initial='Select'
1360
+ required={true}
1361
+ updateField={updateField}
1362
+ options={getColumns(false)}
1363
+ tooltip={
1364
+ <Tooltip style={{ textTransform: 'none' }}>
1365
+ <Tooltip.Target>
1366
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1367
+ </Tooltip.Target>
1368
+ <Tooltip.Content>
1369
+ <p>Select the source data to be visually represented.</p>
1370
+ </Tooltip.Content>
1371
+ </Tooltip>
1372
+ }
1373
+ />
1374
+ )}
1375
+ {config.visualizationType !== 'Pie' && (
1376
+ <>
1377
+ <TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label' updateField={updateField} />
1378
+ {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} />}
1379
+ <TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1380
+ {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} />}
1536
1381
  <TextField
1382
+ value={config.yAxis.size}
1537
1383
  type='number'
1538
- value={config.boxplot.thirdQuartilePercentage ? config.boxplot.thirdQuartilePercentage : 75}
1539
- fieldName='thirdQuartilePercentage'
1540
- label='Upper Quartile'
1541
- section='boxplot'
1542
- max={100}
1543
- updateField={updateField}
1544
- tooltip={
1545
- <Tooltip style={{ textTransform: 'none' }}>
1546
- <Tooltip.Target>
1547
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1548
- </Tooltip.Target>
1549
- <Tooltip.Content>
1550
- <p>Represented by top line of box. 25% of data are higher.</p>
1551
- </Tooltip.Content>
1552
- </Tooltip>
1553
- }
1554
- />
1555
- </AccordionItemPanel>
1556
- </AccordionItem>
1557
- )}
1558
- <AccordionItem>
1559
- <AccordionItemHeading>
1560
- <AccordionItemButton>
1561
- {config.visualizationType !== 'Pie' ? (config.orientation !== 'horizontal' ? 'Left Value Axis' : 'Value Axis') : 'Data Format'}
1562
- {config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1563
- </AccordionItemButton>
1564
- </AccordionItemHeading>
1565
- <AccordionItemPanel>
1566
- {config.visualizationType === 'Pie' && (
1567
- <Select
1568
- value={config.yAxis.dataKey || ''}
1569
1384
  section='yAxis'
1570
- fieldName='dataKey'
1571
- label='Data Column'
1572
- initial='Select'
1573
- required={true}
1385
+ fieldName='size'
1386
+ label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
1387
+ className='number-narrow'
1574
1388
  updateField={updateField}
1575
- options={getColumns(false)}
1576
1389
  tooltip={
1577
1390
  <Tooltip style={{ textTransform: 'none' }}>
1578
1391
  <Tooltip.Target>
1579
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1392
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1580
1393
  </Tooltip.Target>
1581
1394
  <Tooltip.Content>
1582
- <p>Select the source data to be visually represented.</p>
1395
+ <p>{`Increase the size if elements in the ${config.orientation} axis are being crowded or hidden behind other elements. Decrease if less space is required for the value axis.`}</p>
1583
1396
  </Tooltip.Content>
1584
1397
  </Tooltip>
1585
1398
  }
1586
1399
  />
1587
- )}
1588
- {config.visualizationType !== 'Pie' && (
1589
- <>
1590
- <TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label' updateField={updateField} />
1591
- {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} />}
1592
- <TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1593
- {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} />}
1400
+ {config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
1401
+ {(config.orientation === 'vertical' || !config.isResponsiveTicks) && <TextField value={config.yAxis.tickRotation} type='number' min='0' section='yAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
1402
+ {config.isResponsiveTicks && config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && (
1594
1403
  <TextField
1595
- value={config.yAxis.size}
1404
+ value={config.xAxis.maxTickRotation}
1596
1405
  type='number'
1597
- section='yAxis'
1598
- fieldName='size'
1599
- label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
1406
+ min='0'
1407
+ section='xAxis'
1408
+ fieldName='maxTickRotation'
1409
+ label='Max Tick Rotation'
1600
1410
  className='number-narrow'
1601
1411
  updateField={updateField}
1602
1412
  tooltip={
1603
1413
  <Tooltip style={{ textTransform: 'none' }}>
1604
1414
  <Tooltip.Target>
1605
- <Icon display='question' />
1415
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1606
1416
  </Tooltip.Target>
1607
1417
  <Tooltip.Content>
1608
- <p>{`Increase the size if elements in the ${config.orientation} axis are being crowded or hidden behind other elements. Decrease if less space is required for the value axis.`}</p>
1418
+ <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
1609
1419
  </Tooltip.Content>
1610
1420
  </Tooltip>
1611
1421
  }
1612
1422
  />
1613
- {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1614
- {/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1615
- {config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
1616
- {config.orientation !== 'horizontal' && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Display Gridlines' updateField={updateField} />}
1617
- <CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
1618
- {config.visualizationSubType === 'regular' && <CheckBox value={config.useLogScale} fieldName='useLogScale' label='use logarithmic scale' updateField={updateField} />}
1619
- </>
1620
- )}
1621
- <span className='divider-heading'>Number Formatting</span>
1622
- <CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
1623
- <CheckBox
1624
- value={config.dataFormat.abbreviated}
1423
+ )}
1424
+
1425
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1426
+ {/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1427
+ {config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
1428
+ {config.orientation !== 'horizontal' && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Show Gridlines' updateField={updateField} />}
1429
+ <CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
1430
+ {config.visualizationSubType === 'regular' && <CheckBox value={config.useLogScale} fieldName='useLogScale' label='use logarithmic scale' updateField={updateField} />}
1431
+ </>
1432
+ )}
1433
+ <span className='divider-heading'>Number Formatting</span>
1434
+ <CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
1435
+ <CheckBox
1436
+ value={config.dataFormat.abbreviated}
1437
+ section='dataFormat'
1438
+ fieldName='abbreviated'
1439
+ label='Abbreviate Axis Values'
1440
+ updateField={updateField}
1441
+ tooltip={
1442
+ <Tooltip style={{ textTransform: 'none' }}>
1443
+ <Tooltip.Target>
1444
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1445
+ </Tooltip.Target>
1446
+ <Tooltip.Content>
1447
+ <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1448
+ </Tooltip.Content>
1449
+ </Tooltip>
1450
+ }
1451
+ />
1452
+ <TextField value={config.dataFormat.roundTo ? config.dataFormat.roundTo : 0} type='number' section='dataFormat' fieldName='roundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1453
+ <div className='two-col-inputs'>
1454
+ <TextField
1455
+ value={config.dataFormat.prefix}
1625
1456
  section='dataFormat'
1626
- fieldName='abbreviated'
1627
- label='Abbreviate Axis Values'
1457
+ fieldName='prefix'
1458
+ label='Prefix'
1628
1459
  updateField={updateField}
1629
1460
  tooltip={
1630
1461
  <Tooltip style={{ textTransform: 'none' }}>
1631
1462
  <Tooltip.Target>
1632
- <Icon display='question' />
1463
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1633
1464
  </Tooltip.Target>
1634
1465
  <Tooltip.Content>
1635
- <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1466
+ {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1467
+ {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1636
1468
  </Tooltip.Content>
1637
1469
  </Tooltip>
1638
1470
  }
1639
1471
  />
1640
- <TextField value={config.dataFormat.roundTo} type='number' section='dataFormat' fieldName='roundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1641
- <div className='two-col-inputs'>
1642
- <TextField
1643
- value={config.dataFormat.prefix}
1644
- section='dataFormat'
1645
- fieldName='prefix'
1646
- label='Prefix'
1647
- updateField={updateField}
1648
- tooltip={
1649
- <Tooltip style={{ textTransform: 'none' }}>
1650
- <Tooltip.Target>
1472
+ <TextField
1473
+ value={config.dataFormat.suffix}
1474
+ section='dataFormat'
1475
+ fieldName='suffix'
1476
+ label='Suffix'
1477
+ updateField={updateField}
1478
+ tooltip={
1479
+ <Tooltip style={{ textTransform: 'none' }}>
1480
+ <Tooltip.Target>
1481
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1482
+ </Tooltip.Target>
1483
+ <Tooltip.Content>
1484
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1485
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1486
+ </Tooltip.Content>
1487
+ </Tooltip>
1488
+ }
1489
+ />
1490
+ </div>
1491
+
1492
+ {config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
1493
+ <>
1494
+ <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1495
+ <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1496
+ <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1497
+ <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />
1498
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1499
+ <TextField value={config.xAxis.min} section='xAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1500
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1501
+ {config.visualizationType === 'Deviation Bar' && (
1502
+ <>
1503
+ <TextField value={config.xAxis.target} section='xAxis' fieldName='target' type='number' label='Deviation point' placeholder='Auto' updateField={updateField} />
1504
+ <TextField value={config.xAxis.targetLabel || 'Target'} section='xAxis' fieldName='targetLabel' type='text' label='Deviation point Label' updateField={updateField} />
1505
+ <CheckBox value={config.xAxis.showTargetLabel} section='xAxis' fieldName='showTargetLabel' label='Show Deviation point label' updateField={updateField} />
1506
+ </>
1507
+ )}
1508
+ </>
1509
+ ) : (
1510
+ config.visualizationType !== 'Pie' && (
1511
+ <>
1512
+ <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1513
+ <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1514
+ <CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1515
+
1516
+ <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='max value' placeholder='Auto' updateField={updateField} />
1517
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1518
+ <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1519
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1520
+ </>
1521
+ )
1522
+ )}
1523
+
1524
+ {/* start: anchors */}
1525
+ {visHasAnchors() && config.orientation !== 'horizontal' && (
1526
+ <div className='edit-block'>
1527
+ <span className='edit-label column-heading'>Anchors</span>
1528
+ <Accordion allowZeroExpanded>
1529
+ {config.yAxis?.anchors?.map((anchor, index) => (
1530
+ <AccordionItem className='series-item series-item--chart' key={`yaxis-anchors-2-${index}`}>
1531
+ <AccordionItemHeading className='series-item__title'>
1532
+ <>
1533
+ <AccordionItemButton className={'accordion__button accordion__button'}>
1534
+ Anchor {index + 1}
1535
+ <button
1536
+ className='series-list__remove'
1537
+ onClick={e => {
1538
+ e.preventDefault()
1539
+ const copiedAnchorGroups = [...config.yAxis.anchors]
1540
+ copiedAnchorGroups.splice(index, 1)
1541
+ updateConfig({
1542
+ ...config,
1543
+ yAxis: {
1544
+ ...config.yAxis,
1545
+ anchors: copiedAnchorGroups
1546
+ }
1547
+ })
1548
+ }}
1549
+ >
1550
+ Remove
1551
+ </button>
1552
+ </AccordionItemButton>
1553
+ </>
1554
+ </AccordionItemHeading>
1555
+ <AccordionItemPanel>
1556
+ <label>
1557
+ <span>Anchor Value</span>
1558
+ <Tooltip style={{ textTransform: 'none' }}>
1559
+ <Tooltip.Target>
1560
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1561
+ </Tooltip.Target>
1562
+ <Tooltip.Content>
1563
+ <p>Enter the value as its shown in the data column</p>
1564
+ </Tooltip.Content>
1565
+ </Tooltip>
1566
+ <input
1567
+ type='text'
1568
+ value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
1569
+ onChange={e => {
1570
+ e.preventDefault()
1571
+ const copiedAnchors = [...config.yAxis.anchors]
1572
+ copiedAnchors[index].value = e.target.value
1573
+ updateConfig({
1574
+ ...config,
1575
+ yAxis: {
1576
+ ...config.yAxis,
1577
+ anchors: copiedAnchors
1578
+ }
1579
+ })
1580
+ }}
1581
+ />
1582
+ </label>
1583
+
1584
+ <label>
1585
+ <span>Anchor Color</span>
1586
+ <input
1587
+ type='text'
1588
+ value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
1589
+ onChange={e => {
1590
+ e.preventDefault()
1591
+ const copiedAnchors = [...config.yAxis.anchors]
1592
+ copiedAnchors[index].color = e.target.value
1593
+ updateConfig({
1594
+ ...config,
1595
+ yAxis: {
1596
+ ...config.yAxis,
1597
+ anchors: copiedAnchors
1598
+ }
1599
+ })
1600
+ }}
1601
+ />
1602
+ </label>
1603
+
1604
+ <label>
1605
+ Anchor Line Style
1606
+ <select
1607
+ value={config.yAxis.anchors[index].lineStyle || ''}
1608
+ onChange={e => {
1609
+ const copiedAnchors = [...config.yAxis.anchors]
1610
+ copiedAnchors[index].lineStyle = e.target.value
1611
+ updateConfig({
1612
+ ...config,
1613
+ yAxis: {
1614
+ ...config.yAxis,
1615
+ anchors: copiedAnchors
1616
+ }
1617
+ })
1618
+ }}
1619
+ >
1620
+ <option>Select</option>
1621
+ {lineOptions.map(line => (
1622
+ <option key={line.key}>{line.value}</option>
1623
+ ))}
1624
+ </select>
1625
+ </label>
1626
+ </AccordionItemPanel>
1627
+ </AccordionItem>
1628
+ ))}
1629
+ </Accordion>
1630
+
1631
+ <button
1632
+ className='btn full-width'
1633
+ onClick={e => {
1634
+ e.preventDefault()
1635
+ const anchors = [...config.yAxis.anchors]
1636
+ anchors.push({})
1637
+ updateConfig({
1638
+ ...config,
1639
+ yAxis: {
1640
+ ...config.yAxis,
1641
+ anchors
1642
+ }
1643
+ })
1644
+ }}
1645
+ >
1646
+ Add Anchor
1647
+ </button>
1648
+ </div>
1649
+ )}
1650
+
1651
+ {visHasAnchors() && config.orientation === 'horizontal' && (
1652
+ <div className='edit-block'>
1653
+ <span className='edit-label column-heading'>Anchors</span>
1654
+ <Accordion allowZeroExpanded>
1655
+ {config.xAxis?.anchors?.map((anchor, index) => (
1656
+ <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-${index}`}>
1657
+ <AccordionItemHeading className='series-item__title'>
1658
+ <>
1659
+ <AccordionItemButton className={'accordion__button accordion__button'}>
1660
+ Anchor {index + 1}
1661
+ <button
1662
+ className='series-list__remove'
1663
+ onClick={e => {
1664
+ e.preventDefault()
1665
+ const copiedAnchorGroups = [...config.xAxis.anchors]
1666
+ copiedAnchorGroups.splice(index, 1)
1667
+ updateConfig({
1668
+ ...config,
1669
+ xAxis: {
1670
+ ...config.xAxis,
1671
+ anchors: copiedAnchorGroups
1672
+ }
1673
+ })
1674
+ }}
1675
+ >
1676
+ Remove
1677
+ </button>
1678
+ </AccordionItemButton>
1679
+ </>
1680
+ </AccordionItemHeading>
1681
+ <AccordionItemPanel>
1682
+ <label>
1683
+ <span>Anchor Value</span>
1684
+ <Tooltip style={{ textTransform: 'none' }}>
1685
+ <Tooltip.Target>
1686
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1687
+ </Tooltip.Target>
1688
+ <Tooltip.Content>
1689
+ <p>Enter the value as its shown in the data column</p>
1690
+ </Tooltip.Content>
1691
+ </Tooltip>
1692
+ <input
1693
+ type='text'
1694
+ value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
1695
+ onChange={e => {
1696
+ e.preventDefault()
1697
+ const copiedAnchors = [...config.xAxis.anchors]
1698
+ copiedAnchors[index].value = e.target.value
1699
+ updateConfig({
1700
+ ...config,
1701
+ xAxis: {
1702
+ ...config.xAxis,
1703
+ anchors: copiedAnchors
1704
+ }
1705
+ })
1706
+ }}
1707
+ />
1708
+ </label>
1709
+
1710
+ <label>
1711
+ <span>Anchor Color</span>
1712
+ <input
1713
+ type='text'
1714
+ value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
1715
+ onChange={e => {
1716
+ e.preventDefault()
1717
+ const copiedAnchors = [...config.xAxis.anchors]
1718
+ copiedAnchors[index].color = e.target.value
1719
+ updateConfig({
1720
+ ...config,
1721
+ xAxis: {
1722
+ ...config.xAxis,
1723
+ anchors: copiedAnchors
1724
+ }
1725
+ })
1726
+ }}
1727
+ />
1728
+ </label>
1729
+
1730
+ <label>
1731
+ Anchor Line Style
1732
+ <select
1733
+ value={config.xAxis.anchors[index].lineStyle || ''}
1734
+ onChange={e => {
1735
+ const copiedAnchors = [...config.xAxis.anchors]
1736
+ copiedAnchors[index].lineStyle = e.target.value
1737
+ updateConfig({
1738
+ ...config,
1739
+ xAxis: {
1740
+ ...config.xAxis,
1741
+ anchors: copiedAnchors
1742
+ }
1743
+ })
1744
+ }}
1745
+ >
1746
+ <option>Select</option>
1747
+ {lineOptions.map(line => (
1748
+ <option key={line.key}>{line.value}</option>
1749
+ ))}
1750
+ </select>
1751
+ </label>
1752
+ </AccordionItemPanel>
1753
+ </AccordionItem>
1754
+ ))}
1755
+ </Accordion>
1756
+
1757
+ <button
1758
+ className='btn full-width'
1759
+ onClick={e => {
1760
+ e.preventDefault()
1761
+ const anchors = [...config.xAxis.anchors]
1762
+ anchors.push({})
1763
+ updateConfig({
1764
+ ...config,
1765
+ xAxis: {
1766
+ ...config.xAxis,
1767
+ anchors
1768
+ }
1769
+ })
1770
+ }}
1771
+ >
1772
+ Add Anchor
1773
+ </button>
1774
+ </div>
1775
+ )}
1776
+ {/* end: anchors */}
1777
+ </AccordionItemPanel>
1778
+ </AccordionItem>
1779
+ {/* Right Value Axis Settings */}
1780
+ {hasRightAxis && (
1781
+ <AccordionItem>
1782
+ <AccordionItemHeading>
1783
+ <AccordionItemButton>Right Value Axis</AccordionItemButton>
1784
+ </AccordionItemHeading>
1785
+ <AccordionItemPanel>
1786
+ <TextField value={config.yAxis.rightLabel} section='yAxis' fieldName='rightLabel' label='Label' updateField={updateField} />
1787
+ <TextField value={config.yAxis.rightNumTicks} placeholder='Auto' type='number' section='yAxis' fieldName='rightNumTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1788
+ <TextField value={config.yAxis.rightAxisSize} type='number' section='yAxis' fieldName='rightAxisSize' label='Size (Width)' className='number-narrow' updateField={updateField} />
1789
+ <TextField value={config.yAxis.rightLabelOffsetSize} type='number' section='yAxis' fieldName='rightLabelOffsetSize' label='Label Offset' className='number-narrow' updateField={updateField} />
1790
+
1791
+ <span className='divider-heading'>Number Formatting</span>
1792
+ <CheckBox value={config.dataFormat.rightCommas} section='dataFormat' fieldName='rightCommas' label='Add commas' updateField={updateField} />
1793
+ <TextField value={config.dataFormat.rightRoundTo} type='number' section='dataFormat' fieldName='rightRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1794
+ <div className='two-col-inputs'>
1795
+ <TextField
1796
+ value={config.dataFormat.rightPrefix}
1797
+ section='dataFormat'
1798
+ fieldName='rightPrefix'
1799
+ label='Prefix'
1800
+ updateField={updateField}
1801
+ tooltip={
1802
+ <Tooltip style={{ textTransform: 'none' }}>
1803
+ <Tooltip.Target>
1651
1804
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1652
1805
  </Tooltip.Target>
1653
1806
  <Tooltip.Content>
@@ -1658,9 +1811,9 @@ const EditorPanel = () => {
1658
1811
  }
1659
1812
  />
1660
1813
  <TextField
1661
- value={config.dataFormat.suffix}
1814
+ value={config.dataFormat.rightSuffix}
1662
1815
  section='dataFormat'
1663
- fieldName='suffix'
1816
+ fieldName='rightSuffix'
1664
1817
  label='Suffix'
1665
1818
  updateField={updateField}
1666
1819
  tooltip={
@@ -1677,1093 +1830,779 @@ const EditorPanel = () => {
1677
1830
  />
1678
1831
  </div>
1679
1832
 
1680
- {config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
1681
- <>
1682
- <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1683
- <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1684
- <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1685
- <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />
1686
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1687
- <TextField value={config.xAxis.min} section='xAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1688
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1689
- {config.visualizationType === 'Deviation Bar' && (
1690
- <>
1691
- <TextField value={config.xAxis.target} section='xAxis' fieldName='target' type='number' label='Deviation point' placeholder='Auto' updateField={updateField} />
1692
- <TextField value={config.xAxis.targetLabel || 'Target'} section='xAxis' fieldName='targetLabel' type='text' label='Deviation point Label' updateField={updateField} />
1693
- <CheckBox value={config.xAxis.showTargetLabel} section='xAxis' fieldName='showTargetLabel' label='Display Deviation point label' updateField={updateField} />
1694
- </>
1695
- )}
1696
- </>
1697
- ) : (
1698
- config.visualizationType !== 'Pie' && (
1833
+ <CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
1834
+ <CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Label' updateField={updateField} />
1835
+ <CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
1836
+ </AccordionItemPanel>
1837
+ </AccordionItem>
1838
+ )}
1839
+ <AccordionItem>
1840
+ <AccordionItemHeading>
1841
+ <AccordionItemButton>
1842
+ {config.visualizationType !== 'Pie' ? (config.visualizationType === 'Bar' ? 'Date/Category Axis' : 'Date/Category Axis') : 'Segments'}
1843
+ {!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1844
+ </AccordionItemButton>
1845
+ </AccordionItemHeading>
1846
+ <AccordionItemPanel>
1847
+ {config.visualizationType !== 'Pie' && (
1848
+ <>
1849
+ <Select value={config.xAxis.type} section='xAxis' fieldName='type' label='Data Type' updateField={updateField} options={config.visualizationType !== 'Scatter Plot' ? ['categorical', 'date'] : ['categorical', 'continuous', 'date']} />
1850
+ <Select
1851
+ value={config.xAxis.dataKey || setCategoryAxis() || ''}
1852
+ section='xAxis'
1853
+ fieldName='dataKey'
1854
+ label='Data Key'
1855
+ initial='Select'
1856
+ required={true}
1857
+ updateField={updateField}
1858
+ options={getColumns(false)}
1859
+ tooltip={
1860
+ <Tooltip style={{ textTransform: 'none' }}>
1861
+ <Tooltip.Target>
1862
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1863
+ </Tooltip.Target>
1864
+ <Tooltip.Content>
1865
+ <p>Select the column or row containing the categories or dates for this axis. </p>
1866
+ </Tooltip.Content>
1867
+ </Tooltip>
1868
+ }
1869
+ />
1870
+ </>
1871
+ )}
1872
+
1873
+ {config.visualizationType === 'Pie' && (
1874
+ <Select
1875
+ value={config.xAxis.dataKey || ''}
1876
+ section='xAxis'
1877
+ fieldName='dataKey'
1878
+ label='Segment Labels'
1879
+ initial='Select'
1880
+ required={true}
1881
+ updateField={updateField}
1882
+ options={getColumns(false)}
1883
+ tooltip={
1884
+ <Tooltip style={{ textTransform: 'none' }}>
1885
+ <Tooltip.Target>
1886
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1887
+ </Tooltip.Target>
1888
+ <Tooltip.Content>
1889
+ <p>Select the source row or column that contains the segment labels. Depending on the data structure, it may be listed as "Key."</p>
1890
+ </Tooltip.Content>
1891
+ </Tooltip>
1892
+ }
1893
+ />
1894
+ )}
1895
+
1896
+ {config.visualizationType !== 'Pie' && (
1897
+ <>
1898
+ <TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
1899
+
1900
+ {config.xAxis.type === 'continuous' && (
1699
1901
  <>
1700
- <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1701
- <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1702
- <CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1902
+ <TextField
1903
+ value={config.dataFormat.bottomPrefix}
1904
+ section='dataFormat'
1905
+ fieldName='bottomPrefix'
1906
+ label='Prefix'
1907
+ updateField={updateField}
1908
+ tooltip={
1909
+ <Tooltip style={{ textTransform: 'none' }}>
1910
+ <Tooltip.Target>
1911
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1912
+ </Tooltip.Target>
1913
+ <Tooltip.Content>
1914
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1915
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1916
+ </Tooltip.Content>
1917
+ </Tooltip>
1918
+ }
1919
+ />
1703
1920
 
1704
- <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='max value' placeholder='Auto' updateField={updateField} />
1705
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1706
- <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />
1707
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1708
- </>
1709
- )
1710
- )}
1921
+ <TextField
1922
+ value={config.dataFormat.bottomSuffix}
1923
+ section='dataFormat'
1924
+ fieldName='bottomSuffix'
1925
+ label='Suffix'
1926
+ updateField={updateField}
1927
+ tooltip={
1928
+ <Tooltip style={{ textTransform: 'none' }}>
1929
+ <Tooltip.Target>
1930
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1931
+ </Tooltip.Target>
1932
+ <Tooltip.Content>
1933
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1934
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1935
+ </Tooltip.Content>
1936
+ </Tooltip>
1937
+ }
1938
+ />
1711
1939
 
1712
- {/* start: anchors */}
1713
- {visHasAnchors() && config.orientation !== 'horizontal' ? (
1714
- <div className='edit-block'>
1715
- <h3>Anchors</h3>
1716
- <Accordion allowZeroExpanded>
1717
- {config.yAxis?.anchors?.map((anchor, index) => (
1718
- <AccordionItem className='series-item series-item--chart'>
1719
- <AccordionItemHeading className='series-item__title'>
1720
- <>
1721
- <AccordionItemButton className={'accordion__button accordion__button'}>
1722
- Anchor {index + 1}
1723
- <button
1724
- className='series-list__remove'
1725
- onClick={e => {
1726
- e.preventDefault()
1727
- const copiedAnchorGroups = [...config.yAxis.anchors]
1728
- copiedAnchorGroups.splice(index, 1)
1729
- updateConfig({
1730
- ...config,
1731
- yAxis: {
1732
- ...config.yAxis,
1733
- anchors: copiedAnchorGroups
1734
- }
1735
- })
1736
- }}
1737
- >
1738
- Remove
1739
- </button>
1740
- </AccordionItemButton>
1741
- </>
1742
- </AccordionItemHeading>
1743
- <AccordionItemPanel>
1744
- <label>
1745
- <span>Anchor Value</span>
1746
- <Tooltip style={{ textTransform: 'none' }}>
1747
- <Tooltip.Target>
1748
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1749
- </Tooltip.Target>
1750
- <Tooltip.Content>
1751
- <p>Enter the value as its shown in the data column</p>
1752
- </Tooltip.Content>
1753
- </Tooltip>
1754
- <input
1755
- type='text'
1756
- value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
1757
- onChange={e => {
1758
- e.preventDefault()
1759
- const copiedAnchors = [...config.yAxis.anchors]
1760
- copiedAnchors[index].value = e.target.value
1761
- updateConfig({
1762
- ...config,
1763
- yAxis: {
1764
- ...config.yAxis,
1765
- anchors: copiedAnchors
1766
- }
1767
- })
1768
- }}
1769
- />
1770
- </label>
1940
+ <CheckBox
1941
+ value={config.dataFormat.bottomAbbreviated}
1942
+ section='dataFormat'
1943
+ fieldName='bottomAbbreviated'
1944
+ label='Abbreviate Axis Values'
1945
+ updateField={updateField}
1946
+ tooltip={
1947
+ <Tooltip style={{ textTransform: 'none' }}>
1948
+ <Tooltip.Target>
1949
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1950
+ </Tooltip.Target>
1951
+ <Tooltip.Content>
1952
+ <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1953
+ </Tooltip.Content>
1954
+ </Tooltip>
1955
+ }
1956
+ />
1957
+ </>
1958
+ )}
1771
1959
 
1772
- <label>
1773
- <span>Anchor Color</span>
1774
- <input
1775
- type='text'
1776
- value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
1777
- onChange={e => {
1778
- e.preventDefault()
1779
- const copiedAnchors = [...config.yAxis.anchors]
1780
- copiedAnchors[index].color = e.target.value
1781
- updateConfig({
1782
- ...config,
1783
- yAxis: {
1784
- ...config.yAxis,
1785
- anchors: copiedAnchors
1786
- }
1787
- })
1788
- }}
1789
- />
1790
- </label>
1960
+ {config.xAxis.type === 'date' && (
1961
+ <>
1962
+ <p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
1963
+ Format how charts should parse and display your dates using{' '}
1964
+ <a href='https://github.com/d3/d3-time-format#locale_format' target='_blank' rel='noreferrer'>
1965
+ these guidelines
1966
+ </a>
1967
+ .
1968
+ </p>
1969
+ <TextField value={config.xAxis.dateParseFormat} section='xAxis' fieldName='dateParseFormat' placeholder='Ex. %Y-%m-%d' label='Date Parse Format' updateField={updateField} />
1970
+ <TextField value={config.xAxis.dateDisplayFormat} section='xAxis' fieldName='dateDisplayFormat' placeholder='Ex. %Y-%m-%d' label='Date Display Format' updateField={updateField} />
1971
+ </>
1972
+ )}
1791
1973
 
1792
- <label>
1793
- Anchor Line Style
1794
- <select
1795
- value={config.yAxis.anchors[index].lineStyle || ''}
1796
- onChange={e => {
1797
- const copiedAnchors = [...config.yAxis.anchors]
1798
- copiedAnchors[index].lineStyle = e.target.value
1799
- updateConfig({
1800
- ...config,
1801
- yAxis: {
1802
- ...config.yAxis,
1803
- anchors: copiedAnchors
1804
- }
1805
- })
1806
- }}
1807
- >
1808
- <option>Select</option>
1809
- {lineOptions.map(line => (
1810
- <option key={line.key}>{line.value}</option>
1811
- ))}
1812
- </select>
1813
- </label>
1814
- </AccordionItemPanel>
1815
- </AccordionItem>
1816
- ))}
1817
- </Accordion>
1974
+ <CheckBox
1975
+ value={config.exclusions.active}
1976
+ section='exclusions'
1977
+ fieldName='active'
1978
+ label={config.xAxis.type === 'date' ? 'Limit by start and/or end dates' : 'Exclude one or more values'}
1979
+ tooltip={
1980
+ <Tooltip style={{ textTransform: 'none' }}>
1981
+ <Tooltip.Target>
1982
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1983
+ </Tooltip.Target>
1984
+ <Tooltip.Content>
1985
+ <p>When this option is checked, you can select source-file values for exclusion from the date/category axis. </p>
1986
+ </Tooltip.Content>
1987
+ </Tooltip>
1988
+ }
1989
+ updateField={updateField}
1990
+ />
1818
1991
 
1819
- <button
1820
- className='btn full-width'
1821
- onClick={e => {
1822
- e.preventDefault()
1823
- const anchors = [...config.yAxis.anchors]
1824
- anchors.push({})
1825
- updateConfig({
1826
- ...config,
1827
- yAxis: {
1828
- ...config.yAxis,
1829
- anchors
1830
- }
1831
- })
1832
- }}
1833
- >
1834
- Add Anchor
1835
- </button>
1836
- </div>
1837
- ) : (
1838
- <div className='edit-block'>
1839
- <h3>Anchors</h3>
1840
- <Accordion allowZeroExpanded>
1841
- {config.xAxis?.anchors?.map((anchor, index) => (
1842
- <AccordionItem className='series-item series-item--chart'>
1843
- <AccordionItemHeading className='series-item__title'>
1992
+ {config.exclusions.active && (
1993
+ <>
1994
+ {config.xAxis.type === 'categorical' && (
1995
+ <>
1996
+ {config.exclusions.keys.length > 0 && (
1844
1997
  <>
1845
- <AccordionItemButton className={'accordion__button accordion__button'}>
1846
- Anchor {index + 1}
1847
- <button
1848
- className='series-list__remove'
1849
- onClick={e => {
1850
- e.preventDefault()
1851
- const copiedAnchorGroups = [...config.xAxis.anchors]
1852
- copiedAnchorGroups.splice(index, 1)
1853
- updateConfig({
1854
- ...config,
1855
- xAxis: {
1856
- ...config.xAxis,
1857
- anchors: copiedAnchorGroups
1858
- }
1859
- })
1860
- }}
1861
- >
1862
- Remove
1863
- </button>
1864
- </AccordionItemButton>
1998
+ <fieldset>
1999
+ <legend className='edit-label'>Excluded Keys</legend>
2000
+ </fieldset>
2001
+ <ExclusionsList />
1865
2002
  </>
1866
- </AccordionItemHeading>
1867
- <AccordionItemPanel>
1868
- <label>
1869
- <span>Anchor Value</span>
1870
- <Tooltip style={{ textTransform: 'none' }}>
1871
- <Tooltip.Target>
1872
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1873
- </Tooltip.Target>
1874
- <Tooltip.Content>
1875
- <p>Enter the value as its shown in the data column</p>
1876
- </Tooltip.Content>
1877
- </Tooltip>
1878
- <input
1879
- type='text'
1880
- value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
1881
- onChange={e => {
1882
- e.preventDefault()
1883
- const copiedAnchors = [...config.xAxis.anchors]
1884
- copiedAnchors[index].value = e.target.value
1885
- updateConfig({
1886
- ...config,
1887
- xAxis: {
1888
- ...config.xAxis,
1889
- anchors: copiedAnchors
1890
- }
1891
- })
1892
- }}
1893
- />
1894
- </label>
2003
+ )}
1895
2004
 
1896
- <label>
1897
- <span>Anchor Color</span>
1898
- <input
1899
- type='text'
1900
- value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
1901
- onChange={e => {
1902
- e.preventDefault()
1903
- const copiedAnchors = [...config.xAxis.anchors]
1904
- copiedAnchors[index].color = e.target.value
1905
- updateConfig({
1906
- ...config,
1907
- xAxis: {
1908
- ...config.xAxis,
1909
- anchors: copiedAnchors
1910
- }
1911
- })
1912
- }}
1913
- />
1914
- </label>
2005
+ <Select
2006
+ fieldName='visualizationType'
2007
+ label='Add Exclusion'
2008
+ initial='Select'
2009
+ onChange={e => {
2010
+ if (e.target.value !== '' && e.target.value !== 'Select') {
2011
+ addNewExclusion(e.target.value)
2012
+ }
2013
+ e.target.value = ''
2014
+ }}
2015
+ options={getDataValues(config.xAxis.dataKey, true)}
2016
+ />
2017
+ </>
2018
+ )}
2019
+
2020
+ {config.xAxis.type === 'date' && (
2021
+ <>
2022
+ <TextField type='date' section='exclusions' fieldName='dateStart' label='Start Date' updateField={updateField} value={config.exclusions.dateStart || ''} />
2023
+ <TextField type='date' section='exclusions' fieldName='dateEnd' label='End Date' updateField={updateField} value={config.exclusions.dateEnd || ''} />
2024
+ </>
2025
+ )}
2026
+ </>
2027
+ )}
2028
+ <TextField value={config.xAxis.numTicks} placeholder='Auto' type='number' min='1' section='xAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1915
2029
 
1916
- <label>
1917
- Anchor Line Style
1918
- <select
1919
- value={config.xAxis.anchors[index].lineStyle || ''}
1920
- onChange={e => {
1921
- const copiedAnchors = [...config.xAxis.anchors]
1922
- copiedAnchors[index].lineStyle = e.target.value
1923
- updateConfig({
1924
- ...config,
1925
- xAxis: {
1926
- ...config.xAxis,
1927
- anchors: copiedAnchors
1928
- }
1929
- })
1930
- }}
1931
- >
1932
- <option>Select</option>
1933
- {lineOptions.map(line => (
1934
- <option key={line.key}>{line.value}</option>
1935
- ))}
1936
- </select>
1937
- </label>
1938
- </AccordionItemPanel>
1939
- </AccordionItem>
1940
- ))}
1941
- </Accordion>
2030
+ <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} />
1942
2031
 
1943
- <button
1944
- className='btn full-width'
1945
- onClick={e => {
1946
- e.preventDefault()
1947
- const anchors = [...config.xAxis.anchors]
1948
- anchors.push({})
1949
- updateConfig({
1950
- ...config,
1951
- xAxis: {
1952
- ...config.xAxis,
1953
- anchors
1954
- }
1955
- })
1956
- }}
1957
- >
1958
- Add Anchor
1959
- </button>
1960
- </div>
1961
- )}
1962
- {/* end: anchors */}
1963
- </AccordionItemPanel>
1964
- </AccordionItem>
1965
- {/* Right Value Axis Settings */}
1966
- {hasRightAxis && (
1967
- <AccordionItem>
1968
- <AccordionItemHeading>
1969
- <AccordionItemButton>Right Value Axis</AccordionItemButton>
1970
- </AccordionItemHeading>
1971
- <AccordionItemPanel>
1972
- <TextField value={config.yAxis.rightLabel} section='yAxis' fieldName='rightLabel' label='Label' updateField={updateField} />
1973
- <TextField value={config.yAxis.rightNumTicks} placeholder='Auto' type='number' section='yAxis' fieldName='rightNumTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1974
- <TextField value={config.yAxis.rightAxisSize} type='number' section='yAxis' fieldName='rightAxisSize' label='Size (Width)' className='number-narrow' updateField={updateField} />
1975
- <TextField value={config.yAxis.rightLabelOffsetSize} type='number' section='yAxis' fieldName='rightLabelOffsetSize' label='Label Offset' className='number-narrow' updateField={updateField} />
1976
-
1977
- <span className='divider-heading'>Number Formatting</span>
1978
- <CheckBox value={config.dataFormat.rightCommas} section='dataFormat' fieldName='rightCommas' label='Add commas' updateField={updateField} />
1979
- <TextField value={config.dataFormat.rightRoundTo} type='number' section='dataFormat' fieldName='rightRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1980
- <div className='two-col-inputs'>
1981
- <TextField
1982
- value={config.dataFormat.rightPrefix}
1983
- section='dataFormat'
1984
- fieldName='rightPrefix'
1985
- label='Prefix'
1986
- updateField={updateField}
1987
- tooltip={
1988
- <Tooltip style={{ textTransform: 'none' }}>
1989
- <Tooltip.Target>
1990
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1991
- </Tooltip.Target>
1992
- <Tooltip.Content>
1993
- {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1994
- {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1995
- </Tooltip.Content>
1996
- </Tooltip>
1997
- }
1998
- />
2032
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
2033
+ {/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
2034
+
2035
+ {config.xAxis.type === 'continuous' && (
2036
+ <>
2037
+ <CheckBox value={config.dataFormat.bottomCommas} section='dataFormat' fieldName='bottomCommas' label='Add commas' updateField={updateField} />
2038
+ <TextField value={config.dataFormat.bottomRoundTo} type='number' section='dataFormat' fieldName='bottomRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
2039
+ </>
2040
+ )}
2041
+ {config.orientation === 'vertical' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
2042
+ {(config.orientation === 'horizontal' || !config.isResponsiveTicks) && <TextField value={config.xAxis.tickRotation} type='number' min='0' section='xAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
2043
+ {config.orientation === 'vertical' && config.isResponsiveTicks && config.visualizationType !== 'Paired Bar' && (
1999
2044
  <TextField
2000
- value={config.dataFormat.rightSuffix}
2001
- section='dataFormat'
2002
- fieldName='rightSuffix'
2003
- label='Suffix'
2004
- updateField={updateField}
2005
- tooltip={
2006
- <Tooltip style={{ textTransform: 'none' }}>
2007
- <Tooltip.Target>
2008
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2009
- </Tooltip.Target>
2010
- <Tooltip.Content>
2011
- {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
2012
- {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
2013
- </Tooltip.Content>
2014
- </Tooltip>
2015
- }
2016
- />
2017
- </div>
2018
-
2019
- <CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
2020
- <CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Label' updateField={updateField} />
2021
- <CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
2022
- </AccordionItemPanel>
2023
- </AccordionItem>
2024
- )}
2025
- <AccordionItem>
2026
- <AccordionItemHeading>
2027
- <AccordionItemButton>
2028
- {config.visualizationType !== 'Pie' ? (config.visualizationType === 'Bar' ? 'Date/Category Axis' : 'Date/Category Axis') : 'Segments'}
2029
- {!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
2030
- </AccordionItemButton>
2031
- </AccordionItemHeading>
2032
- <AccordionItemPanel>
2033
- {config.visualizationType !== 'Pie' && (
2034
- <>
2035
- <Select value={config.xAxis.type} section='xAxis' fieldName='type' label='Data Type' updateField={updateField} options={config.visualizationType !== 'Scatter Plot' ? ['categorical', 'date'] : ['categorical', 'continuous', 'date']} />
2036
- <Select
2037
- value={config.xAxis.dataKey || setCategoryAxis() || ''}
2045
+ value={config.xAxis.maxTickRotation}
2046
+ type='number'
2047
+ min='0'
2038
2048
  section='xAxis'
2039
- fieldName='dataKey'
2040
- label='Data Key'
2041
- initial='Select'
2042
- required={true}
2049
+ fieldName='maxTickRotation'
2050
+ label='Max Tick Rotation'
2051
+ className='number-narrow'
2043
2052
  updateField={updateField}
2044
- options={getColumns(false)}
2045
2053
  tooltip={
2046
2054
  <Tooltip style={{ textTransform: 'none' }}>
2047
2055
  <Tooltip.Target>
2048
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2056
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2049
2057
  </Tooltip.Target>
2050
2058
  <Tooltip.Content>
2051
- <p>Select the column or row containing the categories or dates for this axis. </p>
2059
+ <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
2052
2060
  </Tooltip.Content>
2053
2061
  </Tooltip>
2054
2062
  }
2055
2063
  />
2056
- </>
2057
- )}
2064
+ )}
2058
2065
 
2059
- {config.visualizationType === 'Pie' && (
2060
- <Select
2061
- value={config.xAxis.dataKey || ''}
2062
- section='xAxis'
2063
- fieldName='dataKey'
2064
- label='Segment Labels'
2065
- initial='Select'
2066
- required={true}
2066
+ {config.orientation === 'horizontal' ? (
2067
+ <>
2068
+ <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
2069
+ <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
2070
+ </>
2071
+ ) : (
2072
+ <>
2073
+ <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
2074
+ <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
2075
+ <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
2076
+ </>
2077
+ )}
2078
+
2079
+ {config.series?.length === 1 && config.visualizationType === 'Bar' && (
2080
+ <>
2081
+ {/* HIGHLIGHTED BARS */}
2082
+ <label htmlFor='barHighlight'>Bar Highlighting</label>
2083
+ {config.series.length === 1 &&
2084
+ highlightedBarValues.map((highlightedBarValue, i) => (
2085
+ <fieldset>
2086
+ <div className='edit-block' key={`highlighted-bar-${i}`}>
2087
+ <button className='remove-column' onClick={e => handleRemoveHighlightedBar(e, i)}>
2088
+ Remove
2089
+ </button>
2090
+ <p>Highlighted Bar {i + 1}</p>
2091
+ <label>
2092
+ <span className='edit-label column-heading'>Value</span>
2093
+ <select value={config.highlightedBarValues[i].value} onChange={e => handleUpdateHighlightedBar(e, i)}>
2094
+ <option value=''>- Select Value -</option>
2095
+ {highlightedSeriesValues && [...new Set(highlightedSeriesValues)].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
2096
+ </select>
2097
+ </label>
2098
+ <label>
2099
+ <span className='edit-label column-heading'>Color</span>
2100
+ <input type='text' value={config.highlightedBarValues[i].color ? config.highlightedBarValues[i].color : ''} onChange={e => handleUpdateHighlightedBarColor(e, i)} />
2101
+ </label>
2102
+ <label>
2103
+ <span className='edit-label column-heading'>Border Width</span>
2104
+ <input max='5' min='0' type='number' value={config.highlightedBarValues[i].borderWidth ? config.highlightedBarValues[i].borderWidth : ''} onChange={e => handleUpdateHighlightedBorderWidth(e, i)} />
2105
+ </label>
2106
+ <label>
2107
+ <span className='edit-label column-heading'>Legend Label</span>
2108
+ <input type='text' value={config.highlightedBarValues[i].legendLabel ? config.highlightedBarValues[i].legendLabel : ''} onChange={e => handleHighlightedBarLegendLabel(e, i)} />
2109
+ </label>
2110
+ </div>
2111
+ </fieldset>
2112
+ ))}
2113
+ <button className='btn full-width' onClick={e => handleAddNewHighlightedBar(e)}>
2114
+ Add Highlighted Bar
2115
+ </button>
2116
+ </>
2117
+ )}
2118
+ </>
2119
+ )}
2120
+
2121
+ {config.visualizationType === 'Pie' && (
2122
+ <>
2123
+ <CheckBox
2124
+ value={config.exclusions.active}
2125
+ section='exclusions'
2126
+ fieldName='active'
2127
+ label={'Exclude one or more values'}
2067
2128
  updateField={updateField}
2068
- options={getColumns(false)}
2069
2129
  tooltip={
2070
2130
  <Tooltip style={{ textTransform: 'none' }}>
2071
2131
  <Tooltip.Target>
2072
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2132
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2073
2133
  </Tooltip.Target>
2074
2134
  <Tooltip.Content>
2075
- <p>Select the source row or column that contains the segment labels. Depending on the data structure, it may be listed as "Key."</p>
2135
+ <p>When this option is checked, you can select values for exclusion from the pie segments.</p>
2076
2136
  </Tooltip.Content>
2077
2137
  </Tooltip>
2078
2138
  }
2079
2139
  />
2080
- )}
2081
-
2082
- {config.visualizationType !== 'Pie' && (
2083
- <>
2084
- <TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
2085
-
2086
- {config.xAxis.type === 'continuous' && (
2087
- <>
2088
- <TextField
2089
- value={config.dataFormat.bottomPrefix}
2090
- section='dataFormat'
2091
- fieldName='bottomPrefix'
2092
- label='Prefix'
2093
- updateField={updateField}
2094
- tooltip={
2095
- <Tooltip style={{ textTransform: 'none' }}>
2096
- <Tooltip.Target>
2097
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2098
- </Tooltip.Target>
2099
- <Tooltip.Content>
2100
- {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
2101
- {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
2102
- </Tooltip.Content>
2103
- </Tooltip>
2140
+ {config.exclusions.active && (
2141
+ <>
2142
+ {config.exclusions.keys.length > 0 && (
2143
+ <>
2144
+ <fieldset>
2145
+ <legend className='edit-label'>Excluded Keys</legend>
2146
+ </fieldset>
2147
+ <ExclusionsList />
2148
+ </>
2149
+ )}
2150
+
2151
+ <Select
2152
+ fieldName='visualizationType'
2153
+ label='Add Exclusion'
2154
+ initial='Select'
2155
+ onChange={e => {
2156
+ if (e.target.value !== '' && e.target.value !== 'Select') {
2157
+ addNewExclusion(e.target.value)
2104
2158
  }
2105
- />
2106
-
2107
- <TextField
2108
- value={config.dataFormat.bottomSuffix}
2109
- section='dataFormat'
2110
- fieldName='bottomSuffix'
2111
- label='Suffix'
2112
- updateField={updateField}
2113
- tooltip={
2159
+ e.target.value = ''
2160
+ }}
2161
+ options={getDataValues(config.xAxis.dataKey, true)}
2162
+ />
2163
+ </>
2164
+ )}
2165
+ </>
2166
+ )}
2167
+
2168
+ {/* anchors */}
2169
+ {visHasAnchors() && config.orientation !== 'horizontal' && (
2170
+ <div className='edit-block'>
2171
+ <span className='edit-label column-heading'>Anchors</span>
2172
+ <Accordion allowZeroExpanded>
2173
+ {config.xAxis?.anchors?.map((anchor, index) => (
2174
+ <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-2-${index}`}>
2175
+ <AccordionItemHeading className='series-item__title'>
2176
+ <>
2177
+ <AccordionItemButton className={'accordion__button accordion__button'}>
2178
+ Anchor {index + 1}
2179
+ <button
2180
+ className='series-list__remove'
2181
+ onClick={e => {
2182
+ e.preventDefault()
2183
+ const copiedAnchorGroups = [...config.xAxis.anchors]
2184
+ copiedAnchorGroups.splice(index, 1)
2185
+ updateConfig({
2186
+ ...config,
2187
+ xAxis: {
2188
+ ...config.xAxis,
2189
+ anchors: copiedAnchorGroups
2190
+ }
2191
+ })
2192
+ }}
2193
+ >
2194
+ Remove
2195
+ </button>
2196
+ </AccordionItemButton>
2197
+ </>
2198
+ </AccordionItemHeading>
2199
+ <AccordionItemPanel>
2200
+ <label>
2201
+ <span>Anchor Value</span>
2114
2202
  <Tooltip style={{ textTransform: 'none' }}>
2115
2203
  <Tooltip.Target>
2116
2204
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2117
2205
  </Tooltip.Target>
2118
2206
  <Tooltip.Content>
2119
- {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
2120
- {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
2207
+ <p>Enter the value as its shown in the data column</p>
2121
2208
  </Tooltip.Content>
2122
2209
  </Tooltip>
2123
- }
2124
- />
2125
-
2126
- <CheckBox
2127
- value={config.dataFormat.bottomAbbreviated}
2128
- section='dataFormat'
2129
- fieldName='bottomAbbreviated'
2130
- label='Abbreviate Axis Values'
2131
- updateField={updateField}
2132
- tooltip={
2210
+ <input
2211
+ type='text'
2212
+ value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
2213
+ onChange={e => {
2214
+ e.preventDefault()
2215
+ const copiedAnchors = [...config.xAxis.anchors]
2216
+ copiedAnchors[index].value = e.target.value
2217
+ updateConfig({
2218
+ ...config,
2219
+ xAxis: {
2220
+ ...config.xAxis,
2221
+ anchors: copiedAnchors
2222
+ }
2223
+ })
2224
+ }}
2225
+ />
2226
+ </label>
2227
+
2228
+ <label>
2229
+ <span>Anchor Color</span>
2230
+ <input
2231
+ type='text'
2232
+ value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
2233
+ onChange={e => {
2234
+ e.preventDefault()
2235
+ const copiedAnchors = [...config.xAxis.anchors]
2236
+ copiedAnchors[index].color = e.target.value
2237
+ updateConfig({
2238
+ ...config,
2239
+ xAxis: {
2240
+ ...config.xAxis,
2241
+ anchors: copiedAnchors
2242
+ }
2243
+ })
2244
+ }}
2245
+ />
2246
+ </label>
2247
+
2248
+ <label>
2249
+ Anchor Line Style
2250
+ <select
2251
+ value={config.xAxis.anchors[index].lineStyle || ''}
2252
+ onChange={e => {
2253
+ const copiedAnchors = [...config.xAxis.anchors]
2254
+ copiedAnchors[index].lineStyle = e.target.value
2255
+ updateConfig({
2256
+ ...config,
2257
+ xAxis: {
2258
+ ...config.xAxis,
2259
+ anchors: copiedAnchors
2260
+ }
2261
+ })
2262
+ }}
2263
+ >
2264
+ <option>Select</option>
2265
+ {lineOptions.map(line => (
2266
+ <option key={line.key}>{line.value}</option>
2267
+ ))}
2268
+ </select>
2269
+ </label>
2270
+ </AccordionItemPanel>
2271
+ </AccordionItem>
2272
+ ))}
2273
+ </Accordion>
2274
+
2275
+ <button
2276
+ className='btn full-width'
2277
+ onClick={e => {
2278
+ e.preventDefault()
2279
+ const anchors = [...config.xAxis.anchors]
2280
+ anchors.push({})
2281
+ updateConfig({
2282
+ ...config,
2283
+ xAxis: {
2284
+ ...config.xAxis,
2285
+ anchors
2286
+ }
2287
+ })
2288
+ }}
2289
+ >
2290
+ Add Anchor
2291
+ </button>
2292
+ </div>
2293
+ )}
2294
+
2295
+ {visHasAnchors() && config.orientation === 'horizontal' && (
2296
+ <div className='edit-block'>
2297
+ <span className='edit-label column-heading'>Anchors</span>
2298
+ <Accordion allowZeroExpanded>
2299
+ {config.yAxis?.anchors?.map((anchor, index) => (
2300
+ <AccordionItem className='series-item series-item--chart' key={`accordion-yaxis-anchors-${index}`}>
2301
+ <AccordionItemHeading className='series-item__title'>
2302
+ <>
2303
+ <AccordionItemButton className={'accordion__button accordion__button'}>
2304
+ Anchor {index + 1}
2305
+ <button
2306
+ className='series-list__remove'
2307
+ onClick={e => {
2308
+ e.preventDefault()
2309
+ const copiedAnchorGroups = [...config.yAxis.anchors]
2310
+ copiedAnchorGroups.splice(index, 1)
2311
+ updateConfig({
2312
+ ...config,
2313
+ yAxis: {
2314
+ ...config.yAxis,
2315
+ anchors: copiedAnchorGroups
2316
+ }
2317
+ })
2318
+ }}
2319
+ >
2320
+ Remove
2321
+ </button>
2322
+ </AccordionItemButton>
2323
+ </>
2324
+ </AccordionItemHeading>
2325
+ <AccordionItemPanel>
2326
+ <label>
2327
+ <span>Anchor Value</span>
2133
2328
  <Tooltip style={{ textTransform: 'none' }}>
2134
2329
  <Tooltip.Target>
2135
- <Icon display='question' />
2330
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2136
2331
  </Tooltip.Target>
2137
2332
  <Tooltip.Content>
2138
- <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
2333
+ <p>Enter the value as its shown in the data column</p>
2139
2334
  </Tooltip.Content>
2140
2335
  </Tooltip>
2141
- }
2142
- />
2143
- </>
2144
- )}
2145
-
2146
- {config.xAxis.type === 'date' && (
2147
- <>
2148
- <p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
2149
- Format how charts should parse and display your dates using{' '}
2150
- <a href='https://github.com/d3/d3-time-format#locale_format' target='_blank' rel='noreferrer'>
2151
- these guidelines
2152
- </a>
2153
- .
2154
- </p>
2155
- <TextField value={config.xAxis.dateParseFormat} section='xAxis' fieldName='dateParseFormat' placeholder='Ex. %Y-%m-%d' label='Date Parse Format' updateField={updateField} />
2156
- <TextField value={config.xAxis.dateDisplayFormat} section='xAxis' fieldName='dateDisplayFormat' placeholder='Ex. %Y-%m-%d' label='Date Display Format' updateField={updateField} />
2157
- </>
2158
- )}
2159
-
2160
- <CheckBox
2161
- value={config.exclusions.active}
2162
- section='exclusions'
2163
- fieldName='active'
2164
- label={config.xAxis.type === 'date' ? 'Limit by start and/or end dates' : 'Exclude one or more values'}
2165
- tooltip={
2166
- <Tooltip style={{ textTransform: 'none' }}>
2167
- <Tooltip.Target>
2168
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2169
- </Tooltip.Target>
2170
- <Tooltip.Content>
2171
- <p>When this option is checked, you can select source-file values for exclusion from the date/category axis. </p>
2172
- </Tooltip.Content>
2173
- </Tooltip>
2174
- }
2175
- updateField={updateField}
2176
- />
2177
-
2178
- {config.exclusions.active && (
2179
- <>
2180
- {config.xAxis.type === 'categorical' && (
2181
- <>
2182
- {config.exclusions.keys.length > 0 && (
2183
- <>
2184
- <fieldset>
2185
- <legend className='edit-label'>Excluded Keys</legend>
2186
- </fieldset>
2187
- <ExclusionsList />
2188
- </>
2189
- )}
2190
-
2191
- <Select
2192
- fieldName='visualizationType'
2193
- label='Add Exclusion'
2194
- initial='Select'
2336
+ <input
2337
+ type='text'
2338
+ value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
2195
2339
  onChange={e => {
2196
- if (e.target.value !== '' && e.target.value !== 'Select') {
2197
- addNewExclusion(e.target.value)
2198
- }
2199
- e.target.value = ''
2340
+ e.preventDefault()
2341
+ const copiedAnchors = [...config.yAxis.anchors]
2342
+ copiedAnchors[index].value = e.target.value
2343
+ updateConfig({
2344
+ ...config,
2345
+ yAxis: {
2346
+ ...config.yAxis,
2347
+ anchors: copiedAnchors
2348
+ }
2349
+ })
2200
2350
  }}
2201
- options={getDataValues(config.xAxis.dataKey, true)}
2202
2351
  />
2203
- </>
2204
- )}
2352
+ </label>
2205
2353
 
2206
- {config.xAxis.type === 'date' && (
2207
- <>
2208
- <TextField type='date' section='exclusions' fieldName='dateStart' label='Start Date' updateField={updateField} value={config.exclusions.dateStart || ''} />
2209
- <TextField type='date' section='exclusions' fieldName='dateEnd' label='End Date' updateField={updateField} value={config.exclusions.dateEnd || ''} />
2210
- </>
2211
- )}
2212
- </>
2213
- )}
2214
- <TextField value={config.xAxis.numTicks} placeholder='Auto' type='number' min='1' section='xAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
2215
-
2216
- <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} />
2217
-
2218
- {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
2219
- {/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
2220
-
2221
- {config.xAxis.type === 'continuous' && (
2222
- <>
2223
- <CheckBox value={config.dataFormat.bottomCommas} section='dataFormat' fieldName='bottomCommas' label='Add commas' updateField={updateField} />
2224
- <TextField value={config.dataFormat.bottomRoundTo} type='number' section='dataFormat' fieldName='bottomRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
2225
- </>
2226
- )}
2227
-
2228
- {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} />}
2229
- {config.orientation === 'horizontal' ? (
2230
- <>
2231
- <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
2232
- <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
2233
- </>
2234
- ) : (
2235
- <>
2236
- <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
2237
- <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
2238
- <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
2239
- </>
2240
- )}
2241
-
2242
- {config.series?.length === 1 && config.visualizationType === 'Bar' && (
2243
- <>
2244
- {/* HIGHLIGHTED BARS */}
2245
- <label htmlFor='barHighlight'>Bar Highlighting</label>
2246
- {config.series.length === 1 &&
2247
- highlightedBarValues.map((highlightedBarValue, i) => (
2248
- <fieldset>
2249
- <div className='edit-block' key={`highlighted-bar-${i}`}>
2250
- <button className='remove-column' onClick={e => handleRemoveHighlightedBar(e, i)}>
2251
- Remove
2252
- </button>
2253
- <p>Highlighted Bar {i + 1}</p>
2254
- <label>
2255
- <span className='edit-label column-heading'>Value</span>
2256
- <select value={config.highlightedBarValues[i].value} onChange={e => handleUpdateHighlightedBar(e, i)}>
2257
- <option value=''>- Select Value -</option>
2258
- {highlightedSeriesValues && [...new Set(highlightedSeriesValues)].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
2259
- </select>
2260
- </label>
2261
- <label>
2262
- <span className='edit-label column-heading'>Color</span>
2263
- <input type='text' value={config.highlightedBarValues[i].color ? config.highlightedBarValues[i].color : ''} onChange={e => handleUpdateHighlightedBarColor(e, i)} />
2264
- </label>
2265
- <label>
2266
- <span className='edit-label column-heading'>Border Width</span>
2267
- <input max='5' min='0' type='number' value={config.highlightedBarValues[i].borderWidth ? config.highlightedBarValues[i].borderWidth : ''} onChange={e => handleUpdateHighlightedBorderWidth(e, i)} />
2268
- </label>
2269
- <label>
2270
- <span className='edit-label column-heading'>Legend Label</span>
2271
- <input type='text' value={config.highlightedBarValues[i].legendLabel ? config.highlightedBarValues[i].legendLabel : ''} onChange={e => handleHighlightedBarLegendLabel(e, i)} />
2272
- </label>
2273
- </div>
2274
- </fieldset>
2275
- ))}
2276
- <button className='btn full-width' onClick={e => handleAddNewHighlightedBar(e)}>
2277
- Add Highlighted Bar
2278
- </button>
2279
- </>
2280
- )}
2281
- </>
2282
- )}
2354
+ <label>
2355
+ <span>Anchor Color</span>
2356
+ <input
2357
+ type='text'
2358
+ value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
2359
+ onChange={e => {
2360
+ e.preventDefault()
2361
+ const copiedAnchors = [...config.yAxis.anchors]
2362
+ copiedAnchors[index].color = e.target.value
2363
+ updateConfig({
2364
+ ...config,
2365
+ yAxis: {
2366
+ ...config.yAxis,
2367
+ anchors: copiedAnchors
2368
+ }
2369
+ })
2370
+ }}
2371
+ />
2372
+ </label>
2283
2373
 
2284
- {config.visualizationType === 'Pie' && (
2285
- <>
2286
- <CheckBox
2287
- value={config.exclusions.active}
2288
- section='exclusions'
2289
- fieldName='active'
2290
- label={'Exclude one or more values'}
2291
- updateField={updateField}
2292
- tooltip={
2374
+ <label>
2375
+ Anchor Line Style
2376
+ <select
2377
+ value={config.yAxis.anchors[index].lineStyle || ''}
2378
+ onChange={e => {
2379
+ const copiedAnchors = [...config.yAxis.anchors]
2380
+ copiedAnchors[index].lineStyle = e.target.value
2381
+ updateConfig({
2382
+ ...config,
2383
+ yAxis: {
2384
+ ...config.yAxis,
2385
+ anchors: copiedAnchors
2386
+ }
2387
+ })
2388
+ }}
2389
+ >
2390
+ <option>Select</option>
2391
+ {lineOptions.map(line => (
2392
+ <option key={line.key}>{line.value}</option>
2393
+ ))}
2394
+ </select>
2395
+ </label>
2396
+ </AccordionItemPanel>
2397
+ </AccordionItem>
2398
+ ))}
2399
+ </Accordion>
2400
+
2401
+ <button
2402
+ className='btn full-width'
2403
+ onClick={e => {
2404
+ e.preventDefault()
2405
+ const anchors = [...config.yAxis.anchors]
2406
+ anchors.push({})
2407
+ updateConfig({
2408
+ ...config,
2409
+ yAxis: {
2410
+ ...config.yAxis,
2411
+ anchors
2412
+ }
2413
+ })
2414
+ }}
2415
+ >
2416
+ Add Anchor
2417
+ </button>
2418
+ </div>
2419
+ )}
2420
+ </AccordionItemPanel>
2421
+ </AccordionItem>
2422
+ {config.visualizationType !== 'Pie' && config.visualizationType !== 'Paired Bar' && (
2423
+ <AccordionItem>
2424
+ <AccordionItemHeading>
2425
+ <AccordionItemButton>Regions</AccordionItemButton>
2426
+ </AccordionItemHeading>
2427
+ <AccordionItemPanel>
2428
+ <Regions config={config} updateConfig={updateConfig} />
2429
+ </AccordionItemPanel>
2430
+ </AccordionItem>
2431
+ )}{' '}
2432
+ {/* Columns */}
2433
+ {config.visualizationType !== 'Box Plot' && config.table.showVertical && (
2434
+ <AccordionItem>
2435
+ <AccordionItemHeading>
2436
+ <AccordionItemButton>Columns</AccordionItemButton>
2437
+ </AccordionItemHeading>
2438
+ <AccordionItemPanel>
2439
+ {'navigation' !== config.type && (
2440
+ <fieldset className='primary-fieldset edit-block'>
2441
+ <label>
2442
+ <span className='edit-label'>
2443
+ Additional Columns
2293
2444
  <Tooltip style={{ textTransform: 'none' }}>
2294
2445
  <Tooltip.Target>
2295
2446
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2296
2447
  </Tooltip.Target>
2297
2448
  <Tooltip.Content>
2298
- <p>When this option is checked, you can select values for exclusion from the pie segments.</p>
2449
+ <p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
2299
2450
  </Tooltip.Content>
2300
2451
  </Tooltip>
2301
- }
2302
- />
2303
- {config.exclusions.active && (
2304
- <>
2305
- {config.exclusions.keys.length > 0 && (
2306
- <>
2307
- <fieldset>
2308
- <legend className='edit-label'>Excluded Keys</legend>
2309
- </fieldset>
2310
- <ExclusionsList />
2311
- </>
2312
- )}
2313
-
2314
- <Select
2315
- fieldName='visualizationType'
2316
- label='Add Exclusion'
2317
- initial='Select'
2318
- onChange={e => {
2319
- if (e.target.value !== '' && e.target.value !== 'Select') {
2320
- addNewExclusion(e.target.value)
2321
- }
2322
- e.target.value = ''
2452
+ </span>
2453
+ </label>
2454
+ {additionalColumns.map(val => (
2455
+ <fieldset className='edit-block' key={val}>
2456
+ <button
2457
+ className='remove-column'
2458
+ onClick={event => {
2459
+ event.preventDefault()
2460
+ removeAdditionalColumn(val)
2323
2461
  }}
2324
- options={getDataValues(config.xAxis.dataKey, true)}
2325
- />
2326
- </>
2327
- )}
2328
- </>
2329
- )}
2330
-
2331
- {/* anchors */}
2332
- {visHasAnchors() && config.orientation !== 'horizontal' ? (
2333
- <div className='edit-block'>
2334
- <h3>Anchors</h3>
2335
- <Accordion allowZeroExpanded>
2336
- {config.xAxis?.anchors?.map((anchor, index) => (
2337
- <AccordionItem className='series-item series-item--chart'>
2338
- <AccordionItemHeading className='series-item__title'>
2339
- <>
2340
- <AccordionItemButton className={'accordion__button accordion__button'}>
2341
- Anchor {index + 1}
2342
- <button
2343
- className='series-list__remove'
2344
- onClick={e => {
2345
- e.preventDefault()
2346
- const copiedAnchorGroups = [...config.xAxis.anchors]
2347
- copiedAnchorGroups.splice(index, 1)
2348
- updateConfig({
2349
- ...config,
2350
- xAxis: {
2351
- ...config.xAxis,
2352
- anchors: copiedAnchorGroups
2353
- }
2354
- })
2355
- }}
2356
- >
2357
- Remove
2358
- </button>
2359
- </AccordionItemButton>
2360
- </>
2361
- </AccordionItemHeading>
2362
- <AccordionItemPanel>
2363
- <label>
2364
- <span>Anchor Value</span>
2365
- <Tooltip style={{ textTransform: 'none' }}>
2366
- <Tooltip.Target>
2367
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2368
- </Tooltip.Target>
2369
- <Tooltip.Content>
2370
- <p>Enter the value as its shown in the data column</p>
2371
- </Tooltip.Content>
2372
- </Tooltip>
2373
- <input
2374
- type='text'
2375
- value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
2376
- onChange={e => {
2377
- e.preventDefault()
2378
- const copiedAnchors = [...config.xAxis.anchors]
2379
- copiedAnchors[index].value = e.target.value
2380
- updateConfig({
2381
- ...config,
2382
- xAxis: {
2383
- ...config.xAxis,
2384
- anchors: copiedAnchors
2385
- }
2386
- })
2387
- }}
2388
- />
2389
- </label>
2390
-
2391
- <label>
2392
- <span>Anchor Color</span>
2462
+ >
2463
+ Remove
2464
+ </button>
2465
+ <label>
2466
+ <span className='edit-label column-heading'>Column</span>
2467
+ <select
2468
+ value={config.columns[val] ? config.columns[val].name : columnsOptions[0]}
2469
+ onChange={event => {
2470
+ editColumn(val, 'name', event.target.value)
2471
+ }}
2472
+ >
2473
+ {columnsOptions}
2474
+ </select>
2475
+ </label>
2476
+ <TextField value={config.columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
2477
+ <ul className='column-edit'>
2478
+ <li className='three-col'>
2479
+ <TextField value={config.columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
2480
+ <TextField value={config.columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
2481
+ <TextField type='number' value={config.columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
2482
+ </li>
2483
+ <li>
2484
+ <label className='checkbox'>
2393
2485
  <input
2394
- type='text'
2395
- value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
2396
- onChange={e => {
2397
- e.preventDefault()
2398
- const copiedAnchors = [...config.xAxis.anchors]
2399
- copiedAnchors[index].color = e.target.value
2400
- updateConfig({
2401
- ...config,
2402
- xAxis: {
2403
- ...config.xAxis,
2404
- anchors: copiedAnchors
2405
- }
2406
- })
2486
+ type='checkbox'
2487
+ checked={config.columns[val].commas}
2488
+ onChange={event => {
2489
+ editColumn(val, 'commas', event.target.checked)
2407
2490
  }}
2408
2491
  />
2492
+ <span className='edit-label'>Add Commas to Numbers</span>
2409
2493
  </label>
2410
-
2411
- <label>
2412
- Anchor Line Style
2413
- <select
2414
- value={config.xAxis.anchors[index].lineStyle || ''}
2415
- onChange={e => {
2416
- const copiedAnchors = [...config.xAxis.anchors]
2417
- copiedAnchors[index].lineStyle = e.target.value
2418
- updateConfig({
2419
- ...config,
2420
- xAxis: {
2421
- ...config.xAxis,
2422
- anchors: copiedAnchors
2423
- }
2424
- })
2425
- }}
2426
- >
2427
- <option>Select</option>
2428
- {lineOptions.map(line => (
2429
- <option key={line.key}>{line.value}</option>
2430
- ))}
2431
- </select>
2432
- </label>
2433
- </AccordionItemPanel>
2434
- </AccordionItem>
2435
- ))}
2436
- </Accordion>
2437
-
2438
- <button
2439
- className='btn full-width'
2440
- onClick={e => {
2441
- e.preventDefault()
2442
- const anchors = [...config.xAxis.anchors]
2443
- anchors.push({})
2444
- updateConfig({
2445
- ...config,
2446
- xAxis: {
2447
- ...config.xAxis,
2448
- anchors
2449
- }
2450
- })
2451
- }}
2452
- >
2453
- Add Anchor
2454
- </button>
2455
- </div>
2456
- ) : (
2457
- <div className='edit-block'>
2458
- <h3>Anchors</h3>
2459
- <Accordion allowZeroExpanded>
2460
- {config.yAxis?.anchors?.map((anchor, index) => (
2461
- <AccordionItem className='series-item series-item--chart'>
2462
- <AccordionItemHeading className='series-item__title'>
2463
- <>
2464
- <AccordionItemButton className={'accordion__button accordion__button'}>
2465
- Anchor {index + 1}
2466
- <button
2467
- className='series-list__remove'
2468
- onClick={e => {
2469
- e.preventDefault()
2470
- const copiedAnchorGroups = [...config.yAxis.anchors]
2471
- copiedAnchorGroups.splice(index, 1)
2472
- updateConfig({
2473
- ...config,
2474
- yAxis: {
2475
- ...config.yAxis,
2476
- anchors: copiedAnchorGroups
2477
- }
2478
- })
2479
- }}
2480
- >
2481
- Remove
2482
- </button>
2483
- </AccordionItemButton>
2484
- </>
2485
- </AccordionItemHeading>
2486
- <AccordionItemPanel>
2487
- <label>
2488
- <span>Anchor Value</span>
2489
- <Tooltip style={{ textTransform: 'none' }}>
2490
- <Tooltip.Target>
2491
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2492
- </Tooltip.Target>
2493
- <Tooltip.Content>
2494
- <p>Enter the value as its shown in the data column</p>
2495
- </Tooltip.Content>
2496
- </Tooltip>
2494
+ </li>
2495
+ <li>
2496
+ <label className='checkbox'>
2497
2497
  <input
2498
- type='text'
2499
- value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
2500
- onChange={e => {
2501
- e.preventDefault()
2502
- const copiedAnchors = [...config.yAxis.anchors]
2503
- copiedAnchors[index].value = e.target.value
2504
- updateConfig({
2505
- ...config,
2506
- yAxis: {
2507
- ...config.yAxis,
2508
- anchors: copiedAnchors
2509
- }
2510
- })
2498
+ type='checkbox'
2499
+ checked={config.columns[val].dataTable}
2500
+ onChange={event => {
2501
+ editColumn(val, 'dataTable', event.target.checked)
2511
2502
  }}
2512
2503
  />
2504
+ <span className='edit-label'>Show in Data Table</span>
2513
2505
  </label>
2514
-
2515
- <label>
2516
- <span>Anchor Color</span>
2506
+ </li>
2507
+ {/* disable for now */}
2508
+ {/*
2509
+ <li>
2510
+ <label className='checkbox'>
2517
2511
  <input
2518
- type='text'
2519
- value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
2520
- onChange={e => {
2521
- e.preventDefault()
2522
- const copiedAnchors = [...config.yAxis.anchors]
2523
- copiedAnchors[index].color = e.target.value
2524
- updateConfig({
2525
- ...config,
2526
- yAxis: {
2527
- ...config.yAxis,
2528
- anchors: copiedAnchors
2529
- }
2530
- })
2512
+ type='checkbox'
2513
+ checked={config.columns[val].tooltip}
2514
+ onChange={event => {
2515
+ editColumn(val, 'tooltip', event.target.checked)
2531
2516
  }}
2532
2517
  />
2518
+ <span className='edit-label'>Display in Tooltips</span>
2533
2519
  </label>
2534
-
2535
- <label>
2536
- Anchor Line Style
2537
- <select
2538
- value={config.yAxis.anchors[index].lineStyle || ''}
2539
- onChange={e => {
2540
- const copiedAnchors = [...config.yAxis.anchors]
2541
- copiedAnchors[index].lineStyle = e.target.value
2542
- updateConfig({
2543
- ...config,
2544
- yAxis: {
2545
- ...config.yAxis,
2546
- anchors: copiedAnchors
2547
- }
2548
- })
2549
- }}
2550
- >
2551
- <option>Select</option>
2552
- {lineOptions.map(line => (
2553
- <option key={line.key}>{line.value}</option>
2554
- ))}
2555
- </select>
2556
- </label>
2557
- </AccordionItemPanel>
2558
- </AccordionItem>
2559
- ))}
2560
- </Accordion>
2561
-
2520
+ </li>
2521
+ */}
2522
+ </ul>
2523
+ </fieldset>
2524
+ ))}
2562
2525
  <button
2563
- className='btn full-width'
2564
- onClick={e => {
2565
- e.preventDefault()
2566
- const anchors = [...config.yAxis.anchors]
2567
- anchors.push({})
2568
- updateConfig({
2569
- ...config,
2570
- yAxis: {
2571
- ...config.yAxis,
2572
- anchors
2573
- }
2574
- })
2526
+ className={'btn full-width'}
2527
+ onClick={event => {
2528
+ event.preventDefault()
2529
+ addAdditionalColumn(additionalColumns.length + 1)
2575
2530
  }}
2576
2531
  >
2577
- Add Anchor
2532
+ Add Column
2578
2533
  </button>
2579
- </div>
2534
+ </fieldset>
2580
2535
  )}
2581
- </AccordionItemPanel>
2582
- </AccordionItem>
2583
- {config.visualizationType !== 'Pie' && config.visualizationType !== 'Paired Bar' && (
2584
- <AccordionItem>
2585
- <AccordionItemHeading>
2586
- <AccordionItemButton>Regions</AccordionItemButton>
2587
- </AccordionItemHeading>
2588
- <AccordionItemPanel>
2589
- <Regions config={config} updateConfig={updateConfig} />
2590
- </AccordionItemPanel>
2591
- </AccordionItem>
2592
- )}{' '}
2593
- {/* Columns */}
2594
- {config.visualizationType !== 'Box Plot' && config.table.showVertical && (
2595
- <AccordionItem>
2596
- <AccordionItemHeading>
2597
- <AccordionItemButton>Columns</AccordionItemButton>
2598
- </AccordionItemHeading>
2599
- <AccordionItemPanel>
2600
- {'navigation' !== config.type && (
2601
- <fieldset className='primary-fieldset edit-block'>
2602
- <label>
2603
- <span className='edit-label'>
2604
- Additional Columns
2605
- <Tooltip style={{ textTransform: 'none' }}>
2606
- <Tooltip.Target>
2607
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2608
- </Tooltip.Target>
2609
- <Tooltip.Content>
2610
- <p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
2611
- </Tooltip.Content>
2612
- </Tooltip>
2613
- </span>
2614
- </label>
2615
- {additionalColumns.map(val => (
2536
+ {'category' === config.legend.type && (
2537
+ <fieldset className='primary-fieldset edit-block'>
2538
+ <label>
2539
+ <span className='edit-label'>
2540
+ Additional Category
2541
+ <Tooltip style={{ textTransform: 'none' }}>
2542
+ <Tooltip.Target>
2543
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2544
+ </Tooltip.Target>
2545
+ <Tooltip.Content>
2546
+ <p>You can provide additional categories to ensure they appear in the legend</p>
2547
+ </Tooltip.Content>
2548
+ </Tooltip>
2549
+ </span>
2550
+ </label>
2551
+ {config.legend.additionalCategories &&
2552
+ config.legend.additionalCategories.map((val, i) => (
2616
2553
  <fieldset className='edit-block' key={val}>
2617
2554
  <button
2618
2555
  className='remove-column'
2619
2556
  onClick={event => {
2620
2557
  event.preventDefault()
2621
- removeAdditionalColumn(val)
2558
+ const updatedAdditionaCategories = [...config.legend.additionalCategories]
2559
+ updatedAdditionaCategories.splice(i, 1)
2560
+ updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2622
2561
  }}
2623
2562
  >
2624
2563
  Remove
2625
2564
  </button>
2626
2565
  <label>
2627
- <span className='edit-label column-heading'>Column</span>
2628
- <select
2629
- value={config.columns[val] ? config.columns[val].name : columnsOptions[0]}
2630
- onChange={event => {
2631
- editColumn(val, 'name', event.target.value)
2566
+ <span className='edit-label column-heading'>Category</span>
2567
+ <TextField
2568
+ value={val}
2569
+ section='legend'
2570
+ subsection={null}
2571
+ fieldName='additionalCategories'
2572
+ updateField={(section, subsection, fieldName, value) => {
2573
+ const updatedAdditionaCategories = [...config.legend.additionalCategories]
2574
+ updatedAdditionaCategories[i] = value
2575
+ updateField(section, subsection, fieldName, updatedAdditionaCategories)
2632
2576
  }}
2633
- >
2634
- {columnsOptions}
2635
- </select>
2577
+ />
2636
2578
  </label>
2637
- <TextField value={config.columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
2638
- <ul className='column-edit'>
2639
- <li className='three-col'>
2640
- <TextField value={config.columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
2641
- <TextField value={config.columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
2642
- <TextField type='number' value={config.columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
2643
- </li>
2644
- <li>
2645
- <label className='checkbox'>
2646
- <input
2647
- type='checkbox'
2648
- checked={config.columns[val].useCommas}
2649
- onChange={event => {
2650
- editColumn(val, 'useCommas', event.target.checked)
2651
- }}
2652
- />
2653
- <span className='edit-label'>Add Commas to Numbers</span>
2654
- </label>
2655
- </li>
2656
- <li>
2657
- <label className='checkbox'>
2658
- <input
2659
- type='checkbox'
2660
- checked={config.columns[val].dataTable}
2661
- onChange={event => {
2662
- editColumn(val, 'dataTable', event.target.checked)
2663
- }}
2664
- />
2665
- <span className='edit-label'>Display in Data Table</span>
2666
- </label>
2667
- </li>
2668
- {/* disable for now */}
2669
- {/*
2670
- <li>
2671
- <label className='checkbox'>
2672
- <input
2673
- type='checkbox'
2674
- checked={config.columns[val].tooltip}
2675
- onChange={event => {
2676
- editColumn(val, 'tooltip', event.target.checked)
2677
- }}
2678
- />
2679
- <span className='edit-label'>Display in Tooltips</span>
2680
- </label>
2681
- </li>
2682
- */}
2683
- </ul>
2684
2579
  </fieldset>
2685
2580
  ))}
2686
- <button
2687
- className={'btn full-width'}
2688
- onClick={event => {
2689
- event.preventDefault()
2690
- addAdditionalColumn(additionalColumns.length + 1)
2691
- }}
2692
- >
2693
- Add Column
2694
- </button>
2695
- </fieldset>
2696
- )}
2697
- {'category' === config.legend.type && (
2698
- <fieldset className='primary-fieldset edit-block'>
2699
- <label>
2700
- <span className='edit-label'>
2701
- Additional Category
2702
- <Tooltip style={{ textTransform: 'none' }}>
2703
- <Tooltip.Target>
2704
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2705
- </Tooltip.Target>
2706
- <Tooltip.Content>
2707
- <p>You can provide additional categories to ensure they appear in the legend</p>
2708
- </Tooltip.Content>
2709
- </Tooltip>
2710
- </span>
2711
- </label>
2712
- {config.legend.additionalCategories &&
2713
- config.legend.additionalCategories.map((val, i) => (
2714
- <fieldset className='edit-block' key={val}>
2715
- <button
2716
- className='remove-column'
2717
- onClick={event => {
2718
- event.preventDefault()
2719
- const updatedAdditionaCategories = [...config.legend.additionalCategories]
2720
- updatedAdditionaCategories.splice(i, 1)
2721
- updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2722
- }}
2723
- >
2724
- Remove
2725
- </button>
2726
- <label>
2727
- <span className='edit-label column-heading'>Category</span>
2728
- <TextField
2729
- value={val}
2730
- section='legend'
2731
- subsection={null}
2732
- fieldName='additionalCategories'
2733
- updateField={(section, subsection, fieldName, value) => {
2734
- const updatedAdditionaCategories = [...config.legend.additionalCategories]
2735
- updatedAdditionaCategories[i] = value
2736
- updateField(section, subsection, fieldName, updatedAdditionaCategories)
2737
- }}
2738
- />
2739
- </label>
2740
- </fieldset>
2741
- ))}
2742
- <button
2743
- className={'btn full-width'}
2744
- onClick={event => {
2745
- event.preventDefault()
2746
- const updatedAdditionaCategories = [...(config.legend.additionalCategories || [])]
2747
- updatedAdditionaCategories.push('')
2748
- updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2749
- }}
2750
- >
2751
- Add Category
2752
- </button>
2753
- </fieldset>
2754
- )}
2755
- </AccordionItemPanel>
2756
- </AccordionItem>
2757
- )}
2758
- {/* End Columns */}
2759
- {visHasLegend() && (
2760
- <AccordionItem>
2761
- <AccordionItemHeading>
2762
- <AccordionItemButton>Legend</AccordionItemButton>
2763
- </AccordionItemHeading>
2764
- <AccordionItemPanel>
2765
- <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
2766
- {/* <fieldset className="checkbox-group">
2581
+ <button
2582
+ className={'btn full-width'}
2583
+ onClick={event => {
2584
+ event.preventDefault()
2585
+ const updatedAdditionaCategories = [...(config.legend.additionalCategories || [])]
2586
+ updatedAdditionaCategories.push('')
2587
+ updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2588
+ }}
2589
+ >
2590
+ Add Category
2591
+ </button>
2592
+ </fieldset>
2593
+ )}
2594
+ </AccordionItemPanel>
2595
+ </AccordionItem>
2596
+ )}
2597
+ {/* End Columns */}
2598
+ {visHasLegend() && (
2599
+ <AccordionItem>
2600
+ <AccordionItemHeading>
2601
+ <AccordionItemButton>Legend</AccordionItemButton>
2602
+ </AccordionItemHeading>
2603
+ <AccordionItemPanel>
2604
+ <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
2605
+ {/* <fieldset className="checkbox-group">
2767
2606
  <CheckBox value={config.legend.dynamicLegend} section="legend" fieldName="dynamicLegend" label="Dynamic Legend" updateField={updateField}/>
2768
2607
  {config.legend.dynamicLegend && (
2769
2608
  <>
@@ -2774,53 +2613,53 @@ const EditorPanel = () => {
2774
2613
  </>
2775
2614
  )}
2776
2615
  </fieldset> */}
2777
- <CheckBox
2778
- value={config.legend.hide ? true : false}
2779
- section='legend'
2780
- fieldName='hide'
2781
- label='Hide Legend'
2782
- updateField={updateField}
2783
- tooltip={
2784
- <Tooltip style={{ textTransform: 'none' }}>
2785
- <Tooltip.Target>
2786
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2787
- </Tooltip.Target>
2788
- <Tooltip.Content>
2789
- <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
2790
- </Tooltip.Content>
2791
- </Tooltip>
2792
- }
2793
- />
2616
+ <CheckBox
2617
+ value={config.legend.hide ? true : false}
2618
+ section='legend'
2619
+ fieldName='hide'
2620
+ label='Hide Legend'
2621
+ updateField={updateField}
2622
+ tooltip={
2623
+ <Tooltip style={{ textTransform: 'none' }}>
2624
+ <Tooltip.Target>
2625
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2626
+ </Tooltip.Target>
2627
+ <Tooltip.Content>
2628
+ <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
2629
+ </Tooltip.Content>
2630
+ </Tooltip>
2631
+ }
2632
+ />
2794
2633
 
2795
- {/* {config.visualizationType === 'Box Plot' &&
2634
+ {/* {config.visualizationType === 'Box Plot' &&
2796
2635
  <>
2797
2636
  <CheckBox value={config.boxplot.legend.displayHowToReadText} fieldName='displayHowToReadText' section='boxplot' subsection='legend' label='Display How To Read Text' updateField={updateField} />
2798
2637
  <TextField type='textarea' value={config.boxplot.legend.howToReadText} updateField={updateField} fieldName='howToReadText' section='boxplot' subsection='legend' label='How to read text' />
2799
2638
  </>
2800
2639
  } */}
2801
2640
 
2802
- {config.visualizationType !== 'Box Plot' && <CheckBox value={config.legend.showLegendValuesTooltip ? true : false} section='legend' fieldName='showLegendValuesTooltip' label='Show Legend Values in Tooltip' updateField={updateField} />}
2641
+ {config.visualizationType !== 'Box Plot' && <CheckBox value={config.legend.showLegendValuesTooltip ? true : false} section='legend' fieldName='showLegendValuesTooltip' label='Show Legend Values in Tooltip' updateField={updateField} />}
2803
2642
 
2804
- {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
2805
- <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
2806
- )}
2807
- <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={updateField} options={['highlight', 'isolate']} />
2808
- <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
2809
- <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
2810
- {config.legend.position === 'bottom' && <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />}
2811
- <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
2812
- </AccordionItemPanel>
2813
- </AccordionItem>
2814
- )}
2815
- <AccordionItem>
2816
- <AccordionItemHeading>
2817
- <AccordionItemButton>Filters</AccordionItemButton>
2818
- </AccordionItemHeading>
2819
- <AccordionItemPanel>
2820
- {config.filters && (
2821
- <>
2822
- {/* prettier-ignore */}
2823
- <Select
2643
+ {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
2644
+ <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
2645
+ )}
2646
+ <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={updateField} options={['highlight', 'isolate']} />
2647
+ <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
2648
+ <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
2649
+ {config.legend.position === 'bottom' && <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />}
2650
+ <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
2651
+ </AccordionItemPanel>
2652
+ </AccordionItem>
2653
+ )}
2654
+ <AccordionItem>
2655
+ <AccordionItemHeading>
2656
+ <AccordionItemButton>Filters</AccordionItemButton>
2657
+ </AccordionItemHeading>
2658
+ <AccordionItemPanel>
2659
+ {config.filters && (
2660
+ <>
2661
+ {/* prettier-ignore */}
2662
+ <Select
2824
2663
  value={config.filterBehavior}
2825
2664
  fieldName='filterBehavior'
2826
2665
  label='Filter Behavior'
@@ -2837,361 +2676,417 @@ const EditorPanel = () => {
2837
2676
  </Tooltip>
2838
2677
  }
2839
2678
  />
2840
- <br />
2841
- </>
2842
- )}
2843
- {config.filters && (
2844
- <ul className='filters-list'>
2845
- {/* Whether filters should apply onChange or Apply Button */}
2846
-
2847
- {config.filters.map((filter, index) => {
2848
- if (filter.type === 'url') return <></>
2849
-
2850
- return (
2851
- <fieldset className='edit-block' key={index}>
2852
- <button
2853
- type='button'
2854
- className='remove-column'
2855
- onClick={() => {
2856
- removeFilter(index)
2679
+ <br />
2680
+ </>
2681
+ )}
2682
+ {config.filters && (
2683
+ <ul className='filters-list'>
2684
+ {/* Whether filters should apply onChange or Apply Button */}
2685
+
2686
+ {config.filters.map((filter, index) => {
2687
+ if (filter.type === 'url') return <></>
2688
+
2689
+ return (
2690
+ <fieldset className='edit-block' key={index}>
2691
+ <button
2692
+ type='button'
2693
+ className='remove-column'
2694
+ onClick={() => {
2695
+ removeFilter(index)
2696
+ }}
2697
+ >
2698
+ Remove
2699
+ </button>
2700
+ <label>
2701
+ <span className='edit-label column-heading'>Filter</span>
2702
+ <select
2703
+ value={filter.columnName}
2704
+ onChange={e => {
2705
+ updateFilterProp('columnName', index, e.target.value)
2857
2706
  }}
2858
2707
  >
2859
- Remove
2860
- </button>
2861
- <label>
2862
- <span className='edit-label column-heading'>Filter</span>
2863
- <select
2864
- value={filter.columnName}
2865
- onChange={e => {
2866
- updateFilterProp('columnName', index, e.target.value)
2867
- }}
2868
- >
2869
- <option value=''>- Select Option -</option>
2870
- {getFilters(true).map((dataKey, index) => (
2871
- <option value={dataKey} key={index}>
2872
- {dataKey}
2873
- </option>
2874
- ))}
2875
- </select>
2876
- </label>
2877
-
2878
- <label>
2879
- <span className='edit-label column-heading'>Filter Style</span>
2708
+ <option value=''>- Select Option -</option>
2709
+ {getFilters(true).map((dataKey, index) => (
2710
+ <option value={dataKey} key={index}>
2711
+ {dataKey}
2712
+ </option>
2713
+ ))}
2714
+ </select>
2715
+ </label>
2880
2716
 
2881
- <select
2882
- value={filter.filterStyle}
2883
- onChange={e => {
2884
- updateFilterProp('filterStyle', index, e.target.value)
2885
- }}
2886
- >
2887
- {filterStyleOptions.map(item => {
2888
- return <option value={item}>{item}</option>
2889
- })}
2890
- </select>
2891
- </label>
2892
- <label>
2893
- <span className='edit-label column-heading'>Label</span>
2894
- <input
2895
- type='text'
2896
- value={filter.label}
2897
- onChange={e => {
2898
- updateFilterProp('label', index, e.target.value)
2899
- }}
2900
- />
2901
- </label>
2717
+ <label>
2718
+ <span className='edit-showDropdown column-heading'>Show Filter Input</span>
2719
+ <input
2720
+ type='checkbox'
2721
+ checked={filter.showDropdown === undefined ? true : filter.showDropdown}
2722
+ onChange={e => {
2723
+ updateFilterProp('showDropdown', index, e.target.checked)
2724
+ }}
2725
+ />
2726
+ </label>
2902
2727
 
2903
- <label>
2904
- <span className='edit-filterOrder column-heading'>Filter Order</span>
2905
- <select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
2906
- {filterOrderOptions.map((option, index) => {
2907
- return (
2908
- <option value={option.value} key={`filter-${index}`}>
2909
- {option.label}
2910
- </option>
2911
- )
2912
- })}
2913
- </select>
2728
+ <label>
2729
+ <span className='edit-label column-heading'>Filter Style</span>
2914
2730
 
2915
- {filter.order === 'cust' && (
2916
- <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, config.filters[index])}>
2917
- <Droppable droppableId='filter_order'>
2918
- {provided => (
2919
- <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
2920
- {config.filters[index]?.values.map((value, index) => {
2921
- return (
2922
- <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
2923
- {(provided, snapshot) => (
2924
- <li>
2925
- <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
2926
- {value}
2927
- </div>
2928
- </li>
2929
- )}
2930
- </Draggable>
2931
- )
2932
- })}
2933
- {provided.placeholder}
2934
- </ul>
2935
- )}
2936
- </Droppable>
2937
- </DragDropContext>
2938
- )}
2939
- </label>
2940
- </fieldset>
2941
- )
2942
- })}
2943
- </ul>
2944
- )}
2945
- {!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2946
- <button type='button' onClick={addNewFilter} className='btn full-width'>
2947
- Add Filter
2948
- </button>
2949
- </AccordionItemPanel>
2950
- </AccordionItem>
2951
- <AccordionItem>
2952
- <AccordionItemHeading>
2953
- <AccordionItemButton>Visual</AccordionItemButton>
2954
- </AccordionItemHeading>
2955
- <AccordionItemPanel>
2956
- {config.isLollipopChart && (
2957
- <>
2958
- <fieldset className='header'>
2959
- <legend className='edit-label'>Lollipop Shape</legend>
2960
- <div
2961
- onChange={e => {
2962
- setLollipopShape(e.target.value)
2963
- }}
2964
- >
2965
- <label className='radio-label'>
2966
- <input type='radio' name='lollipopShape' value='circle' checked={config.lollipopShape === 'circle'} />
2967
- Circle
2731
+ <select
2732
+ value={filter.filterStyle}
2733
+ onChange={e => {
2734
+ updateFilterProp('filterStyle', index, e.target.value)
2735
+ }}
2736
+ >
2737
+ {filterStyleOptions.map(item => {
2738
+ return <option value={item}>{item}</option>
2739
+ })}
2740
+ </select>
2968
2741
  </label>
2969
- <label className='radio-label'>
2970
- <input type='radio' name='lollipopShape' value='square' checked={config.lollipopShape === 'square'} />
2971
- Square
2742
+ <label>
2743
+ <span className='edit-label column-heading'>Label</span>
2744
+ <input
2745
+ type='text'
2746
+ value={filter.label}
2747
+ onChange={e => {
2748
+ updateFilterProp('label', index, e.target.value)
2749
+ }}
2750
+ />
2972
2751
  </label>
2973
- </div>
2974
- </fieldset>
2975
- <Select value={config.lollipopColorStyle ? config.lollipopColorStyle : 'two-tone'} fieldName='lollipopColorStyle' label='Lollipop Color Style' updateField={updateField} options={['regular', 'two-tone']} />
2976
- <Select value={config.lollipopSize ? config.lollipopSize : 'small'} fieldName='lollipopSize' label='Lollipop Size' updateField={updateField} options={['small', 'medium', 'large']} />
2977
- </>
2978
- )}
2979
2752
 
2980
- {config.visualizationType === 'Box Plot' && (
2981
- <fieldset className='fieldset fieldset--boxplot'>
2982
- <legend className=''>Box Plot Settings</legend>
2983
- <Select value={config.boxplot.borders} fieldName='borders' section='boxplot' label='Box Plot Borders' updateField={updateField} options={['true', 'false']} />
2984
- <CheckBox value={config.boxplot.plotOutlierValues} fieldName='plotOutlierValues' section='boxplot' label='Plot Outliers' updateField={updateField} />
2985
- <CheckBox value={config.boxplot.plotNonOutlierValues} fieldName='plotNonOutlierValues' section='boxplot' label='Plot non-outlier values' updateField={updateField} />
2753
+ <label>
2754
+ <span className='edit-filterOrder column-heading'>Filter Order</span>
2755
+ <select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
2756
+ {filterOrderOptions.map((option, index) => {
2757
+ return (
2758
+ <option value={option.value} key={`filter-${index}`}>
2759
+ {option.label}
2760
+ </option>
2761
+ )
2762
+ })}
2763
+ </select>
2764
+
2765
+ {filter.order === 'cust' && (
2766
+ <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, config.filters[index])}>
2767
+ <Droppable droppableId='filter_order'>
2768
+ {provided => (
2769
+ <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
2770
+ {config.filters[index]?.values.map((value, index) => {
2771
+ return (
2772
+ <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
2773
+ {(provided, snapshot) => (
2774
+ <li>
2775
+ <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
2776
+ {value}
2777
+ </div>
2778
+ </li>
2779
+ )}
2780
+ </Draggable>
2781
+ )
2782
+ })}
2783
+ {provided.placeholder}
2784
+ </ul>
2785
+ )}
2786
+ </Droppable>
2787
+ </DragDropContext>
2788
+ )}
2789
+ </label>
2790
+ </fieldset>
2791
+ )
2792
+ })}
2793
+ </ul>
2794
+ )}
2795
+ {!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2796
+ <button type='button' onClick={addNewFilter} className='btn full-width'>
2797
+ Add Filter
2798
+ </button>
2799
+ </AccordionItemPanel>
2800
+ </AccordionItem>
2801
+ <AccordionItem>
2802
+ <AccordionItemHeading>
2803
+ <AccordionItemButton>Visual</AccordionItemButton>
2804
+ </AccordionItemHeading>
2805
+ <AccordionItemPanel>
2806
+ {config.isLollipopChart && (
2807
+ <>
2808
+ <fieldset className='header'>
2809
+ <legend className='edit-label'>Lollipop Shape</legend>
2810
+ <div
2811
+ onChange={e => {
2812
+ setLollipopShape(e.target.value)
2813
+ }}
2814
+ >
2815
+ <label className='radio-label'>
2816
+ <input type='radio' name='lollipopShape' value='circle' checked={config.lollipopShape === 'circle'} />
2817
+ Circle
2818
+ </label>
2819
+ <label className='radio-label'>
2820
+ <input type='radio' name='lollipopShape' value='square' checked={config.lollipopShape === 'square'} />
2821
+ Square
2822
+ </label>
2823
+ </div>
2986
2824
  </fieldset>
2987
- )}
2988
-
2989
- <Select value={config.fontSize} fieldName='fontSize' label='Font Size' updateField={updateField} options={['small', 'medium', 'large']} />
2990
- {visHasBarBorders() && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
2991
- {visCanAnimate() && <CheckBox value={config.animate} fieldName='animate' label='Animate Visualization' updateField={updateField} />}
2992
-
2993
- {/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
2994
-
2995
- {((config.series?.some(series => series.type === 'Line') && config.visualizationType === 'Combo') || config.visualizationType === 'Line' || config.visualizationType === 'Spark Line') && (
2996
- <Select value={config.lineDatapointStyle} fieldName='lineDatapointStyle' label='Line Datapoint Style' updateField={updateField} options={['hidden', 'hover', 'always show']} />
2997
- )}
2998
-
2999
- {/* eslint-disable */}
3000
- <label className='header'>
3001
- <span className='edit-label'>Header Theme</span>
2825
+ <Select value={config.lollipopColorStyle ? config.lollipopColorStyle : 'two-tone'} fieldName='lollipopColorStyle' label='Lollipop Color Style' updateField={updateField} options={['regular', 'two-tone']} />
2826
+ <Select value={config.lollipopSize ? config.lollipopSize : 'small'} fieldName='lollipopSize' label='Lollipop Size' updateField={updateField} options={['small', 'medium', 'large']} />
2827
+ </>
2828
+ )}
2829
+
2830
+ {config.visualizationType === 'Box Plot' && (
2831
+ <fieldset className='fieldset fieldset--boxplot'>
2832
+ <legend className=''>Box Plot Settings</legend>
2833
+ <Select value={config.boxplot.borders} fieldName='borders' section='boxplot' label='Box Plot Borders' updateField={updateField} options={['true', 'false']} />
2834
+ <CheckBox value={config.boxplot.plotOutlierValues} fieldName='plotOutlierValues' section='boxplot' label='Plot Outliers' updateField={updateField} />
2835
+ <CheckBox value={config.boxplot.plotNonOutlierValues} fieldName='plotNonOutlierValues' section='boxplot' label='Plot non-outlier values' updateField={updateField} />
2836
+ </fieldset>
2837
+ )}
2838
+
2839
+ <Select value={config.fontSize} fieldName='fontSize' label='Font Size' updateField={updateField} options={['small', 'medium', 'large']} />
2840
+ {visHasBarBorders() && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
2841
+ {visCanAnimate() && <CheckBox value={config.animate} fieldName='animate' label='Animate Visualization' updateField={updateField} />}
2842
+
2843
+ {/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
2844
+
2845
+ {((config.series?.some(series => series.type === 'Line') && config.visualizationType === 'Combo') || config.visualizationType === 'Line') && (
2846
+ <Select value={config.lineDatapointStyle} fieldName='lineDatapointStyle' label='Line Datapoint Style' updateField={updateField} options={['hidden', 'hover', 'always show']} />
2847
+ )}
2848
+
2849
+ {/* eslint-disable */}
2850
+ <label className='header'>
2851
+ <span className='edit-label'>Header Theme</span>
2852
+ <ul className='color-palette'>
2853
+ {headerColors.map(palette => (
2854
+ <button
2855
+ title={palette}
2856
+ key={palette}
2857
+ onClick={e => {
2858
+ e.preventDefault()
2859
+ updateConfig({ ...config, theme: palette })
2860
+ }}
2861
+ className={config.theme === palette ? 'selected ' + palette : palette}
2862
+ ></button>
2863
+ ))}
2864
+ </ul>
2865
+ </label>
2866
+ <label>
2867
+ <span className='edit-label'>Chart Color Palette</span>
2868
+ </label>
2869
+ {/* eslint-enable */}
2870
+ {config.visualizationType !== 'Paired Bar' && config.visualizationType !== 'Deviation Bar' && (
2871
+ <>
2872
+ <InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.isPaletteReversed} />
2873
+ <span>Sequential</span>
3002
2874
  <ul className='color-palette'>
3003
- {headerColors.map(palette => (
3004
- <button
3005
- title={palette}
3006
- key={palette}
3007
- onClick={e => {
3008
- e.preventDefault()
3009
- updateConfig({ ...config, theme: palette })
3010
- }}
3011
- className={config.theme === palette ? 'selected ' + palette : palette}
3012
- ></button>
3013
- ))}
3014
- </ul>
3015
- </label>
3016
- <label>
3017
- <span className='edit-label'>Chart Color Palette</span>
3018
- </label>
3019
- {/* eslint-enable */}
3020
- {config.visualizationType !== 'Paired Bar' && config.visualizationType !== 'Deviation Bar' && (
3021
- <>
3022
- <InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.isPaletteReversed} />
3023
- <span>Sequential</span>
3024
- <ul className='color-palette'>
3025
- {sequential.map(palette => {
3026
- const colorOne = {
3027
- backgroundColor: colorPalettes[palette][2]
3028
- }
3029
-
3030
- const colorTwo = {
3031
- backgroundColor: colorPalettes[palette][3]
3032
- }
3033
-
3034
- const colorThree = {
3035
- backgroundColor: colorPalettes[palette][5]
3036
- }
2875
+ {sequential.map(palette => {
2876
+ const colorOne = {
2877
+ backgroundColor: colorPalettes[palette][2]
2878
+ }
3037
2879
 
3038
- return (
3039
- <button
3040
- title={palette}
3041
- key={palette}
3042
- onClick={e => {
3043
- e.preventDefault()
3044
- updateConfig({ ...config, palette })
3045
- }}
3046
- className={config.palette === palette ? 'selected' : ''}
3047
- >
3048
- <span style={colorOne}></span>
3049
- <span style={colorTwo}></span>
3050
- <span style={colorThree}></span>
3051
- </button>
3052
- )
3053
- })}
3054
- </ul>
3055
- <span>Non-Sequential</span>
3056
- <ul className='color-palette'>
3057
- {nonSequential.map(palette => {
3058
- const colorOne = {
3059
- backgroundColor: colorPalettes[palette][2]
3060
- }
2880
+ const colorTwo = {
2881
+ backgroundColor: colorPalettes[palette][3]
2882
+ }
3061
2883
 
3062
- const colorTwo = {
3063
- backgroundColor: colorPalettes[palette][4]
3064
- }
2884
+ const colorThree = {
2885
+ backgroundColor: colorPalettes[palette][5]
2886
+ }
3065
2887
 
3066
- const colorThree = {
3067
- backgroundColor: colorPalettes[palette][6]
3068
- }
2888
+ return (
2889
+ <button
2890
+ title={palette}
2891
+ key={palette}
2892
+ onClick={e => {
2893
+ e.preventDefault()
2894
+ updateConfig({ ...config, palette })
2895
+ }}
2896
+ className={config.palette === palette ? 'selected' : ''}
2897
+ >
2898
+ <span style={colorOne}></span>
2899
+ <span style={colorTwo}></span>
2900
+ <span style={colorThree}></span>
2901
+ </button>
2902
+ )
2903
+ })}
2904
+ </ul>
2905
+ <span>Non-Sequential</span>
2906
+ <ul className='color-palette'>
2907
+ {nonSequential.map(palette => {
2908
+ const colorOne = {
2909
+ backgroundColor: colorPalettes[palette][2]
2910
+ }
3069
2911
 
3070
- return (
3071
- <button
3072
- title={palette}
3073
- key={palette}
3074
- onClick={e => {
3075
- e.preventDefault()
3076
- updateConfig({ ...config, palette })
3077
- }}
3078
- className={config.palette === palette ? 'selected' : ''}
3079
- >
3080
- <span style={colorOne}></span>
3081
- <span style={colorTwo}></span>
3082
- <span style={colorThree}></span>
3083
- </button>
3084
- )
3085
- })}
3086
- </ul>
3087
- </>
3088
- )}
3089
- {(config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') && (
3090
- <>
3091
- <InputToggle section='twoColor' fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.twoColor.isPaletteReversed} />
3092
- <ul className='color-palette'>
3093
- {twoColorPalettes.map(palette => {
3094
- const colorOne = {
3095
- backgroundColor: twoColorPalette[palette][0]
3096
- }
2912
+ const colorTwo = {
2913
+ backgroundColor: colorPalettes[palette][4]
2914
+ }
3097
2915
 
3098
- const colorTwo = {
3099
- backgroundColor: twoColorPalette[palette][1]
3100
- }
2916
+ const colorThree = {
2917
+ backgroundColor: colorPalettes[palette][6]
2918
+ }
3101
2919
 
3102
- return (
3103
- <button
3104
- title={palette}
3105
- key={palette}
3106
- onClick={e => {
3107
- e.preventDefault()
3108
- updateConfig({ ...config, twoColor: { ...config.twoColor, palette } })
3109
- }}
3110
- className={config.twoColor.palette === palette ? 'selected' : ''}
3111
- >
3112
- <span className='two-color' style={colorOne}></span>
3113
- <span className='two-color' style={colorTwo}></span>
3114
- </button>
3115
- )
3116
- })}
3117
- </ul>
3118
- </>
3119
- )}
2920
+ return (
2921
+ <button
2922
+ title={palette}
2923
+ key={palette}
2924
+ onClick={e => {
2925
+ e.preventDefault()
2926
+ updateConfig({ ...config, palette })
2927
+ }}
2928
+ className={config.palette === palette ? 'selected' : ''}
2929
+ >
2930
+ <span style={colorOne}></span>
2931
+ <span style={colorTwo}></span>
2932
+ <span style={colorThree}></span>
2933
+ </button>
2934
+ )
2935
+ })}
2936
+ </ul>
2937
+ </>
2938
+ )}
2939
+ {(config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar') && (
2940
+ <>
2941
+ <InputToggle section='twoColor' fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={config.twoColor.isPaletteReversed} />
2942
+ <ul className='color-palette'>
2943
+ {twoColorPalettes.map(palette => {
2944
+ const colorOne = {
2945
+ backgroundColor: twoColorPalette[palette][0]
2946
+ }
3120
2947
 
3121
- {visHasDataCutoff() && (
3122
- <>
3123
- <TextField
3124
- value={config.dataCutoff}
3125
- type='number'
3126
- fieldName='dataCutoff'
3127
- className='number-narrow'
3128
- label='Data Cutoff'
3129
- updateField={updateField}
3130
- tooltip={
3131
- <Tooltip style={{ textTransform: 'none' }}>
3132
- <Tooltip.Target>
3133
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
3134
- </Tooltip.Target>
3135
- <Tooltip.Content>
3136
- <p>Any value below the cut-off value is included in a special "less than" category. This option supports special conditions like suppressed data.</p>
3137
- </Tooltip.Content>
3138
- </Tooltip>
2948
+ const colorTwo = {
2949
+ backgroundColor: twoColorPalette[palette][1]
3139
2950
  }
3140
- />
3141
- </>
3142
- )}
3143
- {config.orientation === 'horizontal' && !config.isLollipopChart && config.yAxis.labelPlacement !== 'On Bar' && <TextField type='number' value={config.barHeight || '25'} fieldName='barHeight' label=' Bar Thickness' updateField={updateField} min='15' />}
3144
- {((config.visualizationType === 'Bar' && config.orientation !== 'horizontal') || config.visualizationType === 'Combo') && <TextField value={config.barThickness} type='number' fieldName='barThickness' label='Bar Thickness' updateField={updateField} />}
3145
- {(config.orientation === 'horizontal' || config.visualizationType === 'Paired Bar') && <TextField type='number' value={config.barSpace || '15'} fieldName='barSpace' label='Bar Space' updateField={updateField} min='0' />}
3146
- {(config.visualizationType === 'Bar' || config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.topAxis.hasLine} section='topAxis' fieldName='hasLine' label='Add Top Axis Line' updateField={updateField} />}
3147
-
3148
- {config.visualizationType === 'Spark Line' && (
3149
- <div className='cove-accordion__panel-section checkbox-group'>
3150
- <CheckBox value={config.visual?.border} section='visual' fieldName='border' label='Display Border' updateField={updateField} />
3151
- <CheckBox value={config.visual?.borderColorTheme} section='visual' fieldName='borderColorTheme' label='Use Border Color Theme' updateField={updateField} />
3152
- <CheckBox value={config.visual?.accent} section='visual' fieldName='accent' label='Use Accent Style' updateField={updateField} />
3153
- <CheckBox value={config.visual?.background} section='visual' fieldName='background' label='Use Theme Background Color' updateField={updateField} />
3154
- <CheckBox value={config.visual?.hideBackgroundColor} section='visual' fieldName='hideBackgroundColor' label='Hide Background Color' updateField={updateField} />
3155
- </div>
3156
- )}
3157
2951
 
3158
- {(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.showLineSeriesLabels} fieldName='showLineSeriesLabels' label='Append Series Name to End of Line Charts' updateField={updateField} />}
3159
- {(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && config.showLineSeriesLabels && (
3160
- <CheckBox value={config.colorMatchLineSeriesLabels} fieldName='colorMatchLineSeriesLabels' label='Match Series Color to Name at End of Line Charts' updateField={updateField} />
3161
- )}
3162
- </AccordionItemPanel>
3163
- </AccordionItem>
3164
- {/* Spark Line has no data table */}
3165
- {config.visualizationType !== 'Spark Line' && (
3166
- <AccordionItem>
3167
- <AccordionItemHeading>
3168
- <AccordionItemButton>Data Table</AccordionItemButton>
3169
- </AccordionItemHeading>
3170
- <AccordionItemPanel>
2952
+ return (
2953
+ <button
2954
+ title={palette}
2955
+ key={palette}
2956
+ onClick={e => {
2957
+ e.preventDefault()
2958
+ updateConfig({ ...config, twoColor: { ...config.twoColor, palette } })
2959
+ }}
2960
+ className={config.twoColor.palette === palette ? 'selected' : ''}
2961
+ >
2962
+ <span className='two-color' style={colorOne}></span>
2963
+ <span className='two-color' style={colorTwo}></span>
2964
+ </button>
2965
+ )
2966
+ })}
2967
+ </ul>
2968
+ </>
2969
+ )}
2970
+
2971
+ {visHasDataCutoff() && (
2972
+ <>
3171
2973
  <TextField
3172
- value={config.table.label}
2974
+ value={config.dataCutoff}
2975
+ type='number'
2976
+ fieldName='dataCutoff'
2977
+ className='number-narrow'
2978
+ label='Data Cutoff'
3173
2979
  updateField={updateField}
3174
- section='table'
3175
- fieldName='label'
3176
- id='tableLabel'
3177
- label='Data Table Title'
3178
- placeholder='Data Table'
3179
2980
  tooltip={
3180
2981
  <Tooltip style={{ textTransform: 'none' }}>
3181
2982
  <Tooltip.Target>
3182
2983
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
3183
2984
  </Tooltip.Target>
3184
2985
  <Tooltip.Content>
3185
- <p>Label is required for Data Table for 508 Compliance</p>
2986
+ <p>Any value below the cut-off value is included in a special "less than" category. This option supports special conditions like suppressed data.</p>
3186
2987
  </Tooltip.Content>
3187
2988
  </Tooltip>
3188
2989
  }
3189
2990
  />
2991
+ </>
2992
+ )}
2993
+ {config.orientation === 'horizontal' && !config.isLollipopChart && config.yAxis.labelPlacement !== 'On Bar' && <TextField type='number' value={config.barHeight || '25'} fieldName='barHeight' label=' Bar Thickness' updateField={updateField} min='15' />}
2994
+ {((config.visualizationType === 'Bar' && config.orientation !== 'horizontal') || config.visualizationType === 'Combo') && <TextField value={config.barThickness} type='number' fieldName='barThickness' label='Bar Thickness' updateField={updateField} />}
2995
+ {(config.orientation === 'horizontal' || config.visualizationType === 'Paired Bar') && <TextField type='number' value={config.barSpace || '15'} fieldName='barSpace' label='Bar Space' updateField={updateField} min='0' />}
2996
+ {(config.visualizationType === 'Bar' || config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.topAxis.hasLine} section='topAxis' fieldName='hasLine' label='Add Top Axis Line' updateField={updateField} />}
2997
+
2998
+ {config.visualizationType === 'Spark Line' && (
2999
+ <div className='cove-accordion__panel-section checkbox-group'>
3000
+ <CheckBox value={config.visual?.border} section='visual' fieldName='border' label='Show Border' updateField={updateField} />
3001
+ <CheckBox value={config.visual?.borderColorTheme} section='visual' fieldName='borderColorTheme' label='Use Border Color Theme' updateField={updateField} />
3002
+ <CheckBox value={config.visual?.accent} section='visual' fieldName='accent' label='Use Accent Style' updateField={updateField} />
3003
+ <CheckBox value={config.visual?.background} section='visual' fieldName='background' label='Use Theme Background Color' updateField={updateField} />
3004
+ <CheckBox value={config.visual?.hideBackgroundColor} section='visual' fieldName='hideBackgroundColor' label='Hide Background Color' updateField={updateField} />
3005
+ </div>
3006
+ )}
3007
+
3008
+ {(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.showLineSeriesLabels} fieldName='showLineSeriesLabels' label='Append Series Name to End of Line Charts' updateField={updateField} />}
3009
+ {(config.visualizationType === 'Line' || config.visualizationType === 'Combo') && config.showLineSeriesLabels && (
3010
+ <CheckBox value={config.colorMatchLineSeriesLabels} fieldName='colorMatchLineSeriesLabels' label='Match Series Color to Name at End of Line Charts' updateField={updateField} />
3011
+ )}
3012
+
3013
+ {visSupportsTooltipLines() && (
3014
+ <>
3015
+ <CheckBox value={config.visual.verticalHoverLine} fieldName='verticalHoverLine' section='visual' label='Vertical Hover Line' updateField={updateField} />
3016
+ <CheckBox value={config.visual.horizontalHoverLine} fieldName='horizontalHoverLine' section='visual' label='Horizontal Hover Line' updateField={updateField} />
3017
+ </>
3018
+ )}
3019
+
3020
+ {
3021
+ <label>
3022
+ <span className='edit-label column-heading'>Tooltip Opacity</span>
3023
+ <input
3024
+ type='number'
3025
+ value={config.tooltips.opacity ? config.tooltips.opacity : 100}
3026
+ onChange={e =>
3027
+ updateConfig({
3028
+ ...config,
3029
+ tooltips: {
3030
+ ...config.tooltips,
3031
+ opacity: e.target.value
3032
+ }
3033
+ })
3034
+ }
3035
+ />
3036
+ </label>
3037
+ }
3038
+ </AccordionItemPanel>
3039
+ </AccordionItem>
3040
+ {/* Spark Line has no data table */}
3041
+ {config.visualizationType !== 'Spark Line' && (
3042
+ <AccordionItem>
3043
+ <AccordionItemHeading>
3044
+ <AccordionItemButton>Data Table</AccordionItemButton>
3045
+ </AccordionItemHeading>
3046
+ <AccordionItemPanel>
3047
+ <TextField
3048
+ value={config.table.label}
3049
+ updateField={updateField}
3050
+ section='table'
3051
+ fieldName='label'
3052
+ id='tableLabel'
3053
+ label='Data Table Title'
3054
+ placeholder='Data Table'
3055
+ tooltip={
3056
+ <Tooltip style={{ textTransform: 'none' }}>
3057
+ <Tooltip.Target>
3058
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
3059
+ </Tooltip.Target>
3060
+ <Tooltip.Content>
3061
+ <p>Label is required for Data Table for 508 Compliance</p>
3062
+ </Tooltip.Content>
3063
+ </Tooltip>
3064
+ }
3065
+ />
3066
+ <CheckBox
3067
+ value={config.table.show}
3068
+ section='table'
3069
+ fieldName='show'
3070
+ label='Show Data Table'
3071
+ updateField={updateField}
3072
+ className='column-heading'
3073
+ tooltip={
3074
+ <Tooltip style={{ textTransform: 'none' }}>
3075
+ <Tooltip.Target>
3076
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
3077
+ </Tooltip.Target>
3078
+ <Tooltip.Content>
3079
+ <p>Hiding the data table may affect accessibility. An alternate form of accessing visualization data is a 508 requirement.</p>
3080
+ </Tooltip.Content>
3081
+ </Tooltip>
3082
+ }
3083
+ />
3084
+ {config.visualizationType !== 'Box Plot' && (
3190
3085
  <CheckBox
3191
- value={config.table.show}
3086
+ value={config.table.showVertical}
3192
3087
  section='table'
3193
- fieldName='show'
3194
- label='Show Data Table'
3088
+ fieldName='showVertical'
3089
+ label='Show Vertical Data'
3195
3090
  updateField={updateField}
3196
3091
  className='column-heading'
3197
3092
  tooltip={
@@ -3200,64 +3095,44 @@ const EditorPanel = () => {
3200
3095
  <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
3201
3096
  </Tooltip.Target>
3202
3097
  <Tooltip.Content>
3203
- <p>Hiding the data table may affect accessibility. An alternate form of accessing visualization data is a 508 requirement.</p>
3204
- </Tooltip.Content>
3205
- </Tooltip>
3206
- }
3207
- />
3208
- {config.visualizationType !== 'Box Plot' && (
3209
- <CheckBox
3210
- value={config.table.showVertical}
3211
- section='table'
3212
- fieldName='showVertical'
3213
- label='Show Vertical Data'
3214
- updateField={updateField}
3215
- className='column-heading'
3216
- tooltip={
3217
- <Tooltip style={{ textTransform: 'none' }}>
3218
- <Tooltip.Target>
3219
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
3220
- </Tooltip.Target>
3221
- <Tooltip.Content>
3222
- <p>This will draw the data table with vertical data instead of horizontal.</p>
3223
- </Tooltip.Content>
3224
- </Tooltip>
3225
- }
3226
- />
3227
- )}
3228
- <TextField value={config.table.indexLabel} section='table' fieldName='indexLabel' label='Index Column Header' updateField={updateField} />
3229
- <TextField
3230
- value={config.table.caption}
3231
- updateField={updateField}
3232
- section='table'
3233
- type='textarea'
3234
- fieldName='caption'
3235
- label='Data Table Caption'
3236
- placeholder=' Data table'
3237
- tooltip={
3238
- <Tooltip style={{ textTransform: 'none' }}>
3239
- <Tooltip.Target>
3240
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
3241
- </Tooltip.Target>
3242
- <Tooltip.Content>
3243
- <p>Enter a description of the data table to be read by screen readers.</p>
3098
+ <p>This will draw the data table with vertical data instead of horizontal.</p>
3244
3099
  </Tooltip.Content>
3245
3100
  </Tooltip>
3246
3101
  }
3247
3102
  />
3248
- <CheckBox value={config.table.limitHeight} section='table' fieldName='limitHeight' label='Limit Table Height' updateField={updateField} />
3249
- {config.table.limitHeight && <TextField value={config.table.height} section='table' fieldName='height' label='Data Table Height' type='number' min='0' max='500' placeholder='Height(px)' updateField={updateField} />}
3250
- <CheckBox value={config.table.expanded} section='table' fieldName='expanded' label='Expanded by Default' updateField={updateField} />
3251
- {isDashboard && <CheckBox value={config.table.showDataTableLink} section='table' fieldName='showDataTableLink' label='Show Data Table Name & Link' updateField={updateField} />}
3252
- {isLoadedFromUrl && <CheckBox value={config.table.showDownloadUrl} section='table' fieldName='showDownloadUrl' label='Show URL to Automatically Updated Data' updateField={updateField} />}
3253
- <CheckBox value={config.table.download} section='table' fieldName='download' label='Show Download CSV Link' updateField={updateField} />
3254
- {/* <CheckBox value={config.table.showDownloadImgButton} section='table' fieldName='showDownloadImgButton' label='Display Image Button' updateField={updateField} /> */}
3255
- {/* <CheckBox value={config.table.showDownloadPdfButton} section='table' fieldName='showDownloadPdfButton' label='Display PDF Button' updateField={updateField} /> */}
3256
- </AccordionItemPanel>
3257
- </AccordionItem>
3258
- )}
3259
- </Accordion>
3260
- </form>
3103
+ )}
3104
+ <TextField value={config.table.indexLabel} section='table' fieldName='indexLabel' label='Index Column Header' updateField={updateField} />
3105
+ <TextField
3106
+ value={config.table.caption}
3107
+ updateField={updateField}
3108
+ section='table'
3109
+ type='textarea'
3110
+ fieldName='caption'
3111
+ label='Data Table Caption'
3112
+ placeholder=' Data table'
3113
+ tooltip={
3114
+ <Tooltip style={{ textTransform: 'none' }}>
3115
+ <Tooltip.Target>
3116
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
3117
+ </Tooltip.Target>
3118
+ <Tooltip.Content>
3119
+ <p>Enter a description of the data table to be read by screen readers.</p>
3120
+ </Tooltip.Content>
3121
+ </Tooltip>
3122
+ }
3123
+ />
3124
+ <CheckBox value={config.table.limitHeight} section='table' fieldName='limitHeight' label='Limit Table Height' updateField={updateField} />
3125
+ {config.table.limitHeight && <TextField value={config.table.height} section='table' fieldName='height' label='Data Table Height' type='number' min='0' max='500' placeholder='Height(px)' updateField={updateField} />}
3126
+ <CheckBox value={config.table.expanded} section='table' fieldName='expanded' label='Expanded by Default' updateField={updateField} />
3127
+ {isDashboard && <CheckBox value={config.table.showDataTableLink} section='table' fieldName='showDataTableLink' label='Show Data Table Name & Link' updateField={updateField} />}
3128
+ {isLoadedFromUrl && <CheckBox value={config.table.showDownloadUrl} section='table' fieldName='showDownloadUrl' label='Show URL to Automatically Updated Data' updateField={updateField} />}
3129
+ <CheckBox value={config.table.download} section='table' fieldName='download' label='Show Download CSV Link' updateField={updateField} />
3130
+ {/* <CheckBox value={config.table.showDownloadImgButton} section='table' fieldName='showDownloadImgButton' label='Display Image Button' updateField={updateField} /> */}
3131
+ {/* <CheckBox value={config.table.showDownloadPdfButton} section='table' fieldName='showDownloadPdfButton' label='Display PDF Button' updateField={updateField} /> */}
3132
+ </AccordionItemPanel>
3133
+ </AccordionItem>
3134
+ )}
3135
+ </Accordion>
3261
3136
  {config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />}
3262
3137
  </section>
3263
3138
  </section>