@cdc/chart 4.24.3 → 4.24.4

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.
@@ -2,6 +2,7 @@ import { useState, useEffect, useCallback, memo, useContext } from 'react'
2
2
  import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd'
3
3
  import { isDateScale } from '@cdc/core/helpers/cove/date'
4
4
  import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
5
+ import Layout from '@cdc/core/components/Layout'
5
6
 
6
7
  // @cdc/core
7
8
  import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
@@ -617,40 +618,10 @@ const EditorPanel = () => {
617
618
 
618
619
  const onBackClick = () => {
619
620
  setDisplayPanel(!displayPanel)
620
- }
621
-
622
- const Error = () => {
623
- return (
624
- <section className='waiting'>
625
- <section className='waiting-container'>
626
- <h3>Error With Configuration</h3>
627
- <p>{config.runtime.editorErrorMessage}</p>
628
- </section>
629
- </section>
630
- )
631
- }
632
-
633
- const Confirm = () => {
634
- const confirmDone = e => {
635
- e.preventDefault()
636
-
637
- let newConfig = { ...config }
638
- delete newConfig.newViz
639
-
640
- updateConfig(newConfig)
641
- }
642
-
643
- return (
644
- <section className='waiting'>
645
- <section className='waiting-container'>
646
- <h3>Finish Configuring</h3>
647
- <p>Set all required options to the left and confirm below to display a preview of the chart.</p>
648
- <button className='btn' style={{ margin: '1em auto' }} disabled={missingRequiredSections()} onClick={confirmDone}>
649
- I'm Done
650
- </button>
651
- </section>
652
- </section>
653
- )
621
+ updateConfig({
622
+ ...config,
623
+ showEditorPanel: !displayPanel
624
+ })
654
625
  }
655
626
 
656
627
  const convertStateToConfig = () => {
@@ -1076,128 +1047,144 @@ const EditorPanel = () => {
1076
1047
  return (
1077
1048
  <EditorPanelContext.Provider value={editorContextValues}>
1078
1049
  <ErrorBoundary component='EditorPanel'>
1079
- {config.newViz && <Confirm />}
1080
- {undefined === config.newViz && config.runtime && config.runtime?.editorErrorMessage && <Error />}
1081
- <button className={displayPanel ? `editor-toggle` : `editor-toggle collapsed`} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick}></button>
1082
- <section className={`${displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'}${isDashboard ? ' dashboard' : ''}`}>
1083
- <div aria-level={2} role='heading' className='heading-2'>
1084
- Configure Chart
1085
- </div>
1086
- <section className='form-container'>
1087
- <Accordion allowZeroExpanded={true}>
1088
- <Panels.General name='General' />
1089
- <Panels.ForestPlot name='Forest Plot Settings' />
1090
- <Panels.Sankey name='Sankey' />
1091
- {config.visualizationType !== 'Pie' && config.visualizationType !== 'Forest Plot' && config.visualizationType !== 'Sankey' && (
1092
- <AccordionItem>
1093
- <AccordionItemHeading>
1094
- <AccordionItemButton>Data Series {(!config.series || config.series.length === 0 || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width='25' className='warning-icon' />}</AccordionItemButton>
1095
- </AccordionItemHeading>
1096
- <AccordionItemPanel>
1097
- {(!config.series || config.series.length === 0) && config.visualizationType !== 'Paired Bar' && <p className='warning'>At least one series is required</p>}
1098
- {(!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>}
1050
+ <Layout.Sidebar displayPanel={displayPanel} isDashboard={isDashboard} title={'Configure Chart'} onBackClick={onBackClick}>
1051
+ <Accordion allowZeroExpanded={true}>
1052
+ <Panels.General name='General' />
1053
+ <Panels.ForestPlot name='Forest Plot Settings' />
1054
+ <Panels.Sankey name='Sankey' />
1055
+ {config.visualizationType !== 'Pie' && config.visualizationType !== 'Forest Plot' && config.visualizationType !== 'Sankey' && (
1056
+ <AccordionItem>
1057
+ <AccordionItemHeading>
1058
+ <AccordionItemButton>Data Series {(!config.series || config.series.length === 0 || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width='25' className='warning-icon' />}</AccordionItemButton>
1059
+ </AccordionItemHeading>
1060
+ <AccordionItemPanel>
1061
+ {(!config.series || config.series.length === 0) && config.visualizationType !== 'Paired Bar' && <p className='warning'>At least one series is required</p>}
1062
+ {(!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>}
1063
+ <>
1064
+ <Select
1065
+ fieldName='visualizationType'
1066
+ label='Add Data Series'
1067
+ initial='Select'
1068
+ onChange={e => {
1069
+ if (e.target.value !== '' && e.target.value !== 'Select') {
1070
+ addNewSeries(e.target.value)
1071
+ }
1072
+ e.target.value = ''
1073
+ }}
1074
+ options={getColumns()}
1075
+ />
1076
+ {config.series && config.series.length !== 0 && (
1077
+ <Panels.Series.Wrapper getColumns={getColumns}>
1078
+ <fieldset>
1079
+ <legend className='edit-label float-left'>Displaying</legend>
1080
+ <Tooltip style={{ textTransform: 'none' }}>
1081
+ <Tooltip.Target>
1082
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1083
+ </Tooltip.Target>
1084
+ <Tooltip.Content>
1085
+ <p>A data series is a set of related data points plotted in a chart and typically represented in the chart legend.</p>
1086
+ </Tooltip.Content>
1087
+ </Tooltip>
1088
+ </fieldset>
1089
+
1090
+ <DragDropContext onDragEnd={({ source, destination }) => handleSeriesChange(source.index, destination.index)}>
1091
+ <Droppable droppableId='filter_order'>
1092
+ {/* prettier-ignore */}
1093
+ {provided => {
1094
+ return (
1095
+ <ul {...provided.droppableProps} className='series-list' ref={provided.innerRef}>
1096
+ <Panels.Series.List series={config.series} getItemStyle={getItemStyle} sortableItemStyles={sortableItemStyles} chartsWithOptions={chartsWithOptions} />
1097
+ {provided.placeholder}
1098
+ </ul>
1099
+ )
1100
+ }}
1101
+ </Droppable>
1102
+ </DragDropContext>
1103
+ </Panels.Series.Wrapper>
1104
+ )}
1105
+ </>
1106
+ {config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
1099
1107
  <>
1100
- <Select
1101
- fieldName='visualizationType'
1102
- label='Add Data Series'
1103
- initial='Select'
1104
- onChange={e => {
1105
- if (e.target.value !== '' && e.target.value !== 'Select') {
1106
- addNewSeries(e.target.value)
1107
- }
1108
- e.target.value = ''
1109
- }}
1110
- options={getColumns()}
1111
- />
1112
- {config.series && config.series.length !== 0 && (
1113
- <Panels.Series.Wrapper getColumns={getColumns}>
1114
- <fieldset>
1115
- <legend className='edit-label float-left'>Displaying</legend>
1116
- <Tooltip style={{ textTransform: 'none' }}>
1117
- <Tooltip.Target>
1118
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1119
- </Tooltip.Target>
1120
- <Tooltip.Content>
1121
- <p>A data series is a set of related data points plotted in a chart and typically represented in the chart legend.</p>
1122
- </Tooltip.Content>
1123
- </Tooltip>
1124
- </fieldset>
1125
-
1126
- <DragDropContext onDragEnd={({ source, destination }) => handleSeriesChange(source.index, destination.index)}>
1127
- <Droppable droppableId='filter_order'>
1128
- {/* prettier-ignore */}
1129
- {provided => {
1130
- return (
1131
- <ul {...provided.droppableProps} className='series-list' ref={provided.innerRef}>
1132
- <Panels.Series.List series={config.series} getItemStyle={getItemStyle} sortableItemStyles={sortableItemStyles} chartsWithOptions={chartsWithOptions} />
1133
- {provided.placeholder}
1134
- </ul>
1135
- )
1136
- }}
1137
- </Droppable>
1138
- </DragDropContext>
1139
- </Panels.Series.Wrapper>
1140
- )}
1108
+ <span className='divider-heading'>Confidence Keys</span>
1109
+ <Select value={config.confidenceKeys.upper || ''} section='confidenceKeys' fieldName='upper' label='Upper' updateField={updateField} initial='Select' options={getColumns()} />
1110
+ <Select value={config.confidenceKeys.lower || ''} section='confidenceKeys' fieldName='lower' label='Lower' updateField={updateField} initial='Select' options={getColumns()} />
1141
1111
  </>
1142
- {config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
1143
- <>
1144
- <span className='divider-heading'>Confidence Keys</span>
1145
- <Select value={config.confidenceKeys.upper || ''} section='confidenceKeys' fieldName='upper' label='Upper' updateField={updateField} initial='Select' options={getColumns()} />
1146
- <Select value={config.confidenceKeys.lower || ''} section='confidenceKeys' fieldName='lower' label='Lower' updateField={updateField} initial='Select' options={getColumns()} />
1147
- </>
1148
- )}
1149
- {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']} />}
1150
- {/* {visHasDataSuppression() && <DataSuppression config={config} updateConfig={updateConfig} data={data} />} */}
1151
- {visSupportsPreliminaryData() && <PreliminaryData config={config} updateConfig={updateConfig} data={data} />}
1152
- </AccordionItemPanel>
1153
- </AccordionItem>
1154
- )}
1155
- <Panels.BoxPlot name='Measures' />
1156
- {/* Left Value Axis */}
1157
- {visSupportsLeftValueAxis() && (
1158
- <AccordionItem>
1159
- <AccordionItemHeading>
1160
- <AccordionItemButton>
1161
- {config.visualizationType === 'Pie' ? 'Data Format' : config.orientation === 'vertical' ? 'Left Value Axis' : 'Value Axis'}
1162
- {config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1163
- </AccordionItemButton>
1164
- </AccordionItemHeading>
1165
- <AccordionItemPanel>
1166
- {config.visualizationType === 'Pie' && (
1167
- <Select
1168
- value={config.yAxis.dataKey || ''}
1112
+ )}
1113
+ {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']} />}
1114
+ {/* {visHasDataSuppression() && <DataSuppression config={config} updateConfig={updateConfig} data={data} />} */}
1115
+ {visSupportsPreliminaryData() && <PreliminaryData config={config} updateConfig={updateConfig} data={data} />}
1116
+ </AccordionItemPanel>
1117
+ </AccordionItem>
1118
+ )}
1119
+ <Panels.BoxPlot name='Measures' />
1120
+ {/* Left Value Axis */}
1121
+ {visSupportsLeftValueAxis() && (
1122
+ <AccordionItem>
1123
+ <AccordionItemHeading>
1124
+ <AccordionItemButton>
1125
+ {config.visualizationType === 'Pie' ? 'Data Format' : config.orientation === 'vertical' ? 'Left Value Axis' : 'Value Axis'}
1126
+ {config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1127
+ </AccordionItemButton>
1128
+ </AccordionItemHeading>
1129
+ <AccordionItemPanel>
1130
+ {config.visualizationType === 'Pie' && (
1131
+ <Select
1132
+ value={config.yAxis.dataKey || ''}
1133
+ section='yAxis'
1134
+ fieldName='dataKey'
1135
+ label='Data Column'
1136
+ initial='Select'
1137
+ required={true}
1138
+ updateField={updateField}
1139
+ options={getColumns(false)}
1140
+ tooltip={
1141
+ <Tooltip style={{ textTransform: 'none' }}>
1142
+ <Tooltip.Target>
1143
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1144
+ </Tooltip.Target>
1145
+ <Tooltip.Content>
1146
+ <p>Select the source data to be visually represented.</p>
1147
+ </Tooltip.Content>
1148
+ </Tooltip>
1149
+ }
1150
+ />
1151
+ )}
1152
+ {config.visualizationType !== 'Pie' && (
1153
+ <>
1154
+ <TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label ' updateField={updateField} />
1155
+ {config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && !['Box Plot', 'Deviation Bar', 'Forest Plot'].includes(config.visualizationType) && (
1156
+ <CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />
1157
+ )}
1158
+ <TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1159
+ <TextField
1160
+ value={config.yAxis.size}
1161
+ type='number'
1169
1162
  section='yAxis'
1170
- fieldName='dataKey'
1171
- label='Data Column'
1172
- initial='Select'
1173
- required={true}
1163
+ fieldName='size'
1164
+ label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
1165
+ className='number-narrow'
1174
1166
  updateField={updateField}
1175
- options={getColumns(false)}
1176
1167
  tooltip={
1177
1168
  <Tooltip style={{ textTransform: 'none' }}>
1178
1169
  <Tooltip.Target>
1179
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1170
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1180
1171
  </Tooltip.Target>
1181
1172
  <Tooltip.Content>
1182
- <p>Select the source data to be visually represented.</p>
1173
+ <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>
1183
1174
  </Tooltip.Content>
1184
1175
  </Tooltip>
1185
1176
  }
1186
1177
  />
1187
- )}
1188
- {config.visualizationType !== 'Pie' && (
1189
- <>
1190
- <TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label ' updateField={updateField} />
1191
- {config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && !['Box Plot', 'Deviation Bar', 'Forest Plot'].includes(config.visualizationType) && (
1192
- <CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />
1193
- )}
1194
- <TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1178
+ {config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
1179
+ {(config.orientation === 'vertical' || !config.isResponsiveTicks) && <TextField value={config.yAxis.tickRotation || 0} type='number' min={0} section='yAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
1180
+ {config.isResponsiveTicks && config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && (
1195
1181
  <TextField
1196
- value={config.yAxis.size}
1182
+ value={config.xAxis.maxTickRotation}
1197
1183
  type='number'
1198
- section='yAxis'
1199
- fieldName='size'
1200
- label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
1184
+ min={0}
1185
+ section='xAxis'
1186
+ fieldName='maxTickRotation'
1187
+ label='Max Tick Rotation'
1201
1188
  className='number-narrow'
1202
1189
  updateField={updateField}
1203
1190
  tooltip={
@@ -1206,552 +1193,507 @@ const EditorPanel = () => {
1206
1193
  <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1207
1194
  </Tooltip.Target>
1208
1195
  <Tooltip.Content>
1209
- <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>
1196
+ <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
1210
1197
  </Tooltip.Content>
1211
1198
  </Tooltip>
1212
1199
  }
1213
1200
  />
1214
- {config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
1215
- {(config.orientation === 'vertical' || !config.isResponsiveTicks) && <TextField value={config.yAxis.tickRotation || 0} type='number' min={0} section='yAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
1216
- {config.isResponsiveTicks && config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && (
1217
- <TextField
1218
- value={config.xAxis.maxTickRotation}
1219
- type='number'
1220
- min={0}
1221
- section='xAxis'
1222
- fieldName='maxTickRotation'
1223
- label='Max Tick Rotation'
1224
- className='number-narrow'
1225
- updateField={updateField}
1226
- tooltip={
1227
- <Tooltip style={{ textTransform: 'none' }}>
1228
- <Tooltip.Target>
1229
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1230
- </Tooltip.Target>
1231
- <Tooltip.Content>
1232
- <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
1233
- </Tooltip.Content>
1234
- </Tooltip>
1235
- }
1236
- />
1237
- )}
1238
-
1239
- {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1240
- {/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1241
- {config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
1242
- {visSupportsValueAxisGridLines() && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Show Gridlines' updateField={updateField} />}
1243
- <CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
1244
- {config.yAxis.enablePadding && <TextField type='number' section='yAxis' fieldName='scalePadding' label='Padding Percentage' className='number-narrow' updateField={updateField} value={config.yAxis.scalePadding} />}
1245
- {config.visualizationSubType === 'regular' && config.visualizationType !== 'Forest Plot' && <CheckBox value={config.useLogScale} fieldName='useLogScale' label='use logarithmic scale' updateField={updateField} />}
1246
- </>
1247
- )}
1248
- <span className='divider-heading'>Number Formatting</span>
1249
- <CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
1250
- <CheckBox
1251
- value={config.dataFormat.abbreviated}
1201
+ )}
1202
+
1203
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1204
+ {/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1205
+ {config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
1206
+ {visSupportsValueAxisGridLines() && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Show Gridlines' updateField={updateField} />}
1207
+ <CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
1208
+ {config.yAxis.enablePadding && <TextField type='number' section='yAxis' fieldName='scalePadding' label='Padding Percentage' className='number-narrow' updateField={updateField} value={config.yAxis.scalePadding} />}
1209
+ {config.visualizationSubType === 'regular' && config.visualizationType !== 'Forest Plot' && <CheckBox value={config.useLogScale} fieldName='useLogScale' label='use logarithmic scale' updateField={updateField} />}
1210
+ </>
1211
+ )}
1212
+ <span className='divider-heading'>Number Formatting</span>
1213
+ <CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
1214
+ <CheckBox
1215
+ value={config.dataFormat.abbreviated}
1216
+ section='dataFormat'
1217
+ fieldName='abbreviated'
1218
+ label='Abbreviate Axis Values'
1219
+ updateField={updateField}
1220
+ tooltip={
1221
+ <Tooltip style={{ textTransform: 'none' }}>
1222
+ <Tooltip.Target>
1223
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1224
+ </Tooltip.Target>
1225
+ <Tooltip.Content>
1226
+ <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1227
+ </Tooltip.Content>
1228
+ </Tooltip>
1229
+ }
1230
+ />
1231
+ <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} />
1232
+ <div className='two-col-inputs'>
1233
+ <TextField
1234
+ value={config.dataFormat.prefix}
1252
1235
  section='dataFormat'
1253
- fieldName='abbreviated'
1254
- label='Abbreviate Axis Values'
1236
+ fieldName='prefix'
1237
+ label='Prefix'
1255
1238
  updateField={updateField}
1256
1239
  tooltip={
1257
1240
  <Tooltip style={{ textTransform: 'none' }}>
1258
1241
  <Tooltip.Target>
1259
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1242
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1260
1243
  </Tooltip.Target>
1261
1244
  <Tooltip.Content>
1262
- <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1245
+ {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1246
+ {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1263
1247
  </Tooltip.Content>
1264
1248
  </Tooltip>
1265
1249
  }
1266
1250
  />
1267
- <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} />
1268
- <div className='two-col-inputs'>
1269
- <TextField
1270
- value={config.dataFormat.prefix}
1271
- section='dataFormat'
1272
- fieldName='prefix'
1273
- label='Prefix'
1274
- updateField={updateField}
1275
- tooltip={
1276
- <Tooltip style={{ textTransform: 'none' }}>
1277
- <Tooltip.Target>
1278
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1279
- </Tooltip.Target>
1280
- <Tooltip.Content>
1281
- {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1282
- {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1283
- </Tooltip.Content>
1284
- </Tooltip>
1285
- }
1286
- />
1287
- <TextField
1288
- value={config.dataFormat.suffix}
1289
- section='dataFormat'
1290
- fieldName='suffix'
1291
- label='Suffix'
1292
- updateField={updateField}
1293
- tooltip={
1294
- <Tooltip style={{ textTransform: 'none' }}>
1295
- <Tooltip.Target>
1296
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1297
- </Tooltip.Target>
1298
- <Tooltip.Content>
1299
- {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1300
- {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1301
- </Tooltip.Content>
1302
- </Tooltip>
1303
- }
1304
- />
1305
- </div>
1251
+ <TextField
1252
+ value={config.dataFormat.suffix}
1253
+ section='dataFormat'
1254
+ fieldName='suffix'
1255
+ label='Suffix'
1256
+ updateField={updateField}
1257
+ tooltip={
1258
+ <Tooltip style={{ textTransform: 'none' }}>
1259
+ <Tooltip.Target>
1260
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1261
+ </Tooltip.Target>
1262
+ <Tooltip.Content>
1263
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1264
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1265
+ </Tooltip.Content>
1266
+ </Tooltip>
1267
+ }
1268
+ />
1269
+ </div>
1306
1270
 
1307
- {config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
1271
+ {config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
1272
+ <>
1273
+ {visSupportsValueAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
1274
+ {visSupportsValueAxisLabels() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
1275
+ {visSupportsValueAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
1276
+ {visSupportsValueAxisMax() && <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />}
1277
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1278
+ {visSupportsValueAxisMin() && <TextField value={config.xAxis.min} section='xAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />}
1279
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1280
+ {config.visualizationType === 'Deviation Bar' && (
1281
+ <>
1282
+ <TextField value={config.xAxis.target} section='xAxis' fieldName='target' type='number' label='Deviation point' placeholder='Auto' updateField={updateField} />
1283
+ <TextField value={config.xAxis.targetLabel || 'Target'} section='xAxis' fieldName='targetLabel' type='text' label='Deviation point Label' updateField={updateField} />
1284
+ <CheckBox value={config.xAxis.showTargetLabel} section='xAxis' fieldName='showTargetLabel' label='Show Deviation point label' updateField={updateField} />
1285
+ </>
1286
+ )}
1287
+ </>
1288
+ ) : (
1289
+ config.visualizationType !== 'Pie' && (
1308
1290
  <>
1309
- {visSupportsValueAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
1310
- {visSupportsValueAxisLabels() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
1311
- {visSupportsValueAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
1312
- {visSupportsValueAxisMax() && <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />}
1291
+ <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1292
+ <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1293
+ <CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1294
+
1295
+ <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='left axis max value' placeholder='Auto' updateField={updateField} />
1313
1296
  <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1314
- {visSupportsValueAxisMin() && <TextField value={config.xAxis.min} section='xAxis' fieldName='min' type='number' label='min value' placeholder='Auto' updateField={updateField} />}
1297
+ <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='left axis min value' placeholder='Auto' updateField={updateField} />
1315
1298
  <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1316
- {config.visualizationType === 'Deviation Bar' && (
1317
- <>
1318
- <TextField value={config.xAxis.target} section='xAxis' fieldName='target' type='number' label='Deviation point' placeholder='Auto' updateField={updateField} />
1319
- <TextField value={config.xAxis.targetLabel || 'Target'} section='xAxis' fieldName='targetLabel' type='text' label='Deviation point Label' updateField={updateField} />
1320
- <CheckBox value={config.xAxis.showTargetLabel} section='xAxis' fieldName='showTargetLabel' label='Show Deviation point label' updateField={updateField} />
1321
- </>
1322
- )}
1323
1299
  </>
1324
- ) : (
1325
- config.visualizationType !== 'Pie' && (
1326
- <>
1327
- <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
1328
- <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
1329
- <CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
1330
-
1331
- <TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='left axis max value' placeholder='Auto' updateField={updateField} />
1332
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
1333
- <TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='left axis min value' placeholder='Auto' updateField={updateField} />
1334
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1335
- </>
1336
- )
1337
- )}
1338
-
1339
- {/* start: anchors */}
1340
- {visHasAnchors() && config.orientation !== 'horizontal' && (
1341
- <div className='edit-block'>
1342
- <span className='edit-label column-heading'>Anchors</span>
1343
- <Accordion allowZeroExpanded>
1344
- {config.yAxis?.anchors?.map((anchor, index) => (
1345
- <AccordionItem className='series-item series-item--chart' key={`yaxis-anchors-2-${index}`}>
1346
- <AccordionItemHeading className='series-item__title'>
1347
- <>
1348
- <AccordionItemButton className={'accordion__button accordion__button'}>
1349
- Anchor {index + 1}
1350
- <button
1351
- className='series-list__remove'
1352
- onClick={e => {
1353
- e.preventDefault()
1354
- const copiedAnchorGroups = [...config.yAxis.anchors]
1355
- copiedAnchorGroups.splice(index, 1)
1356
- updateConfig({
1357
- ...config,
1358
- yAxis: {
1359
- ...config.yAxis,
1360
- anchors: copiedAnchorGroups
1361
- }
1362
- })
1363
- }}
1364
- >
1365
- Remove
1366
- </button>
1367
- </AccordionItemButton>
1368
- </>
1369
- </AccordionItemHeading>
1370
- <AccordionItemPanel>
1371
- <label>
1372
- <span>Anchor Value</span>
1373
- <Tooltip style={{ textTransform: 'none' }}>
1374
- <Tooltip.Target>
1375
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1376
- </Tooltip.Target>
1377
- <Tooltip.Content>
1378
- <p>Enter the value as its shown in the data column</p>
1379
- </Tooltip.Content>
1380
- </Tooltip>
1381
- <input
1382
- type='text'
1383
- value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
1384
- onChange={e => {
1385
- e.preventDefault()
1386
- const copiedAnchors = [...config.yAxis.anchors]
1387
- copiedAnchors[index].value = e.target.value
1388
- updateConfig({
1389
- ...config,
1390
- yAxis: {
1391
- ...config.yAxis,
1392
- anchors: copiedAnchors
1393
- }
1394
- })
1395
- }}
1396
- />
1397
- </label>
1398
-
1399
- <label>
1400
- <span>Anchor Color</span>
1401
- <input
1402
- type='text'
1403
- value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
1404
- onChange={e => {
1300
+ )
1301
+ )}
1302
+
1303
+ {/* start: anchors */}
1304
+ {visHasAnchors() && config.orientation !== 'horizontal' && (
1305
+ <div className='edit-block'>
1306
+ <span className='edit-label column-heading'>Anchors</span>
1307
+ <Accordion allowZeroExpanded>
1308
+ {config.yAxis?.anchors?.map((anchor, index) => (
1309
+ <AccordionItem className='series-item series-item--chart' key={`yaxis-anchors-2-${index}`}>
1310
+ <AccordionItemHeading className='series-item__title'>
1311
+ <>
1312
+ <AccordionItemButton className={'accordion__button accordion__button'}>
1313
+ Anchor {index + 1}
1314
+ <button
1315
+ className='series-list__remove'
1316
+ onClick={e => {
1405
1317
  e.preventDefault()
1406
- const copiedAnchors = [...config.yAxis.anchors]
1407
- copiedAnchors[index].color = e.target.value
1408
- updateConfig({
1409
- ...config,
1410
- yAxis: {
1411
- ...config.yAxis,
1412
- anchors: copiedAnchors
1413
- }
1414
- })
1415
- }}
1416
- />
1417
- </label>
1418
-
1419
- <label>
1420
- Anchor Line Style
1421
- <select
1422
- value={config.yAxis.anchors[index].lineStyle || ''}
1423
- onChange={e => {
1424
- const copiedAnchors = [...config.yAxis.anchors]
1425
- copiedAnchors[index].lineStyle = e.target.value
1318
+ const copiedAnchorGroups = [...config.yAxis.anchors]
1319
+ copiedAnchorGroups.splice(index, 1)
1426
1320
  updateConfig({
1427
1321
  ...config,
1428
1322
  yAxis: {
1429
1323
  ...config.yAxis,
1430
- anchors: copiedAnchors
1324
+ anchors: copiedAnchorGroups
1431
1325
  }
1432
1326
  })
1433
1327
  }}
1434
1328
  >
1435
- <option>Select</option>
1436
- {lineOptions.map(line => (
1437
- <option key={line.key}>{line.value}</option>
1438
- ))}
1439
- </select>
1440
- </label>
1441
- </AccordionItemPanel>
1442
- </AccordionItem>
1443
- ))}
1444
- </Accordion>
1445
-
1446
- <button
1447
- className='btn full-width'
1448
- onClick={e => {
1449
- e.preventDefault()
1450
- const anchors = [...config.yAxis.anchors]
1451
- anchors.push({} as Anchor)
1452
- updateConfig({
1453
- ...config,
1454
- yAxis: {
1455
- ...config.yAxis,
1456
- anchors
1457
- }
1458
- })
1459
- }}
1460
- >
1461
- Add Anchor
1462
- </button>
1463
- </div>
1464
- )}
1329
+ Remove
1330
+ </button>
1331
+ </AccordionItemButton>
1332
+ </>
1333
+ </AccordionItemHeading>
1334
+ <AccordionItemPanel>
1335
+ <label>
1336
+ <span>Anchor Value</span>
1337
+ <Tooltip style={{ textTransform: 'none' }}>
1338
+ <Tooltip.Target>
1339
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1340
+ </Tooltip.Target>
1341
+ <Tooltip.Content>
1342
+ <p>Enter the value as its shown in the data column</p>
1343
+ </Tooltip.Content>
1344
+ </Tooltip>
1345
+ <input
1346
+ type='text'
1347
+ value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
1348
+ onChange={e => {
1349
+ e.preventDefault()
1350
+ const copiedAnchors = [...config.yAxis.anchors]
1351
+ copiedAnchors[index].value = e.target.value
1352
+ updateConfig({
1353
+ ...config,
1354
+ yAxis: {
1355
+ ...config.yAxis,
1356
+ anchors: copiedAnchors
1357
+ }
1358
+ })
1359
+ }}
1360
+ />
1361
+ </label>
1465
1362
 
1466
- {visHasAnchors() && config.orientation === 'horizontal' && (
1467
- <div className='edit-block'>
1468
- <span className='edit-label column-heading'>Anchors</span>
1469
- <Accordion allowZeroExpanded>
1470
- {config.xAxis?.anchors?.map((anchor, index) => (
1471
- <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-${index}`}>
1472
- <AccordionItemHeading className='series-item__title'>
1473
- <>
1474
- <AccordionItemButton className={'accordion__button accordion__button'}>
1475
- Anchor {index + 1}
1476
- <button
1477
- className='series-list__remove'
1478
- onClick={e => {
1479
- e.preventDefault()
1480
- const copiedAnchorGroups = [...config.xAxis.anchors]
1481
- copiedAnchorGroups.splice(index, 1)
1482
- updateConfig({
1483
- ...config,
1484
- xAxis: {
1485
- ...config.xAxis,
1486
- anchors: copiedAnchorGroups
1487
- }
1488
- })
1489
- }}
1490
- >
1491
- Remove
1492
- </button>
1493
- </AccordionItemButton>
1494
- </>
1495
- </AccordionItemHeading>
1496
- <AccordionItemPanel>
1497
- <label>
1498
- <span>Anchor Value</span>
1499
- <Tooltip style={{ textTransform: 'none' }}>
1500
- <Tooltip.Target>
1501
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1502
- </Tooltip.Target>
1503
- <Tooltip.Content>
1504
- <p>Enter the value as its shown in the data column</p>
1505
- </Tooltip.Content>
1506
- </Tooltip>
1507
- <input
1508
- type='text'
1509
- value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
1510
- onChange={e => {
1511
- e.preventDefault()
1512
- const copiedAnchors = [...config.xAxis.anchors]
1513
- copiedAnchors[index].value = e.target.value
1514
- updateConfig({
1515
- ...config,
1516
- xAxis: {
1517
- ...config.xAxis,
1518
- anchors: copiedAnchors
1519
- }
1520
- })
1521
- }}
1522
- />
1523
- </label>
1363
+ <label>
1364
+ <span>Anchor Color</span>
1365
+ <input
1366
+ type='text'
1367
+ value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
1368
+ onChange={e => {
1369
+ e.preventDefault()
1370
+ const copiedAnchors = [...config.yAxis.anchors]
1371
+ copiedAnchors[index].color = e.target.value
1372
+ updateConfig({
1373
+ ...config,
1374
+ yAxis: {
1375
+ ...config.yAxis,
1376
+ anchors: copiedAnchors
1377
+ }
1378
+ })
1379
+ }}
1380
+ />
1381
+ </label>
1524
1382
 
1525
- <label>
1526
- <span>Anchor Color</span>
1527
- <input
1528
- type='text'
1529
- value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
1530
- onChange={e => {
1383
+ <label>
1384
+ Anchor Line Style
1385
+ <select
1386
+ value={config.yAxis.anchors[index].lineStyle || ''}
1387
+ onChange={e => {
1388
+ const copiedAnchors = [...config.yAxis.anchors]
1389
+ copiedAnchors[index].lineStyle = e.target.value
1390
+ updateConfig({
1391
+ ...config,
1392
+ yAxis: {
1393
+ ...config.yAxis,
1394
+ anchors: copiedAnchors
1395
+ }
1396
+ })
1397
+ }}
1398
+ >
1399
+ <option>Select</option>
1400
+ {lineOptions.map(line => (
1401
+ <option key={line.key}>{line.value}</option>
1402
+ ))}
1403
+ </select>
1404
+ </label>
1405
+ </AccordionItemPanel>
1406
+ </AccordionItem>
1407
+ ))}
1408
+ </Accordion>
1409
+
1410
+ <button
1411
+ className='btn full-width'
1412
+ onClick={e => {
1413
+ e.preventDefault()
1414
+ const anchors = [...config.yAxis.anchors]
1415
+ anchors.push({} as Anchor)
1416
+ updateConfig({
1417
+ ...config,
1418
+ yAxis: {
1419
+ ...config.yAxis,
1420
+ anchors
1421
+ }
1422
+ })
1423
+ }}
1424
+ >
1425
+ Add Anchor
1426
+ </button>
1427
+ </div>
1428
+ )}
1429
+
1430
+ {visHasAnchors() && config.orientation === 'horizontal' && (
1431
+ <div className='edit-block'>
1432
+ <span className='edit-label column-heading'>Anchors</span>
1433
+ <Accordion allowZeroExpanded>
1434
+ {config.xAxis?.anchors?.map((anchor, index) => (
1435
+ <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-${index}`}>
1436
+ <AccordionItemHeading className='series-item__title'>
1437
+ <>
1438
+ <AccordionItemButton className={'accordion__button accordion__button'}>
1439
+ Anchor {index + 1}
1440
+ <button
1441
+ className='series-list__remove'
1442
+ onClick={e => {
1531
1443
  e.preventDefault()
1532
- const copiedAnchors = [...config.xAxis.anchors]
1533
- copiedAnchors[index].color = e.target.value
1534
- updateConfig({
1535
- ...config,
1536
- xAxis: {
1537
- ...config.xAxis,
1538
- anchors: copiedAnchors
1539
- }
1540
- })
1541
- }}
1542
- />
1543
- </label>
1544
-
1545
- <label>
1546
- Anchor Line Style
1547
- <select
1548
- value={config.xAxis.anchors[index].lineStyle || ''}
1549
- onChange={e => {
1550
- const copiedAnchors = [...config.xAxis.anchors]
1551
- copiedAnchors[index].lineStyle = e.target.value
1444
+ const copiedAnchorGroups = [...config.xAxis.anchors]
1445
+ copiedAnchorGroups.splice(index, 1)
1552
1446
  updateConfig({
1553
1447
  ...config,
1554
1448
  xAxis: {
1555
1449
  ...config.xAxis,
1556
- anchors: copiedAnchors
1450
+ anchors: copiedAnchorGroups
1557
1451
  }
1558
1452
  })
1559
1453
  }}
1560
1454
  >
1561
- <option>Select</option>
1562
- {lineOptions.map(line => (
1563
- <option key={line.key}>{line.value}</option>
1564
- ))}
1565
- </select>
1566
- </label>
1567
- </AccordionItemPanel>
1568
- </AccordionItem>
1569
- ))}
1570
- </Accordion>
1571
-
1572
- <button
1573
- className='btn full-width'
1574
- onClick={e => {
1575
- e.preventDefault()
1576
- const anchors = [...config.xAxis.anchors]
1577
- anchors.push({} as Anchor)
1578
- updateConfig({
1579
- ...config,
1580
- xAxis: {
1581
- ...config.xAxis,
1582
- anchors
1583
- }
1584
- })
1585
- }}
1586
- >
1587
- Add Anchor
1588
- </button>
1589
- </div>
1590
- )}
1591
- {/* end: anchors */}
1592
- </AccordionItemPanel>
1593
- </AccordionItem>
1594
- )}
1595
- {/* Right Value Axis Settings */}
1596
- {hasRightAxis && (
1597
- <AccordionItem>
1598
- <AccordionItemHeading>
1599
- <AccordionItemButton>Right Value Axis</AccordionItemButton>
1600
- </AccordionItemHeading>
1601
- <AccordionItemPanel>
1602
- <TextField value={config.yAxis.rightLabel} section='yAxis' fieldName='rightLabel' label='Label' updateField={updateField} />
1603
- <TextField value={config.yAxis.rightNumTicks} placeholder='Auto' type='number' section='yAxis' fieldName='rightNumTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1604
- <TextField value={config.yAxis.rightAxisSize} type='number' section='yAxis' fieldName='rightAxisSize' label='Size (Width)' className='number-narrow' updateField={updateField} />
1605
- <TextField value={config.yAxis.rightLabelOffsetSize} type='number' section='yAxis' fieldName='rightLabelOffsetSize' label='Label Offset' className='number-narrow' updateField={updateField} />
1606
-
1607
- <span className='divider-heading'>Number Formatting</span>
1608
- <CheckBox value={config.dataFormat.rightCommas} section='dataFormat' fieldName='rightCommas' label='Add commas' updateField={updateField} />
1609
- <TextField value={config.dataFormat.rightRoundTo} type='number' section='dataFormat' fieldName='rightRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1610
- <div className='two-col-inputs'>
1611
- <TextField
1612
- value={config.dataFormat.rightPrefix}
1613
- section='dataFormat'
1614
- fieldName='rightPrefix'
1615
- label='Prefix'
1616
- updateField={updateField}
1617
- tooltip={
1618
- <Tooltip style={{ textTransform: 'none' }}>
1619
- <Tooltip.Target>
1620
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1621
- </Tooltip.Target>
1622
- <Tooltip.Content>
1623
- {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1624
- {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1625
- </Tooltip.Content>
1626
- </Tooltip>
1627
- }
1628
- />
1629
- <TextField
1630
- value={config.dataFormat.rightSuffix}
1631
- section='dataFormat'
1632
- fieldName='rightSuffix'
1633
- label='Suffix'
1634
- updateField={updateField}
1635
- tooltip={
1636
- <Tooltip style={{ textTransform: 'none' }}>
1637
- <Tooltip.Target>
1638
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1639
- </Tooltip.Target>
1640
- <Tooltip.Content>
1641
- {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1642
- {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1643
- </Tooltip.Content>
1644
- </Tooltip>
1645
- }
1646
- />
1647
- </div>
1648
-
1649
- <CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
1650
- <CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Label' updateField={updateField} />
1651
- <CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
1652
-
1653
- <TextField value={config.yAxis.max} section='yAxis' fieldName='rightMax' type='number' label='right axis max value' placeholder='Auto' updateField={updateField} />
1654
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.rightMaxMessage}</span>
1655
- <TextField value={config.yAxis.min} section='yAxis' fieldName='rightMin' type='number' label='right axis min value' placeholder='Auto' updateField={updateField} />
1656
- <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1657
- </AccordionItemPanel>
1658
- </AccordionItem>
1659
- )}
1660
- {visSupportsDateCategoryAxis() && (
1661
- <AccordionItem>
1662
- <AccordionItemHeading>
1663
- <AccordionItemButton>
1664
- {config.visualizationType === 'Pie' ? 'Segments' : 'Date/Category Axis'}
1665
- {!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1666
- </AccordionItemButton>
1667
- </AccordionItemHeading>
1668
- <AccordionItemPanel>
1669
- {config.visualizationType !== 'Pie' && (
1670
- <>
1671
- {config.visualizationType !== 'Forest Plot' && (
1672
- <>
1673
- <label>
1674
- <span className='edit-label'>
1675
- Data Scaling Type
1676
- <Tooltip style={{ textTransform: 'none', display: 'inline-block' }}>
1455
+ Remove
1456
+ </button>
1457
+ </AccordionItemButton>
1458
+ </>
1459
+ </AccordionItemHeading>
1460
+ <AccordionItemPanel>
1461
+ <label>
1462
+ <span>Anchor Value</span>
1463
+ <Tooltip style={{ textTransform: 'none' }}>
1677
1464
  <Tooltip.Target>
1678
1465
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1679
1466
  </Tooltip.Target>
1680
- <Tooltip.Content>Linear scales are employed for quantitative data, while time scales are used for time-series data.</Tooltip.Content>
1467
+ <Tooltip.Content>
1468
+ <p>Enter the value as its shown in the data column</p>
1469
+ </Tooltip.Content>
1681
1470
  </Tooltip>
1682
- </span>
1683
- <select
1684
- value={config.xAxis.type}
1685
- onChange={e =>
1686
- updateConfig({
1687
- ...config,
1688
- xAxis: {
1689
- ...config.xAxis,
1690
- type: e.target.value
1691
- }
1692
- })
1693
- }
1694
- >
1695
- <option value='categorical'>Categorical (Linear Scale)</option>
1696
- <option value='date'>Date (Linear Scale)</option>
1697
- <option value='date-time'>Date (Date Time Scale)</option>
1698
- {config.visualizationType === 'Scatter Plot' && <option value={'continuous'}>Continuous</option>}
1699
- </select>
1700
- </label>
1471
+ <input
1472
+ type='text'
1473
+ value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
1474
+ onChange={e => {
1475
+ e.preventDefault()
1476
+ const copiedAnchors = [...config.xAxis.anchors]
1477
+ copiedAnchors[index].value = e.target.value
1478
+ updateConfig({
1479
+ ...config,
1480
+ xAxis: {
1481
+ ...config.xAxis,
1482
+ anchors: copiedAnchors
1483
+ }
1484
+ })
1485
+ }}
1486
+ />
1487
+ </label>
1701
1488
 
1702
- {visSupportsDateCategoryAxisPadding() && (
1703
- <TextField
1704
- value={config.xAxis.padding}
1705
- type='number'
1706
- min={0}
1707
- section='xAxis'
1708
- fieldName='padding'
1709
- label={'Padding (Percent)'}
1710
- className='number-narrow'
1711
- updateField={updateField}
1712
- tooltip={
1713
- <Tooltip style={{ textTransform: 'none' }}>
1714
- <Tooltip.Target>
1715
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1716
- </Tooltip.Target>
1717
- <Tooltip.Content>
1718
- <p>For use with date scale. Extends the earliest and latest dates represented on the scale by the percentage specified.</p>
1719
- </Tooltip.Content>
1720
- </Tooltip>
1721
- }
1722
- />
1723
- )}
1724
- </>
1725
- )}
1726
- <Select
1727
- value={config.xAxis.dataKey || setCategoryAxis() || ''}
1728
- section='xAxis'
1729
- fieldName='dataKey'
1730
- label='Data Key'
1731
- initial='Select'
1732
- required={true}
1733
- updateField={updateField}
1734
- options={getColumns(false)}
1735
- tooltip={
1736
- <Tooltip style={{ textTransform: 'none' }}>
1737
- <Tooltip.Target>
1738
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1739
- </Tooltip.Target>
1740
- <Tooltip.Content>
1741
- <p>Select the column or row containing the categories or dates for this axis. </p>
1742
- </Tooltip.Content>
1743
- </Tooltip>
1744
- }
1745
- />
1746
- </>
1747
- )}
1489
+ <label>
1490
+ <span>Anchor Color</span>
1491
+ <input
1492
+ type='text'
1493
+ value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
1494
+ onChange={e => {
1495
+ e.preventDefault()
1496
+ const copiedAnchors = [...config.xAxis.anchors]
1497
+ copiedAnchors[index].color = e.target.value
1498
+ updateConfig({
1499
+ ...config,
1500
+ xAxis: {
1501
+ ...config.xAxis,
1502
+ anchors: copiedAnchors
1503
+ }
1504
+ })
1505
+ }}
1506
+ />
1507
+ </label>
1508
+
1509
+ <label>
1510
+ Anchor Line Style
1511
+ <select
1512
+ value={config.xAxis.anchors[index].lineStyle || ''}
1513
+ onChange={e => {
1514
+ const copiedAnchors = [...config.xAxis.anchors]
1515
+ copiedAnchors[index].lineStyle = e.target.value
1516
+ updateConfig({
1517
+ ...config,
1518
+ xAxis: {
1519
+ ...config.xAxis,
1520
+ anchors: copiedAnchors
1521
+ }
1522
+ })
1523
+ }}
1524
+ >
1525
+ <option>Select</option>
1526
+ {lineOptions.map(line => (
1527
+ <option key={line.key}>{line.value}</option>
1528
+ ))}
1529
+ </select>
1530
+ </label>
1531
+ </AccordionItemPanel>
1532
+ </AccordionItem>
1533
+ ))}
1534
+ </Accordion>
1535
+
1536
+ <button
1537
+ className='btn full-width'
1538
+ onClick={e => {
1539
+ e.preventDefault()
1540
+ const anchors = [...config.xAxis.anchors]
1541
+ anchors.push({} as Anchor)
1542
+ updateConfig({
1543
+ ...config,
1544
+ xAxis: {
1545
+ ...config.xAxis,
1546
+ anchors
1547
+ }
1548
+ })
1549
+ }}
1550
+ >
1551
+ Add Anchor
1552
+ </button>
1553
+ </div>
1554
+ )}
1555
+ {/* end: anchors */}
1556
+ </AccordionItemPanel>
1557
+ </AccordionItem>
1558
+ )}
1559
+ {/* Right Value Axis Settings */}
1560
+ {hasRightAxis && (
1561
+ <AccordionItem>
1562
+ <AccordionItemHeading>
1563
+ <AccordionItemButton>Right Value Axis</AccordionItemButton>
1564
+ </AccordionItemHeading>
1565
+ <AccordionItemPanel>
1566
+ <TextField value={config.yAxis.rightLabel} section='yAxis' fieldName='rightLabel' label='Label' updateField={updateField} />
1567
+ <TextField value={config.yAxis.rightNumTicks} placeholder='Auto' type='number' section='yAxis' fieldName='rightNumTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1568
+ <TextField value={config.yAxis.rightAxisSize} type='number' section='yAxis' fieldName='rightAxisSize' label='Size (Width)' className='number-narrow' updateField={updateField} />
1569
+ <TextField value={config.yAxis.rightLabelOffsetSize} type='number' section='yAxis' fieldName='rightLabelOffsetSize' label='Label Offset' className='number-narrow' updateField={updateField} />
1570
+
1571
+ <span className='divider-heading'>Number Formatting</span>
1572
+ <CheckBox value={config.dataFormat.rightCommas} section='dataFormat' fieldName='rightCommas' label='Add commas' updateField={updateField} />
1573
+ <TextField value={config.dataFormat.rightRoundTo} type='number' section='dataFormat' fieldName='rightRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1574
+ <div className='two-col-inputs'>
1575
+ <TextField
1576
+ value={config.dataFormat.rightPrefix}
1577
+ section='dataFormat'
1578
+ fieldName='rightPrefix'
1579
+ label='Prefix'
1580
+ updateField={updateField}
1581
+ tooltip={
1582
+ <Tooltip style={{ textTransform: 'none' }}>
1583
+ <Tooltip.Target>
1584
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1585
+ </Tooltip.Target>
1586
+ <Tooltip.Content>
1587
+ {config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
1588
+ {config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
1589
+ </Tooltip.Content>
1590
+ </Tooltip>
1591
+ }
1592
+ />
1593
+ <TextField
1594
+ value={config.dataFormat.rightSuffix}
1595
+ section='dataFormat'
1596
+ fieldName='rightSuffix'
1597
+ label='Suffix'
1598
+ updateField={updateField}
1599
+ tooltip={
1600
+ <Tooltip style={{ textTransform: 'none' }}>
1601
+ <Tooltip.Target>
1602
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1603
+ </Tooltip.Target>
1604
+ <Tooltip.Content>
1605
+ {config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
1606
+ {config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
1607
+ </Tooltip.Content>
1608
+ </Tooltip>
1609
+ }
1610
+ />
1611
+ </div>
1612
+
1613
+ <CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
1614
+ <CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Label' updateField={updateField} />
1615
+ <CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
1616
+
1617
+ <TextField value={config.yAxis.max} section='yAxis' fieldName='rightMax' type='number' label='right axis max value' placeholder='Auto' updateField={updateField} />
1618
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.rightMaxMessage}</span>
1619
+ <TextField value={config.yAxis.min} section='yAxis' fieldName='rightMin' type='number' label='right axis min value' placeholder='Auto' updateField={updateField} />
1620
+ <span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
1621
+ </AccordionItemPanel>
1622
+ </AccordionItem>
1623
+ )}
1624
+ {visSupportsDateCategoryAxis() && (
1625
+ <AccordionItem>
1626
+ <AccordionItemHeading>
1627
+ <AccordionItemButton>
1628
+ {config.visualizationType === 'Pie' ? 'Segments' : 'Date/Category Axis'}
1629
+ {!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
1630
+ </AccordionItemButton>
1631
+ </AccordionItemHeading>
1632
+ <AccordionItemPanel>
1633
+ {config.visualizationType !== 'Pie' && (
1634
+ <>
1635
+ {config.visualizationType !== 'Forest Plot' && (
1636
+ <>
1637
+ <label>
1638
+ <span className='edit-label'>
1639
+ Data Scaling Type
1640
+ <Tooltip style={{ textTransform: 'none', display: 'inline-block' }}>
1641
+ <Tooltip.Target>
1642
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1643
+ </Tooltip.Target>
1644
+ <Tooltip.Content>Linear scales are employed for quantitative data, while time scales are used for time-series data.</Tooltip.Content>
1645
+ </Tooltip>
1646
+ </span>
1647
+ <select
1648
+ value={config.xAxis.type}
1649
+ onChange={e =>
1650
+ updateConfig({
1651
+ ...config,
1652
+ xAxis: {
1653
+ ...config.xAxis,
1654
+ type: e.target.value
1655
+ }
1656
+ })
1657
+ }
1658
+ >
1659
+ <option value='categorical'>Categorical (Linear Scale)</option>
1660
+ <option value='date'>Date (Linear Scale)</option>
1661
+ <option value='date-time'>Date (Date Time Scale)</option>
1662
+ {config.visualizationType === 'Scatter Plot' && <option value={'continuous'}>Continuous</option>}
1663
+ </select>
1664
+ </label>
1748
1665
 
1749
- {config.visualizationType === 'Pie' && (
1666
+ <CheckBox value={config.xAxis.manual} section='xAxis' fieldName='manual' label='Manual Ticks' updateField={updateField} />
1667
+
1668
+ {visSupportsDateCategoryAxisPadding() && (
1669
+ <TextField
1670
+ value={config.xAxis.padding}
1671
+ type='number'
1672
+ min={0}
1673
+ section='xAxis'
1674
+ fieldName='padding'
1675
+ label={'Padding (Percent)'}
1676
+ className='number-narrow'
1677
+ updateField={updateField}
1678
+ tooltip={
1679
+ <Tooltip style={{ textTransform: 'none' }}>
1680
+ <Tooltip.Target>
1681
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1682
+ </Tooltip.Target>
1683
+ <Tooltip.Content>
1684
+ <p>For use with date scale. Extends the earliest and latest dates represented on the scale by the percentage specified.</p>
1685
+ </Tooltip.Content>
1686
+ </Tooltip>
1687
+ }
1688
+ />
1689
+ )}
1690
+ </>
1691
+ )}
1750
1692
  <Select
1751
- value={config.xAxis.dataKey || ''}
1693
+ value={config.xAxis.dataKey || setCategoryAxis() || ''}
1752
1694
  section='xAxis'
1753
1695
  fieldName='dataKey'
1754
- label='Segment Labels'
1696
+ label='Data Key'
1755
1697
  initial='Select'
1756
1698
  required={true}
1757
1699
  updateField={updateField}
@@ -1762,317 +1704,268 @@ const EditorPanel = () => {
1762
1704
  <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1763
1705
  </Tooltip.Target>
1764
1706
  <Tooltip.Content>
1765
- <p>Select the source row or column that contains the segment labels. Depending on the data structure, it may be listed as "Key."</p>
1707
+ <p>Select the column or row containing the categories or dates for this axis. </p>
1766
1708
  </Tooltip.Content>
1767
1709
  </Tooltip>
1768
1710
  }
1769
1711
  />
1770
- )}
1771
-
1772
- {config.visualizationType !== 'Pie' && (
1773
- <>
1774
- <TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
1775
-
1776
- {config.xAxis.type === 'continuous' && (
1777
- <>
1778
- <TextField
1779
- value={config.dataFormat.bottomPrefix}
1780
- section='dataFormat'
1781
- fieldName='bottomPrefix'
1782
- label='Prefix'
1783
- updateField={updateField}
1784
- tooltip={
1785
- <Tooltip style={{ textTransform: 'none' }}>
1786
- <Tooltip.Target>
1787
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1788
- </Tooltip.Target>
1789
- <Tooltip.Content>
1790
- <p>Enter a data suffix (such as "%"), if applicable.</p>
1791
- </Tooltip.Content>
1792
- </Tooltip>
1793
- }
1794
- />
1712
+ </>
1713
+ )}
1714
+
1715
+ {config.visualizationType === 'Pie' && (
1716
+ <Select
1717
+ value={config.xAxis.dataKey || ''}
1718
+ section='xAxis'
1719
+ fieldName='dataKey'
1720
+ label='Segment Labels'
1721
+ initial='Select'
1722
+ required={true}
1723
+ updateField={updateField}
1724
+ options={getColumns(false)}
1725
+ tooltip={
1726
+ <Tooltip style={{ textTransform: 'none' }}>
1727
+ <Tooltip.Target>
1728
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
1729
+ </Tooltip.Target>
1730
+ <Tooltip.Content>
1731
+ <p>Select the source row or column that contains the segment labels. Depending on the data structure, it may be listed as "Key."</p>
1732
+ </Tooltip.Content>
1733
+ </Tooltip>
1734
+ }
1735
+ />
1736
+ )}
1795
1737
 
1796
- <TextField
1797
- value={config.dataFormat.bottomSuffix}
1798
- section='dataFormat'
1799
- fieldName='bottomSuffix'
1800
- label='Suffix'
1801
- updateField={updateField}
1802
- tooltip={
1803
- <Tooltip style={{ textTransform: 'none' }}>
1804
- <Tooltip.Target>
1805
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1806
- </Tooltip.Target>
1807
- <Tooltip.Content>
1808
- <p>Enter a data suffix (such as "%"), if applicable.</p>
1809
- </Tooltip.Content>
1810
- </Tooltip>
1811
- }
1812
- />
1738
+ {config.visualizationType !== 'Pie' && (
1739
+ <>
1740
+ <TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
1813
1741
 
1814
- <CheckBox
1815
- value={config.dataFormat.bottomAbbreviated}
1816
- section='dataFormat'
1817
- fieldName='bottomAbbreviated'
1818
- label='Abbreviate Axis Values'
1819
- updateField={updateField}
1820
- tooltip={
1821
- <Tooltip style={{ textTransform: 'none' }}>
1822
- <Tooltip.Target>
1823
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1824
- </Tooltip.Target>
1825
- <Tooltip.Content>
1826
- <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1827
- </Tooltip.Content>
1828
- </Tooltip>
1829
- }
1830
- />
1831
- </>
1832
- )}
1833
-
1834
- {isDateScale(config.xAxis) && (
1835
- <>
1836
- <p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
1837
- Format how charts should parse and display your dates using{' '}
1838
- <a href='https://github.com/d3/d3-time-format#locale_format' target='_blank' rel='noreferrer'>
1839
- these guidelines
1840
- </a>
1841
- .
1842
- </p>
1843
- <TextField
1844
- tooltip={
1845
- <Tooltip style={{ textTransform: 'none' }}>
1846
- <Tooltip.Target>
1847
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1848
- </Tooltip.Target>
1849
- <Tooltip.Content>
1850
- <p>This field specifies the pattern used to read and interpret dates in your dataset, ensuring the dates are correctly understood and processed. </p>
1851
- </Tooltip.Content>
1852
- </Tooltip>
1853
- }
1854
- value={config.xAxis.dateParseFormat}
1855
- section='xAxis'
1856
- fieldName='dateParseFormat'
1857
- placeholder='Ex. %Y-%m-%d'
1858
- label='Date Parse Format'
1859
- updateField={updateField}
1860
- />
1861
- <TextField
1862
- tooltip={
1863
- <Tooltip style={{ textTransform: 'none' }}>
1864
- <Tooltip.Target>
1865
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1866
- </Tooltip.Target>
1867
- <Tooltip.Content>
1868
- <p> Adjusts the date display format on the axis for clear, visual date representation.</p>
1869
- </Tooltip.Content>
1870
- </Tooltip>
1871
- }
1872
- value={config.xAxis.dateDisplayFormat}
1873
- section='xAxis'
1874
- fieldName='dateDisplayFormat'
1875
- placeholder='Ex. %Y-%m-%d'
1876
- label='AXIS DATE DISPLAY FORMAT'
1877
- updateField={updateField}
1878
- />
1879
- <TextField
1880
- tooltip={
1881
- <Tooltip style={{ textTransform: 'none' }}>
1882
- <Tooltip.Target>
1883
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1884
- </Tooltip.Target>
1885
- <Tooltip.Content>
1886
- <p>Specify a custom format for displaying dates in data table. If left empty, dates will adopt the Axis Date Display format. </p>
1887
- </Tooltip.Content>
1888
- </Tooltip>
1889
- }
1890
- value={config.table.dateDisplayFormat}
1891
- section='table'
1892
- fieldName='dateDisplayFormat'
1893
- placeholder='Ex. %Y-%m-%d'
1894
- label='DATA TABLE DATE DISPLAY FORMAT'
1895
- updateField={updateField}
1896
- />
1897
- <TextField
1898
- tooltip={
1899
- <Tooltip style={{ textTransform: 'none' }}>
1900
- <Tooltip.Target>
1901
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1902
- </Tooltip.Target>
1903
- <Tooltip.Content>
1904
- <p>Specify a custom format for displaying dates on hovers. If left empty, dates will adopt the Axis Date Display format. </p>
1905
- </Tooltip.Content>
1906
- </Tooltip>
1907
- }
1908
- value={config.tooltips.dateDisplayFormat}
1909
- section='tooltips'
1910
- fieldName='dateDisplayFormat'
1911
- placeholder='Ex. %Y-%m-%d'
1912
- label='HOVER DATE DISPLAY FORMAT'
1913
- updateField={updateField}
1914
- />
1915
- </>
1916
- )}
1917
-
1918
- <CheckBox
1919
- value={config.exclusions.active}
1920
- section='exclusions'
1921
- fieldName='active'
1922
- label={config.xAxis.type === 'date' ? 'Limit by start and/or end dates' : 'Exclude one or more values'}
1923
- tooltip={
1924
- <Tooltip style={{ textTransform: 'none' }}>
1925
- <Tooltip.Target>
1926
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1927
- </Tooltip.Target>
1928
- <Tooltip.Content>
1929
- <p>When this option is checked, you can select source-file values for exclusion from the date/category axis. </p>
1930
- </Tooltip.Content>
1931
- </Tooltip>
1932
- }
1933
- updateField={updateField}
1934
- />
1935
- {/* {visHasBrushChart && <CheckBox value={config.brush.active} section='brush' fieldName='active' label='Brush Slider ' updateField={updateField} />} */}
1742
+ {config.xAxis.type === 'continuous' && (
1743
+ <>
1744
+ <TextField
1745
+ value={config.dataFormat.bottomPrefix}
1746
+ section='dataFormat'
1747
+ fieldName='bottomPrefix'
1748
+ label='Prefix'
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>Enter a data prefix (such as "$"), if applicable.</p>
1757
+ </Tooltip.Content>
1758
+ </Tooltip>
1759
+ }
1760
+ />
1936
1761
 
1937
- {config.exclusions.active && (
1938
- <>
1939
- {config.xAxis.type === 'categorical' && (
1940
- <>
1941
- {config.exclusions.keys.length > 0 && (
1942
- <>
1943
- <fieldset>
1944
- <legend className='edit-label'>Excluded Keys</legend>
1945
- </fieldset>
1946
- <ExclusionsList />
1947
- </>
1948
- )}
1762
+ <TextField
1763
+ value={config.dataFormat.bottomSuffix}
1764
+ section='dataFormat'
1765
+ fieldName='bottomSuffix'
1766
+ label='Suffix'
1767
+ updateField={updateField}
1768
+ tooltip={
1769
+ <Tooltip style={{ textTransform: 'none' }}>
1770
+ <Tooltip.Target>
1771
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1772
+ </Tooltip.Target>
1773
+ <Tooltip.Content>
1774
+ <p>Enter a data suffix (such as "%"), if applicable.</p>
1775
+ </Tooltip.Content>
1776
+ </Tooltip>
1777
+ }
1778
+ />
1949
1779
 
1950
- <Select
1951
- fieldName='visualizationType'
1952
- label='Add Exclusion'
1953
- initial='Select'
1954
- onChange={e => {
1955
- if (e.target.value !== '' && e.target.value !== 'Select') {
1956
- addNewExclusion(e.target.value)
1957
- }
1958
- e.target.value = ''
1959
- }}
1960
- options={getDataValues(config.xAxis.dataKey, true)}
1961
- />
1962
- </>
1963
- )}
1780
+ <CheckBox
1781
+ value={config.dataFormat.bottomAbbreviated}
1782
+ section='dataFormat'
1783
+ fieldName='bottomAbbreviated'
1784
+ label='Abbreviate Axis Values'
1785
+ updateField={updateField}
1786
+ tooltip={
1787
+ <Tooltip style={{ textTransform: 'none' }}>
1788
+ <Tooltip.Target>
1789
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1790
+ </Tooltip.Target>
1791
+ <Tooltip.Content>
1792
+ <p>{`This option abbreviates very large or very small numbers on the value axis`}</p>
1793
+ </Tooltip.Content>
1794
+ </Tooltip>
1795
+ }
1796
+ />
1797
+ </>
1798
+ )}
1964
1799
 
1965
- {config.xAxis.type === 'date' && (
1966
- <>
1967
- <TextField type='date' section='exclusions' fieldName='dateStart' label='Start Date' updateField={updateField} value={config.exclusions.dateStart || ''} />
1968
- <TextField type='date' section='exclusions' fieldName='dateEnd' label='End Date' updateField={updateField} value={config.exclusions.dateEnd || ''} />
1969
- </>
1970
- )}
1971
- </>
1972
- )}
1973
-
1974
- {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} />}
1975
- {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} />}
1976
-
1977
- {visSupportsDateCategoryAxisPadding() && <TextField value={config.xAxis.padding} type='number' min={0} section='xAxis' fieldName='padding' label={'Padding (Percent)'} className='number-narrow' updateField={updateField} />}
1978
-
1979
- {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1980
- {/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1981
- {(config.xAxis.type === 'continuous' || config.forestPlot.type === 'Logarithmic') && (
1982
- <>
1983
- <CheckBox value={config.dataFormat.bottomCommas} section='dataFormat' fieldName='bottomCommas' label='Add commas' updateField={updateField} />
1984
- <TextField value={config.dataFormat.bottomRoundTo} type='number' section='dataFormat' fieldName='bottomRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1985
- </>
1986
- )}
1987
- {visSupportsResponsiveTicks() && config.orientation === 'vertical' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
1988
- {(config.orientation === 'horizontal' || !config.isResponsiveTicks) && visSupportsDateCategoryTickRotation() && (
1989
- <TextField value={config.xAxis.tickRotation} type='number' min={0} section='xAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />
1990
- )}
1991
- {config.orientation === 'vertical' && config.isResponsiveTicks && config.visualizationType !== 'Paired Bar' && (
1800
+ {isDateScale(config.xAxis) && (
1801
+ <>
1802
+ <p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
1803
+ Format how charts should parse and display your dates using{' '}
1804
+ <a href='https://github.com/d3/d3-time-format#locale_format' target='_blank' rel='noreferrer'>
1805
+ these guidelines
1806
+ </a>
1807
+ .
1808
+ </p>
1992
1809
  <TextField
1993
- value={config.xAxis.maxTickRotation}
1994
- type='number'
1995
- min={0}
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>This field specifies the pattern used to read and interpret dates in your dataset, ensuring the dates are correctly understood and processed. </p>
1817
+ </Tooltip.Content>
1818
+ </Tooltip>
1819
+ }
1820
+ value={config.xAxis.dateParseFormat}
1821
+ section='xAxis'
1822
+ fieldName='dateParseFormat'
1823
+ placeholder='Ex. %Y-%m-%d'
1824
+ label='Date Parse 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> Adjusts the date display format on the axis for clear, visual date representation.</p>
1835
+ </Tooltip.Content>
1836
+ </Tooltip>
1837
+ }
1838
+ value={config.xAxis.dateDisplayFormat}
1996
1839
  section='xAxis'
1997
- fieldName='maxTickRotation'
1998
- label='Max Tick Rotation'
1999
- className='number-narrow'
1840
+ fieldName='dateDisplayFormat'
1841
+ placeholder='Ex. %Y-%m-%d'
1842
+ label='AXIS DATE DISPLAY FORMAT'
2000
1843
  updateField={updateField}
1844
+ />
1845
+ <TextField
2001
1846
  tooltip={
2002
1847
  <Tooltip style={{ textTransform: 'none' }}>
2003
1848
  <Tooltip.Target>
2004
1849
  <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2005
1850
  </Tooltip.Target>
2006
1851
  <Tooltip.Content>
2007
- <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
1852
+ <p>Specify a custom format for displaying dates in data table. If left empty, dates will adopt the Axis Date Display format. </p>
2008
1853
  </Tooltip.Content>
2009
1854
  </Tooltip>
2010
1855
  }
1856
+ value={config.table.dateDisplayFormat}
1857
+ section='table'
1858
+ fieldName='dateDisplayFormat'
1859
+ placeholder='Ex. %Y-%m-%d'
1860
+ label='DATA TABLE DATE DISPLAY FORMAT'
1861
+ updateField={updateField}
2011
1862
  />
2012
- )}
2013
-
2014
- {config.orientation === 'horizontal' ? (
2015
- <>
2016
- {visSupportsDateCategoryAxisLine() && <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
2017
- {visSupportsDateCategoryAxisLabel() && <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
2018
- </>
2019
- ) : (
2020
- <>
2021
- {visSupportsDateCategoryAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
2022
- {visSupportsDateCategoryAxisLabel() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
2023
- {visSupportsDateCategoryAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
2024
- </>
2025
- )}
2026
-
2027
- {config.series?.length === 1 && config.visualizationType === 'Bar' && (
2028
- <>
2029
- {/* HIGHLIGHTED BARS */}
2030
- <label htmlFor='barHighlight'>Bar Highlighting</label>
2031
- {config.series.length === 1 &&
2032
- highlightedBarValues.map((highlightedBarValue, i) => (
2033
- <fieldset>
2034
- <div className='edit-block' key={`highlighted-bar-${i}`}>
2035
- <button className='remove-column' onClick={e => handleRemoveHighlightedBar(e, i)}>
2036
- Remove
2037
- </button>
2038
- <p>Highlighted Bar {i + 1}</p>
2039
- <label>
2040
- <span className='edit-label column-heading'>Value</span>
2041
- <select value={config.highlightedBarValues[i].value} onChange={e => handleUpdateHighlightedBar(e, i)}>
2042
- <option value=''>- Select Value -</option>
2043
- {highlightedSeriesValues && [...new Set(highlightedSeriesValues)].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
2044
- </select>
2045
- </label>
2046
- <label>
2047
- <span className='edit-label column-heading'>Color</span>
2048
- <input type='text' value={config.highlightedBarValues[i].color ? config.highlightedBarValues[i].color : ''} onChange={e => handleUpdateHighlightedBarColor(e, i)} />
2049
- </label>
2050
- <label>
2051
- <span className='edit-label column-heading'>Border Width</span>
2052
- <input max='5' min='0' type='number' value={config.highlightedBarValues[i].borderWidth ? config.highlightedBarValues[i].borderWidth : ''} onChange={e => handleUpdateHighlightedBorderWidth(e, i)} />
2053
- </label>
2054
- <label>
2055
- <span className='edit-label column-heading'>Legend Label</span>
2056
- <input type='text' value={config.highlightedBarValues[i].legendLabel ? config.highlightedBarValues[i].legendLabel : ''} onChange={e => handleHighlightedBarLegendLabel(e, i)} />
2057
- </label>
2058
- </div>
2059
- </fieldset>
2060
- ))}
2061
- <button className='btn full-width' onClick={e => handleAddNewHighlightedBar(e)}>
2062
- Add Highlighted Bar
2063
- </button>
2064
- </>
2065
- )}
2066
- </>
2067
- )}
1863
+ <TextField
1864
+ tooltip={
1865
+ <Tooltip style={{ textTransform: 'none' }}>
1866
+ <Tooltip.Target>
1867
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1868
+ </Tooltip.Target>
1869
+ <Tooltip.Content>
1870
+ <p>Specify a custom format for displaying dates on hovers. If left empty, dates will adopt the Axis Date Display format. </p>
1871
+ </Tooltip.Content>
1872
+ </Tooltip>
1873
+ }
1874
+ value={config.tooltips.dateDisplayFormat}
1875
+ section='tooltips'
1876
+ fieldName='dateDisplayFormat'
1877
+ placeholder='Ex. %Y-%m-%d'
1878
+ label='HOVER DATE DISPLAY FORMAT'
1879
+ updateField={updateField}
1880
+ />
1881
+ </>
1882
+ )}
2068
1883
 
2069
- {config.visualizationType === 'Pie' && (
2070
- <>
2071
- <CheckBox
2072
- value={config.exclusions.active}
2073
- section='exclusions'
2074
- fieldName='active'
2075
- label={'Exclude one or more values'}
1884
+ <CheckBox
1885
+ value={config.exclusions.active}
1886
+ section='exclusions'
1887
+ fieldName='active'
1888
+ label={config.xAxis.type === 'date' ? 'Limit by start and/or end dates' : 'Exclude one or more values'}
1889
+ tooltip={
1890
+ <Tooltip style={{ textTransform: 'none' }}>
1891
+ <Tooltip.Target>
1892
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
1893
+ </Tooltip.Target>
1894
+ <Tooltip.Content>
1895
+ <p>When this option is checked, you can select source-file values for exclusion from the date/category axis. </p>
1896
+ </Tooltip.Content>
1897
+ </Tooltip>
1898
+ }
1899
+ updateField={updateField}
1900
+ />
1901
+ {/* {visHasBrushChart && <CheckBox value={config.brush.active} section='brush' fieldName='active' label='Brush Slider ' updateField={updateField} />} */}
1902
+
1903
+ {config.exclusions.active && (
1904
+ <>
1905
+ {config.xAxis.type === 'categorical' && (
1906
+ <>
1907
+ {config.exclusions.keys.length > 0 && (
1908
+ <>
1909
+ <fieldset>
1910
+ <legend className='edit-label'>Excluded Keys</legend>
1911
+ </fieldset>
1912
+ <ExclusionsList />
1913
+ </>
1914
+ )}
1915
+
1916
+ <Select
1917
+ fieldName='visualizationType'
1918
+ label='Add Exclusion'
1919
+ initial='Select'
1920
+ onChange={e => {
1921
+ if (e.target.value !== '' && e.target.value !== 'Select') {
1922
+ addNewExclusion(e.target.value)
1923
+ }
1924
+ e.target.value = ''
1925
+ }}
1926
+ options={getDataValues(config.xAxis.dataKey, true)}
1927
+ />
1928
+ </>
1929
+ )}
1930
+
1931
+ {config.xAxis.type === 'date' && (
1932
+ <>
1933
+ <TextField type='date' section='exclusions' fieldName='dateStart' label='Start Date' updateField={updateField} value={config.exclusions.dateStart || ''} />
1934
+ <TextField type='date' section='exclusions' fieldName='dateEnd' label='End Date' updateField={updateField} value={config.exclusions.dateEnd || ''} />
1935
+ </>
1936
+ )}
1937
+ </>
1938
+ )}
1939
+
1940
+ {visSupportsDateCategoryNumTicks() && config.xAxis.type !== 'date-time' && config.xAxis.manual && (
1941
+ <TextField value={config.xAxis.manualStep} placeholder='Auto' type='number' min={1} section='xAxis' fieldName='manualStep' label='Step count' className='number-narrow' updateField={updateField} />
1942
+ )}
1943
+ {visSupportsDateCategoryNumTicks() && (config.xAxis.type === 'date-time' || !config.xAxis.manual) && (
1944
+ <TextField value={config.xAxis.numTicks} placeholder='Auto' type='number' min={1} section='xAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
1945
+ )}
1946
+ {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} />}
1947
+
1948
+ {/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
1949
+ {/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
1950
+ {(config.xAxis.type === 'continuous' || config.forestPlot.type === 'Logarithmic') && (
1951
+ <>
1952
+ <CheckBox value={config.dataFormat.bottomCommas} section='dataFormat' fieldName='bottomCommas' label='Add commas' updateField={updateField} />
1953
+ <TextField value={config.dataFormat.bottomRoundTo} type='number' section='dataFormat' fieldName='bottomRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
1954
+ </>
1955
+ )}
1956
+ {visSupportsResponsiveTicks() && config.orientation === 'vertical' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
1957
+ {(config.orientation === 'horizontal' || !config.isResponsiveTicks) && visSupportsDateCategoryTickRotation() && (
1958
+ <TextField value={config.xAxis.tickRotation} type='number' min={0} section='xAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />
1959
+ )}
1960
+ {config.orientation === 'vertical' && config.isResponsiveTicks && config.visualizationType !== 'Paired Bar' && (
1961
+ <TextField
1962
+ value={config.xAxis.maxTickRotation}
1963
+ type='number'
1964
+ min={0}
1965
+ section='xAxis'
1966
+ fieldName='maxTickRotation'
1967
+ label='Max Tick Rotation'
1968
+ className='number-narrow'
2076
1969
  updateField={updateField}
2077
1970
  tooltip={
2078
1971
  <Tooltip style={{ textTransform: 'none' }}>
@@ -2080,543 +1973,619 @@ const EditorPanel = () => {
2080
1973
  <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2081
1974
  </Tooltip.Target>
2082
1975
  <Tooltip.Content>
2083
- <p>When this option is checked, you can select values for exclusion from the pie segments.</p>
1976
+ <p>Degrees ticks will be rotated if values overlap, especially in smaller viewports.</p>
2084
1977
  </Tooltip.Content>
2085
1978
  </Tooltip>
2086
1979
  }
2087
1980
  />
2088
- {config.exclusions.active && (
2089
- <>
2090
- {config.exclusions.keys.length > 0 && (
2091
- <>
2092
- <fieldset>
2093
- <legend className='edit-label'>Excluded Keys</legend>
2094
- </fieldset>
2095
- <ExclusionsList />
2096
- </>
2097
- )}
1981
+ )}
2098
1982
 
2099
- <Select
2100
- fieldName='visualizationType'
2101
- label='Add Exclusion'
2102
- initial='Select'
2103
- onChange={e => {
2104
- if (e.target.value !== '' && e.target.value !== 'Select') {
2105
- addNewExclusion(e.target.value)
2106
- }
2107
- e.target.value = ''
2108
- }}
2109
- options={getDataValues(config.xAxis.dataKey, true)}
2110
- />
2111
- </>
2112
- )}
2113
- </>
2114
- )}
1983
+ {config.orientation === 'horizontal' ? (
1984
+ <>
1985
+ {visSupportsDateCategoryAxisLine() && <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
1986
+ {visSupportsDateCategoryAxisLabel() && <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
1987
+ </>
1988
+ ) : (
1989
+ <>
1990
+ {visSupportsDateCategoryAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
1991
+ {visSupportsDateCategoryAxisLabel() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />}
1992
+ {visSupportsDateCategoryAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
1993
+ </>
1994
+ )}
2115
1995
 
2116
- {/* anchors */}
2117
- {visHasAnchors() && config.orientation !== 'horizontal' && (
2118
- <div className='edit-block'>
2119
- <span className='edit-label column-heading'>Anchors</span>
2120
- <Accordion allowZeroExpanded>
2121
- {config.xAxis?.anchors?.map((anchor, index) => (
2122
- <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-2-${index}`}>
2123
- <AccordionItemHeading className='series-item__title'>
2124
- <>
2125
- <AccordionItemButton className={'accordion__button accordion__button'}>
2126
- Anchor {index + 1}
2127
- <button
2128
- className='series-list__remove'
2129
- onClick={e => {
2130
- e.preventDefault()
2131
- const copiedAnchorGroups = [...config.xAxis.anchors]
2132
- copiedAnchorGroups.splice(index, 1)
2133
- updateConfig({
2134
- ...config,
2135
- xAxis: {
2136
- ...config.xAxis,
2137
- anchors: copiedAnchorGroups
2138
- }
2139
- })
2140
- }}
2141
- >
2142
- Remove
2143
- </button>
2144
- </AccordionItemButton>
2145
- </>
2146
- </AccordionItemHeading>
2147
- <AccordionItemPanel>
2148
- <label>
2149
- <span>Anchor Value</span>
2150
- <Tooltip style={{ textTransform: 'none' }}>
2151
- <Tooltip.Target>
2152
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2153
- </Tooltip.Target>
2154
- <Tooltip.Content>
2155
- <p>Enter the value as its shown in the data column</p>
2156
- </Tooltip.Content>
2157
- </Tooltip>
2158
- <input
2159
- type='text'
2160
- value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
2161
- onChange={e => {
2162
- e.preventDefault()
2163
- const copiedAnchors = [...config.xAxis.anchors]
2164
- copiedAnchors[index].value = e.target.value
2165
- updateConfig({
2166
- ...config,
2167
- xAxis: {
2168
- ...config.xAxis,
2169
- anchors: copiedAnchors
2170
- }
2171
- })
2172
- }}
2173
- />
2174
- </label>
1996
+ {config.series?.length === 1 && config.visualizationType === 'Bar' && (
1997
+ <>
1998
+ {/* HIGHLIGHTED BARS */}
1999
+ <label htmlFor='barHighlight'>Bar Highlighting</label>
2000
+ {config.series.length === 1 &&
2001
+ highlightedBarValues.map((highlightedBarValue, i) => (
2002
+ <fieldset>
2003
+ <div className='edit-block' key={`highlighted-bar-${i}`}>
2004
+ <button className='remove-column' onClick={e => handleRemoveHighlightedBar(e, i)}>
2005
+ Remove
2006
+ </button>
2007
+ <p>Highlighted Bar {i + 1}</p>
2008
+ <label>
2009
+ <span className='edit-label column-heading'>Value</span>
2010
+ <select value={config.highlightedBarValues[i].value} onChange={e => handleUpdateHighlightedBar(e, i)}>
2011
+ <option value=''>- Select Value -</option>
2012
+ {highlightedSeriesValues && [...new Set(highlightedSeriesValues)].sort().map(option => <option key={`special-class-value-option-${i}-${option}`}>{option}</option>)}
2013
+ </select>
2014
+ </label>
2015
+ <label>
2016
+ <span className='edit-label column-heading'>Color</span>
2017
+ <input type='text' value={config.highlightedBarValues[i].color ? config.highlightedBarValues[i].color : ''} onChange={e => handleUpdateHighlightedBarColor(e, i)} />
2018
+ </label>
2019
+ <label>
2020
+ <span className='edit-label column-heading'>Border Width</span>
2021
+ <input max='5' min='0' type='number' value={config.highlightedBarValues[i].borderWidth ? config.highlightedBarValues[i].borderWidth : ''} onChange={e => handleUpdateHighlightedBorderWidth(e, i)} />
2022
+ </label>
2023
+ <label>
2024
+ <span className='edit-label column-heading'>Legend Label</span>
2025
+ <input type='text' value={config.highlightedBarValues[i].legendLabel ? config.highlightedBarValues[i].legendLabel : ''} onChange={e => handleHighlightedBarLegendLabel(e, i)} />
2026
+ </label>
2027
+ </div>
2028
+ </fieldset>
2029
+ ))}
2030
+ <button className='btn full-width' onClick={e => handleAddNewHighlightedBar(e)}>
2031
+ Add Highlighted Bar
2032
+ </button>
2033
+ </>
2034
+ )}
2035
+ </>
2036
+ )}
2175
2037
 
2176
- <label>
2177
- <span>Anchor Color</span>
2178
- <input
2179
- type='text'
2180
- value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
2181
- onChange={e => {
2038
+ {config.visualizationType === 'Pie' && (
2039
+ <>
2040
+ <CheckBox
2041
+ value={config.exclusions.active}
2042
+ section='exclusions'
2043
+ fieldName='active'
2044
+ label={'Exclude one or more values'}
2045
+ updateField={updateField}
2046
+ tooltip={
2047
+ <Tooltip style={{ textTransform: 'none' }}>
2048
+ <Tooltip.Target>
2049
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2050
+ </Tooltip.Target>
2051
+ <Tooltip.Content>
2052
+ <p>When this option is checked, you can select values for exclusion from the pie segments.</p>
2053
+ </Tooltip.Content>
2054
+ </Tooltip>
2055
+ }
2056
+ />
2057
+ {config.exclusions.active && (
2058
+ <>
2059
+ {config.exclusions.keys.length > 0 && (
2060
+ <>
2061
+ <fieldset>
2062
+ <legend className='edit-label'>Excluded Keys</legend>
2063
+ </fieldset>
2064
+ <ExclusionsList />
2065
+ </>
2066
+ )}
2067
+
2068
+ <Select
2069
+ fieldName='visualizationType'
2070
+ label='Add Exclusion'
2071
+ initial='Select'
2072
+ onChange={e => {
2073
+ if (e.target.value !== '' && e.target.value !== 'Select') {
2074
+ addNewExclusion(e.target.value)
2075
+ }
2076
+ e.target.value = ''
2077
+ }}
2078
+ options={getDataValues(config.xAxis.dataKey, true)}
2079
+ />
2080
+ </>
2081
+ )}
2082
+ </>
2083
+ )}
2084
+
2085
+ {/* anchors */}
2086
+ {visHasAnchors() && config.orientation !== 'horizontal' && (
2087
+ <div className='edit-block'>
2088
+ <span className='edit-label column-heading'>Anchors</span>
2089
+ <Accordion allowZeroExpanded>
2090
+ {config.xAxis?.anchors?.map((anchor, index) => (
2091
+ <AccordionItem className='series-item series-item--chart' key={`xaxis-anchors-2-${index}`}>
2092
+ <AccordionItemHeading className='series-item__title'>
2093
+ <>
2094
+ <AccordionItemButton className={'accordion__button accordion__button'}>
2095
+ Anchor {index + 1}
2096
+ <button
2097
+ className='series-list__remove'
2098
+ onClick={e => {
2182
2099
  e.preventDefault()
2183
- const copiedAnchors = [...config.xAxis.anchors]
2184
- copiedAnchors[index].color = e.target.value
2185
- updateConfig({
2186
- ...config,
2187
- xAxis: {
2188
- ...config.xAxis,
2189
- anchors: copiedAnchors
2190
- }
2191
- })
2192
- }}
2193
- />
2194
- </label>
2195
-
2196
- <label>
2197
- Anchor Line Style
2198
- <select
2199
- value={config.xAxis.anchors[index].lineStyle || ''}
2200
- onChange={e => {
2201
- const copiedAnchors = [...config.xAxis.anchors]
2202
- copiedAnchors[index].lineStyle = e.target.value
2100
+ const copiedAnchorGroups = [...config.xAxis.anchors]
2101
+ copiedAnchorGroups.splice(index, 1)
2203
2102
  updateConfig({
2204
2103
  ...config,
2205
2104
  xAxis: {
2206
2105
  ...config.xAxis,
2207
- anchors: copiedAnchors
2106
+ anchors: copiedAnchorGroups
2208
2107
  }
2209
2108
  })
2210
2109
  }}
2211
2110
  >
2212
- <option>Select</option>
2213
- {lineOptions.map(line => (
2214
- <option key={line.key}>{line.value}</option>
2215
- ))}
2216
- </select>
2217
- </label>
2218
- </AccordionItemPanel>
2219
- </AccordionItem>
2220
- ))}
2221
- </Accordion>
2222
-
2223
- <button
2224
- className='btn full-width'
2225
- onClick={e => {
2226
- e.preventDefault()
2227
- const anchors = [...config.xAxis.anchors]
2228
- anchors.push({} as Anchor)
2229
- updateConfig({
2230
- ...config,
2231
- xAxis: {
2232
- ...config.xAxis,
2233
- anchors
2234
- }
2235
- })
2236
- }}
2237
- >
2238
- Add Anchor
2239
- </button>
2240
- </div>
2241
- )}
2111
+ Remove
2112
+ </button>
2113
+ </AccordionItemButton>
2114
+ </>
2115
+ </AccordionItemHeading>
2116
+ <AccordionItemPanel>
2117
+ <label>
2118
+ <span>Anchor Value</span>
2119
+ <Tooltip style={{ textTransform: 'none' }}>
2120
+ <Tooltip.Target>
2121
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2122
+ </Tooltip.Target>
2123
+ <Tooltip.Content>
2124
+ <p>Enter the value as its shown in the data column</p>
2125
+ </Tooltip.Content>
2126
+ </Tooltip>
2127
+ <input
2128
+ type='text'
2129
+ value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
2130
+ onChange={e => {
2131
+ e.preventDefault()
2132
+ const copiedAnchors = [...config.xAxis.anchors]
2133
+ copiedAnchors[index].value = e.target.value
2134
+ updateConfig({
2135
+ ...config,
2136
+ xAxis: {
2137
+ ...config.xAxis,
2138
+ anchors: copiedAnchors
2139
+ }
2140
+ })
2141
+ }}
2142
+ />
2143
+ </label>
2242
2144
 
2243
- {visHasAnchors() && config.orientation === 'horizontal' && (
2244
- <div className='edit-block'>
2245
- <span className='edit-label column-heading'>Anchors</span>
2246
- <Accordion allowZeroExpanded>
2247
- {config.yAxis?.anchors?.map((anchor, index) => (
2248
- <AccordionItem className='series-item series-item--chart' key={`accordion-yaxis-anchors-${index}`}>
2249
- <AccordionItemHeading className='series-item__title'>
2250
- <>
2251
- <AccordionItemButton className={'accordion__button accordion__button'}>
2252
- Anchor {index + 1}
2253
- <button
2254
- className='series-list__remove'
2255
- onClick={e => {
2256
- e.preventDefault()
2257
- const copiedAnchorGroups = [...config.yAxis.anchors]
2258
- copiedAnchorGroups.splice(index, 1)
2259
- updateConfig({
2260
- ...config,
2261
- yAxis: {
2262
- ...config.yAxis,
2263
- anchors: copiedAnchorGroups
2264
- }
2265
- })
2266
- }}
2267
- >
2268
- Remove
2269
- </button>
2270
- </AccordionItemButton>
2271
- </>
2272
- </AccordionItemHeading>
2273
- <AccordionItemPanel>
2274
- <label>
2275
- <span>Anchor Value</span>
2276
- <Tooltip style={{ textTransform: 'none' }}>
2277
- <Tooltip.Target>
2278
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2279
- </Tooltip.Target>
2280
- <Tooltip.Content>
2281
- <p>Enter the value as its shown in the data column</p>
2282
- </Tooltip.Content>
2283
- </Tooltip>
2284
- <input
2285
- type='text'
2286
- value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
2287
- onChange={e => {
2288
- e.preventDefault()
2289
- const copiedAnchors = [...config.yAxis.anchors]
2290
- copiedAnchors[index].value = e.target.value
2291
- updateConfig({
2292
- ...config,
2293
- yAxis: {
2294
- ...config.yAxis,
2295
- anchors: copiedAnchors
2296
- }
2297
- })
2298
- }}
2299
- />
2300
- </label>
2145
+ <label>
2146
+ <span>Anchor Color</span>
2147
+ <input
2148
+ type='text'
2149
+ value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
2150
+ onChange={e => {
2151
+ e.preventDefault()
2152
+ const copiedAnchors = [...config.xAxis.anchors]
2153
+ copiedAnchors[index].color = e.target.value
2154
+ updateConfig({
2155
+ ...config,
2156
+ xAxis: {
2157
+ ...config.xAxis,
2158
+ anchors: copiedAnchors
2159
+ }
2160
+ })
2161
+ }}
2162
+ />
2163
+ </label>
2301
2164
 
2302
- <label>
2303
- <span>Anchor Color</span>
2304
- <input
2305
- type='text'
2306
- value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
2307
- onChange={e => {
2165
+ <label>
2166
+ Anchor Line Style
2167
+ <select
2168
+ value={config.xAxis.anchors[index].lineStyle || ''}
2169
+ onChange={e => {
2170
+ const copiedAnchors = [...config.xAxis.anchors]
2171
+ copiedAnchors[index].lineStyle = e.target.value
2172
+ updateConfig({
2173
+ ...config,
2174
+ xAxis: {
2175
+ ...config.xAxis,
2176
+ anchors: copiedAnchors
2177
+ }
2178
+ })
2179
+ }}
2180
+ >
2181
+ <option>Select</option>
2182
+ {lineOptions.map(line => (
2183
+ <option key={line.key}>{line.value}</option>
2184
+ ))}
2185
+ </select>
2186
+ </label>
2187
+ </AccordionItemPanel>
2188
+ </AccordionItem>
2189
+ ))}
2190
+ </Accordion>
2191
+
2192
+ <button
2193
+ className='btn full-width'
2194
+ onClick={e => {
2195
+ e.preventDefault()
2196
+ const anchors = [...config.xAxis.anchors]
2197
+ anchors.push({} as Anchor)
2198
+ updateConfig({
2199
+ ...config,
2200
+ xAxis: {
2201
+ ...config.xAxis,
2202
+ anchors
2203
+ }
2204
+ })
2205
+ }}
2206
+ >
2207
+ Add Anchor
2208
+ </button>
2209
+ </div>
2210
+ )}
2211
+
2212
+ {visHasAnchors() && config.orientation === 'horizontal' && (
2213
+ <div className='edit-block'>
2214
+ <span className='edit-label column-heading'>Anchors</span>
2215
+ <Accordion allowZeroExpanded>
2216
+ {config.yAxis?.anchors?.map((anchor, index) => (
2217
+ <AccordionItem className='series-item series-item--chart' key={`accordion-yaxis-anchors-${index}`}>
2218
+ <AccordionItemHeading className='series-item__title'>
2219
+ <>
2220
+ <AccordionItemButton className={'accordion__button accordion__button'}>
2221
+ Anchor {index + 1}
2222
+ <button
2223
+ className='series-list__remove'
2224
+ onClick={e => {
2308
2225
  e.preventDefault()
2309
- const copiedAnchors = [...config.yAxis.anchors]
2310
- copiedAnchors[index].color = e.target.value
2311
- updateConfig({
2312
- ...config,
2313
- yAxis: {
2314
- ...config.yAxis,
2315
- anchors: copiedAnchors
2316
- }
2317
- })
2318
- }}
2319
- />
2320
- </label>
2321
-
2322
- <label>
2323
- Anchor Line Style
2324
- <select
2325
- value={config.yAxis.anchors[index].lineStyle || ''}
2326
- onChange={e => {
2327
- const copiedAnchors = [...config.yAxis.anchors]
2328
- copiedAnchors[index].lineStyle = e.target.value
2226
+ const copiedAnchorGroups = [...config.yAxis.anchors]
2227
+ copiedAnchorGroups.splice(index, 1)
2329
2228
  updateConfig({
2330
2229
  ...config,
2331
2230
  yAxis: {
2332
2231
  ...config.yAxis,
2333
- anchors: copiedAnchors
2232
+ anchors: copiedAnchorGroups
2334
2233
  }
2335
2234
  })
2336
2235
  }}
2337
2236
  >
2338
- <option>Select</option>
2339
- {lineOptions.map(line => (
2340
- <option key={line.key}>{line.value}</option>
2341
- ))}
2342
- </select>
2343
- </label>
2344
- </AccordionItemPanel>
2345
- </AccordionItem>
2346
- ))}
2347
- </Accordion>
2348
-
2349
- <button
2350
- className='btn full-width'
2351
- onClick={e => {
2352
- e.preventDefault()
2353
- const anchors = [...config.yAxis.anchors]
2354
- anchors.push({} as Anchor)
2355
- updateConfig({
2356
- ...config,
2357
- yAxis: {
2358
- ...config.yAxis,
2359
- anchors
2360
- }
2361
- })
2362
- }}
2363
- >
2364
- Add Anchor
2365
- </button>
2366
- </div>
2367
- )}
2368
- </AccordionItemPanel>
2369
- </AccordionItem>
2370
- )}
2371
- <Panels.Regions name='Regions' />
2372
- {/* Columns */}
2373
- {config.visualizationType !== 'Box Plot' && (
2374
- <AccordionItem>
2375
- <AccordionItemHeading>
2376
- <AccordionItemButton>Columns</AccordionItemButton>
2377
- </AccordionItemHeading>
2378
- <AccordionItemPanel>
2379
- {'navigation' !== config.type && (
2380
- <fieldset className='primary-fieldset edit-block'>
2381
- <label>
2382
- <span className='edit-label'>
2383
- Additional Columns
2384
- <Tooltip style={{ textTransform: 'none' }}>
2385
- <Tooltip.Target>
2386
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2387
- </Tooltip.Target>
2388
- <Tooltip.Content>
2389
- <p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
2390
- </Tooltip.Content>
2391
- </Tooltip>
2392
- </span>
2393
- </label>
2394
- {additionalColumns.map(val => (
2395
- <fieldset className='edit-block' key={val}>
2396
- <button
2397
- className='remove-column'
2398
- onClick={event => {
2399
- event.preventDefault()
2400
- removeAdditionalColumn(val)
2237
+ Remove
2238
+ </button>
2239
+ </AccordionItemButton>
2240
+ </>
2241
+ </AccordionItemHeading>
2242
+ <AccordionItemPanel>
2243
+ <label>
2244
+ <span>Anchor Value</span>
2245
+ <Tooltip style={{ textTransform: 'none' }}>
2246
+ <Tooltip.Target>
2247
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2248
+ </Tooltip.Target>
2249
+ <Tooltip.Content>
2250
+ <p>Enter the value as its shown in the data column</p>
2251
+ </Tooltip.Content>
2252
+ </Tooltip>
2253
+ <input
2254
+ type='text'
2255
+ value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
2256
+ onChange={e => {
2257
+ e.preventDefault()
2258
+ const copiedAnchors = [...config.yAxis.anchors]
2259
+ copiedAnchors[index].value = e.target.value
2260
+ updateConfig({
2261
+ ...config,
2262
+ yAxis: {
2263
+ ...config.yAxis,
2264
+ anchors: copiedAnchors
2265
+ }
2266
+ })
2267
+ }}
2268
+ />
2269
+ </label>
2270
+
2271
+ <label>
2272
+ <span>Anchor Color</span>
2273
+ <input
2274
+ type='text'
2275
+ value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
2276
+ onChange={e => {
2277
+ e.preventDefault()
2278
+ const copiedAnchors = [...config.yAxis.anchors]
2279
+ copiedAnchors[index].color = e.target.value
2280
+ updateConfig({
2281
+ ...config,
2282
+ yAxis: {
2283
+ ...config.yAxis,
2284
+ anchors: copiedAnchors
2285
+ }
2286
+ })
2287
+ }}
2288
+ />
2289
+ </label>
2290
+
2291
+ <label>
2292
+ Anchor Line Style
2293
+ <select
2294
+ value={config.yAxis.anchors[index].lineStyle || ''}
2295
+ onChange={e => {
2296
+ const copiedAnchors = [...config.yAxis.anchors]
2297
+ copiedAnchors[index].lineStyle = e.target.value
2298
+ updateConfig({
2299
+ ...config,
2300
+ yAxis: {
2301
+ ...config.yAxis,
2302
+ anchors: copiedAnchors
2303
+ }
2304
+ })
2305
+ }}
2306
+ >
2307
+ <option>Select</option>
2308
+ {lineOptions.map(line => (
2309
+ <option key={line.key}>{line.value}</option>
2310
+ ))}
2311
+ </select>
2312
+ </label>
2313
+ </AccordionItemPanel>
2314
+ </AccordionItem>
2315
+ ))}
2316
+ </Accordion>
2317
+
2318
+ <button
2319
+ className='btn full-width'
2320
+ onClick={e => {
2321
+ e.preventDefault()
2322
+ const anchors = [...config.yAxis.anchors]
2323
+ anchors.push({} as Anchor)
2324
+ updateConfig({
2325
+ ...config,
2326
+ yAxis: {
2327
+ ...config.yAxis,
2328
+ anchors
2329
+ }
2330
+ })
2331
+ }}
2332
+ >
2333
+ Add Anchor
2334
+ </button>
2335
+ </div>
2336
+ )}
2337
+ </AccordionItemPanel>
2338
+ </AccordionItem>
2339
+ )}
2340
+ <Panels.Regions name='Regions' />
2341
+ {/* Columns */}
2342
+ {config.visualizationType !== 'Box Plot' && (
2343
+ <AccordionItem>
2344
+ <AccordionItemHeading>
2345
+ <AccordionItemButton>Columns</AccordionItemButton>
2346
+ </AccordionItemHeading>
2347
+ <AccordionItemPanel>
2348
+ {'navigation' !== config.type && (
2349
+ <fieldset className='primary-fieldset edit-block'>
2350
+ <label>
2351
+ <span className='edit-label'>
2352
+ Additional Columns
2353
+ <Tooltip style={{ textTransform: 'none' }}>
2354
+ <Tooltip.Target>
2355
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2356
+ </Tooltip.Target>
2357
+ <Tooltip.Content>
2358
+ <p>You can specify additional columns to display in tooltips and / or the supporting data table.</p>
2359
+ </Tooltip.Content>
2360
+ </Tooltip>
2361
+ </span>
2362
+ </label>
2363
+ {additionalColumns.map(val => (
2364
+ <fieldset className='edit-block' key={val}>
2365
+ <button
2366
+ className='remove-column'
2367
+ onClick={event => {
2368
+ event.preventDefault()
2369
+ removeAdditionalColumn(val)
2370
+ }}
2371
+ >
2372
+ Remove
2373
+ </button>
2374
+ <label>
2375
+ <span className='edit-label column-heading'>Column</span>
2376
+ <select
2377
+ value={config.columns[val] ? config.columns[val].name : getColumns()[0]}
2378
+ onChange={event => {
2379
+ editColumn(val, 'name', event.target.value)
2380
+ }}
2381
+ >
2382
+ {getColumns().map(option => (
2383
+ <option>{option}</option>
2384
+ ))}
2385
+ </select>
2386
+ </label>
2387
+ <label>
2388
+ <span className='edit-label column-heading'>Associate to Series</span>
2389
+ <select
2390
+ value={config.columns[val] ? config.columns[val].series : ''}
2391
+ onChange={event => {
2392
+ editColumn(val, 'series', event.target.value)
2401
2393
  }}
2402
2394
  >
2403
- Remove
2404
- </button>
2405
- <label>
2406
- <span className='edit-label column-heading'>Column</span>
2407
- <select
2408
- value={config.columns[val] ? config.columns[val].name : getColumns()[0]}
2409
- onChange={event => {
2410
- editColumn(val, 'name', event.target.value)
2411
- }}
2412
- >
2413
- {getColumns().map(option => (
2414
- <option>{option}</option>
2415
- ))}
2416
- </select>
2417
- </label>
2418
- <label>
2419
- <span className='edit-label column-heading'>Associate to Series</span>
2420
- <select
2421
- value={config.columns[val] ? config.columns[val].series : ''}
2422
- onChange={event => {
2423
- editColumn(val, 'series', event.target.value)
2424
- }}
2425
- >
2426
- <option value=''>Select series</option>
2427
- {config.series.map(series => (
2428
- <option>{series.dataKey}</option>
2429
- ))}
2430
- </select>
2431
- </label>
2432
- <TextField value={config.columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
2433
- <ul className='column-edit'>
2434
- <li className='three-col'>
2435
- <TextField value={config.columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
2436
- <TextField value={config.columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
2437
- <TextField type='number' value={config.columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
2438
- </li>
2395
+ <option value=''>Select series</option>
2396
+ {config.series.map(series => (
2397
+ <option>{series.dataKey}</option>
2398
+ ))}
2399
+ </select>
2400
+ </label>
2401
+ <TextField value={config.columns[val].label} section='columns' subsection={val} fieldName='label' label='Label' updateField={updateField} />
2402
+ <ul className='column-edit'>
2403
+ <li className='three-col'>
2404
+ <TextField value={config.columns[val].prefix} section='columns' subsection={val} fieldName='prefix' label='Prefix' updateField={updateField} />
2405
+ <TextField value={config.columns[val].suffix} section='columns' subsection={val} fieldName='suffix' label='Suffix' updateField={updateField} />
2406
+ <TextField type='number' value={config.columns[val].roundToPlace} section='columns' subsection={val} fieldName='roundToPlace' label='Round' updateField={updateField} />
2407
+ </li>
2408
+ <li>
2409
+ <label className='checkbox'>
2410
+ <input
2411
+ type='checkbox'
2412
+ checked={config.columns[val].commas}
2413
+ onChange={event => {
2414
+ editColumn(val, 'commas', event.target.checked)
2415
+ }}
2416
+ />
2417
+ <span className='edit-label'>Add Commas to Numbers</span>
2418
+ </label>
2419
+ </li>
2420
+ <li>
2421
+ {config.table.showVertical && (
2422
+ <label className='checkbox'>
2423
+ <input
2424
+ type='checkbox'
2425
+ checked={config.columns[val].dataTable}
2426
+ onChange={event => {
2427
+ editColumn(val, 'dataTable', event.target.checked)
2428
+ }}
2429
+ />
2430
+ <span className='edit-label'>Show in Data Table</span>
2431
+ </label>
2432
+ )}
2433
+ </li>
2434
+ {config.visualizationType === 'Pie' && (
2439
2435
  <li>
2440
2436
  <label className='checkbox'>
2441
2437
  <input
2442
2438
  type='checkbox'
2443
- checked={config.columns[val].commas}
2439
+ checked={config.columns[val].showInViz}
2444
2440
  onChange={event => {
2445
- editColumn(val, 'commas', event.target.checked)
2441
+ editColumn(val, 'showInViz', event.target.checked)
2446
2442
  }}
2447
2443
  />
2448
- <span className='edit-label'>Add Commas to Numbers</span>
2444
+ <span className='edit-label'>Show in Visualization</span>
2449
2445
  </label>
2450
2446
  </li>
2451
- <li>
2452
- {config.table.showVertical && (
2447
+ )}
2448
+
2449
+ {/* disable for now */}
2450
+
2451
+ <li>
2452
+ <label className='checkbox'>
2453
+ <input
2454
+ type='checkbox'
2455
+ checked={config.columns[val].tooltips || false}
2456
+ onChange={event => {
2457
+ updateSeriesTooltip(val, event.target.checked)
2458
+ }}
2459
+ />
2460
+ <span className='edit-label'>Show in tooltip</span>
2461
+ </label>
2462
+ </li>
2463
+
2464
+ {config.visualizationType === 'Forest Plot' && (
2465
+ <>
2466
+ <li>
2453
2467
  <label className='checkbox'>
2454
2468
  <input
2455
2469
  type='checkbox'
2456
- checked={config.columns[val].dataTable}
2470
+ checked={config.columns[val].forestPlot || false}
2457
2471
  onChange={event => {
2458
- editColumn(val, 'dataTable', event.target.checked)
2472
+ editColumn(val, 'forestPlot', event.target.checked)
2459
2473
  }}
2460
2474
  />
2461
- <span className='edit-label'>Show in Data Table</span>
2475
+ <span className='edit-label'>Show in Forest Plot</span>
2462
2476
  </label>
2463
- )}
2464
- </li>
2465
- {config.visualizationType === 'Pie' && (
2477
+ </li>
2466
2478
  <li>
2467
2479
  <label className='checkbox'>
2468
2480
  <input
2469
2481
  type='checkbox'
2470
- checked={config.columns[val].showInViz}
2482
+ checked={config.columns[val].forestPlotAlignRight || false}
2471
2483
  onChange={event => {
2472
- editColumn(val, 'showInViz', event.target.checked)
2484
+ editColumn(val, 'forestPlotAlignRight', event.target.checked)
2473
2485
  }}
2474
2486
  />
2475
- <span className='edit-label'>Show in Visualization</span>
2487
+ <span className='edit-label'>Align Right</span>
2476
2488
  </label>
2477
2489
  </li>
2478
- )}
2479
-
2480
- {/* disable for now */}
2481
2490
 
2482
- <li>
2483
- <label className='checkbox'>
2484
- <input
2485
- type='checkbox'
2486
- checked={config.columns[val].tooltips || false}
2487
- onChange={event => {
2488
- updateSeriesTooltip(val, event.target.checked)
2489
- }}
2490
- />
2491
- <span className='edit-label'>Show in tooltip</span>
2492
- </label>
2493
- </li>
2494
-
2495
- {config.visualizationType === 'Forest Plot' && (
2496
- <>
2497
- <li>
2498
- <label className='checkbox'>
2499
- <input
2500
- type='checkbox'
2501
- checked={config.columns[val].forestPlot || false}
2502
- onChange={event => {
2503
- editColumn(val, 'forestPlot', event.target.checked)
2504
- }}
2505
- />
2506
- <span className='edit-label'>Show in Forest Plot</span>
2507
- </label>
2508
- </li>
2491
+ {!config.columns[val].forestPlotAlignRight && (
2509
2492
  <li>
2510
- <label className='checkbox'>
2493
+ <label className='text'>
2494
+ <span className='edit-label'>Forest Plot Starting Point</span>
2511
2495
  <input
2512
- type='checkbox'
2513
- checked={config.columns[val].forestPlotAlignRight || false}
2496
+ type='number'
2497
+ value={config.columns[val].forestPlotStartingPoint || 0}
2514
2498
  onChange={event => {
2515
- editColumn(val, 'forestPlotAlignRight', event.target.checked)
2499
+ editColumn(val, 'forestPlotStartingPoint', event.target.value)
2516
2500
  }}
2517
2501
  />
2518
- <span className='edit-label'>Align Right</span>
2519
2502
  </label>
2520
2503
  </li>
2521
-
2522
- {!config.columns[val].forestPlotAlignRight && (
2523
- <li>
2524
- <label className='text'>
2525
- <span className='edit-label'>Forest Plot Starting Point</span>
2526
- <input
2527
- type='number'
2528
- value={config.columns[val].forestPlotStartingPoint || 0}
2529
- onChange={event => {
2530
- editColumn(val, 'forestPlotStartingPoint', event.target.value)
2531
- }}
2532
- />
2533
- </label>
2534
- </li>
2535
- )}
2536
- </>
2537
- )}
2538
- </ul>
2504
+ )}
2505
+ </>
2506
+ )}
2507
+ </ul>
2508
+ </fieldset>
2509
+ ))}
2510
+ <button
2511
+ className={'btn full-width'}
2512
+ onClick={event => {
2513
+ event.preventDefault()
2514
+ addAdditionalColumn(additionalColumns.length + 1)
2515
+ }}
2516
+ >
2517
+ Add Column
2518
+ </button>
2519
+ </fieldset>
2520
+ )}
2521
+ {'category' === config.legend.type && (
2522
+ <fieldset className='primary-fieldset edit-block'>
2523
+ <label>
2524
+ <span className='edit-label'>
2525
+ Additional Category
2526
+ <Tooltip style={{ textTransform: 'none' }}>
2527
+ <Tooltip.Target>
2528
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2529
+ </Tooltip.Target>
2530
+ <Tooltip.Content>
2531
+ <p>You can provide additional categories to ensure they appear in the legend</p>
2532
+ </Tooltip.Content>
2533
+ </Tooltip>
2534
+ </span>
2535
+ </label>
2536
+ {config.legend.additionalCategories &&
2537
+ config.legend.additionalCategories.map((val, i) => (
2538
+ <fieldset className='edit-block' key={val}>
2539
+ <button
2540
+ className='remove-column'
2541
+ onClick={event => {
2542
+ event.preventDefault()
2543
+ const updatedAdditionaCategories = [...config.legend.additionalCategories]
2544
+ updatedAdditionaCategories.splice(i, 1)
2545
+ updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2546
+ }}
2547
+ >
2548
+ Remove
2549
+ </button>
2550
+ <TextField
2551
+ value={val}
2552
+ label='Category'
2553
+ section='legend'
2554
+ subsection={null}
2555
+ fieldName='additionalCategories'
2556
+ updateField={(section, subsection, fieldName, value) => {
2557
+ const updatedAdditionaCategories = [...config.legend.additionalCategories]
2558
+ updatedAdditionaCategories[i] = value
2559
+ updateField(section, subsection, fieldName, updatedAdditionaCategories)
2560
+ }}
2561
+ />
2539
2562
  </fieldset>
2540
2563
  ))}
2541
- <button
2542
- className={'btn full-width'}
2543
- onClick={event => {
2544
- event.preventDefault()
2545
- addAdditionalColumn(additionalColumns.length + 1)
2546
- }}
2547
- >
2548
- Add Column
2549
- </button>
2550
- </fieldset>
2551
- )}
2552
- {'category' === config.legend.type && (
2553
- <fieldset className='primary-fieldset edit-block'>
2554
- <label>
2555
- <span className='edit-label'>
2556
- Additional Category
2557
- <Tooltip style={{ textTransform: 'none' }}>
2558
- <Tooltip.Target>
2559
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2560
- </Tooltip.Target>
2561
- <Tooltip.Content>
2562
- <p>You can provide additional categories to ensure they appear in the legend</p>
2563
- </Tooltip.Content>
2564
- </Tooltip>
2565
- </span>
2566
- </label>
2567
- {config.legend.additionalCategories &&
2568
- config.legend.additionalCategories.map((val, i) => (
2569
- <fieldset className='edit-block' key={val}>
2570
- <button
2571
- className='remove-column'
2572
- onClick={event => {
2573
- event.preventDefault()
2574
- const updatedAdditionaCategories = [...config.legend.additionalCategories]
2575
- updatedAdditionaCategories.splice(i, 1)
2576
- updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2577
- }}
2578
- >
2579
- Remove
2580
- </button>
2581
- <TextField
2582
- value={val}
2583
- label='Category'
2584
- section='legend'
2585
- subsection={null}
2586
- fieldName='additionalCategories'
2587
- updateField={(section, subsection, fieldName, value) => {
2588
- const updatedAdditionaCategories = [...config.legend.additionalCategories]
2589
- updatedAdditionaCategories[i] = value
2590
- updateField(section, subsection, fieldName, updatedAdditionaCategories)
2591
- }}
2592
- />
2593
- </fieldset>
2594
- ))}
2595
- <button
2596
- className={'btn full-width'}
2597
- onClick={event => {
2598
- event.preventDefault()
2599
- const updatedAdditionaCategories = [...(config.legend.additionalCategories || [])]
2600
- updatedAdditionaCategories.push('')
2601
- updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2602
- }}
2603
- >
2604
- Add Category
2605
- </button>
2606
- </fieldset>
2607
- )}
2608
- </AccordionItemPanel>
2609
- </AccordionItem>
2610
- )}
2611
- {/* End Columns */}
2612
- {visHasLegend() && (
2613
- <AccordionItem>
2614
- <AccordionItemHeading>
2615
- <AccordionItemButton>Legend</AccordionItemButton>
2616
- </AccordionItemHeading>
2617
- <AccordionItemPanel>
2618
- <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
2619
- {/* <fieldset className="checkbox-group">
2564
+ <button
2565
+ className={'btn full-width'}
2566
+ onClick={event => {
2567
+ event.preventDefault()
2568
+ const updatedAdditionaCategories = [...(config.legend.additionalCategories || [])]
2569
+ updatedAdditionaCategories.push('')
2570
+ updateField('legend', null, 'additionalCategories', updatedAdditionaCategories)
2571
+ }}
2572
+ >
2573
+ Add Category
2574
+ </button>
2575
+ </fieldset>
2576
+ )}
2577
+ </AccordionItemPanel>
2578
+ </AccordionItem>
2579
+ )}
2580
+ {/* End Columns */}
2581
+ {visHasLegend() && (
2582
+ <AccordionItem>
2583
+ <AccordionItemHeading>
2584
+ <AccordionItemButton>Legend</AccordionItemButton>
2585
+ </AccordionItemHeading>
2586
+ <AccordionItemPanel>
2587
+ <CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
2588
+ {/* <fieldset className="checkbox-group">
2620
2589
  <CheckBox value={config.legend.dynamicLegend} section="legend" fieldName="dynamicLegend" label="Dynamic Legend" updateField={updateField}/>
2621
2590
  {config.legend.dynamicLegend && (
2622
2591
  <>
@@ -2627,128 +2596,128 @@ const EditorPanel = () => {
2627
2596
  </>
2628
2597
  )}
2629
2598
  </fieldset> */}
2630
- <CheckBox
2631
- value={config.legend.hide ? true : false}
2632
- section='legend'
2633
- fieldName='hide'
2634
- label='Hide Legend'
2635
- updateField={updateField}
2636
- tooltip={
2637
- <Tooltip style={{ textTransform: 'none' }}>
2638
- <Tooltip.Target>
2639
- <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2640
- </Tooltip.Target>
2641
- <Tooltip.Content>
2642
- <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
2643
- </Tooltip.Content>
2644
- </Tooltip>
2645
- }
2646
- />
2647
- {/* {config.visualizationType === 'Box Plot' &&
2599
+ <CheckBox
2600
+ value={config.legend.hide ? true : false}
2601
+ section='legend'
2602
+ fieldName='hide'
2603
+ label='Hide Legend'
2604
+ updateField={updateField}
2605
+ tooltip={
2606
+ <Tooltip style={{ textTransform: 'none' }}>
2607
+ <Tooltip.Target>
2608
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
2609
+ </Tooltip.Target>
2610
+ <Tooltip.Content>
2611
+ <p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
2612
+ </Tooltip.Content>
2613
+ </Tooltip>
2614
+ }
2615
+ />
2616
+ {/* {config.visualizationType === 'Box Plot' &&
2648
2617
  <>
2649
2618
  <CheckBox value={config.boxplot.legend.displayHowToReadText} fieldName='displayHowToReadText' section='boxplot' subsection='legend' label='Display How To Read Text' updateField={updateField} />
2650
2619
  <TextField type='textarea' value={config.boxplot.legend.howToReadText} updateField={updateField} fieldName='howToReadText' section='boxplot' subsection='legend' label='How to read text' />
2651
2620
  </>
2652
2621
  } */}
2653
- {config.visualizationType === 'Line' && <CheckBox value={config.legend.lineMode} section='legend' fieldName='lineMode' label='Show Lined Style Legend' updateField={updateField} />}
2654
- {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
2655
- <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
2656
- )}
2657
- <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={(...[section, , fieldName, value]) => updateBehavior(section, fieldName, value)} options={['highlight', 'isolate']} />
2658
- {visHasLegendAxisAlign() && <CheckBox value={config.legend.axisAlign} fieldName='axisAlign' section='legend' label='Align to Axis on Isolate' updateField={updateField} />}
2659
-
2660
- {config.legend.behavior === 'highlight' && config.tooltips.singleSeries && <CheckBox value={config.legend.highlightOnHover} section='legend' fieldName='highlightOnHover' label='HIGHLIGHT DATA SERIES ON HOVER' updateField={updateField} />}
2661
-
2662
- {/* start: isolated values */}
2663
- {visHasSelectableLegendValues && config.legend.behavior === 'isolate' && !colorCodeByCategory && (
2664
- <fieldset className='primary-fieldset edit-block' key={'additional-highlight-values'}>
2665
- <label>
2666
- <span className='edit-label'>
2667
- Isolate Data Series
2668
- <Tooltip style={{ textTransform: 'none' }}>
2669
- <Tooltip.Target>
2670
- <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2671
- </Tooltip.Target>
2672
- <Tooltip.Content>
2673
- <p>You can choose data series that are shown on load. Others will be added when the user clicks on them in the legend.</p>
2674
- </Tooltip.Content>
2675
- </Tooltip>
2676
- </span>
2677
- </label>
2678
- {config.legend.seriesHighlight &&
2679
- config.legend.seriesHighlight.map((val, i) => (
2680
- <fieldset className='edit-block' key={`${val}-${i}`}>
2681
- <button
2682
- className='remove-column'
2683
- onClick={event => {
2684
- event.preventDefault()
2685
- const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2686
- updatedSeriesHighlight.splice(i, 1)
2687
- updateField('legend', null, 'seriesHighlight', updatedSeriesHighlight)
2688
- if (!updatedSeriesHighlight.length) {
2689
- highlightReset()
2690
- }
2691
- }}
2692
- >
2693
- Remove
2694
- </button>
2695
- <Select
2696
- value={config.legend.seriesHighlight[i]}
2697
- fieldName='seriesHighlight'
2698
- label='Isolate Value'
2699
- onChange={e => {
2700
- const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2701
- if (!updatedSeriesHighlight.includes(e.target.value)) {
2702
- updatedSeriesHighlight[i] = e.target.value
2703
- updateSeriesIsolateValues([...updatedSeriesHighlight])
2704
- }
2705
- }}
2706
- options={getLegendColumns()}
2707
- />
2708
- </fieldset>
2709
- ))}
2710
- <button
2711
- className={'btn full-width'}
2712
- onClick={event => {
2713
- event.preventDefault()
2714
- const legendColumns = getLegendColumns()
2715
- const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2716
- const seriesLength = updatedSeriesHighlight.length
2717
- if (seriesLength < legendColumns.length) {
2718
- const [newSeriesHighlight] = legendColumns.filter(d => !updatedSeriesHighlight.includes(d))
2719
- updatedSeriesHighlight.push(newSeriesHighlight)
2720
- updateSeriesIsolateValues([...updatedSeriesHighlight])
2721
- }
2722
- }}
2723
- >
2724
- Add Isolate Value
2725
- </button>
2726
- </fieldset>
2727
- )}
2728
- {/* end: isolated values */}
2729
-
2730
- <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
2731
- <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
2732
- {config.legend.position === 'bottom' && (
2733
- <>
2734
- <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />
2735
- <CheckBox value={config.legend.verticalSorted} section='legend' fieldName='verticalSorted' label='Vertical sorted Legend' updateField={updateField} />
2736
- </>
2737
- )}
2738
- <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
2739
- </AccordionItemPanel>
2740
- </AccordionItem>
2741
- )}
2742
- {visSupportsFilters() && (
2743
- <AccordionItem>
2744
- <AccordionItemHeading>
2745
- <AccordionItemButton>Filters</AccordionItemButton>
2746
- </AccordionItemHeading>
2747
- <AccordionItemPanel>
2748
- {config.filters && (
2749
- <>
2750
- {/* prettier-ignore */}
2751
- <Select
2622
+ {config.visualizationType === 'Line' && <CheckBox value={config.legend.lineMode} section='legend' fieldName='lineMode' label='Show Lined Style Legend' updateField={updateField} />}
2623
+ {config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
2624
+ <Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
2625
+ )}
2626
+ <Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={(...[section, , fieldName, value]) => updateBehavior(section, fieldName, value)} options={['highlight', 'isolate']} />
2627
+ {visHasLegendAxisAlign() && <CheckBox value={config.legend.axisAlign} fieldName='axisAlign' section='legend' label='Align to Axis on Isolate' updateField={updateField} />}
2628
+
2629
+ {config.legend.behavior === 'highlight' && config.tooltips.singleSeries && <CheckBox value={config.legend.highlightOnHover} section='legend' fieldName='highlightOnHover' label='HIGHLIGHT DATA SERIES ON HOVER' updateField={updateField} />}
2630
+
2631
+ {/* start: isolated values */}
2632
+ {visHasSelectableLegendValues && config.legend.behavior === 'isolate' && !colorCodeByCategory && (
2633
+ <fieldset className='primary-fieldset edit-block' key={'additional-highlight-values'}>
2634
+ <label>
2635
+ <span className='edit-label'>
2636
+ Isolate Data Series
2637
+ <Tooltip style={{ textTransform: 'none' }}>
2638
+ <Tooltip.Target>
2639
+ <Icon display='question' style={{ marginLeft: '0.5rem' }} />
2640
+ </Tooltip.Target>
2641
+ <Tooltip.Content>
2642
+ <p>You can choose data series that are shown on load. Others will be added when the user clicks on them in the legend.</p>
2643
+ </Tooltip.Content>
2644
+ </Tooltip>
2645
+ </span>
2646
+ </label>
2647
+ {config.legend.seriesHighlight &&
2648
+ config.legend.seriesHighlight.map((val, i) => (
2649
+ <fieldset className='edit-block' key={`${val}-${i}`}>
2650
+ <button
2651
+ className='remove-column'
2652
+ onClick={event => {
2653
+ event.preventDefault()
2654
+ const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2655
+ updatedSeriesHighlight.splice(i, 1)
2656
+ updateField('legend', null, 'seriesHighlight', updatedSeriesHighlight)
2657
+ if (!updatedSeriesHighlight.length) {
2658
+ highlightReset()
2659
+ }
2660
+ }}
2661
+ >
2662
+ Remove
2663
+ </button>
2664
+ <Select
2665
+ value={config.legend.seriesHighlight[i]}
2666
+ fieldName='seriesHighlight'
2667
+ label='Isolate Value'
2668
+ onChange={e => {
2669
+ const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2670
+ if (!updatedSeriesHighlight.includes(e.target.value)) {
2671
+ updatedSeriesHighlight[i] = e.target.value
2672
+ updateSeriesIsolateValues([...updatedSeriesHighlight])
2673
+ }
2674
+ }}
2675
+ options={getLegendColumns()}
2676
+ />
2677
+ </fieldset>
2678
+ ))}
2679
+ <button
2680
+ className={'btn full-width'}
2681
+ onClick={event => {
2682
+ event.preventDefault()
2683
+ const legendColumns = getLegendColumns()
2684
+ const updatedSeriesHighlight = [...config.legend.seriesHighlight]
2685
+ const seriesLength = updatedSeriesHighlight.length
2686
+ if (seriesLength < legendColumns.length) {
2687
+ const [newSeriesHighlight] = legendColumns.filter(d => !updatedSeriesHighlight.includes(d))
2688
+ updatedSeriesHighlight.push(newSeriesHighlight)
2689
+ updateSeriesIsolateValues([...updatedSeriesHighlight])
2690
+ }
2691
+ }}
2692
+ >
2693
+ Add Isolate Value
2694
+ </button>
2695
+ </fieldset>
2696
+ )}
2697
+ {/* end: isolated values */}
2698
+
2699
+ <TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
2700
+ <Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
2701
+ {config.legend.position === 'bottom' && (
2702
+ <>
2703
+ <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />
2704
+ <CheckBox value={config.legend.verticalSorted} section='legend' fieldName='verticalSorted' label='Vertical sorted Legend' updateField={updateField} />
2705
+ </>
2706
+ )}
2707
+ <TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
2708
+ </AccordionItemPanel>
2709
+ </AccordionItem>
2710
+ )}
2711
+ {visSupportsFilters() && (
2712
+ <AccordionItem>
2713
+ <AccordionItemHeading>
2714
+ <AccordionItemButton>Filters</AccordionItemButton>
2715
+ </AccordionItemHeading>
2716
+ <AccordionItemPanel>
2717
+ {config.filters && (
2718
+ <>
2719
+ {/* prettier-ignore */}
2720
+ <Select
2752
2721
  value={config.filterBehavior}
2753
2722
  fieldName='filterBehavior'
2754
2723
  label='Filter Behavior'
@@ -2765,161 +2734,160 @@ const EditorPanel = () => {
2765
2734
  </Tooltip>
2766
2735
  }
2767
2736
  />
2768
- <br />
2769
- </>
2770
- )}
2771
- {config.filters && (
2772
- <ul className='filters-list'>
2773
- {/* Whether filters should apply onChange or Apply Button */}
2774
-
2775
- {config.filters.map((filter, index) => {
2776
- if (filter.type === 'url') return <></>
2777
-
2778
- return (
2779
- <fieldset className='edit-block' key={index}>
2780
- <button
2781
- type='button'
2782
- className='remove-column'
2783
- onClick={() => {
2784
- removeFilter(index)
2737
+ <br />
2738
+ </>
2739
+ )}
2740
+ {config.filters && (
2741
+ <ul className='filters-list'>
2742
+ {/* Whether filters should apply onChange or Apply Button */}
2743
+
2744
+ {config.filters.map((filter, index) => {
2745
+ if (filter.type === 'url') return <></>
2746
+
2747
+ return (
2748
+ <fieldset className='edit-block' key={index}>
2749
+ <button
2750
+ type='button'
2751
+ className='remove-column'
2752
+ onClick={() => {
2753
+ removeFilter(index)
2754
+ }}
2755
+ >
2756
+ Remove
2757
+ </button>
2758
+ <label>
2759
+ <span className='edit-label column-heading'>Filter</span>
2760
+ <select
2761
+ value={filter.columnName}
2762
+ onChange={e => {
2763
+ updateFilterProp('columnName', index, e.target.value)
2785
2764
  }}
2786
2765
  >
2787
- Remove
2788
- </button>
2789
- <label>
2790
- <span className='edit-label column-heading'>Filter</span>
2791
- <select
2792
- value={filter.columnName}
2793
- onChange={e => {
2794
- updateFilterProp('columnName', index, e.target.value)
2795
- }}
2796
- >
2797
- <option value=''>- Select Option -</option>
2798
- {getFilters().map((dataKey, index) => (
2799
- <option value={dataKey} key={index}>
2800
- {dataKey}
2801
- </option>
2802
- ))}
2803
- </select>
2804
- </label>
2766
+ <option value=''>- Select Option -</option>
2767
+ {getFilters().map((dataKey, index) => (
2768
+ <option value={dataKey} key={index}>
2769
+ {dataKey}
2770
+ </option>
2771
+ ))}
2772
+ </select>
2773
+ </label>
2805
2774
 
2806
- <label>
2807
- <span className='edit-showDropdown column-heading'>Show Filter Input</span>
2808
- <input
2809
- type='checkbox'
2810
- checked={filter.showDropdown === undefined ? true : filter.showDropdown}
2811
- onChange={e => {
2812
- updateFilterProp('showDropdown', index, e.target.checked)
2813
- }}
2814
- />
2815
- </label>
2775
+ <label>
2776
+ <span className='edit-showDropdown column-heading'>Show Filter Input</span>
2777
+ <input
2778
+ type='checkbox'
2779
+ checked={filter.showDropdown === undefined ? true : filter.showDropdown}
2780
+ onChange={e => {
2781
+ updateFilterProp('showDropdown', index, e.target.checked)
2782
+ }}
2783
+ />
2784
+ </label>
2816
2785
 
2817
- <label>
2818
- <span className='edit-label column-heading'>Filter Style</span>
2786
+ <label>
2787
+ <span className='edit-label column-heading'>Filter Style</span>
2819
2788
 
2820
- <select
2821
- value={filter.filterStyle}
2822
- onChange={e => {
2823
- updateFilterProp('filterStyle', index, e.target.value)
2824
- }}
2825
- >
2826
- {filterStyleOptions.map((item, index) => {
2827
- return (
2828
- <option key={`filter-style-${index}`} value={item}>
2829
- {item}
2830
- </option>
2831
- )
2832
- })}
2833
- </select>
2834
- </label>
2835
- <label>
2836
- <span className='edit-label column-heading'>Label</span>
2837
- <input
2838
- type='text'
2839
- value={filter.label}
2840
- onChange={e => {
2841
- updateFilterProp('label', index, e.target.value)
2842
- }}
2843
- />
2844
- </label>
2789
+ <select
2790
+ value={filter.filterStyle}
2791
+ onChange={e => {
2792
+ updateFilterProp('filterStyle', index, e.target.value)
2793
+ }}
2794
+ >
2795
+ {filterStyleOptions.map((item, index) => {
2796
+ return (
2797
+ <option key={`filter-style-${index}`} value={item}>
2798
+ {item}
2799
+ </option>
2800
+ )
2801
+ })}
2802
+ </select>
2803
+ </label>
2804
+ <label>
2805
+ <span className='edit-label column-heading'>Label</span>
2806
+ <input
2807
+ type='text'
2808
+ value={filter.label}
2809
+ onChange={e => {
2810
+ updateFilterProp('label', index, e.target.value)
2811
+ }}
2812
+ />
2813
+ </label>
2845
2814
 
2846
- <label>
2847
- <span className='edit-label column-heading'>Default Value Set By Query String Parameter</span>
2848
- <input
2849
- type='text'
2850
- value={filter.setByQueryParameter}
2851
- onChange={e => {
2852
- updateFilterProp('setByQueryParameter', index, e.target.value)
2853
- }}
2854
- />
2855
- </label>
2815
+ <label>
2816
+ <span className='edit-label column-heading'>Default Value Set By Query String Parameter</span>
2817
+ <input
2818
+ type='text'
2819
+ value={filter.setByQueryParameter}
2820
+ onChange={e => {
2821
+ updateFilterProp('setByQueryParameter', index, e.target.value)
2822
+ }}
2823
+ />
2824
+ </label>
2856
2825
 
2857
- <label>
2858
- <span className='edit-filterOrder column-heading'>Filter Order</span>
2859
- <select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
2860
- {filterOrderOptions.map((option, index) => {
2861
- return (
2862
- <option value={option.value} key={`filter-${index}`}>
2863
- {option.label}
2864
- </option>
2865
- )
2866
- })}
2867
- </select>
2826
+ <label>
2827
+ <span className='edit-filterOrder column-heading'>Filter Order</span>
2828
+ <select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
2829
+ {filterOrderOptions.map((option, index) => {
2830
+ return (
2831
+ <option value={option.value} key={`filter-${index}`}>
2832
+ {option.label}
2833
+ </option>
2834
+ )
2835
+ })}
2836
+ </select>
2868
2837
 
2869
- {filter.order === 'cust' && (
2870
- <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, config.filters[index])}>
2871
- <Droppable droppableId='filter_order'>
2872
- {provided => (
2873
- <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
2874
- {config.filters[index]?.values.map((value, index) => {
2875
- return (
2876
- <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
2877
- {(provided, snapshot) => (
2878
- <li>
2879
- <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
2880
- {value}
2881
- </div>
2882
- </li>
2883
- )}
2884
- </Draggable>
2885
- )
2886
- })}
2887
- {provided.placeholder}
2888
- </ul>
2889
- )}
2890
- </Droppable>
2891
- </DragDropContext>
2892
- )}
2893
- </label>
2894
- </fieldset>
2895
- )
2896
- })}
2897
- </ul>
2898
- )}
2899
- {!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2900
- <button type='button' onClick={addNewFilter} className='btn full-width'>
2901
- Add Filter
2902
- </button>
2903
- </AccordionItemPanel>
2904
- </AccordionItem>
2905
- )}
2906
- <Panels.Visual name='Visual' />
2907
- {/* Spark Line has no data table */}
2908
- {config.visualizationType !== 'Spark Line' && (
2909
- <AccordionItem>
2910
- <AccordionItemHeading>
2911
- <AccordionItemButton>Data Table</AccordionItemButton>
2912
- </AccordionItemHeading>
2913
- <AccordionItemPanel>
2914
- <DataTableEditor config={config} columns={Object.keys(data[0] || {})} updateField={updateField} isDashboard={isDashboard} isLoadedFromUrl={isLoadedFromUrl} />{' '}
2915
- </AccordionItemPanel>
2916
- </AccordionItem>
2917
- )}
2918
- {/* {(config.visualizationType === 'Bar' || config.visualizationType === 'Line') && <Panels.DateHighlighting name='Date Highlighting' />} */}
2919
- </Accordion>
2920
- {config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />}
2921
- </section>
2922
- </section>
2838
+ {filter.order === 'cust' && (
2839
+ <DragDropContext onDragEnd={({ source, destination }) => handleFilterOrder(source.index, destination.index, index, config.filters[index])}>
2840
+ <Droppable droppableId='filter_order'>
2841
+ {provided => (
2842
+ <ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
2843
+ {config.filters[index]?.values.map((value, index) => {
2844
+ return (
2845
+ <Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
2846
+ {(provided, snapshot) => (
2847
+ <li>
2848
+ <div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
2849
+ {value}
2850
+ </div>
2851
+ </li>
2852
+ )}
2853
+ </Draggable>
2854
+ )
2855
+ })}
2856
+ {provided.placeholder}
2857
+ </ul>
2858
+ )}
2859
+ </Droppable>
2860
+ </DragDropContext>
2861
+ )}
2862
+ </label>
2863
+ </fieldset>
2864
+ )
2865
+ })}
2866
+ </ul>
2867
+ )}
2868
+ {!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
2869
+ <button type='button' onClick={addNewFilter} className='btn full-width'>
2870
+ Add Filter
2871
+ </button>
2872
+ </AccordionItemPanel>
2873
+ </AccordionItem>
2874
+ )}
2875
+ <Panels.Visual name='Visual' />
2876
+ {/* Spark Line has no data table */}
2877
+ {config.visualizationType !== 'Spark Line' && (
2878
+ <AccordionItem>
2879
+ <AccordionItemHeading>
2880
+ <AccordionItemButton>Data Table</AccordionItemButton>
2881
+ </AccordionItemHeading>
2882
+ <AccordionItemPanel>
2883
+ <DataTableEditor config={config} columns={Object.keys(data[0] || {})} updateField={updateField} isDashboard={isDashboard} isLoadedFromUrl={isLoadedFromUrl} />{' '}
2884
+ </AccordionItemPanel>
2885
+ </AccordionItem>
2886
+ )}
2887
+ {/* {(config.visualizationType === 'Bar' || config.visualizationType === 'Line') && <Panels.DateHighlighting name='Date Highlighting' />} */}
2888
+ </Accordion>
2889
+ {config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />}
2890
+ </Layout.Sidebar>
2923
2891
  </ErrorBoundary>
2924
2892
  </EditorPanelContext.Provider>
2925
2893
  )