@cdc/chart 4.22.10 → 4.22.11
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.
- package/README.md +5 -5
- package/dist/cdcchart.js +4 -4
- package/examples/age-adjusted-rates.json +1486 -1218
- package/examples/case-rate-example-config.json +1 -1
- package/examples/covid-confidence-example-config.json +33 -33
- package/examples/covid-example-config.json +34 -34
- package/examples/covid-example-data-confidence.json +30 -30
- package/examples/covid-example-data.json +20 -20
- package/examples/cutoff-example-config.json +36 -36
- package/examples/cutoff-example-data.json +36 -36
- package/examples/date-exclusions-config.json +1 -1
- package/examples/dynamic-legends.json +124 -124
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +191 -197
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +230 -240
- package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +239 -247
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +136 -136
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +79 -79
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +80 -80
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +67 -67
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +110 -110
- package/examples/gallery/lollipop/lollipop-style-horizontal.json +215 -219
- package/examples/gallery/paired-bar/paired-bar-chart.json +195 -195
- package/examples/horizontal-chart.json +35 -35
- package/examples/horizontal-stacked-bar-chart.json +34 -34
- package/examples/line-chart.json +75 -75
- package/examples/paired-bar-data.json +16 -14
- package/examples/paired-bar-example.json +48 -48
- package/examples/paired-bar-formatted.json +36 -36
- package/examples/planet-chart-horizontal-example-config.json +33 -33
- package/examples/planet-combo-example-config.json +34 -31
- package/examples/planet-example-config.json +35 -33
- package/examples/planet-example-data.json +56 -56
- package/examples/planet-pie-example-config.json +28 -28
- package/examples/private/filters.json +170 -0
- package/examples/private/line-test-data.json +21 -21
- package/examples/private/line-test-two.json +209 -215
- package/examples/private/line-test.json +101 -101
- package/examples/private/new.json +48800 -0
- package/examples/private/shawn.json +1105 -1295
- package/examples/private/test.json +10123 -10123
- package/examples/private/yaxis-test.json +4 -3
- package/examples/private/yaxis.json +26 -26
- package/examples/stacked-vertical-bar-example.json +1 -1
- package/examples/temp-example-config.json +61 -54
- package/examples/temp-example-data.json +1 -1
- package/package.json +2 -2
- package/src/CdcChart.tsx +339 -380
- package/src/components/BarChart.tsx +425 -469
- package/src/components/DataTable.tsx +164 -195
- package/src/components/EditorPanel.js +1009 -710
- package/src/components/Legend.js +279 -329
- package/src/components/LineChart.tsx +90 -79
- package/src/components/LinearChart.tsx +376 -434
- package/src/components/PairedBarChart.tsx +197 -213
- package/src/components/PieChart.tsx +95 -151
- package/src/components/SparkLine.js +179 -201
- package/src/components/useIntersectionObserver.tsx +17 -20
- package/src/context.tsx +3 -3
- package/src/data/initial-state.js +37 -16
- package/src/hooks/useActiveElement.js +13 -13
- package/src/hooks/useChartClasses.js +34 -28
- package/src/hooks/useColorPalette.ts +56 -63
- package/src/hooks/useLegendClasses.js +18 -10
- package/src/hooks/useReduceData.ts +62 -78
- package/src/hooks/useRightAxis.js +25 -0
- package/src/hooks/useTopAxis.js +6 -0
- package/src/index.html +45 -45
- package/src/index.tsx +13 -16
- package/src/scss/DataTable.scss +5 -4
- package/src/scss/editor-panel.scss +71 -69
- package/src/scss/main.scss +157 -114
- package/src/scss/variables.scss +1 -1
|
@@ -1,46 +1,44 @@
|
|
|
1
1
|
import React, { useState, useEffect, useCallback, memo, useContext } from 'react'
|
|
2
2
|
import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd'
|
|
3
3
|
|
|
4
|
-
import {
|
|
5
|
-
Accordion,
|
|
6
|
-
AccordionItem,
|
|
7
|
-
AccordionItemHeading,
|
|
8
|
-
AccordionItemPanel,
|
|
9
|
-
AccordionItemButton,
|
|
10
|
-
} from 'react-accessible-accordion'
|
|
4
|
+
import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemPanel, AccordionItemButton } from 'react-accessible-accordion'
|
|
11
5
|
|
|
12
6
|
import { timeParse, timeFormat } from 'd3-time-format'
|
|
13
7
|
import { useDebounce, useDebouncedCallback } from 'use-debounce'
|
|
14
8
|
|
|
15
9
|
import Context from '../context'
|
|
16
10
|
import WarningImage from '../images/warning.svg'
|
|
17
|
-
import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
11
|
+
import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
18
12
|
|
|
19
|
-
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
20
|
-
import Waiting from '@cdc/core/components/Waiting'
|
|
21
|
-
import QuestionIcon from '@cdc/core/assets/icon-question-circle.svg'
|
|
22
|
-
import {useColorPalette} from '../hooks/useColorPalette'
|
|
13
|
+
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
14
|
+
import Waiting from '@cdc/core/components/Waiting'
|
|
15
|
+
import QuestionIcon from '@cdc/core/assets/icon-question-circle.svg' //TODO: Update with Icon component
|
|
16
|
+
import { useColorPalette } from '../hooks/useColorPalette'
|
|
23
17
|
|
|
24
|
-
import InputCheckbox from '@cdc/core/components/inputs/InputCheckbox'
|
|
25
|
-
import InputToggle from '@cdc/core/components/inputs/InputToggle'
|
|
18
|
+
import InputCheckbox from '@cdc/core/components/inputs/InputCheckbox'
|
|
19
|
+
import InputToggle from '@cdc/core/components/inputs/InputToggle'
|
|
26
20
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
27
21
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
28
|
-
import useReduceData from '../hooks/useReduceData'
|
|
22
|
+
import useReduceData from '../hooks/useReduceData'
|
|
23
|
+
import useRightAxis from '../hooks/useRightAxis'
|
|
29
24
|
|
|
30
|
-
|
|
31
|
-
|
|
25
|
+
// TODO: Remove unused imports
|
|
26
|
+
// TDOO: Move inline styles to a scss file
|
|
32
27
|
|
|
33
|
-
|
|
28
|
+
const TextField = memo(({ label, tooltip, section = null, subsection = null, fieldName, updateField, value: stateValue, type = 'input', i = null, min = null, ...attributes }) => {
|
|
29
|
+
const [value, setValue] = useState(stateValue)
|
|
30
|
+
|
|
31
|
+
const [debouncedValue] = useDebounce(value, 500)
|
|
34
32
|
|
|
35
33
|
useEffect(() => {
|
|
36
34
|
if ('string' === typeof debouncedValue && stateValue !== debouncedValue) {
|
|
37
35
|
updateField(section, subsection, fieldName, debouncedValue, i)
|
|
38
36
|
}
|
|
39
|
-
}, [
|
|
37
|
+
}, [debouncedValue])
|
|
40
38
|
|
|
41
39
|
let name = subsection ? `${section}-${subsection}-${fieldName}` : `${section}-${subsection}-${fieldName}`
|
|
42
40
|
|
|
43
|
-
const onChange =
|
|
41
|
+
const onChange = e => {
|
|
44
42
|
if ('number' !== type || min === null) {
|
|
45
43
|
setValue(e.target.value)
|
|
46
44
|
} else {
|
|
@@ -52,52 +50,79 @@ const TextField = memo(({label, tooltip, section = null, subsection = null, fiel
|
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
let formElement = <input type=
|
|
53
|
+
let formElement = <input type='text' name={name} onChange={onChange} {...attributes} value={value} />
|
|
56
54
|
|
|
57
55
|
if ('textarea' === type) {
|
|
58
|
-
formElement =
|
|
59
|
-
<textarea name={name} onChange={onChange} {...attributes} value={value}></textarea>
|
|
60
|
-
)
|
|
56
|
+
formElement = <textarea name={name} onChange={onChange} {...attributes} value={value}></textarea>
|
|
61
57
|
}
|
|
62
58
|
|
|
63
59
|
if ('number' === type) {
|
|
64
|
-
formElement = <input type=
|
|
60
|
+
formElement = <input type='number' name={name} onChange={onChange} {...attributes} value={value} />
|
|
65
61
|
}
|
|
66
62
|
|
|
67
63
|
if ('date' === type) {
|
|
68
|
-
formElement = <input type=
|
|
64
|
+
formElement = <input type='date' name={name} onChange={onChange} {...attributes} value={value} />
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
return (
|
|
72
68
|
<label>
|
|
73
|
-
<span className=
|
|
69
|
+
<span className='edit-label column-heading'>
|
|
70
|
+
{label}
|
|
71
|
+
{tooltip}
|
|
72
|
+
</span>
|
|
74
73
|
{formElement}
|
|
75
74
|
</label>
|
|
76
75
|
)
|
|
77
76
|
})
|
|
78
77
|
|
|
79
78
|
const CheckBox = memo(({ label, value, fieldName, section = null, subsection = null, tooltip, updateField, ...attributes }) => (
|
|
80
|
-
<label className=
|
|
81
|
-
<input
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
79
|
+
<label className='checkbox'>
|
|
80
|
+
<input
|
|
81
|
+
type='checkbox'
|
|
82
|
+
name={fieldName}
|
|
83
|
+
checked={value}
|
|
84
|
+
onChange={() => {
|
|
85
|
+
updateField(section, subsection, fieldName, !value)
|
|
86
|
+
}}
|
|
87
|
+
{...attributes}
|
|
88
|
+
/>
|
|
89
|
+
<span className='edit-label'>
|
|
90
|
+
{label}
|
|
91
|
+
{tooltip}
|
|
92
|
+
</span>
|
|
85
93
|
</label>
|
|
86
94
|
))
|
|
87
95
|
|
|
88
96
|
const Select = memo(({ label, value, options, fieldName, section = null, subsection = null, required = false, tooltip, updateField, initial: initialValue, ...attributes }) => {
|
|
89
|
-
let optionsJsx = options.map((optionName, index) =>
|
|
97
|
+
let optionsJsx = options.map((optionName, index) => (
|
|
98
|
+
<option value={optionName} key={index}>
|
|
99
|
+
{optionName}
|
|
100
|
+
</option>
|
|
101
|
+
))
|
|
90
102
|
|
|
91
103
|
if (initialValue) {
|
|
92
|
-
optionsJsx.unshift(
|
|
104
|
+
optionsJsx.unshift(
|
|
105
|
+
<option value='' key='initial'>
|
|
106
|
+
{initialValue}
|
|
107
|
+
</option>
|
|
108
|
+
)
|
|
93
109
|
}
|
|
94
110
|
|
|
95
111
|
return (
|
|
96
112
|
<label>
|
|
97
|
-
<span className=
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
113
|
+
<span className='edit-label'>
|
|
114
|
+
{label}
|
|
115
|
+
{tooltip}
|
|
116
|
+
</span>
|
|
117
|
+
<select
|
|
118
|
+
className={required && !value ? 'warning' : ''}
|
|
119
|
+
name={fieldName}
|
|
120
|
+
value={value}
|
|
121
|
+
onChange={event => {
|
|
122
|
+
updateField(section, subsection, fieldName, event.target.value)
|
|
123
|
+
}}
|
|
124
|
+
{...attributes}
|
|
125
|
+
>
|
|
101
126
|
{optionsJsx}
|
|
102
127
|
</select>
|
|
103
128
|
</label>
|
|
@@ -109,7 +134,7 @@ const Regions = memo(({ config, updateConfig }) => {
|
|
|
109
134
|
let regions = []
|
|
110
135
|
|
|
111
136
|
if (config.regions) {
|
|
112
|
-
regions = [
|
|
137
|
+
regions = [...config.regions]
|
|
113
138
|
}
|
|
114
139
|
|
|
115
140
|
regions[i][fieldName] = value
|
|
@@ -118,11 +143,11 @@ const Regions = memo(({ config, updateConfig }) => {
|
|
|
118
143
|
|
|
119
144
|
let updateField = (section, subsection, fieldName, value, i) => regionUpdate(fieldName, value, i)
|
|
120
145
|
|
|
121
|
-
let removeColumn =
|
|
146
|
+
let removeColumn = i => {
|
|
122
147
|
let regions = []
|
|
123
148
|
|
|
124
149
|
if (config.regions) {
|
|
125
|
-
regions = [
|
|
150
|
+
regions = [...config.regions]
|
|
126
151
|
}
|
|
127
152
|
|
|
128
153
|
regions.splice(i, 1)
|
|
@@ -131,11 +156,10 @@ const Regions = memo(({ config, updateConfig }) => {
|
|
|
131
156
|
}
|
|
132
157
|
|
|
133
158
|
let addColumn = () => {
|
|
134
|
-
|
|
135
159
|
let regions = []
|
|
136
160
|
|
|
137
161
|
if (config.regions) {
|
|
138
|
-
regions = [
|
|
162
|
+
regions = [...config.regions]
|
|
139
163
|
}
|
|
140
164
|
|
|
141
165
|
regions.push({})
|
|
@@ -145,63 +169,83 @@ const Regions = memo(({ config, updateConfig }) => {
|
|
|
145
169
|
|
|
146
170
|
return (
|
|
147
171
|
<>
|
|
148
|
-
{config.regions &&
|
|
149
|
-
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
172
|
+
{config.regions &&
|
|
173
|
+
config.regions.map(({ label, color, from, to, background }, i) => (
|
|
174
|
+
<div className='edit-block' key={`region-${i}`}>
|
|
175
|
+
<button
|
|
176
|
+
type='button'
|
|
177
|
+
className='remove-column'
|
|
178
|
+
onClick={event => {
|
|
179
|
+
event.preventDefault()
|
|
180
|
+
removeColumn(i)
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
Remove
|
|
184
|
+
</button>
|
|
185
|
+
<TextField value={label} label='Region Label' fieldName='label' i={i} updateField={updateField} />
|
|
186
|
+
<div className='two-col-inputs'>
|
|
187
|
+
<TextField value={color} label='Text Color' fieldName='color' updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)} />
|
|
188
|
+
<TextField value={background} label='Background' fieldName='background' updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)} />
|
|
189
|
+
</div>
|
|
190
|
+
<div className='two-col-inputs'>
|
|
191
|
+
<TextField value={from} label='From Value' fieldName='from' updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)} />
|
|
192
|
+
<TextField value={to} label='To Value' fieldName='to' updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)} />
|
|
193
|
+
</div>
|
|
159
194
|
</div>
|
|
160
|
-
|
|
161
|
-
<TextField value={from} label="From Value" fieldName="from" updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}/>
|
|
162
|
-
<TextField value={to} label="To Value" fieldName="to" updateField={(section, subsection, fieldName, value) => regionUpdate(fieldName, value, i)}/>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
))}
|
|
195
|
+
))}
|
|
166
196
|
{!config.regions && <p style={{ textAlign: 'center' }}>There are currently no regions.</p>}
|
|
167
|
-
<button
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
197
|
+
<button
|
|
198
|
+
type='button'
|
|
199
|
+
className='btn full-width'
|
|
200
|
+
onClick={e => {
|
|
201
|
+
e.preventDefault()
|
|
202
|
+
addColumn()
|
|
203
|
+
}}
|
|
204
|
+
>
|
|
205
|
+
Add Region
|
|
171
206
|
</button>
|
|
172
207
|
</>
|
|
173
208
|
)
|
|
174
209
|
})
|
|
175
210
|
|
|
176
|
-
const headerColors = [
|
|
211
|
+
const headerColors = ['theme-blue', 'theme-purple', 'theme-brown', 'theme-teal', 'theme-pink', 'theme-orange', 'theme-slate', 'theme-indigo', 'theme-cyan', 'theme-green', 'theme-amber']
|
|
177
212
|
|
|
178
213
|
const EditorPanel = () => {
|
|
179
|
-
const {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
unfilteredData,
|
|
186
|
-
excludedData,
|
|
187
|
-
transformedData,
|
|
188
|
-
isDashboard,
|
|
189
|
-
setParentConfig,
|
|
190
|
-
missingRequiredSections,
|
|
191
|
-
setFilteredData
|
|
192
|
-
} = useContext(Context)
|
|
193
|
-
|
|
194
|
-
const {minValue,maxValue,existPositiveValue} = useReduceData(config,unfilteredData);
|
|
195
|
-
const {paletteName,isPaletteReversed,filteredPallets,filteredQualitative,dispatch} = useColorPalette(colorPalettes,config);
|
|
196
|
-
useEffect(()=>{
|
|
197
|
-
if(paletteName) updateConfig({...config, palette:paletteName})
|
|
214
|
+
const { config, updateConfig, transformedData: data, loading, colorPalettes, unfilteredData, excludedData, transformedData, isDashboard, setParentConfig, missingRequiredSections, setFilteredData } = useContext(Context)
|
|
215
|
+
|
|
216
|
+
const { minValue, maxValue, existPositiveValue } = useReduceData(config, unfilteredData)
|
|
217
|
+
const { paletteName, isPaletteReversed, filteredPallets, filteredQualitative, dispatch } = useColorPalette(colorPalettes, config)
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
if (paletteName) updateConfig({ ...config, palette: paletteName })
|
|
198
220
|
}, [paletteName])
|
|
199
221
|
|
|
222
|
+
useEffect(() => {
|
|
223
|
+
dispatch({ type: 'GET_PALETTE', payload: colorPalettes, paletteName: config.palette })
|
|
224
|
+
}, [dispatch, config.palette])
|
|
225
|
+
|
|
226
|
+
// when the visualization type changes we
|
|
227
|
+
// have to update the individual series type & axis details
|
|
228
|
+
// dataKey is unchanged here.
|
|
229
|
+
// ie. { dataKey: 'series_name', type: 'Bar', axis: 'Left'}
|
|
230
|
+
useEffect(() => {
|
|
231
|
+
let newSeries = []
|
|
232
|
+
if (config.series) {
|
|
233
|
+
newSeries = config.series.map(series => {
|
|
234
|
+
return {
|
|
235
|
+
...series,
|
|
236
|
+
type: config.visualizationType === 'Combo' ? 'Bar' : config.visualizationType ? config.visualizationType : 'Bar',
|
|
237
|
+
axis: 'Left'
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
updateConfig({
|
|
243
|
+
...config,
|
|
244
|
+
series: newSeries
|
|
245
|
+
})
|
|
246
|
+
}, [config.visualizationType])
|
|
200
247
|
|
|
201
|
-
|
|
202
|
-
useEffect(()=>{
|
|
203
|
-
dispatch({type:"GET_PALETTE",payload:colorPalettes,paletteName:config.palette})
|
|
204
|
-
}, [dispatch, config.palette]);
|
|
248
|
+
const { hasRightAxis } = useRightAxis({ config: config, yMax: config.yAxis.size, data: config.data, updateConfig })
|
|
205
249
|
|
|
206
250
|
const filterOptions = [
|
|
207
251
|
{
|
|
@@ -219,7 +263,7 @@ const EditorPanel = () => {
|
|
|
219
263
|
]
|
|
220
264
|
|
|
221
265
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
|
222
|
-
...draggableStyle
|
|
266
|
+
...draggableStyle
|
|
223
267
|
})
|
|
224
268
|
|
|
225
269
|
const sortableItemStyles = {
|
|
@@ -235,10 +279,10 @@ const EditorPanel = () => {
|
|
|
235
279
|
marginRight: '.3em',
|
|
236
280
|
marginBottom: '.3em',
|
|
237
281
|
cursor: 'move',
|
|
238
|
-
zIndex: '999'
|
|
282
|
+
zIndex: '999'
|
|
239
283
|
}
|
|
240
284
|
|
|
241
|
-
const enforceRestrictions =
|
|
285
|
+
const enforceRestrictions = updatedConfig => {
|
|
242
286
|
if (updatedConfig.orientation === 'horizontal') {
|
|
243
287
|
updatedConfig.labels = false
|
|
244
288
|
}
|
|
@@ -260,11 +304,11 @@ const EditorPanel = () => {
|
|
|
260
304
|
|
|
261
305
|
const isArray = Array.isArray(config[section])
|
|
262
306
|
|
|
263
|
-
let sectionValue = isArray ? [
|
|
307
|
+
let sectionValue = isArray ? [...config[section], newValue] : { ...config[section], [fieldName]: newValue }
|
|
264
308
|
|
|
265
309
|
if (null !== subsection) {
|
|
266
310
|
if (isArray) {
|
|
267
|
-
sectionValue = [
|
|
311
|
+
sectionValue = [...config[section]]
|
|
268
312
|
sectionValue[subsection] = { ...sectionValue[subsection], [fieldName]: newValue }
|
|
269
313
|
} else if (typeof newValue === 'string') {
|
|
270
314
|
sectionValue[subsection] = newValue
|
|
@@ -280,22 +324,22 @@ const EditorPanel = () => {
|
|
|
280
324
|
updateConfig(updatedConfig)
|
|
281
325
|
}
|
|
282
326
|
|
|
283
|
-
const [
|
|
284
|
-
const [
|
|
327
|
+
const [displayPanel, setDisplayPanel] = useState(true)
|
|
328
|
+
const [lollipopColorStyle, setLollipopColorStyle] = useState('two-tone')
|
|
285
329
|
|
|
286
330
|
if (loading) {
|
|
287
331
|
return null
|
|
288
332
|
}
|
|
289
333
|
|
|
290
|
-
const setLollipopShape =
|
|
334
|
+
const setLollipopShape = shape => {
|
|
291
335
|
updateConfig({
|
|
292
336
|
...config,
|
|
293
337
|
lollipopShape: shape
|
|
294
338
|
})
|
|
295
339
|
}
|
|
296
340
|
|
|
297
|
-
const removeFilter =
|
|
298
|
-
let filters = [
|
|
341
|
+
const removeFilter = index => {
|
|
342
|
+
let filters = [...config.filters]
|
|
299
343
|
|
|
300
344
|
filters.splice(index, 1)
|
|
301
345
|
|
|
@@ -303,7 +347,7 @@ const EditorPanel = () => {
|
|
|
303
347
|
}
|
|
304
348
|
|
|
305
349
|
const updateFilterProp = (name, index, value) => {
|
|
306
|
-
let filters = [
|
|
350
|
+
let filters = [...config.filters]
|
|
307
351
|
|
|
308
352
|
filters[index][name] = value
|
|
309
353
|
|
|
@@ -311,29 +355,28 @@ const EditorPanel = () => {
|
|
|
311
355
|
}
|
|
312
356
|
|
|
313
357
|
const addNewFilter = () => {
|
|
314
|
-
let filters = config.filters ? [
|
|
358
|
+
let filters = config.filters ? [...config.filters] : []
|
|
315
359
|
|
|
316
|
-
filters.push({ values: [] })
|
|
360
|
+
filters.push({ values: [] })
|
|
317
361
|
|
|
318
|
-
updateConfig({ ...config, filters })
|
|
362
|
+
updateConfig({ ...config, filters })
|
|
319
363
|
}
|
|
320
364
|
|
|
321
|
-
const addNewSeries =
|
|
322
|
-
let newSeries = config.series ? [
|
|
323
|
-
newSeries.push({ dataKey: seriesKey, type: 'Bar' })
|
|
324
|
-
updateConfig({ ...config, series: newSeries })
|
|
365
|
+
const addNewSeries = seriesKey => {
|
|
366
|
+
let newSeries = config.series ? [...config.series] : []
|
|
367
|
+
newSeries.push({ dataKey: seriesKey, type: 'Bar' })
|
|
368
|
+
updateConfig({ ...config, series: newSeries }) // left axis series keys
|
|
325
369
|
}
|
|
326
370
|
|
|
327
|
-
const sortSeries =
|
|
371
|
+
const sortSeries = e => {
|
|
328
372
|
const series = config.series[0].dataKey
|
|
329
|
-
const sorted = data.sort((a, b) => a[series] - b[series])
|
|
330
|
-
const newData = e ===
|
|
331
|
-
updateConfig({ ...config }, newData)
|
|
373
|
+
const sorted = data.sort((a, b) => a[series] - b[series])
|
|
374
|
+
const newData = e === 'asc' ? sorted : sorted.reverse()
|
|
375
|
+
updateConfig({ ...config }, newData)
|
|
332
376
|
}
|
|
333
377
|
|
|
334
|
-
const removeSeries =
|
|
335
|
-
|
|
336
|
-
let series = [ ...config.series ]
|
|
378
|
+
const removeSeries = seriesKey => {
|
|
379
|
+
let series = [...config.series]
|
|
337
380
|
let seriesIndex = -1
|
|
338
381
|
|
|
339
382
|
for (let i = 0; i < series.length; i++) {
|
|
@@ -363,17 +406,17 @@ const EditorPanel = () => {
|
|
|
363
406
|
}
|
|
364
407
|
}
|
|
365
408
|
|
|
366
|
-
const addNewExclusion =
|
|
367
|
-
let newExclusion = [
|
|
409
|
+
const addNewExclusion = exclusionKey => {
|
|
410
|
+
let newExclusion = [...config.exclusions.keys]
|
|
368
411
|
newExclusion.push(exclusionKey)
|
|
369
412
|
|
|
370
413
|
let payload = { ...config.exclusions, keys: newExclusion }
|
|
371
414
|
updateConfig({ ...config, exclusions: payload })
|
|
372
415
|
}
|
|
373
416
|
|
|
374
|
-
const removeExclusion =
|
|
417
|
+
const removeExclusion = excludeValue => {
|
|
375
418
|
let exclusionsIndex = -1
|
|
376
|
-
let exclusions = [
|
|
419
|
+
let exclusions = [...config.exclusions.keys]
|
|
377
420
|
|
|
378
421
|
for (let i = 0; i < exclusions.length; i++) {
|
|
379
422
|
if (exclusions[i] === excludeValue) {
|
|
@@ -400,12 +443,12 @@ const EditorPanel = () => {
|
|
|
400
443
|
let columns = {}
|
|
401
444
|
|
|
402
445
|
unfilteredData.map(row => {
|
|
403
|
-
Object.keys(row).forEach(columnName => columns[columnName] = true)
|
|
446
|
+
Object.keys(row).forEach(columnName => (columns[columnName] = true))
|
|
404
447
|
})
|
|
405
448
|
|
|
406
449
|
if (filter) {
|
|
407
|
-
let confidenceUpper = config.confidenceKeys?.upper && config.confidenceKeys?.upper !== ''
|
|
408
|
-
let confidenceLower = config.confidenceKeys?.lower && config.confidenceKeys?.lower !== ''
|
|
450
|
+
let confidenceUpper = config.confidenceKeys?.upper && config.confidenceKeys?.upper !== '' // TODO: remove?
|
|
451
|
+
let confidenceLower = config.confidenceKeys?.lower && config.confidenceKeys?.lower !== '' // TODO: remove?
|
|
409
452
|
|
|
410
453
|
Object.keys(columns).forEach(key => {
|
|
411
454
|
if (
|
|
@@ -424,32 +467,30 @@ const EditorPanel = () => {
|
|
|
424
467
|
return Object.keys(columns)
|
|
425
468
|
}
|
|
426
469
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
for (
|
|
432
|
-
|
|
433
|
-
set.add(key)
|
|
434
|
-
}
|
|
435
|
-
|
|
470
|
+
const getDataValueOptions = data => {
|
|
471
|
+
if (!data) return []
|
|
472
|
+
const set = new Set()
|
|
473
|
+
for (let i = 0; i < data.length; i++) {
|
|
474
|
+
for (const [key, value] of Object.entries(data[i])) {
|
|
475
|
+
set.add(key)
|
|
436
476
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
477
|
+
}
|
|
478
|
+
return Array.from(set)
|
|
479
|
+
}
|
|
480
|
+
|
|
440
481
|
const getDataValues = (dataKey, unique = false) => {
|
|
441
482
|
let values = []
|
|
442
483
|
excludedData.map(e => {
|
|
443
484
|
values.push(e[dataKey])
|
|
444
485
|
})
|
|
445
|
-
return unique ? [
|
|
486
|
+
return unique ? [...new Set(values)] : values
|
|
446
487
|
}
|
|
447
488
|
|
|
448
|
-
const showBarStyleOptions = ()=>{
|
|
449
|
-
if (config.visualizationType === 'Bar' && config.visualizationSubType !== 'stacked' && (config.orientation==='horizontal' || config.orientation==='vertical')
|
|
450
|
-
return ['flat','rounded','lollipop']
|
|
489
|
+
const showBarStyleOptions = () => {
|
|
490
|
+
if (config.visualizationType === 'Bar' && config.visualizationSubType !== 'stacked' && (config.orientation === 'horizontal' || config.orientation === 'vertical')) {
|
|
491
|
+
return ['flat', 'rounded', 'lollipop']
|
|
451
492
|
} else {
|
|
452
|
-
return ['flat','rounded']
|
|
493
|
+
return ['flat', 'rounded']
|
|
453
494
|
}
|
|
454
495
|
}
|
|
455
496
|
|
|
@@ -459,18 +500,17 @@ const EditorPanel = () => {
|
|
|
459
500
|
|
|
460
501
|
const Error = () => {
|
|
461
502
|
return (
|
|
462
|
-
<section className=
|
|
463
|
-
<section className=
|
|
503
|
+
<section className='waiting'>
|
|
504
|
+
<section className='waiting-container'>
|
|
464
505
|
<h3>Error With Configuration</h3>
|
|
465
506
|
<p>{config.runtime.editorErrorMessage}</p>
|
|
466
507
|
</section>
|
|
467
508
|
</section>
|
|
468
509
|
)
|
|
469
|
-
|
|
470
510
|
}
|
|
471
511
|
|
|
472
512
|
const Confirm = () => {
|
|
473
|
-
const confirmDone =
|
|
513
|
+
const confirmDone = e => {
|
|
474
514
|
e.preventDefault()
|
|
475
515
|
|
|
476
516
|
let newConfig = { ...config }
|
|
@@ -480,11 +520,13 @@ const EditorPanel = () => {
|
|
|
480
520
|
}
|
|
481
521
|
|
|
482
522
|
return (
|
|
483
|
-
<section className=
|
|
484
|
-
<section className=
|
|
523
|
+
<section className='waiting'>
|
|
524
|
+
<section className='waiting-container'>
|
|
485
525
|
<h3>Finish Configuring</h3>
|
|
486
526
|
<p>Set all required options to the left and confirm below to display a preview of the chart.</p>
|
|
487
|
-
<button className=
|
|
527
|
+
<button className='btn' style={{ margin: '1em auto' }} disabled={missingRequiredSections()} onClick={confirmDone}>
|
|
528
|
+
I'm Done
|
|
529
|
+
</button>
|
|
488
530
|
</section>
|
|
489
531
|
</section>
|
|
490
532
|
)
|
|
@@ -508,17 +550,17 @@ const EditorPanel = () => {
|
|
|
508
550
|
}
|
|
509
551
|
|
|
510
552
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
511
|
-
}, [
|
|
512
|
-
|
|
553
|
+
}, [config])
|
|
554
|
+
|
|
513
555
|
// Set paired bars to be horizontal, even though that option doesn't display
|
|
514
556
|
useEffect(() => {
|
|
515
|
-
if(config.visualizationType === 'Paired Bar') {
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
557
|
+
if (config.visualizationType === 'Paired Bar') {
|
|
558
|
+
updateConfig({
|
|
559
|
+
...config,
|
|
560
|
+
orientation: 'horizontal'
|
|
519
561
|
})
|
|
520
562
|
}
|
|
521
|
-
}, [])
|
|
563
|
+
}, [])
|
|
522
564
|
|
|
523
565
|
useEffect(() => {
|
|
524
566
|
if (config.orientation === 'horizontal') {
|
|
@@ -527,32 +569,32 @@ const EditorPanel = () => {
|
|
|
527
569
|
lollipopShape: config.lollipopShape
|
|
528
570
|
})
|
|
529
571
|
}
|
|
530
|
-
}, [
|
|
572
|
+
}, [config.isLollipopChart, config.lollipopShape])
|
|
531
573
|
|
|
532
574
|
const ExclusionsList = useCallback(() => {
|
|
533
|
-
const exclusions = [
|
|
575
|
+
const exclusions = [...config.exclusions.keys]
|
|
534
576
|
return (
|
|
535
|
-
<ul className=
|
|
577
|
+
<ul className='series-list'>
|
|
536
578
|
{exclusions.map((exclusion, index) => {
|
|
537
579
|
return (
|
|
538
580
|
<li key={exclusion}>
|
|
539
|
-
<div className=
|
|
540
|
-
<div className=
|
|
541
|
-
{exclusion}
|
|
542
|
-
</div>
|
|
581
|
+
<div className='series-list__name' data-title={exclusion}>
|
|
582
|
+
<div className='series-list__name--text'>{exclusion}</div>
|
|
543
583
|
</div>
|
|
544
|
-
<button className=
|
|
584
|
+
<button className='series-list__remove' onClick={() => removeExclusion(exclusion)}>
|
|
585
|
+
×
|
|
586
|
+
</button>
|
|
545
587
|
</li>
|
|
546
588
|
)
|
|
547
589
|
})}
|
|
548
590
|
</ul>
|
|
549
591
|
)
|
|
550
|
-
}, [
|
|
592
|
+
}, [config])
|
|
551
593
|
|
|
552
594
|
const ErrorWithLolliopChart = ({ message }) => {
|
|
553
595
|
return (
|
|
554
|
-
<section className=
|
|
555
|
-
<section className=
|
|
596
|
+
<section className='waiting'>
|
|
597
|
+
<section className='waiting-container'>
|
|
556
598
|
<h3>Error With Configuration</h3>
|
|
557
599
|
<p>{message}</p>
|
|
558
600
|
</section>
|
|
@@ -560,17 +602,21 @@ const EditorPanel = () => {
|
|
|
560
602
|
)
|
|
561
603
|
}
|
|
562
604
|
|
|
605
|
+
const checkIsLine = type => {
|
|
606
|
+
return type === ('Line' || 'dashed-sm')
|
|
607
|
+
}
|
|
608
|
+
|
|
563
609
|
const handleFilterChange = (idx1, idx2, filterIndex, filter) => {
|
|
564
610
|
let filterOrder = filter.values
|
|
565
|
-
let [
|
|
611
|
+
let [movedItem] = filterOrder.splice(idx1, 1)
|
|
566
612
|
filterOrder.splice(idx2, 0, movedItem)
|
|
567
|
-
let filters = [
|
|
613
|
+
let filters = [...config.filters]
|
|
568
614
|
let filterItem = { ...config.filters[filterIndex] }
|
|
569
615
|
filterItem.active = filter.values[0]
|
|
570
|
-
filterItem.
|
|
616
|
+
filterItem.orderedValues = filterOrder
|
|
571
617
|
filterItem.order = 'cust'
|
|
572
618
|
filters[filterIndex] = filterItem
|
|
573
|
-
|
|
619
|
+
updateConfig({ ...config, filters });
|
|
574
620
|
}
|
|
575
621
|
|
|
576
622
|
if (config.isLollipopChart && config?.series?.length > 1) {
|
|
@@ -581,500 +627,741 @@ const EditorPanel = () => {
|
|
|
581
627
|
config.runtime.editorErrorMessage = 'Add a data series'
|
|
582
628
|
}
|
|
583
629
|
|
|
584
|
-
const section = config.orientation==='horizontal'
|
|
585
|
-
const [warningMsg,setWarningMsg] = useState({maxMsg:'',minMsg:''})
|
|
630
|
+
const section = config.orientation === 'horizontal' ? 'xAxis' : 'yAxis'
|
|
631
|
+
const [warningMsg, setWarningMsg] = useState({ maxMsg: '', minMsg: '' })
|
|
586
632
|
|
|
587
633
|
const validateMaxValue = () => {
|
|
588
|
-
const enteredValue = config[section].max
|
|
589
|
-
let message = ''
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
}
|
|
634
|
+
const enteredValue = config[section].max
|
|
635
|
+
let message = ''
|
|
636
|
+
|
|
637
|
+
switch (true) {
|
|
638
|
+
case enteredValue && parseFloat(enteredValue) < parseFloat(maxValue) && existPositiveValue:
|
|
639
|
+
message = 'Max value must be more than ' + maxValue
|
|
640
|
+
break
|
|
641
|
+
case enteredValue && parseFloat(enteredValue) < 0 && !existPositiveValue:
|
|
642
|
+
message = 'Value must be more than or equal to 0'
|
|
643
|
+
break
|
|
644
|
+
default:
|
|
645
|
+
message = ''
|
|
646
|
+
}
|
|
647
|
+
setWarningMsg(function (prevMsg) {
|
|
648
|
+
return { ...prevMsg, maxMsg: message }
|
|
649
|
+
})
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
const validateMinValue = () => {
|
|
653
|
+
const enteredValue = config[section].min
|
|
654
|
+
let minVal = Number(minValue)
|
|
655
|
+
let message = ''
|
|
656
|
+
|
|
657
|
+
switch (true) {
|
|
658
|
+
case (config.visualizationType === 'Line' || config.visualizationType === 'Spark Line') && enteredValue && parseFloat(enteredValue) > minVal:
|
|
659
|
+
message = 'Value must be less than ' + minValue
|
|
660
|
+
break
|
|
661
|
+
case (config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && enteredValue && minVal > 0 && parseFloat(enteredValue) > 0:
|
|
662
|
+
message = 'Value must be less than or equal to 0'
|
|
663
|
+
break
|
|
664
|
+
case enteredValue && minVal < 0 && parseFloat(enteredValue) > minVal:
|
|
665
|
+
message = 'Value must be less than ' + minValue
|
|
666
|
+
break
|
|
667
|
+
default:
|
|
668
|
+
message = ''
|
|
669
|
+
}
|
|
670
|
+
setWarningMsg(function (prevMsg) {
|
|
671
|
+
return { ...prevMsg, minMsg: message }
|
|
672
|
+
})
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
useEffect(() => {
|
|
676
|
+
validateMinValue()
|
|
677
|
+
validateMaxValue()
|
|
678
|
+
}, [minValue, maxValue, config])
|
|
628
679
|
|
|
629
680
|
return (
|
|
630
|
-
<ErrorBoundary component=
|
|
631
|
-
{config.newViz && <Confirm/>}
|
|
632
|
-
{undefined === config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error/>}
|
|
681
|
+
<ErrorBoundary component='EditorPanel'>
|
|
682
|
+
{config.newViz && <Confirm />}
|
|
683
|
+
{undefined === config.newViz && config.runtime && config.runtime.editorErrorMessage && <Error />}
|
|
633
684
|
<button className={displayPanel ? `editor-toggle` : `editor-toggle collapsed`} title={displayPanel ? `Collapse Editor` : `Expand Editor`} onClick={onBackClick}></button>
|
|
634
685
|
<section className={`${displayPanel ? 'editor-panel cove' : 'hidden editor-panel cove'}${isDashboard ? ' dashboard' : ''}`}>
|
|
635
|
-
<div aria-level=
|
|
636
|
-
|
|
686
|
+
<div aria-level='2' role='heading' className='heading-2'>
|
|
687
|
+
Configure Chart
|
|
688
|
+
</div>
|
|
689
|
+
<section className='form-container'>
|
|
637
690
|
<form>
|
|
638
691
|
<Accordion allowZeroExpanded={true}>
|
|
639
|
-
<AccordionItem>
|
|
692
|
+
<AccordionItem>
|
|
693
|
+
{' '}
|
|
694
|
+
{/* General */}
|
|
640
695
|
<AccordionItemHeading>
|
|
641
|
-
<AccordionItemButton>
|
|
642
|
-
General
|
|
643
|
-
</AccordionItemButton>
|
|
696
|
+
<AccordionItemButton>General</AccordionItemButton>
|
|
644
697
|
</AccordionItemHeading>
|
|
645
698
|
<AccordionItemPanel>
|
|
646
|
-
<Select value={config.visualizationType} fieldName=
|
|
647
|
-
{(config.visualizationType === 'Bar'|| config.visualizationType === 'Combo') && <Select value={config.visualizationSubType || 'Regular'} fieldName=
|
|
648
|
-
{config.visualizationType === 'Bar' && <Select value={config.orientation || 'vertical'} fieldName=
|
|
649
|
-
{config.visualizationType === 'Bar' &&
|
|
650
|
-
{
|
|
651
|
-
{
|
|
652
|
-
{
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
<CheckBox value={config.
|
|
657
|
-
): config.visualizationType !== 'Pie' && (
|
|
658
|
-
<CheckBox value={config.labels} fieldName="labels" label="Display label on data" updateField={updateField}/>
|
|
699
|
+
<Select value={config.visualizationType} fieldName='visualizationType' label='Chart Type' updateField={updateField} options={['Pie', 'Line', 'Bar', 'Combo', 'Paired Bar', 'Spark Line']} />
|
|
700
|
+
{(config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && <Select value={config.visualizationSubType || 'Regular'} fieldName='visualizationSubType' label='Chart Subtype' updateField={updateField} options={['regular', 'stacked']} />}
|
|
701
|
+
{config.visualizationType === 'Bar' && <Select value={config.orientation || 'vertical'} fieldName='orientation' label='Orientation' updateField={updateField} options={['vertical', 'horizontal']} />}
|
|
702
|
+
{config.visualizationType === 'Bar' && <Select value={config.isLollipopChart ? 'lollipop' : config.barStyle || 'flat'} fieldName='barStyle' label='bar style' updateField={updateField} options={showBarStyleOptions()} />}
|
|
703
|
+
{config.visualizationType === 'Bar' && config.barStyle === 'rounded' && <Select value={config.tipRounding || 'top'} fieldName='tipRounding' label='tip rounding' updateField={updateField} options={['top', 'full']} />}
|
|
704
|
+
{config.visualizationType === 'Bar' && config.barStyle === 'rounded' && <Select value={config.roundingStyle || 'standard'} fieldName='roundingStyle' label='rounding style' updateField={updateField} options={['standard', 'shallow', 'finger']} />}
|
|
705
|
+
{config.visualizationType === 'Bar' && config.orientation === 'horizontal' && <Select value={config.yAxis.labelPlacement || 'Below Bar'} section='yAxis' fieldName='labelPlacement' label='Label Placement' updateField={updateField} options={['Below Bar', 'On Date/Category Axis']} />}
|
|
706
|
+
{config.orientation === 'horizontal' && (config.yAxis.labelPlacement === 'Below Bar' || config.yAxis.labelPlacement === 'On Date/Category Axis' || config.visualizationType === 'Paired Bar') ? (
|
|
707
|
+
<CheckBox value={config.yAxis.displayNumbersOnBar} section='yAxis' fieldName='displayNumbersOnBar' label={config.isLollipopChart ? 'Display Numbers after Bar' : 'Display Numbers on Bar'} updateField={updateField} />
|
|
708
|
+
) : (
|
|
709
|
+
config.visualizationType !== 'Pie' && <CheckBox value={config.labels} fieldName='labels' label='Display label on data' updateField={updateField} />
|
|
659
710
|
)}
|
|
660
|
-
{config.visualizationType === 'Pie' && <Select fieldName=
|
|
661
|
-
<TextField value={config.title} fieldName=
|
|
662
|
-
|
|
711
|
+
{config.visualizationType === 'Pie' && <Select fieldName='pieType' label='Pie Chart Type' updateField={updateField} options={['Regular', 'Donut']} />}
|
|
712
|
+
<TextField value={config.title} fieldName='title' label='Title' updateField={updateField} />
|
|
713
|
+
|
|
663
714
|
<TextField
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
<Tooltip style={{textTransform: 'none'}}>
|
|
671
|
-
<Tooltip.Target
|
|
715
|
+
value={config.superTitle}
|
|
716
|
+
updateField={updateField}
|
|
717
|
+
fieldName='superTitle'
|
|
718
|
+
label='Super Title'
|
|
719
|
+
placeholder='Super Title'
|
|
720
|
+
tooltip={
|
|
721
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
722
|
+
<Tooltip.Target>
|
|
723
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
724
|
+
</Tooltip.Target>
|
|
672
725
|
<Tooltip.Content>
|
|
673
|
-
|
|
726
|
+
<p>Super Title</p>
|
|
674
727
|
</Tooltip.Content>
|
|
675
728
|
</Tooltip>
|
|
676
|
-
|
|
729
|
+
}
|
|
677
730
|
/>
|
|
678
|
-
|
|
731
|
+
|
|
679
732
|
<TextField
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
<Tooltip style={{textTransform: 'none'}}>
|
|
687
|
-
<Tooltip.Target
|
|
733
|
+
type='textarea'
|
|
734
|
+
value={config.introText}
|
|
735
|
+
updateField={updateField}
|
|
736
|
+
fieldName='introText'
|
|
737
|
+
label='Intro Text'
|
|
738
|
+
tooltip={
|
|
739
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
740
|
+
<Tooltip.Target>
|
|
741
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
742
|
+
</Tooltip.Target>
|
|
688
743
|
<Tooltip.Content>
|
|
689
|
-
|
|
744
|
+
<p>Intro Text</p>
|
|
690
745
|
</Tooltip.Content>
|
|
691
746
|
</Tooltip>
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
<TextField type="textarea" value={config.description} fieldName="description" label="Subtext" updateField={updateField} tooltip={
|
|
696
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
697
|
-
<Tooltip.Target><Icon display="question" style={{ marginLeft: '0.5rem' }}/></Tooltip.Target>
|
|
698
|
-
<Tooltip.Content>
|
|
699
|
-
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
700
|
-
</Tooltip.Content>
|
|
701
|
-
</Tooltip>
|
|
702
|
-
} />
|
|
703
|
-
|
|
747
|
+
}
|
|
748
|
+
/>
|
|
749
|
+
|
|
704
750
|
<TextField
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
<Tooltip style={{textTransform: 'none'}}>
|
|
712
|
-
<Tooltip.Target
|
|
751
|
+
type='textarea'
|
|
752
|
+
value={config.description}
|
|
753
|
+
fieldName='description'
|
|
754
|
+
label='Subtext'
|
|
755
|
+
updateField={updateField}
|
|
756
|
+
tooltip={
|
|
757
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
758
|
+
<Tooltip.Target>
|
|
759
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
760
|
+
</Tooltip.Target>
|
|
713
761
|
<Tooltip.Content>
|
|
714
|
-
|
|
762
|
+
<p>Enter supporting text to display below the data visualization, if applicable. The following HTML tags are supported: strong, em, sup, and sub.</p>
|
|
715
763
|
</Tooltip.Content>
|
|
716
764
|
</Tooltip>
|
|
717
|
-
|
|
718
|
-
|
|
765
|
+
}
|
|
766
|
+
/>
|
|
719
767
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
768
|
+
<TextField
|
|
769
|
+
type='textarea'
|
|
770
|
+
value={config.footnotes}
|
|
771
|
+
updateField={updateField}
|
|
772
|
+
fieldName='footnotes'
|
|
773
|
+
label='Footnotes'
|
|
774
|
+
tooltip={
|
|
775
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
776
|
+
<Tooltip.Target>
|
|
777
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
778
|
+
</Tooltip.Target>
|
|
779
|
+
<Tooltip.Content>
|
|
780
|
+
<p>Footnotes</p>
|
|
781
|
+
</Tooltip.Content>
|
|
782
|
+
</Tooltip>
|
|
783
|
+
}
|
|
784
|
+
/>
|
|
785
|
+
|
|
786
|
+
{config.visualizationSubType !== 'horizontal' && <TextField type='number' value={config.height} fieldName='height' label='Chart Height' updateField={updateField} />}
|
|
723
787
|
</AccordionItemPanel>
|
|
724
788
|
</AccordionItem>
|
|
725
789
|
|
|
726
|
-
|
|
727
|
-
{config.visualizationType !== 'Pie' &&
|
|
790
|
+
{config.visualizationType !== 'Pie' && (
|
|
728
791
|
<AccordionItem>
|
|
729
792
|
<AccordionItemHeading>
|
|
730
|
-
<AccordionItemButton>
|
|
731
|
-
Data Series {((!config.series || config.series.length === 0) || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width="25" className="warning-icon"/>}
|
|
732
|
-
</AccordionItemButton>
|
|
793
|
+
<AccordionItemButton>Data Series {(!config.series || config.series.length === 0 || (config.visualizationType === 'Paired Bar' && config.series.length < 2)) && <WarningImage width='25' className='warning-icon' />}</AccordionItemButton>
|
|
733
794
|
</AccordionItemHeading>
|
|
734
795
|
<AccordionItemPanel>
|
|
735
|
-
{(
|
|
736
|
-
{(
|
|
796
|
+
{(!config.series || config.series.length === 0) && config.visualizationType !== 'Paired Bar' && <p className='warning'>At least one series is required</p>}
|
|
797
|
+
{(!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>}
|
|
737
798
|
{config.series && config.series.length !== 0 && (
|
|
738
799
|
<>
|
|
739
800
|
<fieldset>
|
|
740
|
-
<legend className=
|
|
741
|
-
Displaying
|
|
742
|
-
</legend>
|
|
801
|
+
<legend className='edit-label float-left'>Displaying</legend>
|
|
743
802
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
744
|
-
<Tooltip.Target
|
|
803
|
+
<Tooltip.Target>
|
|
804
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
805
|
+
</Tooltip.Target>
|
|
745
806
|
<Tooltip.Content>
|
|
746
807
|
<p>A data series is a set of related data points plotted in a chart and typically represented in the chart legend.</p>
|
|
747
808
|
</Tooltip.Content>
|
|
748
809
|
</Tooltip>
|
|
749
810
|
</fieldset>
|
|
750
|
-
<ul className=
|
|
751
|
-
{config.series
|
|
811
|
+
<ul className='series-list'>
|
|
812
|
+
{config.series &&
|
|
813
|
+
config.series.map((series, i) => {
|
|
814
|
+
if (config.visualizationType === 'Combo') {
|
|
815
|
+
let changeType = (i, value) => {
|
|
816
|
+
let series = [...config.series]
|
|
817
|
+
series[i].type = value
|
|
818
|
+
|
|
819
|
+
series[i].axis = 'Left'
|
|
820
|
+
|
|
821
|
+
updateConfig({ ...config, series })
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
let typeDropdown = (
|
|
825
|
+
<select
|
|
826
|
+
value={series.type}
|
|
827
|
+
onChange={event => {
|
|
828
|
+
changeType(i, event.target.value)
|
|
829
|
+
}}
|
|
830
|
+
style={{ width: '100px', marginRight: '10px' }}
|
|
831
|
+
>
|
|
832
|
+
<option value='' default>
|
|
833
|
+
Select
|
|
834
|
+
</option>
|
|
835
|
+
<option value='Bar'>Bar</option>
|
|
836
|
+
<option value='Line'>Solid Line</option>
|
|
837
|
+
<option value='dashed-sm'>Small Dashed</option>
|
|
838
|
+
<option value='dashed-md'>Medium Dashed</option>
|
|
839
|
+
<option value='dashed-lg'>Large Dashed</option>
|
|
840
|
+
</select>
|
|
841
|
+
)
|
|
842
|
+
|
|
843
|
+
return (
|
|
844
|
+
<li key={series.dataKey}>
|
|
845
|
+
<div className={`series-list__name${series.dataKey.length > 15 ? ' series-list__name--truncate' : ''}`} data-title={series.dataKey}>
|
|
846
|
+
<div className='series-list__name-text'>{series.dataKey}</div>
|
|
847
|
+
</div>
|
|
848
|
+
<span>
|
|
849
|
+
<span className='series-list__dropdown'>{typeDropdown}</span>
|
|
850
|
+
{config.series && config.series.length > 1 && (
|
|
851
|
+
<button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
|
|
852
|
+
×
|
|
853
|
+
</button>
|
|
854
|
+
)}
|
|
855
|
+
</span>
|
|
856
|
+
</li>
|
|
857
|
+
)
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
return (
|
|
861
|
+
<li key={series.dataKey}>
|
|
862
|
+
<div className='series-list__name' data-title={series.dataKey}>
|
|
863
|
+
<div className='series-list__name--text'>{series.dataKey}</div>
|
|
864
|
+
</div>
|
|
865
|
+
{config.series && config.series.length > 1 && (
|
|
866
|
+
<button className='series-list__remove' onClick={() => removeSeries(series.dataKey)}>
|
|
867
|
+
×
|
|
868
|
+
</button>
|
|
869
|
+
)}
|
|
870
|
+
</li>
|
|
871
|
+
)
|
|
872
|
+
})}
|
|
873
|
+
</ul>
|
|
874
|
+
</>
|
|
875
|
+
)}
|
|
876
|
+
|
|
877
|
+
<Select
|
|
878
|
+
fieldName='visualizationType'
|
|
879
|
+
label='Add Data Series'
|
|
880
|
+
initial='Select'
|
|
881
|
+
onChange={e => {
|
|
882
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
883
|
+
addNewSeries(e.target.value)
|
|
884
|
+
}
|
|
885
|
+
e.target.value = ''
|
|
886
|
+
}}
|
|
887
|
+
options={getColumns()}
|
|
888
|
+
/>
|
|
889
|
+
{config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
|
|
890
|
+
<>
|
|
891
|
+
<span className='divider-heading'>Confidence Keys</span>
|
|
892
|
+
<Select value={config.confidenceKeys.upper || ''} section='confidenceKeys' fieldName='upper' label='Upper' updateField={updateField} initial='Select' options={getColumns()} />
|
|
893
|
+
<Select value={config.confidenceKeys.lower || ''} section='confidenceKeys' fieldName='lower' label='Lower' updateField={updateField} initial='Select' options={getColumns()} />
|
|
894
|
+
</>
|
|
895
|
+
)}
|
|
752
896
|
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
897
|
+
{config.series && config.series.length === 1 && <Select fieldName='visualizationType' label='Rank by Value' initial='Select' onChange={e => sortSeries(e.target.value)} options={['asc', 'desc']} />}
|
|
898
|
+
</AccordionItemPanel>
|
|
899
|
+
</AccordionItem>
|
|
900
|
+
)}
|
|
901
|
+
|
|
902
|
+
{hasRightAxis && config.series && config.visualizationType === 'Combo' && (
|
|
903
|
+
<AccordionItem>
|
|
904
|
+
<AccordionItemHeading>
|
|
905
|
+
<AccordionItemButton>Assign Data Series Axis</AccordionItemButton>
|
|
906
|
+
</AccordionItemHeading>
|
|
907
|
+
<AccordionItemPanel>
|
|
908
|
+
<p>Only line series data can be assigned to the right axis. Check the data series section above.</p>
|
|
909
|
+
{config.series && config.series.filter(series => checkIsLine(series.type)) && (
|
|
910
|
+
<>
|
|
911
|
+
<fieldset>
|
|
912
|
+
<legend className='edit-label float-left'>Displaying</legend>
|
|
913
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
914
|
+
<Tooltip.Target>
|
|
915
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
916
|
+
</Tooltip.Target>
|
|
917
|
+
<Tooltip.Content>
|
|
918
|
+
<p>Assign an axis for the series</p>
|
|
919
|
+
</Tooltip.Content>
|
|
920
|
+
</Tooltip>
|
|
921
|
+
</fieldset>
|
|
922
|
+
<ul className='series-list'>
|
|
923
|
+
{config.series &&
|
|
924
|
+
config.series.map((series, i) => {
|
|
925
|
+
if (series.type === 'Bar') return false // can't set individual bars atm.
|
|
926
|
+
|
|
927
|
+
let changeAxis = (i, value) => {
|
|
928
|
+
let series = [...config.series]
|
|
929
|
+
series[i].axis = value
|
|
757
930
|
updateConfig({ ...config, series })
|
|
758
931
|
}
|
|
759
932
|
|
|
760
|
-
let
|
|
761
|
-
<select
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
<option value=
|
|
769
|
-
|
|
933
|
+
let axisDropdown = (
|
|
934
|
+
<select
|
|
935
|
+
value={series.axis}
|
|
936
|
+
onChange={event => {
|
|
937
|
+
changeAxis(i, event.target.value)
|
|
938
|
+
}}
|
|
939
|
+
style={{ width: '100px', marginRight: '10px' }}
|
|
940
|
+
>
|
|
941
|
+
<option value='Left' default>
|
|
942
|
+
left
|
|
943
|
+
</option>
|
|
944
|
+
<option value='Right'>right</option>
|
|
770
945
|
</select>
|
|
771
946
|
)
|
|
772
947
|
|
|
773
948
|
return (
|
|
774
949
|
<li key={series.dataKey}>
|
|
775
950
|
<div className={`series-list__name${series.dataKey.length > 15 ? ' series-list__name--truncate' : ''}`} data-title={series.dataKey}>
|
|
776
|
-
<div className=
|
|
951
|
+
<div className='series-list__name-text'>{series.dataKey}</div>
|
|
777
952
|
</div>
|
|
778
953
|
<span>
|
|
779
|
-
<span className=
|
|
780
|
-
{config.series && config.series.length > 1 &&
|
|
781
|
-
<button className="series-list__remove" onClick={() => removeSeries(series.dataKey)}>×</button>
|
|
782
|
-
}
|
|
954
|
+
<span className='series-list__dropdown'>{axisDropdown}</span>
|
|
783
955
|
</span>
|
|
784
956
|
</li>
|
|
785
957
|
)
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
return (
|
|
789
|
-
<li key={series.dataKey}>
|
|
790
|
-
<div className="series-list__name" data-title={series.dataKey}>
|
|
791
|
-
<div className="series-list__name--text">
|
|
792
|
-
{series.dataKey}
|
|
793
|
-
</div>
|
|
794
|
-
</div>
|
|
795
|
-
{config.series && config.series.length > 1 &&
|
|
796
|
-
<button className="series-list__remove" onClick={() => removeSeries(series.dataKey)}>×</button>
|
|
797
|
-
}
|
|
798
|
-
</li>
|
|
799
|
-
)
|
|
800
|
-
})}
|
|
958
|
+
})}
|
|
801
959
|
</ul>
|
|
802
|
-
</>)}
|
|
803
|
-
|
|
804
|
-
<Select fieldName="visualizationType" label="Add Data Series" initial="Select" onChange={(e) => {
|
|
805
|
-
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
806
|
-
addNewSeries(e.target.value)
|
|
807
|
-
}
|
|
808
|
-
e.target.value = ''
|
|
809
|
-
}} options={getColumns()}/>
|
|
810
|
-
{config.series && config.series.length <= 1 && config.visualizationType === 'Bar' && (
|
|
811
|
-
<>
|
|
812
|
-
<span className="divider-heading">Confidence Keys</span>
|
|
813
|
-
<Select value={config.confidenceKeys.upper || ''} section="confidenceKeys" fieldName="upper" label="Upper" updateField={updateField} initial="Select" options={getColumns()}/>
|
|
814
|
-
<Select value={config.confidenceKeys.lower || ''} section="confidenceKeys" fieldName="lower" label="Lower" updateField={updateField} initial="Select" options={getColumns()}/>
|
|
815
960
|
</>
|
|
816
961
|
)}
|
|
817
|
-
|
|
818
|
-
{config.series && config.series.length === 1 && <Select
|
|
819
|
-
fieldName="visualizationType"
|
|
820
|
-
label="Rank by Value"
|
|
821
|
-
initial="Select"
|
|
822
|
-
onChange={(e) => sortSeries(e.target.value)}
|
|
823
|
-
options={['asc', 'desc']} />}
|
|
824
|
-
|
|
825
962
|
</AccordionItemPanel>
|
|
826
963
|
</AccordionItem>
|
|
827
|
-
}
|
|
964
|
+
)}
|
|
828
965
|
|
|
829
966
|
<AccordionItem>
|
|
830
967
|
<AccordionItemHeading>
|
|
831
968
|
<AccordionItemButton>
|
|
832
|
-
{config.visualizationType !== 'Pie'
|
|
833
|
-
|
|
834
|
-
: 'Data Format'
|
|
835
|
-
}
|
|
836
|
-
{config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width="25" className="warning-icon"/>}
|
|
969
|
+
{config.visualizationType !== 'Pie' ? (config.visualizationType === 'Bar' ? 'Left Value Axis' : 'Left Value Axis') : 'Data Format'}
|
|
970
|
+
{config.visualizationType === 'Pie' && !config.yAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
|
|
837
971
|
</AccordionItemButton>
|
|
838
972
|
</AccordionItemHeading>
|
|
839
973
|
<AccordionItemPanel>
|
|
840
|
-
{config.visualizationType === 'Pie' &&
|
|
841
|
-
<Select
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
974
|
+
{config.visualizationType === 'Pie' && (
|
|
975
|
+
<Select
|
|
976
|
+
value={config.yAxis.dataKey || ''}
|
|
977
|
+
section='yAxis'
|
|
978
|
+
fieldName='dataKey'
|
|
979
|
+
label='Data Column'
|
|
980
|
+
initial='Select'
|
|
981
|
+
required={true}
|
|
982
|
+
updateField={updateField}
|
|
983
|
+
options={getColumns(false)}
|
|
984
|
+
tooltip={
|
|
985
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
986
|
+
<Tooltip.Target>
|
|
987
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
988
|
+
</Tooltip.Target>
|
|
989
|
+
<Tooltip.Content>
|
|
990
|
+
<p>Select the source data to be visually represented.</p>
|
|
991
|
+
</Tooltip.Content>
|
|
992
|
+
</Tooltip>
|
|
993
|
+
}
|
|
994
|
+
/>
|
|
995
|
+
)}
|
|
850
996
|
{config.visualizationType !== 'Pie' && (
|
|
851
997
|
<>
|
|
852
|
-
<TextField value={config.yAxis.label} section=
|
|
853
|
-
<
|
|
854
|
-
<TextField value={config.yAxis.
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
998
|
+
<TextField value={config.yAxis.label} section='yAxis' fieldName='label' label='Label' updateField={updateField} />
|
|
999
|
+
<CheckBox value={config.yAxis.isLegendValue} section='yAxis' fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />
|
|
1000
|
+
<TextField value={config.yAxis.numTicks} placeholder='Auto' type='number' section='yAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
|
|
1001
|
+
<TextField
|
|
1002
|
+
value={config.yAxis.size}
|
|
1003
|
+
type='number'
|
|
1004
|
+
section='yAxis'
|
|
1005
|
+
fieldName='size'
|
|
1006
|
+
label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
|
|
1007
|
+
className='number-narrow'
|
|
1008
|
+
updateField={updateField}
|
|
1009
|
+
tooltip={
|
|
1010
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1011
|
+
<Tooltip.Target>
|
|
1012
|
+
<Icon display='question' />
|
|
1013
|
+
</Tooltip.Target>
|
|
1014
|
+
<Tooltip.Content>
|
|
1015
|
+
<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>
|
|
1016
|
+
</Tooltip.Content>
|
|
1017
|
+
</Tooltip>
|
|
1018
|
+
}
|
|
1019
|
+
/>
|
|
1020
|
+
{config.orientation !== 'horizontal' && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Display Gridlines' updateField={updateField} />}
|
|
863
1021
|
</>
|
|
864
1022
|
)}
|
|
865
|
-
<span className=
|
|
866
|
-
<CheckBox value={config.dataFormat.commas} section=
|
|
867
|
-
<TextField value={config.dataFormat.roundTo} type=
|
|
868
|
-
<div className=
|
|
869
|
-
<TextField
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
</Tooltip
|
|
885
|
-
|
|
886
|
-
|
|
1023
|
+
<span className='divider-heading'>Number Formatting</span>
|
|
1024
|
+
<CheckBox value={config.dataFormat.commas} section='dataFormat' fieldName='commas' label='Add commas' updateField={updateField} />
|
|
1025
|
+
<TextField value={config.dataFormat.roundTo} type='number' section='dataFormat' fieldName='roundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
|
|
1026
|
+
<div className='two-col-inputs'>
|
|
1027
|
+
<TextField
|
|
1028
|
+
value={config.dataFormat.prefix}
|
|
1029
|
+
section='dataFormat'
|
|
1030
|
+
fieldName='prefix'
|
|
1031
|
+
label='Prefix'
|
|
1032
|
+
updateField={updateField}
|
|
1033
|
+
tooltip={
|
|
1034
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1035
|
+
<Tooltip.Target>
|
|
1036
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1037
|
+
</Tooltip.Target>
|
|
1038
|
+
<Tooltip.Content>
|
|
1039
|
+
{config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
|
|
1040
|
+
{config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
|
|
1041
|
+
</Tooltip.Content>
|
|
1042
|
+
</Tooltip>
|
|
1043
|
+
}
|
|
1044
|
+
/>
|
|
1045
|
+
<TextField
|
|
1046
|
+
value={config.dataFormat.suffix}
|
|
1047
|
+
section='dataFormat'
|
|
1048
|
+
fieldName='suffix'
|
|
1049
|
+
label='Suffix'
|
|
1050
|
+
updateField={updateField}
|
|
1051
|
+
tooltip={
|
|
1052
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1053
|
+
<Tooltip.Target>
|
|
1054
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1055
|
+
</Tooltip.Target>
|
|
1056
|
+
<Tooltip.Content>
|
|
1057
|
+
{config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
|
|
1058
|
+
{config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
|
|
1059
|
+
</Tooltip.Content>
|
|
1060
|
+
</Tooltip>
|
|
1061
|
+
}
|
|
1062
|
+
/>
|
|
887
1063
|
</div>
|
|
888
|
-
|
|
889
|
-
{
|
|
890
|
-
<>
|
|
891
|
-
<CheckBox value={config.xAxis.hideAxis} section="xAxis" fieldName="hideAxis" label="Hide Axis" updateField={updateField} />
|
|
892
|
-
<CheckBox value={config.xAxis.hideLabel} section="xAxis" fieldName="hideLabel" label="Hide Label" updateField={updateField} />
|
|
893
|
-
<CheckBox value={config.xAxis.hideTicks} section="xAxis" fieldName="hideTicks" label="Hide Ticks" updateField={updateField} />
|
|
894
|
-
<TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='update max value' type='number' placeholder='Auto' updateField={updateField} />
|
|
895
|
-
<span style={{color:'red',display:'block'}} >{warningMsg.maxMsg}</span>
|
|
896
|
-
</>
|
|
897
|
-
: (config.visualizationType !=='Pie') &&
|
|
1064
|
+
|
|
1065
|
+
{config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
|
|
898
1066
|
<>
|
|
899
|
-
<CheckBox value={config.
|
|
900
|
-
<CheckBox value={config.
|
|
901
|
-
<CheckBox value={config.
|
|
902
|
-
<TextField value={config.
|
|
903
|
-
<span style={{color:'red',display:'block'}}
|
|
904
|
-
<TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='update min value' placeholder='Auto' updateField={updateField} />
|
|
905
|
-
<span style={{color:'red',display:'block'}} >{warningMsg.minMsg}</span>
|
|
1067
|
+
<CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
|
|
1068
|
+
<CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
|
|
1069
|
+
<CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1070
|
+
<TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='update max value' type='number' placeholder='Auto' updateField={updateField} />
|
|
1071
|
+
<span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
|
|
906
1072
|
</>
|
|
907
|
-
|
|
1073
|
+
) : (
|
|
1074
|
+
config.visualizationType !== 'Pie' && (
|
|
1075
|
+
<>
|
|
1076
|
+
<CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
|
|
1077
|
+
<CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
|
|
1078
|
+
<CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1079
|
+
<TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='update max value' placeholder='Auto' updateField={updateField} />
|
|
1080
|
+
<span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
|
|
1081
|
+
<TextField value={config.yAxis.min} section='yAxis' fieldName='min' type='number' label='update min value' placeholder='Auto' updateField={updateField} />
|
|
1082
|
+
<span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
|
|
1083
|
+
</>
|
|
1084
|
+
)
|
|
1085
|
+
)}
|
|
908
1086
|
</AccordionItemPanel>
|
|
909
1087
|
</AccordionItem>
|
|
910
1088
|
|
|
1089
|
+
{/* Right Value Axis Settings */}
|
|
1090
|
+
{hasRightAxis && (
|
|
1091
|
+
<AccordionItem>
|
|
1092
|
+
<AccordionItemHeading>
|
|
1093
|
+
<AccordionItemButton>Right Value Axis</AccordionItemButton>
|
|
1094
|
+
</AccordionItemHeading>
|
|
1095
|
+
<AccordionItemPanel>
|
|
1096
|
+
<TextField value={config.yAxis.rightLabel} section='yAxis' fieldName='rightLabel' label='Label' updateField={updateField} />
|
|
1097
|
+
<TextField value={config.yAxis.rightNumTicks} placeholder='Auto' type='number' section='yAxis' fieldName='rightNumTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
|
|
1098
|
+
<TextField value={config.yAxis.rightAxisSize} type='number' section='yAxis' fieldName='rightAxisSize' label='Size (Width)' className='number-narrow' updateField={updateField} />
|
|
1099
|
+
<TextField value={config.yAxis.rightLabelOffsetSize} type='number' section='yAxis' fieldName='rightLabelOffsetSize' label='Label Offset' className='number-narrow' updateField={updateField} />
|
|
1100
|
+
|
|
1101
|
+
<span className='divider-heading'>Number Formatting</span>
|
|
1102
|
+
<CheckBox value={config.dataFormat.rightCommas} section='dataFormat' fieldName='rightCommas' label='Add commas' updateField={updateField} />
|
|
1103
|
+
<TextField value={config.dataFormat.rightRoundTo} type='number' section='dataFormat' fieldName='rightRoundTo' label='Round to decimal point' className='number-narrow' updateField={updateField} min={0} />
|
|
1104
|
+
<div className='two-col-inputs'>
|
|
1105
|
+
<TextField
|
|
1106
|
+
value={config.dataFormat.rightPrefix}
|
|
1107
|
+
section='dataFormat'
|
|
1108
|
+
fieldName='rightPrefix'
|
|
1109
|
+
label='Prefix'
|
|
1110
|
+
updateField={updateField}
|
|
1111
|
+
tooltip={
|
|
1112
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1113
|
+
<Tooltip.Target>
|
|
1114
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1115
|
+
</Tooltip.Target>
|
|
1116
|
+
<Tooltip.Content>
|
|
1117
|
+
{config.visualizationType === 'Pie' && <p>Enter a data prefix to display in the data table and chart tooltips, if applicable.</p>}
|
|
1118
|
+
{config.visualizationType !== 'Pie' && <p>Enter a data prefix (such as "$"), if applicable.</p>}
|
|
1119
|
+
</Tooltip.Content>
|
|
1120
|
+
</Tooltip>
|
|
1121
|
+
}
|
|
1122
|
+
/>
|
|
1123
|
+
<TextField
|
|
1124
|
+
value={config.dataFormat.rightSuffix}
|
|
1125
|
+
section='dataFormat'
|
|
1126
|
+
fieldName='rightSuffix'
|
|
1127
|
+
label='Suffix'
|
|
1128
|
+
updateField={updateField}
|
|
1129
|
+
tooltip={
|
|
1130
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1131
|
+
<Tooltip.Target>
|
|
1132
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1133
|
+
</Tooltip.Target>
|
|
1134
|
+
<Tooltip.Content>
|
|
1135
|
+
{config.visualizationType === 'Pie' && <p>Enter a data suffix to display in the data table and tooltips, if applicable.</p>}
|
|
1136
|
+
{config.visualizationType !== 'Pie' && <p>Enter a data suffix (such as "%"), if applicable.</p>}
|
|
1137
|
+
</Tooltip.Content>
|
|
1138
|
+
</Tooltip>
|
|
1139
|
+
}
|
|
1140
|
+
/>
|
|
1141
|
+
</div>
|
|
1142
|
+
|
|
1143
|
+
<CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
|
|
1144
|
+
<CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Label' updateField={updateField} />
|
|
1145
|
+
<CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1146
|
+
</AccordionItemPanel>
|
|
1147
|
+
</AccordionItem>
|
|
1148
|
+
)}
|
|
1149
|
+
|
|
911
1150
|
<AccordionItem>
|
|
912
1151
|
<AccordionItemHeading>
|
|
913
1152
|
<AccordionItemButton>
|
|
914
|
-
{config.visualizationType !== 'Pie'
|
|
915
|
-
|
|
916
|
-
: 'Segments'
|
|
917
|
-
}
|
|
918
|
-
{!config.xAxis.dataKey && <WarningImage width="25" className="warning-icon"/>}
|
|
1153
|
+
{config.visualizationType !== 'Pie' ? (config.visualizationType === 'Bar' ? 'Date/Category Axis' : 'Date/Category Axis') : 'Segments'}
|
|
1154
|
+
{!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
|
|
919
1155
|
</AccordionItemButton>
|
|
920
1156
|
</AccordionItemHeading>
|
|
921
1157
|
<AccordionItemPanel>
|
|
922
|
-
{config.visualizationType !== 'Pie' &&
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
<
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1158
|
+
{config.visualizationType !== 'Pie' && (
|
|
1159
|
+
<>
|
|
1160
|
+
<Select value={config.xAxis.type} section='xAxis' fieldName='type' label='Data Type' updateField={updateField} options={['categorical', 'date']} />
|
|
1161
|
+
<Select
|
|
1162
|
+
value={config.xAxis.dataKey || ''}
|
|
1163
|
+
section='xAxis'
|
|
1164
|
+
fieldName='dataKey'
|
|
1165
|
+
label='Data Key'
|
|
1166
|
+
initial='Select'
|
|
1167
|
+
required={true}
|
|
1168
|
+
updateField={updateField}
|
|
1169
|
+
options={getColumns(false)}
|
|
1170
|
+
tooltip={
|
|
1171
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1172
|
+
<Tooltip.Target>
|
|
1173
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1174
|
+
</Tooltip.Target>
|
|
1175
|
+
<Tooltip.Content>
|
|
1176
|
+
<p>Select the column or row containing the categories or dates for this axis. </p>
|
|
1177
|
+
</Tooltip.Content>
|
|
1178
|
+
</Tooltip>
|
|
1179
|
+
}
|
|
1180
|
+
/>
|
|
1181
|
+
</>
|
|
1182
|
+
)}
|
|
933
1183
|
|
|
934
|
-
{config.visualizationType === 'Pie' &&
|
|
935
|
-
<Select
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
1184
|
+
{config.visualizationType === 'Pie' && (
|
|
1185
|
+
<Select
|
|
1186
|
+
value={config.xAxis.dataKey || ''}
|
|
1187
|
+
section='xAxis'
|
|
1188
|
+
fieldName='dataKey'
|
|
1189
|
+
label='Segment Labels'
|
|
1190
|
+
initial='Select'
|
|
1191
|
+
required={true}
|
|
1192
|
+
updateField={updateField}
|
|
1193
|
+
options={getColumns(false)}
|
|
1194
|
+
tooltip={
|
|
1195
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1196
|
+
<Tooltip.Target>
|
|
1197
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1198
|
+
</Tooltip.Target>
|
|
1199
|
+
<Tooltip.Content>
|
|
1200
|
+
<p>Select the source row or column that contains the segment labels. Depending on the data structure, it may be listed as "Key."</p>
|
|
1201
|
+
</Tooltip.Content>
|
|
1202
|
+
</Tooltip>
|
|
1203
|
+
}
|
|
1204
|
+
/>
|
|
1205
|
+
)}
|
|
944
1206
|
|
|
945
1207
|
{config.visualizationType !== 'Pie' && (
|
|
946
1208
|
<>
|
|
947
|
-
<TextField value={config.xAxis.label} section=
|
|
1209
|
+
<TextField value={config.xAxis.label} section='xAxis' fieldName='label' label='Label' updateField={updateField} />
|
|
948
1210
|
|
|
949
1211
|
{config.xAxis.type === 'date' && (
|
|
950
1212
|
<>
|
|
951
|
-
<p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
|
|
952
|
-
|
|
953
|
-
|
|
1213
|
+
<p style={{ padding: '1.5em 0 0.5em', fontSize: '.9rem', lineHeight: '1rem' }}>
|
|
1214
|
+
Format how charts should parse and display your dates using{' '}
|
|
1215
|
+
<a href='https://github.com/d3/d3-time-format#locale_format' target='_blank' rel='noreferrer'>
|
|
1216
|
+
these guidelines
|
|
1217
|
+
</a>
|
|
1218
|
+
.
|
|
1219
|
+
</p>
|
|
1220
|
+
<TextField value={config.xAxis.dateParseFormat} section='xAxis' fieldName='dateParseFormat' placeholder='Ex. %Y-%m-%d' label='Date Parse Format' updateField={updateField} />
|
|
1221
|
+
<TextField value={config.xAxis.dateDisplayFormat} section='xAxis' fieldName='dateDisplayFormat' placeholder='Ex. %Y-%m-%d' label='Date Display Format' updateField={updateField} />
|
|
954
1222
|
</>
|
|
955
1223
|
)}
|
|
956
1224
|
|
|
957
|
-
<CheckBox
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
1225
|
+
<CheckBox
|
|
1226
|
+
value={config.exclusions.active}
|
|
1227
|
+
section='exclusions'
|
|
1228
|
+
fieldName='active'
|
|
1229
|
+
label={config.xAxis.type === 'date' ? 'Limit by start and/or end dates' : 'Exclude one or more values'}
|
|
1230
|
+
tooltip={
|
|
1231
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1232
|
+
<Tooltip.Target>
|
|
1233
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1234
|
+
</Tooltip.Target>
|
|
1235
|
+
<Tooltip.Content>
|
|
1236
|
+
<p>When this option is checked, you can select source-file values for exclusion from the date/category axis. </p>
|
|
1237
|
+
</Tooltip.Content>
|
|
1238
|
+
</Tooltip>
|
|
1239
|
+
}
|
|
1240
|
+
updateField={updateField}
|
|
1241
|
+
/>
|
|
965
1242
|
|
|
966
|
-
{config.exclusions.active &&
|
|
1243
|
+
{config.exclusions.active && (
|
|
967
1244
|
<>
|
|
968
|
-
{config.xAxis.type === 'categorical' &&
|
|
1245
|
+
{config.xAxis.type === 'categorical' && (
|
|
969
1246
|
<>
|
|
970
|
-
{config.exclusions.keys.length > 0 &&
|
|
1247
|
+
{config.exclusions.keys.length > 0 && (
|
|
971
1248
|
<>
|
|
972
1249
|
<fieldset>
|
|
973
|
-
<legend className=
|
|
1250
|
+
<legend className='edit-label'>Excluded Keys</legend>
|
|
974
1251
|
</fieldset>
|
|
975
|
-
<ExclusionsList/>
|
|
1252
|
+
<ExclusionsList />
|
|
976
1253
|
</>
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
<Select
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
e
|
|
984
|
-
|
|
1254
|
+
)}
|
|
1255
|
+
|
|
1256
|
+
<Select
|
|
1257
|
+
fieldName='visualizationType'
|
|
1258
|
+
label='Add Exclusion'
|
|
1259
|
+
initial='Select'
|
|
1260
|
+
onChange={e => {
|
|
1261
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
1262
|
+
addNewExclusion(e.target.value)
|
|
1263
|
+
}
|
|
1264
|
+
e.target.value = ''
|
|
1265
|
+
}}
|
|
1266
|
+
options={getDataValues(config.xAxis.dataKey, true)}
|
|
1267
|
+
/>
|
|
985
1268
|
</>
|
|
986
|
-
}
|
|
1269
|
+
)}
|
|
987
1270
|
|
|
988
|
-
{config.xAxis.type === 'date' &&
|
|
1271
|
+
{config.xAxis.type === 'date' && (
|
|
989
1272
|
<>
|
|
990
|
-
<TextField type=
|
|
991
|
-
<TextField type=
|
|
1273
|
+
<TextField type='date' section='exclusions' fieldName='dateStart' label='Start Date' updateField={updateField} value={config.exclusions.dateStart || ''} />
|
|
1274
|
+
<TextField type='date' section='exclusions' fieldName='dateEnd' label='End Date' updateField={updateField} value={config.exclusions.dateEnd || ''} />
|
|
992
1275
|
</>
|
|
993
|
-
}
|
|
994
|
-
</>
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
{config.xAxis.type === 'date' &&
|
|
998
|
-
<>
|
|
999
|
-
<TextField value={config.xAxis.numTicks} placeholder="Auto" type="number" min="1" section="xAxis" fieldName="numTicks" label="Number of ticks" className="number-narrow" updateField={updateField}/>
|
|
1276
|
+
)}
|
|
1000
1277
|
</>
|
|
1001
|
-
}
|
|
1278
|
+
)}
|
|
1279
|
+
<TextField value={config.xAxis.numTicks} placeholder='Auto' type='number' min='1' section='xAxis' fieldName='numTicks' label='Number of ticks' className='number-narrow' updateField={updateField} />
|
|
1002
1280
|
|
|
1003
|
-
<TextField value={config.xAxis.size} type=
|
|
1281
|
+
<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} />
|
|
1004
1282
|
|
|
1005
|
-
{config.yAxis.labelPlacement !== 'Below Bar' &&
|
|
1006
|
-
|
|
1007
|
-
}
|
|
1008
|
-
{(config.orientation === 'horizontal') ?
|
|
1283
|
+
{config.yAxis.labelPlacement !== 'Below Bar' && <TextField value={config.xAxis.tickRotation} type='number' min='0' section='xAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
|
|
1284
|
+
{config.orientation === 'horizontal' ? (
|
|
1009
1285
|
<>
|
|
1010
|
-
<CheckBox value={config.yAxis.hideAxis} section=
|
|
1011
|
-
<CheckBox value={config.yAxis.hideLabel} section=
|
|
1286
|
+
<CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
|
|
1287
|
+
<CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
|
|
1012
1288
|
</>
|
|
1013
|
-
|
|
1289
|
+
) : (
|
|
1014
1290
|
<>
|
|
1015
|
-
<CheckBox value={config.xAxis.hideAxis} section=
|
|
1016
|
-
<CheckBox value={config.xAxis.hideLabel} section=
|
|
1017
|
-
<CheckBox value={config.xAxis.hideTicks} section=
|
|
1291
|
+
<CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
|
|
1292
|
+
<CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Label' updateField={updateField} />
|
|
1293
|
+
<CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1018
1294
|
</>
|
|
1019
|
-
}
|
|
1295
|
+
)}
|
|
1020
1296
|
</>
|
|
1021
1297
|
)}
|
|
1022
1298
|
|
|
1023
|
-
{config.visualizationType === 'Pie' &&
|
|
1299
|
+
{config.visualizationType === 'Pie' && (
|
|
1024
1300
|
<>
|
|
1025
|
-
<CheckBox
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1301
|
+
<CheckBox
|
|
1302
|
+
value={config.exclusions.active}
|
|
1303
|
+
section='exclusions'
|
|
1304
|
+
fieldName='active'
|
|
1305
|
+
label={'Exclude one or more values'}
|
|
1306
|
+
updateField={updateField}
|
|
1307
|
+
tooltip={
|
|
1308
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1309
|
+
<Tooltip.Target>
|
|
1310
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1311
|
+
</Tooltip.Target>
|
|
1312
|
+
<Tooltip.Content>
|
|
1313
|
+
<p>When this option is checked, you can select values for exclusion from the pie segments.</p>
|
|
1314
|
+
</Tooltip.Content>
|
|
1315
|
+
</Tooltip>
|
|
1316
|
+
}
|
|
1317
|
+
/>
|
|
1318
|
+
{config.exclusions.active && (
|
|
1034
1319
|
<>
|
|
1035
|
-
{config.exclusions.keys.length > 0 &&
|
|
1320
|
+
{config.exclusions.keys.length > 0 && (
|
|
1036
1321
|
<>
|
|
1037
1322
|
<fieldset>
|
|
1038
|
-
<legend className=
|
|
1323
|
+
<legend className='edit-label'>Excluded Keys</legend>
|
|
1039
1324
|
</fieldset>
|
|
1040
|
-
<ExclusionsList/>
|
|
1325
|
+
<ExclusionsList />
|
|
1041
1326
|
</>
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
<Select
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
e
|
|
1049
|
-
|
|
1327
|
+
)}
|
|
1328
|
+
|
|
1329
|
+
<Select
|
|
1330
|
+
fieldName='visualizationType'
|
|
1331
|
+
label='Add Exclusion'
|
|
1332
|
+
initial='Select'
|
|
1333
|
+
onChange={e => {
|
|
1334
|
+
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
1335
|
+
addNewExclusion(e.target.value)
|
|
1336
|
+
}
|
|
1337
|
+
e.target.value = ''
|
|
1338
|
+
}}
|
|
1339
|
+
options={getDataValues(config.xAxis.dataKey, true)}
|
|
1340
|
+
/>
|
|
1050
1341
|
</>
|
|
1051
|
-
}
|
|
1342
|
+
)}
|
|
1052
1343
|
</>
|
|
1053
|
-
}
|
|
1344
|
+
)}
|
|
1054
1345
|
</AccordionItemPanel>
|
|
1055
1346
|
</AccordionItem>
|
|
1056
1347
|
|
|
1057
|
-
{
|
|
1348
|
+
{config.visualizationType !== 'Pie' && config.visualizationType !== 'Paired Bar' && (
|
|
1058
1349
|
<AccordionItem>
|
|
1059
1350
|
<AccordionItemHeading>
|
|
1060
|
-
<AccordionItemButton>
|
|
1061
|
-
Regions
|
|
1062
|
-
</AccordionItemButton>
|
|
1351
|
+
<AccordionItemButton>Regions</AccordionItemButton>
|
|
1063
1352
|
</AccordionItemHeading>
|
|
1064
1353
|
<AccordionItemPanel>
|
|
1065
|
-
<Regions config={config} updateConfig={updateConfig}/>
|
|
1354
|
+
<Regions config={config} updateConfig={updateConfig} />
|
|
1066
1355
|
</AccordionItemPanel>
|
|
1067
1356
|
</AccordionItem>
|
|
1068
|
-
}
|
|
1357
|
+
)}
|
|
1069
1358
|
|
|
1070
1359
|
<AccordionItem>
|
|
1071
1360
|
<AccordionItemHeading>
|
|
1072
|
-
<AccordionItemButton>
|
|
1073
|
-
Legend
|
|
1074
|
-
</AccordionItemButton>
|
|
1361
|
+
<AccordionItemButton>Legend</AccordionItemButton>
|
|
1075
1362
|
</AccordionItemHeading>
|
|
1076
1363
|
<AccordionItemPanel>
|
|
1077
|
-
|
|
1364
|
+
<CheckBox value={config.legend.reverseLabelOrder} section='legend' fieldName='reverseLabelOrder' label='Reverse Labels' updateField={updateField} />
|
|
1078
1365
|
{/* <fieldset className="checkbox-group">
|
|
1079
1366
|
<CheckBox value={config.legend.dynamicLegend} section="legend" fieldName="dynamicLegend" label="Dynamic Legend" updateField={updateField}/>
|
|
1080
1367
|
{config.legend.dynamicLegend && (
|
|
@@ -1086,88 +1373,103 @@ useEffect(()=>{
|
|
|
1086
1373
|
</>
|
|
1087
1374
|
)}
|
|
1088
1375
|
</fieldset> */}
|
|
1089
|
-
<CheckBox
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1376
|
+
<CheckBox
|
|
1377
|
+
value={config.legend.hide}
|
|
1378
|
+
section='legend'
|
|
1379
|
+
fieldName='hide'
|
|
1380
|
+
label='Hide Legend'
|
|
1381
|
+
updateField={updateField}
|
|
1382
|
+
tooltip={
|
|
1383
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1384
|
+
<Tooltip.Target>
|
|
1385
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1386
|
+
</Tooltip.Target>
|
|
1387
|
+
<Tooltip.Content>
|
|
1388
|
+
<p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
|
|
1389
|
+
</Tooltip.Content>
|
|
1390
|
+
</Tooltip>
|
|
1391
|
+
}
|
|
1392
|
+
/>
|
|
1393
|
+
|
|
1394
|
+
{config.visualizationType === 'Bar' && config.visualizationSubType === 'regular' && config.runtime.seriesKeys.length === 1 && (
|
|
1395
|
+
<Select value={config.legend.colorCode} section='legend' fieldName='colorCode' label='Color code by category' initial='Select' updateField={updateField} options={getDataValueOptions(data)} />
|
|
1100
1396
|
)}
|
|
1101
|
-
<Select value={config.legend.behavior} section=
|
|
1102
|
-
<TextField value={config.legend.label} section=
|
|
1103
|
-
<Select value={config.legend.position} section=
|
|
1104
|
-
|
|
1397
|
+
<Select value={config.legend.behavior} section='legend' fieldName='behavior' label='Legend Behavior (When clicked)' updateField={updateField} options={['highlight', 'isolate']} />
|
|
1398
|
+
<TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
|
|
1399
|
+
<Select value={config.legend.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
|
|
1400
|
+
{config.legend.position === 'bottom' && <CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />}
|
|
1401
|
+
<TextField type='textarea' value={config.legend.description} updateField={updateField} section='legend' fieldName='description' label='Legend Description' />
|
|
1105
1402
|
</AccordionItemPanel>
|
|
1106
1403
|
</AccordionItem>
|
|
1107
1404
|
|
|
1108
1405
|
<AccordionItem>
|
|
1109
1406
|
<AccordionItemHeading>
|
|
1110
|
-
<AccordionItemButton>
|
|
1111
|
-
Filters
|
|
1112
|
-
</AccordionItemButton>
|
|
1407
|
+
<AccordionItemButton>Filters</AccordionItemButton>
|
|
1113
1408
|
</AccordionItemHeading>
|
|
1114
1409
|
<AccordionItemPanel>
|
|
1115
|
-
{config.filters &&
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1410
|
+
{config.filters && (
|
|
1411
|
+
<ul className='filters-list'>
|
|
1412
|
+
{config.filters.map((filter, index) => (
|
|
1413
|
+
<fieldset className='edit-block' key={index}>
|
|
1414
|
+
<button
|
|
1415
|
+
type='button'
|
|
1416
|
+
className='remove-column'
|
|
1417
|
+
onClick={() => {
|
|
1418
|
+
removeFilter(index)
|
|
1419
|
+
}}
|
|
1420
|
+
>
|
|
1421
|
+
Remove
|
|
1121
1422
|
</button>
|
|
1122
1423
|
<label>
|
|
1123
|
-
<span className=
|
|
1124
|
-
<select
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1424
|
+
<span className='edit-label column-heading'>Filter</span>
|
|
1425
|
+
<select
|
|
1426
|
+
value={filter.columnName}
|
|
1427
|
+
onChange={e => {
|
|
1428
|
+
updateFilterProp('columnName', index, e.target.value)
|
|
1429
|
+
}}
|
|
1430
|
+
>
|
|
1431
|
+
<option value=''>- Select Option -</option>
|
|
1128
1432
|
{getColumns().map((dataKey, index) => (
|
|
1129
|
-
<option value={dataKey} key={index}>
|
|
1433
|
+
<option value={dataKey} key={index}>
|
|
1434
|
+
{dataKey}
|
|
1435
|
+
</option>
|
|
1130
1436
|
))}
|
|
1131
1437
|
</select>
|
|
1132
1438
|
</label>
|
|
1133
1439
|
<label>
|
|
1134
|
-
<span className=
|
|
1135
|
-
<input
|
|
1136
|
-
|
|
1137
|
-
|
|
1440
|
+
<span className='edit-label column-heading'>Label</span>
|
|
1441
|
+
<input
|
|
1442
|
+
type='text'
|
|
1443
|
+
value={filter.label}
|
|
1444
|
+
onChange={e => {
|
|
1445
|
+
updateFilterProp('label', index, e.target.value)
|
|
1446
|
+
}}
|
|
1447
|
+
/>
|
|
1138
1448
|
</label>
|
|
1139
1449
|
|
|
1140
1450
|
<label>
|
|
1141
|
-
<span className=
|
|
1142
|
-
<select value={filter.order ? filter.order : 'asc'} onChange={
|
|
1451
|
+
<span className='edit-filterOrder column-heading'>Filter Order</span>
|
|
1452
|
+
<select value={filter.order ? filter.order : 'asc'} onChange={e => updateFilterProp('order', index, e.target.value)}>
|
|
1143
1453
|
{filterOptions.map((option, index) => {
|
|
1144
|
-
return
|
|
1454
|
+
return (
|
|
1455
|
+
<option value={option.value} key={`filter-${index}`}>
|
|
1456
|
+
{option.label}
|
|
1457
|
+
</option>
|
|
1458
|
+
)
|
|
1145
1459
|
})}
|
|
1146
1460
|
</select>
|
|
1147
1461
|
|
|
1148
|
-
{filter.order === 'cust' &&
|
|
1149
|
-
<DragDropContext
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
<Droppable droppableId="filter_order">
|
|
1154
|
-
{(provided) => (
|
|
1155
|
-
<ul
|
|
1156
|
-
{...provided.droppableProps}
|
|
1157
|
-
className="sort-list"
|
|
1158
|
-
ref={provided.innerRef}
|
|
1159
|
-
style={{ marginTop: '1em' }}
|
|
1160
|
-
>
|
|
1462
|
+
{filter.order === 'cust' && (
|
|
1463
|
+
<DragDropContext onDragEnd={({ source, destination }) => handleFilterChange(source.index, destination.index, index, config.filters[index])}>
|
|
1464
|
+
<Droppable droppableId='filter_order'>
|
|
1465
|
+
{provided => (
|
|
1466
|
+
<ul {...provided.droppableProps} className='sort-list' ref={provided.innerRef} style={{ marginTop: '1em' }}>
|
|
1161
1467
|
{config.filters[index]?.values.map((value, index) => {
|
|
1162
1468
|
return (
|
|
1163
1469
|
<Draggable key={value} draggableId={`draggableFilter-${value}`} index={index}>
|
|
1164
1470
|
{(provided, snapshot) => (
|
|
1165
1471
|
<li>
|
|
1166
|
-
<div className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
1167
|
-
style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)}
|
|
1168
|
-
ref={provided.innerRef}
|
|
1169
|
-
{...provided.draggableProps}
|
|
1170
|
-
{...provided.dragHandleProps}>
|
|
1472
|
+
<div className={snapshot.isDragging ? 'currently-dragging' : ''} style={getItemStyle(snapshot.isDragging, provided.draggableProps.style, sortableItemStyles)} ref={provided.innerRef} {...provided.draggableProps} {...provided.dragHandleProps}>
|
|
1171
1473
|
{value}
|
|
1172
1474
|
</div>
|
|
1173
1475
|
</li>
|
|
@@ -1180,98 +1482,84 @@ useEffect(()=>{
|
|
|
1180
1482
|
)}
|
|
1181
1483
|
</Droppable>
|
|
1182
1484
|
</DragDropContext>
|
|
1183
|
-
}
|
|
1485
|
+
)}
|
|
1184
1486
|
</label>
|
|
1185
|
-
|
|
1186
1487
|
</fieldset>
|
|
1187
|
-
)
|
|
1188
|
-
|
|
1189
|
-
|
|
1488
|
+
))}
|
|
1489
|
+
</ul>
|
|
1490
|
+
)}
|
|
1190
1491
|
{!config.filters && <p style={{ textAlign: 'center' }}>There are currently no filters.</p>}
|
|
1191
|
-
<button type=
|
|
1492
|
+
<button type='button' onClick={addNewFilter} className='btn full-width'>
|
|
1493
|
+
Add Filter
|
|
1494
|
+
</button>
|
|
1192
1495
|
</AccordionItemPanel>
|
|
1193
1496
|
</AccordionItem>
|
|
1194
1497
|
|
|
1195
1498
|
<AccordionItem>
|
|
1196
1499
|
<AccordionItemHeading>
|
|
1197
|
-
<AccordionItemButton>
|
|
1198
|
-
Visual
|
|
1199
|
-
</AccordionItemButton>
|
|
1500
|
+
<AccordionItemButton>Visual</AccordionItemButton>
|
|
1200
1501
|
</AccordionItemHeading>
|
|
1201
1502
|
<AccordionItemPanel>
|
|
1202
|
-
|
|
1203
|
-
{config.isLollipopChart &&
|
|
1503
|
+
{config.isLollipopChart && (
|
|
1204
1504
|
<>
|
|
1205
|
-
<fieldset className=
|
|
1206
|
-
<legend className=
|
|
1207
|
-
<div
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
value="circle"
|
|
1215
|
-
checked={config.lollipopShape === 'circle'}
|
|
1216
|
-
/>
|
|
1505
|
+
<fieldset className='header'>
|
|
1506
|
+
<legend className='edit-label'>Lollipop Shape</legend>
|
|
1507
|
+
<div
|
|
1508
|
+
onChange={e => {
|
|
1509
|
+
setLollipopShape(e.target.value)
|
|
1510
|
+
}}
|
|
1511
|
+
>
|
|
1512
|
+
<label className='radio-label'>
|
|
1513
|
+
<input type='radio' name='lollipopShape' value='circle' checked={config.lollipopShape === 'circle'} />
|
|
1217
1514
|
Circle
|
|
1218
1515
|
</label>
|
|
1219
|
-
<label className=
|
|
1220
|
-
<input
|
|
1221
|
-
type="radio"
|
|
1222
|
-
name="lollipopShape"
|
|
1223
|
-
value="square"
|
|
1224
|
-
checked={config.lollipopShape === 'square'}
|
|
1225
|
-
/>
|
|
1516
|
+
<label className='radio-label'>
|
|
1517
|
+
<input type='radio' name='lollipopShape' value='square' checked={config.lollipopShape === 'square'} />
|
|
1226
1518
|
Square
|
|
1227
1519
|
</label>
|
|
1228
1520
|
</div>
|
|
1229
|
-
|
|
1230
1521
|
</fieldset>
|
|
1231
|
-
<Select value={config.lollipopColorStyle ? config.lollipopColorStyle : 'two-tone'} fieldName=
|
|
1232
|
-
<Select value={config.lollipopSize ? config.lollipopSize : 'small'} fieldName=
|
|
1522
|
+
<Select value={config.lollipopColorStyle ? config.lollipopColorStyle : 'two-tone'} fieldName='lollipopColorStyle' label='Lollipop Color Style' updateField={updateField} options={['regular', 'two-tone']} />
|
|
1523
|
+
<Select value={config.lollipopSize ? config.lollipopSize : 'small'} fieldName='lollipopSize' label='Lollipop Size' updateField={updateField} options={['small', 'medium', 'large']} />
|
|
1233
1524
|
</>
|
|
1234
|
-
}
|
|
1525
|
+
)}
|
|
1235
1526
|
|
|
1236
|
-
<Select value={config.fontSize} fieldName=
|
|
1527
|
+
<Select value={config.fontSize} fieldName='fontSize' label='Font Size' updateField={updateField} options={['small', 'medium', 'large']} />
|
|
1237
1528
|
|
|
1238
|
-
{config.series?.some(series => series.type === 'Bar' || series.type === 'Paired Bar') &&
|
|
1239
|
-
<Select value={config.barHasBorder} fieldName="barHasBorder" label="Bar Borders" updateField={updateField} options={[ 'true', 'false' ]}/>
|
|
1240
|
-
}
|
|
1529
|
+
{config.series?.some(series => series.type === 'Bar' || series.type === 'Paired Bar') && <Select value={config.barHasBorder} fieldName='barHasBorder' label='Bar Borders' updateField={updateField} options={['true', 'false']} />}
|
|
1241
1530
|
|
|
1242
1531
|
{/* <CheckBox value={config.animate} fieldName="animate" label="Animate Visualization" updateField={updateField} /> */}
|
|
1243
1532
|
|
|
1244
1533
|
{/*<CheckBox value={config.animateReplay} fieldName="animateReplay" label="Replay Animation When Filters Are Changed" updateField={updateField} />*/}
|
|
1245
1534
|
|
|
1246
|
-
{((config.series?.some(series => series.type === 'Line') && config.visualizationType === 'Combo') || config.visualizationType === 'Line' || config.visualizationType ===
|
|
1247
|
-
<Select value={config.lineDatapointStyle} fieldName=
|
|
1248
|
-
}
|
|
1535
|
+
{((config.series?.some(series => series.type === 'Line') && config.visualizationType === 'Combo') || config.visualizationType === 'Line' || config.visualizationType === 'Spark Line') && (
|
|
1536
|
+
<Select value={config.lineDatapointStyle} fieldName='lineDatapointStyle' label='Line Datapoint Style' updateField={updateField} options={['hidden', 'hover', 'always show']} />
|
|
1537
|
+
)}
|
|
1249
1538
|
|
|
1250
|
-
<label className=
|
|
1251
|
-
<span className=
|
|
1252
|
-
<ul className=
|
|
1253
|
-
{headerColors.map(
|
|
1254
|
-
<button
|
|
1539
|
+
<label className='header'>
|
|
1540
|
+
<span className='edit-label'>Header Theme</span>
|
|
1541
|
+
<ul className='color-palette'>
|
|
1542
|
+
{headerColors.map(palette => (
|
|
1543
|
+
<button
|
|
1255
1544
|
title={palette}
|
|
1256
|
-
key={palette}
|
|
1257
|
-
onClick={
|
|
1258
|
-
e.preventDefault()
|
|
1545
|
+
key={palette}
|
|
1546
|
+
onClick={e => {
|
|
1547
|
+
e.preventDefault()
|
|
1259
1548
|
updateConfig({ ...config, theme: palette })
|
|
1260
|
-
}}
|
|
1261
|
-
className={config.theme === palette ? 'selected ' + palette : palette}
|
|
1262
|
-
|
|
1549
|
+
}}
|
|
1550
|
+
className={config.theme === palette ? 'selected ' + palette : palette}
|
|
1551
|
+
></button>
|
|
1263
1552
|
))}
|
|
1264
1553
|
</ul>
|
|
1265
1554
|
</label>
|
|
1266
1555
|
<label>
|
|
1267
|
-
<span className=
|
|
1556
|
+
<span className='edit-label'>Chart Color Palette</span>
|
|
1268
1557
|
</label>
|
|
1269
1558
|
{/* <InputCheckbox fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} /> */}
|
|
1270
|
-
<InputToggle fieldName=
|
|
1559
|
+
<InputToggle fieldName='isPaletteReversed' size='small' label='Use selected palette in reverse order' updateField={updateField} value={isPaletteReversed} />
|
|
1271
1560
|
<span>Sequential</span>
|
|
1272
|
-
<ul className=
|
|
1273
|
-
{filteredPallets.map(
|
|
1274
|
-
|
|
1561
|
+
<ul className='color-palette'>
|
|
1562
|
+
{filteredPallets.map(palette => {
|
|
1275
1563
|
const colorOne = {
|
|
1276
1564
|
backgroundColor: colorPalettes[palette][2]
|
|
1277
1565
|
}
|
|
@@ -1285,11 +1573,11 @@ useEffect(()=>{
|
|
|
1285
1573
|
}
|
|
1286
1574
|
|
|
1287
1575
|
return (
|
|
1288
|
-
<button
|
|
1289
|
-
title={palette}
|
|
1290
|
-
key={palette}
|
|
1291
|
-
onClick={
|
|
1292
|
-
e.preventDefault()
|
|
1576
|
+
<button
|
|
1577
|
+
title={palette}
|
|
1578
|
+
key={palette}
|
|
1579
|
+
onClick={e => {
|
|
1580
|
+
e.preventDefault()
|
|
1293
1581
|
updateConfig({ ...config, palette })
|
|
1294
1582
|
}}
|
|
1295
1583
|
className={config.palette === palette ? 'selected' : ''}
|
|
@@ -1302,9 +1590,8 @@ useEffect(()=>{
|
|
|
1302
1590
|
})}
|
|
1303
1591
|
</ul>
|
|
1304
1592
|
<span>Non-Sequential</span>
|
|
1305
|
-
<ul className=
|
|
1306
|
-
{filteredQualitative.map(
|
|
1307
|
-
|
|
1593
|
+
<ul className='color-palette'>
|
|
1594
|
+
{filteredQualitative.map(palette => {
|
|
1308
1595
|
const colorOne = {
|
|
1309
1596
|
backgroundColor: colorPalettes[palette][2]
|
|
1310
1597
|
}
|
|
@@ -1317,13 +1604,12 @@ useEffect(()=>{
|
|
|
1317
1604
|
backgroundColor: colorPalettes[palette][6]
|
|
1318
1605
|
}
|
|
1319
1606
|
|
|
1320
|
-
|
|
1321
1607
|
return (
|
|
1322
|
-
<button
|
|
1323
|
-
title={palette}
|
|
1324
|
-
key={palette}
|
|
1325
|
-
onClick={
|
|
1326
|
-
e.preventDefault()
|
|
1608
|
+
<button
|
|
1609
|
+
title={palette}
|
|
1610
|
+
key={palette}
|
|
1611
|
+
onClick={e => {
|
|
1612
|
+
e.preventDefault()
|
|
1327
1613
|
updateConfig({ ...config, palette })
|
|
1328
1614
|
}}
|
|
1329
1615
|
className={config.palette === palette ? 'selected' : ''}
|
|
@@ -1338,82 +1624,95 @@ useEffect(()=>{
|
|
|
1338
1624
|
|
|
1339
1625
|
{config.visualizationType !== 'Pie' && (
|
|
1340
1626
|
<>
|
|
1341
|
-
<TextField
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1627
|
+
<TextField
|
|
1628
|
+
value={config.dataCutoff}
|
|
1629
|
+
type='number'
|
|
1630
|
+
fieldName='dataCutoff'
|
|
1631
|
+
className='number-narrow'
|
|
1632
|
+
label='Data Cutoff'
|
|
1633
|
+
updateField={updateField}
|
|
1634
|
+
tooltip={
|
|
1635
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1636
|
+
<Tooltip.Target>
|
|
1637
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1638
|
+
</Tooltip.Target>
|
|
1639
|
+
<Tooltip.Content>
|
|
1640
|
+
<p>Any value below the cut-off value is included in a special "less than" category. This option supports special conditions like suppressed data.</p>
|
|
1641
|
+
</Tooltip.Content>
|
|
1642
|
+
</Tooltip>
|
|
1643
|
+
}
|
|
1644
|
+
/>
|
|
1349
1645
|
</>
|
|
1350
1646
|
)}
|
|
1351
|
-
{
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
{(
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
<CheckBox value={config.visual?.
|
|
1361
|
-
<CheckBox value={config.visual?.
|
|
1362
|
-
<CheckBox value={config.visual?.
|
|
1363
|
-
<CheckBox value={config.visual?.background} section="visual" fieldName="background" label="Use Theme Background Color" updateField={updateField} />
|
|
1364
|
-
<CheckBox value={config.visual?.hideBackgroundColor} section="visual" fieldName="hideBackgroundColor" label="Hide Background Color" updateField={updateField} />
|
|
1647
|
+
{config.orientation === 'horizontal' && config.yAxis.labelPlacement !== 'On Bar' && <TextField type='number' value={config.barHeight || '25'} fieldName='barHeight' label='Bar Thickness' updateField={updateField} min='15' />}
|
|
1648
|
+
{((config.visualizationType === 'Bar' && config.orientation !== 'horizontal') || config.visualizationType === 'Combo') && <TextField value={config.barThickness} type='number' fieldName='barThickness' label='Bar Thickness' updateField={updateField} />}
|
|
1649
|
+
|
|
1650
|
+
{(config.visualizationType === 'Bar' || config.visualizationType === 'Line' || config.visualizationType === 'Combo') && <CheckBox value={config.topAxis.hasLine} section='topAxis' fieldName='hasLine' label='Add Top Axis Line' updateField={updateField} />}
|
|
1651
|
+
|
|
1652
|
+
{config.visualizationType === 'Spark Line' && (
|
|
1653
|
+
<div className='cove-accordion__panel-section checkbox-group'>
|
|
1654
|
+
<CheckBox value={config.visual?.border} section='visual' fieldName='border' label='Display Border' updateField={updateField} />
|
|
1655
|
+
<CheckBox value={config.visual?.borderColorTheme} section='visual' fieldName='borderColorTheme' label='Use Border Color Theme' updateField={updateField} />
|
|
1656
|
+
<CheckBox value={config.visual?.accent} section='visual' fieldName='accent' label='Use Accent Style' updateField={updateField} />
|
|
1657
|
+
<CheckBox value={config.visual?.background} section='visual' fieldName='background' label='Use Theme Background Color' updateField={updateField} />
|
|
1658
|
+
<CheckBox value={config.visual?.hideBackgroundColor} section='visual' fieldName='hideBackgroundColor' label='Hide Background Color' updateField={updateField} />
|
|
1365
1659
|
</div>
|
|
1366
|
-
}
|
|
1660
|
+
)}
|
|
1367
1661
|
</AccordionItemPanel>
|
|
1368
1662
|
</AccordionItem>
|
|
1369
1663
|
|
|
1370
1664
|
<AccordionItem>
|
|
1371
1665
|
<AccordionItemHeading>
|
|
1372
|
-
<AccordionItemButton>
|
|
1373
|
-
Data Table
|
|
1374
|
-
</AccordionItemButton>
|
|
1666
|
+
<AccordionItemButton>Data Table</AccordionItemButton>
|
|
1375
1667
|
</AccordionItemHeading>
|
|
1376
1668
|
<AccordionItemPanel>
|
|
1377
|
-
<CheckBox
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1669
|
+
<CheckBox
|
|
1670
|
+
value={config.table.show}
|
|
1671
|
+
section='table'
|
|
1672
|
+
fieldName='show'
|
|
1673
|
+
label='Show Table'
|
|
1674
|
+
updateField={updateField}
|
|
1675
|
+
tooltip={
|
|
1676
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1677
|
+
<Tooltip.Target>
|
|
1678
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1679
|
+
</Tooltip.Target>
|
|
1680
|
+
<Tooltip.Content>
|
|
1681
|
+
<p>Hiding the data table may affect accessibility. An alternate form of accessing visualization data is a 508 requirement.</p>
|
|
1682
|
+
</Tooltip.Content>
|
|
1683
|
+
</Tooltip>
|
|
1684
|
+
}
|
|
1685
|
+
/>
|
|
1686
|
+
<TextField
|
|
1687
|
+
value={config.table.caption}
|
|
1688
|
+
updateField={updateField}
|
|
1689
|
+
section='table'
|
|
1690
|
+
type='textarea'
|
|
1691
|
+
fieldName='caption'
|
|
1692
|
+
label='Data Table Caption'
|
|
1693
|
+
placeholder=' Data table'
|
|
1694
|
+
tooltip={
|
|
1695
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1696
|
+
<Tooltip.Target>
|
|
1697
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1698
|
+
</Tooltip.Target>
|
|
1699
|
+
<Tooltip.Content>
|
|
1700
|
+
<p>Enter a description of the data table to be read by screen readers.</p>
|
|
1701
|
+
</Tooltip.Content>
|
|
1702
|
+
</Tooltip>
|
|
1703
|
+
}
|
|
1704
|
+
/>
|
|
1705
|
+
<CheckBox value={config.table.limitHeight} section='table' fieldName='limitHeight' label='Limit Table Height' updateField={updateField} />
|
|
1706
|
+
{config.table.limitHeight && <TextField value={config.table.height} section='table' fieldName='height' label='Data Table Height' type='number' min='0' max='500' placeholder='Height(px)' updateField={updateField} />}
|
|
1707
|
+
<CheckBox value={config.table.expanded} section='table' fieldName='expanded' label='Expanded by Default' updateField={updateField} />
|
|
1708
|
+
<CheckBox value={config.table.download} section='table' fieldName='download' label='Display Download Button' updateField={updateField} />
|
|
1709
|
+
<TextField value={config.table.label} section='table' fieldName='label' label='Label' updateField={updateField} />
|
|
1710
|
+
{config.visualizationType !== 'Pie' && <TextField value={config.table.indexLabel} section='table' fieldName='indexLabel' label='Index Column Header' updateField={updateField} />}
|
|
1410
1711
|
</AccordionItemPanel>
|
|
1411
1712
|
</AccordionItem>
|
|
1412
1713
|
</Accordion>
|
|
1413
1714
|
</form>
|
|
1414
|
-
{config.type !== 'Spark Line' &&
|
|
1415
|
-
<AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />
|
|
1416
|
-
}
|
|
1715
|
+
{config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} state={config} convertStateToConfig={convertStateToConfig} />}
|
|
1417
1716
|
</section>
|
|
1418
1717
|
</section>
|
|
1419
1718
|
</ErrorBoundary>
|