@cdc/chart 4.23.5 → 4.23.6

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