@cdc/chart 4.24.5 → 4.24.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdcchart.js +39128 -35959
- package/examples/feature/annotations/index.json +542 -0
- package/examples/xaxis.json +493 -0
- package/index.html +5 -4
- package/package.json +5 -4
- package/src/CdcChart.tsx +104 -64
- package/src/_stories/Chart.stories.tsx +18 -171
- package/src/_stories/ChartAnnotation.stories.tsx +32 -0
- package/src/_stories/_mock/annotation_category_mock.json +473 -0
- package/src/_stories/_mock/annotation_date-linear_mock.json +530 -0
- package/src/_stories/_mock/annotation_date-time_mock.json +530 -0
- package/src/_stories/_mock/line_chart_two_points_new_chart.json +128 -0
- package/src/_stories/_mock/line_chart_two_points_regression_test.json +127 -0
- package/src/_stories/_mock/lollipop.json +171 -0
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +31 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +154 -0
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +14 -0
- package/src/components/Annotations/components/AnnotationDropdown.tsx +72 -0
- package/src/components/Annotations/components/AnnotationList.styles.css +45 -0
- package/src/components/Annotations/components/AnnotationList.tsx +42 -0
- package/src/components/Annotations/components/findNearestDatum.ts +138 -0
- package/src/components/Annotations/components/helpers/index.tsx +46 -0
- package/src/components/Annotations/index.tsx +13 -0
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +1 -1
- package/src/components/AreaChart/components/AreaChart.jsx +1 -1
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +44 -42
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +1 -2
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +11 -11
- package/src/components/BarChart/components/BarChart.Vertical.tsx +50 -22
- package/src/components/BarChart/helpers/index.ts +102 -0
- package/src/components/EditorPanel/EditorPanel.tsx +232 -98
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +306 -0
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +117 -6
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +2 -3
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +3 -2
- package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
- package/src/components/EditorPanel/components/panels.scss +4 -0
- package/src/components/EditorPanel/editor-panel.scss +19 -0
- package/src/components/EditorPanel/useEditorPermissions.js +19 -2
- package/src/components/Legend/Legend.Component.tsx +7 -8
- package/src/components/Legend/helpers/createFormatLabels.tsx +1 -1
- package/src/components/Legend/helpers/index.ts +5 -0
- package/src/components/LineChart/LineChartProps.ts +3 -0
- package/src/components/LineChart/helpers.ts +21 -7
- package/src/components/LineChart/index.tsx +7 -7
- package/src/components/LinearChart.jsx +179 -136
- package/src/components/PairedBarChart.jsx +9 -9
- package/src/components/PieChart/PieChart.tsx +4 -4
- package/src/components/Sankey/index.tsx +73 -20
- package/src/components/ScatterPlot/ScatterPlot.jsx +22 -8
- package/src/components/ZoomBrush.tsx +90 -44
- package/src/data/initial-state.js +14 -6
- package/src/helpers/handleChartTabbing.ts +8 -0
- package/src/helpers/isConvertLineToBarGraph.ts +4 -0
- package/src/hooks/{useBarChart.js → useBarChart.ts} +2 -40
- package/src/hooks/useColorScale.ts +1 -1
- package/src/hooks/useMinMax.ts +8 -3
- package/src/hooks/useScales.ts +25 -3
- package/src/hooks/useTooltip.tsx +58 -11
- package/src/scss/main.scss +21 -14
- package/src/types/ChartConfig.ts +50 -3
- package/src/types/ChartContext.ts +9 -0
- package/tests-examples/helpers/testZeroValue.test.ts +30 -0
- package/LICENSE +0 -201
- package/src/helpers/filterData.ts +0 -18
- package/src/helpers/tests/computeMarginBottom.test.ts +0 -21
- /package/src/hooks/{useLegendClasses.js → useLegendClasses.ts} +0 -0
- /package/src/hooks/{useReduceData.js → useReduceData.ts} +0 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Define an interface for the function's parameter
|
|
2
|
+
interface BarConfigProps {
|
|
3
|
+
defaultBarWidth?: number
|
|
4
|
+
defaultBarHeight?: number
|
|
5
|
+
bar?: { [key: string]: any }
|
|
6
|
+
isNumber?: Function
|
|
7
|
+
config: { [key: string]: any }
|
|
8
|
+
getTextWidth: Function
|
|
9
|
+
barWidth: number
|
|
10
|
+
isVertical: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Function to create bar width based on suppression status and missing data label
|
|
14
|
+
export const getBarConfig = ({ bar, defaultBarHeight, defaultBarWidth, config, isNumber, getTextWidth, barWidth, isVertical }: BarConfigProps) => {
|
|
15
|
+
const heightMini = 3 /// height of small bars aka suppressed/NA/Zero valued
|
|
16
|
+
let barHeight = defaultBarHeight
|
|
17
|
+
|
|
18
|
+
let barWidthHorizontal = defaultBarWidth
|
|
19
|
+
|
|
20
|
+
let barLabel = ''
|
|
21
|
+
let isSuppressed = false
|
|
22
|
+
let showMissingDataLabel = false
|
|
23
|
+
let showZeroValueDataLabel = false
|
|
24
|
+
const showSuppressedSymbol = config.general.showSuppressedSymbol
|
|
25
|
+
|
|
26
|
+
config.preliminaryData.forEach(pd => {
|
|
27
|
+
const hasColumn = !pd.column || pd.column === bar.key
|
|
28
|
+
if (hasColumn && pd.type === 'suppression' && pd.value && String(pd.value) === String(bar.value)) {
|
|
29
|
+
if (!pd.hideBarSymbol && showSuppressedSymbol) {
|
|
30
|
+
barHeight = barWidth > 10 ? heightMini : 0
|
|
31
|
+
barWidthHorizontal = heightMini
|
|
32
|
+
isSuppressed = true
|
|
33
|
+
} else {
|
|
34
|
+
barHeight = 0
|
|
35
|
+
barWidthHorizontal = 0
|
|
36
|
+
isSuppressed = true
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Handle undefined, null, or non-calculable bar.value
|
|
42
|
+
if (!isSuppressed && !isNumber(bar.value) && config.general.showMissingDataLabel) {
|
|
43
|
+
const labelWidth = getTextWidth(barLabel, `normal ${barWidth / 2}px sans-serif`)
|
|
44
|
+
const labelFits = labelWidth < barWidth && barWidth > 10
|
|
45
|
+
showMissingDataLabel = true
|
|
46
|
+
barHeight = labelFits ? heightMini : 0
|
|
47
|
+
barWidthHorizontal = heightMini
|
|
48
|
+
}
|
|
49
|
+
// handle zero values
|
|
50
|
+
if (!isSuppressed && String(bar.value) === '0' && config.general.showZeroValueDataLabel) {
|
|
51
|
+
const labelWidth = getTextWidth(barLabel, `normal ${barWidth / 2}px sans-serif`)
|
|
52
|
+
const labelFits = labelWidth < barWidth && barWidth > 10
|
|
53
|
+
barHeight = config.isLollipopChart ? heightMini * 2 : !config.isLollipopChart && labelFits ? heightMini : 0
|
|
54
|
+
barWidthHorizontal = heightMini
|
|
55
|
+
showZeroValueDataLabel = true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const getBarY = (defaultBarY, yScale) => {
|
|
59
|
+
// calculate Y position of small bars (suppressed,N/A,Zero valued) bars
|
|
60
|
+
if (isSuppressed || showMissingDataLabel || showZeroValueDataLabel) {
|
|
61
|
+
if (config.isLollipopChart) {
|
|
62
|
+
return yScale - heightMini * 2
|
|
63
|
+
} else {
|
|
64
|
+
return yScale - heightMini
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return defaultBarY
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Function to determine the label for a bar in a bar chart vertical/Horizontal
|
|
71
|
+
const getAbsentDataLabel = yAxisValue => {
|
|
72
|
+
// Initialize label with the yAxisValue
|
|
73
|
+
let label = ''
|
|
74
|
+
// Check if the label is exactly '0' and if so, hide it
|
|
75
|
+
if (String(yAxisValue) === '0') label = ''
|
|
76
|
+
// Check if the bar is marked as suppressed. If so, do not show any label.
|
|
77
|
+
if (isSuppressed) label = ''
|
|
78
|
+
// If the config is set to show a label for missing data, display 'N/A'
|
|
79
|
+
if (showMissingDataLabel) label = 'N/A'
|
|
80
|
+
// If the config is set to specifically show zero values, set the label to '0'
|
|
81
|
+
if (showZeroValueDataLabel) label = '0'
|
|
82
|
+
|
|
83
|
+
// determine label width in pixels & check if it fits to the bar width
|
|
84
|
+
const labelWidth = getTextWidth(barLabel, `normal ${barWidth / 2}px sans-serif`)
|
|
85
|
+
const labelFits = labelWidth < barWidth && barWidth > 10
|
|
86
|
+
if (config.isLollipopChart) {
|
|
87
|
+
return label
|
|
88
|
+
} else {
|
|
89
|
+
return labelFits && isVertical ? label : !isVertical ? label : ''
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return { barWidthHorizontal, barHeight, isSuppressed, showMissingDataLabel, showZeroValueDataLabel, getBarY, getAbsentDataLabel }
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const testZeroValue = value => {
|
|
97
|
+
if (value === undefined || value === null) {
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
const regex = /^0(\.0)?$/
|
|
101
|
+
return regex.test(value.toString())
|
|
102
|
+
}
|
|
@@ -13,6 +13,7 @@ import DataTableEditor from '@cdc/core/components/EditorPanel/DataTableEditor'
|
|
|
13
13
|
import VizFilterEditor from '@cdc/core/components/EditorPanel/VizFilterEditor'
|
|
14
14
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
15
15
|
import { Select, TextField, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
16
|
+
import { viewports } from '@cdc/core/helpers/getViewport'
|
|
16
17
|
|
|
17
18
|
// chart components
|
|
18
19
|
import Panels from './components/Panels'
|
|
@@ -60,17 +61,16 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
60
61
|
'Dashed Small': '\u002D \u002D \u002D',
|
|
61
62
|
'Dashed Medium': '\u2013 \u2013',
|
|
62
63
|
'Dashed Large': '\u2014 \u2013',
|
|
63
|
-
'Open Circles': '\u25EF'
|
|
64
|
+
'Open Circles': '\u25EF',
|
|
65
|
+
'Filled Circles': ''
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
const getStyleOptions = type => {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return options
|
|
73
|
-
}
|
|
69
|
+
const options = Object.keys(lineCodes)
|
|
70
|
+
if (type === 'suppression') {
|
|
71
|
+
return options.slice(0, -1)
|
|
72
|
+
} else {
|
|
73
|
+
return options
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -107,7 +107,10 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
107
107
|
displayTable: true,
|
|
108
108
|
symbol: '',
|
|
109
109
|
iconCode: '',
|
|
110
|
-
lineCode: ''
|
|
110
|
+
lineCode: '',
|
|
111
|
+
hideBarSymbol: false,
|
|
112
|
+
hideLineStyle: false,
|
|
113
|
+
circleSize: 6
|
|
111
114
|
}
|
|
112
115
|
preliminaryData.push(defaultValues)
|
|
113
116
|
updateConfig({ ...config, preliminaryData })
|
|
@@ -133,7 +136,7 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
133
136
|
return (
|
|
134
137
|
<>
|
|
135
138
|
{config.preliminaryData &&
|
|
136
|
-
config.preliminaryData?.map(({ column, displayLegend, displayTable, displayTooltip, label, seriesKey, style, symbol, type, value }, i) => {
|
|
139
|
+
config.preliminaryData?.map(({ circleSize, column, displayLegend, displayTable, displayTooltip, label, seriesKey, style, symbol, type, value, hideBarSymbol, hideLineStyle }, i) => {
|
|
137
140
|
return (
|
|
138
141
|
<div key={`preliminaryData-${i}`} className='edit-block'>
|
|
139
142
|
<p> {type === 'suppression' ? 'Suppressed' : 'Effect'} Data</p>
|
|
@@ -158,7 +161,7 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
158
161
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
159
162
|
</Tooltip.Target>
|
|
160
163
|
<Tooltip.Content>
|
|
161
|
-
<p>If no “Data Series" is selected, the symbol will be applied to "all" suppressed values indicated in the dataset.</p>
|
|
164
|
+
<p> If no “Data Series" is selected, the symbol will be applied to "all" suppressed values indicated in the dataset. If you select a particular data series, there's no need to fill in “suppression line style” and “suppression symbol” below.</p>
|
|
162
165
|
</Tooltip.Content>
|
|
163
166
|
</Tooltip>
|
|
164
167
|
}
|
|
@@ -171,45 +174,51 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
171
174
|
/>
|
|
172
175
|
<TextField value={value} fieldName='value' label='Suppressed Data Value' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} />
|
|
173
176
|
{(hasComboLineSeries || config.visualizationType === 'Line') && (
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<Tooltip
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
<
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
177
|
+
<>
|
|
178
|
+
<Select
|
|
179
|
+
tooltip={
|
|
180
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
181
|
+
<Tooltip.Target>
|
|
182
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
183
|
+
</Tooltip.Target>
|
|
184
|
+
<Tooltip.Content>
|
|
185
|
+
<p>The recommended approach for presenting data is to include a footnote indicating any data suppression.</p>
|
|
186
|
+
</Tooltip.Content>
|
|
187
|
+
</Tooltip>
|
|
188
|
+
}
|
|
189
|
+
value={style}
|
|
190
|
+
initial='Select'
|
|
191
|
+
fieldName='style'
|
|
192
|
+
label={'suppression line style'}
|
|
193
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
194
|
+
options={getStyleOptions(type)}
|
|
195
|
+
/>
|
|
196
|
+
<CheckBox value={hideLineStyle} fieldName='hideLineStyle' label='Hide Suppressed line Style' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} />
|
|
197
|
+
</>
|
|
192
198
|
)}
|
|
193
199
|
|
|
194
200
|
{(hasComboBarSeries || config.visualizationType === 'Bar') && (
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
<Tooltip
|
|
199
|
-
<
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
<
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
201
|
+
<>
|
|
202
|
+
<Select
|
|
203
|
+
tooltip={
|
|
204
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
205
|
+
<Tooltip.Target>
|
|
206
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
207
|
+
</Tooltip.Target>
|
|
208
|
+
<Tooltip.Content>
|
|
209
|
+
<p>The suggested method for presenting suppressed data is to use "double asterisks". If "double asterisks" are already used elsewhere (e.g., footnotes), please select an alternative symbol from the menu to denote data suppression.</p>
|
|
210
|
+
</Tooltip.Content>
|
|
211
|
+
</Tooltip>
|
|
212
|
+
}
|
|
213
|
+
value={symbol}
|
|
214
|
+
initial='Select'
|
|
215
|
+
fieldName='symbol'
|
|
216
|
+
label={config.visualizationType === 'Combo' ? 'suppression bar symbol' : 'suppression symbol'}
|
|
217
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
218
|
+
options={getSymbolOptions()}
|
|
219
|
+
/>
|
|
220
|
+
<CheckBox value={hideBarSymbol} fieldName='hideBarSymbol' label='Hide Suppressed Bar Symbol ' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} />
|
|
221
|
+
</>
|
|
213
222
|
)}
|
|
214
223
|
|
|
215
224
|
<TextField
|
|
@@ -282,9 +291,25 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
282
291
|
<>
|
|
283
292
|
<Select value={seriesKey} initial='Select' fieldName='seriesKey' label='ASSOCIATE TO SERIES' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} options={config.runtime.lineSeriesKeys ?? config.runtime?.seriesKeys} />
|
|
284
293
|
<Select value={column} initial='Select' fieldName='column' label='COLUMN WITH CONFIGURATION VALUE' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} options={getColumnOptions()} />
|
|
285
|
-
<TextField
|
|
294
|
+
<TextField
|
|
295
|
+
tooltip={
|
|
296
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
297
|
+
<Tooltip.Target>
|
|
298
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
299
|
+
</Tooltip.Target>
|
|
300
|
+
<Tooltip.Content>
|
|
301
|
+
<p>If 'Filled Circles' is selected as the style, this field is optional, and the style 'Filled Circles' will apply to all points within the associated series data.</p>
|
|
302
|
+
</Tooltip.Content>
|
|
303
|
+
</Tooltip>
|
|
304
|
+
}
|
|
305
|
+
value={value}
|
|
306
|
+
fieldName='value'
|
|
307
|
+
label='VALUE TO TRIGGER'
|
|
308
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
309
|
+
/>
|
|
286
310
|
<Select value={style} initial='Select' fieldName='style' label='Style' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} options={getStyleOptions(type)} />
|
|
287
|
-
<TextField value={
|
|
311
|
+
{style.includes('Circles') && <TextField className='number-narrow' type='number' value={circleSize} fieldName='circleSize' label='circle size' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} />}
|
|
312
|
+
{style !== 'Filled Circles' && <TextField value={label} fieldName='label' label='Label' placeholder='' updateField={(_, __, fieldName, value) => update(fieldName, value, i)} />}
|
|
288
313
|
</>
|
|
289
314
|
)}
|
|
290
315
|
</div>
|
|
@@ -318,7 +343,8 @@ const EditorPanel = () => {
|
|
|
318
343
|
lineOptions,
|
|
319
344
|
rawData,
|
|
320
345
|
highlight,
|
|
321
|
-
highlightReset
|
|
346
|
+
highlightReset,
|
|
347
|
+
dimensions
|
|
322
348
|
} = useContext<ChartContext>(ConfigContext)
|
|
323
349
|
|
|
324
350
|
const { minValue, maxValue, existPositiveValue, isAllLine } = useReduceData(config, unfilteredData)
|
|
@@ -448,6 +474,12 @@ const EditorPanel = () => {
|
|
|
448
474
|
if (isDateScale(updatedConfig.xAxis) && !updatedConfig.xAxis.padding) {
|
|
449
475
|
updatedConfig.xAxis.padding = 6
|
|
450
476
|
}
|
|
477
|
+
// DEV-8008 - Remove Bar styling when Line is converted to Bar
|
|
478
|
+
if (updatedConfig.visualizationType === 'Line') {
|
|
479
|
+
updatedConfig.visualizationSubType = 'regular'
|
|
480
|
+
updatedConfig.barStyle = 'flat'
|
|
481
|
+
updatedConfig.isLollipopChart = false
|
|
482
|
+
}
|
|
451
483
|
}
|
|
452
484
|
|
|
453
485
|
const updateField = (section, subsection, fieldName, newValue) => {
|
|
@@ -531,6 +563,7 @@ const EditorPanel = () => {
|
|
|
531
563
|
}
|
|
532
564
|
|
|
533
565
|
const [displayPanel, setDisplayPanel] = useState(true)
|
|
566
|
+
const [displayViewportOverrides, setDisplayViewportOverrides] = useState(false)
|
|
534
567
|
|
|
535
568
|
if (loading) {
|
|
536
569
|
return null
|
|
@@ -1021,6 +1054,14 @@ const EditorPanel = () => {
|
|
|
1021
1054
|
updateConfig(updatedConfig)
|
|
1022
1055
|
}
|
|
1023
1056
|
|
|
1057
|
+
const updateViewportOverrides = (property, viewport, numTicks) => {
|
|
1058
|
+
const propertyObject = { ...config.xAxis[property] }
|
|
1059
|
+
propertyObject[viewport] = numTicks
|
|
1060
|
+
const updatedConfig = { ...config, xAxis: { ...config.xAxis, [property]: propertyObject } }
|
|
1061
|
+
|
|
1062
|
+
updateConfig(updatedConfig)
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1024
1065
|
const editorContextValues = {
|
|
1025
1066
|
addNewExclusion,
|
|
1026
1067
|
data,
|
|
@@ -1157,7 +1198,26 @@ const EditorPanel = () => {
|
|
|
1157
1198
|
{config.runtime.seriesKeys && config.runtime.seriesKeys.length === 1 && !['Box Plot', 'Deviation Bar', 'Forest Plot'].includes(config.visualizationType) && (
|
|
1158
1199
|
<CheckBox value={config.isLegendValue} fieldName='isLegendValue' label='Use Legend Value in Hover' updateField={updateField} />
|
|
1159
1200
|
)}
|
|
1160
|
-
<TextField
|
|
1201
|
+
<TextField
|
|
1202
|
+
value={config.yAxis.numTicks}
|
|
1203
|
+
placeholder='Auto'
|
|
1204
|
+
type='number'
|
|
1205
|
+
section='yAxis'
|
|
1206
|
+
fieldName='numTicks'
|
|
1207
|
+
label='Number of ticks'
|
|
1208
|
+
className='number-narrow'
|
|
1209
|
+
tooltip={
|
|
1210
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1211
|
+
<Tooltip.Target>
|
|
1212
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
1213
|
+
</Tooltip.Target>
|
|
1214
|
+
<Tooltip.Content>
|
|
1215
|
+
<p>Apporoximate number of ticks. Other factors such as space available and data may change the exact number of ticks used.</p>
|
|
1216
|
+
</Tooltip.Content>
|
|
1217
|
+
</Tooltip>
|
|
1218
|
+
}
|
|
1219
|
+
updateField={updateField}
|
|
1220
|
+
/>
|
|
1161
1221
|
<TextField
|
|
1162
1222
|
value={config.yAxis.size}
|
|
1163
1223
|
type='number'
|
|
@@ -1177,6 +1237,7 @@ const EditorPanel = () => {
|
|
|
1177
1237
|
</Tooltip>
|
|
1178
1238
|
}
|
|
1179
1239
|
/>
|
|
1240
|
+
<TextField value={config.yAxis.labelOffset} section='yAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />
|
|
1180
1241
|
{config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && <CheckBox value={config.isResponsiveTicks} fieldName='isResponsiveTicks' label='Use Responsive Ticks' updateField={updateField} />}
|
|
1181
1242
|
{(config.orientation === 'vertical' || !config.isResponsiveTicks) && <TextField value={config.yAxis.tickRotation || 0} type='number' min={0} section='yAxis' fieldName='tickRotation' label='Tick rotation (Degrees)' className='number-narrow' updateField={updateField} />}
|
|
1182
1243
|
{config.isResponsiveTicks && config.orientation === 'horizontal' && config.visualizationType !== 'Paired Bar' && (
|
|
@@ -1204,7 +1265,6 @@ const EditorPanel = () => {
|
|
|
1204
1265
|
|
|
1205
1266
|
{/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
|
|
1206
1267
|
{/* <TextField value={config.yAxis.axisPadding} type='number' max={10} min={0} section='yAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
|
|
1207
|
-
{config.orientation === 'horizontal' && <TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />}
|
|
1208
1268
|
{visSupportsValueAxisGridLines() && <CheckBox value={config.yAxis.gridLines} section='yAxis' fieldName='gridLines' label='Show Gridlines' updateField={updateField} />}
|
|
1209
1269
|
<CheckBox value={config.yAxis.enablePadding} section='yAxis' fieldName='enablePadding' label='Add Padding to Value Axis Scale' updateField={updateField} />
|
|
1210
1270
|
{config.yAxis.enablePadding && <TextField type='number' section='yAxis' fieldName='scalePadding' label='Padding Percentage' className='number-narrow' updateField={updateField} value={config.yAxis.scalePadding} />}
|
|
@@ -1289,7 +1349,7 @@ const EditorPanel = () => {
|
|
|
1289
1349
|
{config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
|
|
1290
1350
|
<>
|
|
1291
1351
|
{visSupportsValueAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
|
|
1292
|
-
{visSupportsValueAxisLabels() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide
|
|
1352
|
+
{visSupportsValueAxisLabels() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Tick Labels' updateField={updateField} />}
|
|
1293
1353
|
{visSupportsValueAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
|
|
1294
1354
|
{visSupportsValueAxisMax() && <TextField value={config.xAxis.max} section='xAxis' fieldName='max' label='max value' type='number' placeholder='Auto' updateField={updateField} />}
|
|
1295
1355
|
<span style={{ color: 'red', display: 'block' }}>{warningMsg.maxMsg}</span>
|
|
@@ -1307,7 +1367,7 @@ const EditorPanel = () => {
|
|
|
1307
1367
|
config.visualizationType !== 'Pie' && (
|
|
1308
1368
|
<>
|
|
1309
1369
|
<CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />
|
|
1310
|
-
<CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide
|
|
1370
|
+
<CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Tick Labels' updateField={updateField} />
|
|
1311
1371
|
<CheckBox value={config.yAxis.hideTicks} section='yAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1312
1372
|
|
|
1313
1373
|
<TextField value={config.yAxis.max} section='yAxis' fieldName='max' type='number' label='left axis max value' placeholder='Auto' updateField={updateField} />
|
|
@@ -1629,7 +1689,7 @@ const EditorPanel = () => {
|
|
|
1629
1689
|
</div>
|
|
1630
1690
|
|
|
1631
1691
|
<CheckBox value={config.yAxis.rightHideAxis} section='yAxis' fieldName='rightHideAxis' label='Hide Axis' updateField={updateField} />
|
|
1632
|
-
<CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide
|
|
1692
|
+
<CheckBox value={config.yAxis.rightHideLabel} section='yAxis' fieldName='rightHideLabel' label='Hide Tick Labels' updateField={updateField} />
|
|
1633
1693
|
<CheckBox value={config.yAxis.rightHideTicks} section='yAxis' fieldName='rightHideTicks' label='Hide Ticks' updateField={updateField} />
|
|
1634
1694
|
|
|
1635
1695
|
<TextField value={config.yAxis.max} section='yAxis' fieldName='rightMax' type='number' label='right axis max value' placeholder='Auto' updateField={updateField} />
|
|
@@ -1916,7 +1976,25 @@ const EditorPanel = () => {
|
|
|
1916
1976
|
}
|
|
1917
1977
|
updateField={updateField}
|
|
1918
1978
|
/>
|
|
1919
|
-
{
|
|
1979
|
+
{false && visHasBrushChart && (
|
|
1980
|
+
<CheckBox
|
|
1981
|
+
value={config.brush?.active}
|
|
1982
|
+
section='brush'
|
|
1983
|
+
fieldName='active'
|
|
1984
|
+
label='Brush Slider '
|
|
1985
|
+
updateField={updateField}
|
|
1986
|
+
tooltip={
|
|
1987
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
1988
|
+
<Tooltip.Target>
|
|
1989
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
1990
|
+
</Tooltip.Target>
|
|
1991
|
+
<Tooltip.Content>
|
|
1992
|
+
<p>Use the brush slider to narrow down your data view to specific values along the axis. This tool is useful for examining detailed data segments within the larger dataset. </p>
|
|
1993
|
+
</Tooltip.Content>
|
|
1994
|
+
</Tooltip>
|
|
1995
|
+
}
|
|
1996
|
+
/>
|
|
1997
|
+
)}
|
|
1920
1998
|
|
|
1921
1999
|
{config.exclusions.active && (
|
|
1922
2000
|
<>
|
|
@@ -1956,12 +2034,101 @@ const EditorPanel = () => {
|
|
|
1956
2034
|
)}
|
|
1957
2035
|
|
|
1958
2036
|
{visSupportsDateCategoryNumTicks() && config.xAxis.type !== 'date-time' && config.xAxis.manual && (
|
|
1959
|
-
|
|
2037
|
+
<>
|
|
2038
|
+
<TextField
|
|
2039
|
+
value={config.xAxis.manualStep}
|
|
2040
|
+
placeholder='Auto'
|
|
2041
|
+
type='number'
|
|
2042
|
+
min={1}
|
|
2043
|
+
section='xAxis'
|
|
2044
|
+
fieldName='manualStep'
|
|
2045
|
+
label='Step count'
|
|
2046
|
+
className='number-narrow'
|
|
2047
|
+
updateField={updateField}
|
|
2048
|
+
tooltip={
|
|
2049
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2050
|
+
<Tooltip.Target>
|
|
2051
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2052
|
+
</Tooltip.Target>
|
|
2053
|
+
<Tooltip.Content>
|
|
2054
|
+
<p>Number of data points which are assigned a tick, starting from the right most data point. Value of 1 will show a tick at every data point, value of 2 will show a tick for every other, etc.</p>
|
|
2055
|
+
</Tooltip.Content>
|
|
2056
|
+
</Tooltip>
|
|
2057
|
+
}
|
|
2058
|
+
/>
|
|
2059
|
+
<div className='viewport-overrides'>
|
|
2060
|
+
<label>
|
|
2061
|
+
<button onClick={() => setDisplayViewportOverrides(!displayViewportOverrides)} className='edit-label'>
|
|
2062
|
+
Step Count: viewport overrides <span style={{ transform: `rotate(${displayViewportOverrides ? '90deg' : '0deg'})` }}>></span>
|
|
2063
|
+
</button>
|
|
2064
|
+
</label>
|
|
2065
|
+
{displayViewportOverrides && (
|
|
2066
|
+
<div className='edit-block'>
|
|
2067
|
+
{Object.keys(viewports).map(viewport => (
|
|
2068
|
+
<TextField
|
|
2069
|
+
key={`viewport-step-count-input-${viewport}`}
|
|
2070
|
+
value={config.xAxis.viewportStepCount ? config.xAxis.viewportStepCount[viewport] : undefined}
|
|
2071
|
+
placeholder='Auto'
|
|
2072
|
+
type='number'
|
|
2073
|
+
label={viewport}
|
|
2074
|
+
className='number-narrow'
|
|
2075
|
+
updateField={(section, fieldName, label, val) => updateViewportOverrides('viewportStepCount', viewport, val)}
|
|
2076
|
+
/>
|
|
2077
|
+
))}
|
|
2078
|
+
</div>
|
|
2079
|
+
)}
|
|
2080
|
+
</div>
|
|
2081
|
+
</>
|
|
1960
2082
|
)}
|
|
1961
2083
|
{visSupportsDateCategoryNumTicks() && (config.xAxis.type === 'date-time' || !config.xAxis.manual) && (
|
|
1962
|
-
|
|
2084
|
+
<>
|
|
2085
|
+
<TextField
|
|
2086
|
+
value={config.xAxis.numTicks}
|
|
2087
|
+
placeholder='Auto'
|
|
2088
|
+
type='number'
|
|
2089
|
+
min={1}
|
|
2090
|
+
section='xAxis'
|
|
2091
|
+
fieldName='numTicks'
|
|
2092
|
+
label='Number of ticks'
|
|
2093
|
+
className='number-narrow'
|
|
2094
|
+
updateField={updateField}
|
|
2095
|
+
tooltip={
|
|
2096
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2097
|
+
<Tooltip.Target>
|
|
2098
|
+
<Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
|
|
2099
|
+
</Tooltip.Target>
|
|
2100
|
+
<Tooltip.Content>
|
|
2101
|
+
<p>Apporoximate number of ticks. Other factors such as space available and data may change the exact number of ticks used. To enforce an exact number of ticks, check "Manual Ticks" above.</p>
|
|
2102
|
+
</Tooltip.Content>
|
|
2103
|
+
</Tooltip>
|
|
2104
|
+
}
|
|
2105
|
+
/>
|
|
2106
|
+
<div className='viewport-overrides'>
|
|
2107
|
+
<label>
|
|
2108
|
+
<button onClick={() => setDisplayViewportOverrides(!displayViewportOverrides)} className='edit-label'>
|
|
2109
|
+
Number of ticks: viewport overrides <span style={{ transform: `rotate(${displayViewportOverrides ? '90deg' : '0deg'})` }}>></span>
|
|
2110
|
+
</button>
|
|
2111
|
+
</label>
|
|
2112
|
+
{displayViewportOverrides && (
|
|
2113
|
+
<div className='edit-block'>
|
|
2114
|
+
{Object.keys(viewports).map(viewport => (
|
|
2115
|
+
<TextField
|
|
2116
|
+
key={`viewport-num-ticks-input-${viewport}`}
|
|
2117
|
+
value={config.xAxis.viewportNumTicks ? config.xAxis.viewportNumTicks[viewport] : undefined}
|
|
2118
|
+
placeholder='Auto'
|
|
2119
|
+
type='number'
|
|
2120
|
+
label={viewport}
|
|
2121
|
+
className='number-narrow'
|
|
2122
|
+
updateField={(section, fieldName, label, val) => updateViewportOverrides('viewportNumTicks', viewport, val)}
|
|
2123
|
+
/>
|
|
2124
|
+
))}
|
|
2125
|
+
</div>
|
|
2126
|
+
)}
|
|
2127
|
+
</div>
|
|
2128
|
+
</>
|
|
1963
2129
|
)}
|
|
1964
|
-
{visSupportsDateCategoryHeight() && <TextField value={config.xAxis.
|
|
2130
|
+
{visSupportsDateCategoryHeight() && <TextField value={config.xAxis.size} type='number' min={0} section='xAxis' fieldName='size' label={config.orientation === 'horizontal' ? 'Size (Width)' : 'Size (Height)'} className='number-narrow' updateField={updateField} />}
|
|
2131
|
+
<TextField value={config.xAxis.labelOffset} section='xAxis' fieldName='labelOffset' label='Label offset' type='number' className='number-narrow' updateField={updateField} />
|
|
1965
2132
|
|
|
1966
2133
|
{/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
|
|
1967
2134
|
{/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateField} /> */}
|
|
@@ -2001,49 +2168,15 @@ const EditorPanel = () => {
|
|
|
2001
2168
|
{config.orientation === 'horizontal' ? (
|
|
2002
2169
|
<>
|
|
2003
2170
|
{visSupportsDateCategoryAxisLine() && <CheckBox value={config.yAxis.hideAxis} section='yAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
|
|
2004
|
-
{visSupportsDateCategoryAxisLabel() && <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide
|
|
2171
|
+
{visSupportsDateCategoryAxisLabel() && <CheckBox value={config.yAxis.hideLabel} section='yAxis' fieldName='hideLabel' label='Hide Tick Labels' updateField={updateField} />}
|
|
2005
2172
|
</>
|
|
2006
2173
|
) : (
|
|
2007
2174
|
<>
|
|
2008
2175
|
{visSupportsDateCategoryAxisLine() && <CheckBox value={config.xAxis.hideAxis} section='xAxis' fieldName='hideAxis' label='Hide Axis' updateField={updateField} />}
|
|
2009
|
-
{visSupportsDateCategoryAxisLabel() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide
|
|
2176
|
+
{visSupportsDateCategoryAxisLabel() && <CheckBox value={config.xAxis.hideLabel} section='xAxis' fieldName='hideLabel' label='Hide Tick Labels' updateField={updateField} />}
|
|
2010
2177
|
{visSupportsDateCategoryAxisTicks() && <CheckBox value={config.xAxis.hideTicks} section='xAxis' fieldName='hideTicks' label='Hide Ticks' updateField={updateField} />}
|
|
2011
2178
|
</>
|
|
2012
2179
|
)}
|
|
2013
|
-
<CheckBox
|
|
2014
|
-
tooltip={
|
|
2015
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2016
|
-
<Tooltip.Target>
|
|
2017
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2018
|
-
</Tooltip.Target>
|
|
2019
|
-
<Tooltip.Content>
|
|
2020
|
-
<p>Selecting this option will display a "thin line" slightly above the Date/Category Axis to indicate "suppressed data" where "suppressed data" values are indicated in the Data Series.</p>
|
|
2021
|
-
</Tooltip.Content>
|
|
2022
|
-
</Tooltip>
|
|
2023
|
-
}
|
|
2024
|
-
value={config.xAxis.showSuppressedLine}
|
|
2025
|
-
section='xAxis'
|
|
2026
|
-
fieldName='showSuppressedLine'
|
|
2027
|
-
label='Display suppressed data line'
|
|
2028
|
-
updateField={updateField}
|
|
2029
|
-
/>
|
|
2030
|
-
<CheckBox
|
|
2031
|
-
tooltip={
|
|
2032
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2033
|
-
<Tooltip.Target>
|
|
2034
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2035
|
-
</Tooltip.Target>
|
|
2036
|
-
<Tooltip.Content>
|
|
2037
|
-
<p>Selecting this option will display "suppressed data symbol" on the Date/Category Axis where suppressed data values are indicated in the Data Series, unless a different symbol was chosen from the data series (e.g., suppression symbol) menu.</p>
|
|
2038
|
-
</Tooltip.Content>
|
|
2039
|
-
</Tooltip>
|
|
2040
|
-
}
|
|
2041
|
-
value={config.xAxis.showSuppressedSymbol}
|
|
2042
|
-
section='xAxis'
|
|
2043
|
-
fieldName='showSuppressedSymbol'
|
|
2044
|
-
label='Display suppressed data symbol'
|
|
2045
|
-
updateField={updateField}
|
|
2046
|
-
/>
|
|
2047
2180
|
|
|
2048
2181
|
{config.series?.length === 1 && config.visualizationType === 'Bar' && (
|
|
2049
2182
|
<>
|
|
@@ -2392,7 +2525,7 @@ const EditorPanel = () => {
|
|
|
2392
2525
|
<Panels.Regions name='Regions' />
|
|
2393
2526
|
|
|
2394
2527
|
{/* Columns */}
|
|
2395
|
-
{config.visualizationType !== 'Box Plot' && (
|
|
2528
|
+
{config.visualizationType !== 'Box Plot' && config.visualizationType !== 'Sankey' && (
|
|
2396
2529
|
<AccordionItem>
|
|
2397
2530
|
<AccordionItemHeading>
|
|
2398
2531
|
<AccordionItemButton>Columns</AccordionItemButton>
|
|
@@ -2539,7 +2672,7 @@ const EditorPanel = () => {
|
|
|
2539
2672
|
{/* end: isolated values */}
|
|
2540
2673
|
|
|
2541
2674
|
<TextField value={config.legend.label} section='legend' fieldName='label' label='Title' updateField={updateField} />
|
|
2542
|
-
<Select value={config.legend
|
|
2675
|
+
<Select value={config.legend?.position} section='legend' fieldName='position' label='Position' updateField={updateField} options={['right', 'left', 'bottom']} />
|
|
2543
2676
|
{config.legend.position === 'bottom' && (
|
|
2544
2677
|
<>
|
|
2545
2678
|
<CheckBox value={config.legend.singleRow} section='legend' fieldName='singleRow' label='Single Row Legend' updateField={updateField} />
|
|
@@ -2572,9 +2705,10 @@ const EditorPanel = () => {
|
|
|
2572
2705
|
</AccordionItemPanel>
|
|
2573
2706
|
</AccordionItem>
|
|
2574
2707
|
)}
|
|
2708
|
+
<Panels.Annotate name='Text Annotations' />
|
|
2575
2709
|
{/* {(config.visualizationType === 'Bar' || config.visualizationType === 'Line') && <Panels.DateHighlighting name='Date Highlighting' />} */}
|
|
2576
2710
|
</Accordion>
|
|
2577
|
-
{config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig}
|
|
2711
|
+
{config.type !== 'Spark Line' && <AdvancedEditor loadConfig={updateConfig} config={config} convertStateToConfig={convertStateToConfig} />}
|
|
2578
2712
|
</Layout.Sidebar>
|
|
2579
2713
|
</ErrorBoundary>
|
|
2580
2714
|
</EditorPanelContext.Provider>
|