@cdc/chart 4.24.1 → 4.24.2

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