@cdc/chart 4.26.2 → 4.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONFIG.md +169 -0
- package/README.md +42 -17
- package/dist/cdcchart.js +39419 -35180
- package/examples/__data__/data-with-metadata.json +10 -0
- package/examples/feature/bar/additional-column-tooltip.json +3 -3
- package/examples/feature/deviation/planet-deviation-config.json +2 -2
- package/examples/feature/paired-bar/paired-bar-example.json +2 -2
- package/examples/feature/pie/planet-pie-example-config.json +2 -1
- package/examples/feature/tests-case-rate/case-rate-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-confidence-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-example-config.json +2 -2
- package/examples/feature/tests-cutoff/cutoff-example-config.json +2 -2
- package/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json +2 -2
- package/examples/metadata-variables.json +58 -0
- package/examples/minimal-example.json +24 -0
- package/examples/private/test2.json +35012 -0
- package/package.json +4 -4
- package/src/CdcChart.tsx +8 -4
- package/src/CdcChartComponent.tsx +326 -290
- package/src/_stories/Chart.CustomColors.smoke.stories.tsx +97 -0
- package/src/_stories/Chart.Defaults.smoke.stories.tsx +95 -0
- package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
- package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
- package/src/_stories/{Chart.SmallMultiples.stories.tsx → Chart.SmallMultiples.smoke.stories.tsx} +17 -1
- package/src/_stories/Chart.SmallestLeftAxisMax.smoke.stories.tsx +64 -0
- package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +48 -2
- package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +177 -115
- package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
- package/src/_stories/ChartEditor.Editor.stories.tsx +24 -1
- package/src/_stories/{Chart.CustomColors.stories.tsx → ChartLine.DashedDates.smoke.stories.tsx} +4 -4
- package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
- package/src/_stories/_mock/paired-bar-abbr.json +421 -0
- package/src/_stories/_mock/paired-bar.json +1 -1
- package/src/_stories/_mock/pie_custom_colors.json +268 -0
- package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +10 -10
- package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -1
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -1
- package/src/components/Annotations/components/AnnotationList.styles.css +11 -11
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
- package/src/components/Axis/BottomAxis.tsx +10 -3
- package/src/components/Axis/LeftAxis.tsx +2 -4
- package/src/components/Axis/LeftAxisGridlines.tsx +1 -3
- package/src/components/Axis/PairedBarAxis.tsx +10 -4
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +21 -33
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +21 -35
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +21 -36
- package/src/components/BarChart/components/BarChart.Vertical.tsx +21 -34
- package/src/components/BarChart/components/BarChart.tsx +2 -6
- package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
- package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
- package/src/components/BarChart/helpers/useBarChart.ts +4 -1
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
- package/src/components/Brush/BrushSelector.tsx +2 -1
- package/src/components/Brush/MiniChartPreview.tsx +21 -26
- package/src/components/EditorPanel/EditorPanel.tsx +692 -954
- package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +218 -167
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +39 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +169 -135
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +154 -109
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +95 -28
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +45 -42
- package/src/components/EditorPanel/editor-panel.scss +1 -1
- package/src/components/EditorPanel/useEditorPermissions.ts +1 -10
- package/src/components/Forecasting/Forecasting.tsx +2 -2
- package/src/components/ForestPlot/ForestPlot.tsx +26 -22
- package/src/components/HorizonChart/HorizonChart.tsx +10 -2
- package/src/components/HoverLine/HoverLine.tsx +6 -8
- package/src/components/Legend/Legend.Component.tsx +4 -4
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +9 -4
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
- package/src/components/Legend/helpers/createFormatLabels.tsx +3 -2
- package/src/components/Legend/helpers/index.ts +0 -2
- package/src/components/LineChart/LineChartProps.ts +1 -0
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +3 -2
- package/src/components/LineChart/index.tsx +11 -4
- package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
- package/src/components/LinearChart/tests/LinearChart.test.tsx +224 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +2 -0
- package/src/components/LinearChart.tsx +124 -47
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/PieChart/PieChart.tsx +30 -13
- package/src/components/RadarChart/RadarChart.tsx +1 -1
- package/src/components/Regions/components/Regions.tsx +36 -26
- package/src/components/Sankey/components/Sankey.tsx +3 -3
- package/src/components/Sankey/sankey.scss +1 -1
- package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +1 -0
- package/src/components/SmallMultiples/SmallMultiples.css +5 -5
- package/src/components/Sparkline/components/SparkLine.tsx +1 -1
- package/src/components/Sparkline/index.scss +4 -2
- package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
- package/src/data/initial-state.js +24 -14
- package/src/data/legacy-defaults.ts +18 -0
- package/src/helpers/abbreviateNumber.ts +24 -17
- package/src/helpers/calculateLeftYAxisWidth.ts +193 -0
- package/src/helpers/getChartPatternId.ts +17 -0
- package/src/helpers/getMinMax.ts +16 -2
- package/src/helpers/seriesColumnSettings.ts +114 -0
- package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
- package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
- package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
- package/src/helpers/tooltipHelpers.ts +176 -0
- package/src/hooks/useHighlightedBars.ts +9 -16
- package/src/hooks/useProgrammaticTooltip.ts +16 -2
- package/src/hooks/useRightAxis.ts +14 -0
- package/src/hooks/useScales.ts +92 -56
- package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
- package/src/hooks/useTooltip.tsx +186 -40
- package/src/scss/main.scss +152 -79
- package/src/test/CdcChart.test.jsx +26 -2
- package/src/types/ChartConfig.ts +5 -0
- package/tests/fixtures/chart-config-with-metadata.json +29 -0
- package/tests/fixtures/data-with-metadata.json +10 -0
- package/examples/chart-regression-2.json +0 -2360
- package/examples/feature/__data__/age-adjusted-rates.json +0 -1486
- package/examples/feature/__data__/city-temperature.json +0 -2198
- package/examples/feature/bar/Barchart_with_negative.json +0 -34
- package/examples/feature/boxplot/box-plot-data.json +0 -71
- package/examples/feature/boxplot/boxplot-data.json +0 -156
- package/examples/feature/combo/combochart-categories_are_numbers .json +0 -18
- package/examples/feature/forest-plot/log.json +0 -26
- package/examples/feature/tests-date-exclusions/date-exclusions-data.json +0 -162
- package/examples/region-issue.json +0 -2065
- package/examples/xaxis.json +0 -493
- /package/examples/feature/bar/{tall-data.json → __data__/tall-data.json} +0 -0
- /package/examples/feature/deviation/{planet-deviation-data.json → __data__/planet-deviation-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-data.json → __data__/paired-bar-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-formatted.json → __data__/paired-bar-formatted.json} +0 -0
- /package/examples/feature/tests-case-rate/{case-rate-example-data.json → __data__/case-rate-example-data.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data-confidence.json → __data__/covid-example-data-confidence.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data.json → __data__/covid-example-data.json} +0 -0
- /package/examples/feature/tests-cutoff/{cutoff-example-data.json → __data__/cutoff-example-data.json} +0 -0
- /package/examples/feature/tests-non-numerics/{planet-example-data-nonnumeric.json → __data__/planet-example-data-nonnumeric.json} +0 -0
- /package/src/_stories/{Chart.Anchors.stories.tsx → Chart.Anchors.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.BoxPlot.stories.tsx → Chart.BoxPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.CI.stories.tsx → Chart.CI.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Combo.stories.tsx → Chart.Combo.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.DynamicSeries.stories.tsx → Chart.DynamicSeries.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Filters.stories.tsx → Chart.Filters.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Forecast.stories.tsx → Chart.Forecast.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Legend.Gradient.stories.tsx → Chart.Legend.Gradient.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Patterns.stories.tsx → Chart.Patterns.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.PreserveDecimals.stories.tsx → Chart.PreserveDecimals.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.Categorical.stories.tsx → Chart.Regions.Categorical.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateScale.stories.tsx → Chart.Regions.DateScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateTimeScale.stories.tsx → Chart.Regions.DateTimeScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.ScatterPlot.stories.tsx → Chart.ScatterPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAnnotation.stories.tsx → ChartAnnotation.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAxisLabels.stories.tsx → ChartAxisLabels.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Continuous.stories.tsx → ChartBrush.Matrix.Continuous.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Date.stories.tsx → ChartBrush.Matrix.Date.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.DateTime.stories.tsx → ChartBrush.Matrix.DateTime.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.QuadrantAngles.stories.tsx → ChartLine.QuadrantAngles.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Suppression.stories.tsx → ChartLine.Suppression.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Symbols.stories.tsx → ChartLine.Symbols.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartPrefixSuffix.stories.tsx → ChartPrefixSuffix.smoke.stories.tsx} +0 -0
- /package/src/_stories/{TechAdoptionWithLinks.stories.tsx → TechAdoptionWithLinks.smoke.stories.tsx} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback, memo, useContext, useMemo } from 'react'
|
|
2
|
-
import {
|
|
2
|
+
import { Draggable } from '@hello-pangea/dnd'
|
|
3
3
|
import chroma from 'chroma-js'
|
|
4
|
-
import { isDateScale } from '@cdc/core/helpers/cove/date'
|
|
4
|
+
import { getAutoDetectedDateParseFormat, isDateScale } from '@cdc/core/helpers/cove/date'
|
|
5
5
|
import {
|
|
6
6
|
Accordion,
|
|
7
7
|
AccordionItem,
|
|
@@ -16,10 +16,12 @@ import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
|
16
16
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
17
17
|
import ColumnsEditor from '@cdc/core/components/EditorPanel/ColumnsEditor'
|
|
18
18
|
import DataTableEditor from '@cdc/core/components/EditorPanel/DataTableEditor'
|
|
19
|
+
import GroupedList from '@cdc/core/components/EditorPanel/GroupedList'
|
|
19
20
|
import VizFilterEditor from '@cdc/core/components/EditorPanel/VizFilterEditor'
|
|
20
21
|
import Tooltip from '@cdc/core/components/ui/Tooltip'
|
|
21
22
|
import { Select, TextField, CheckBox } from '@cdc/core/components/EditorPanel/Inputs'
|
|
22
23
|
import MultiSelect from '@cdc/core/components/MultiSelect'
|
|
24
|
+
import Button from '@cdc/core/components/elements/Button'
|
|
23
25
|
import { viewports } from '@cdc/core/helpers/getViewport'
|
|
24
26
|
import { approvedCurveTypes } from '@cdc/core/helpers/lineChartHelpers'
|
|
25
27
|
import PanelMarkup from '@cdc/core/components/EditorPanel/components/PanelMarkup'
|
|
@@ -45,7 +47,10 @@ import '@cdc/core/components/EditorPanel/EditorPanel.styles.css'
|
|
|
45
47
|
import './editor-panel.scss'
|
|
46
48
|
import { Anchor } from '@cdc/core/types/Axis'
|
|
47
49
|
import EditorPanelContext from './EditorPanelContext'
|
|
48
|
-
import
|
|
50
|
+
import cloneDeep from 'lodash/cloneDeep'
|
|
51
|
+
import flatMap from 'lodash/flatMap'
|
|
52
|
+
import keys from 'lodash/keys'
|
|
53
|
+
import uniq from 'lodash/uniq'
|
|
49
54
|
import { adjustedSymbols as symbolCodes } from '@cdc/core/helpers/footnoteSymbols'
|
|
50
55
|
import { updateFieldRankByValue } from './helpers/updateFieldRankByValue'
|
|
51
56
|
import cloneConfig from '@cdc/core/helpers/cloneConfig'
|
|
@@ -55,6 +60,7 @@ import { updateFieldFactory } from '@cdc/core/helpers/updateFieldFactory'
|
|
|
55
60
|
import { paletteMigrationMap, twoColorPaletteMigrationMap } from '@cdc/core/helpers/palettes/migratePaletteName'
|
|
56
61
|
import { isV1Palette, migratePaletteWithMap } from '@cdc/core/helpers/palettes/utils'
|
|
57
62
|
import { USE_V2_MIGRATION } from '@cdc/core/helpers/constants'
|
|
63
|
+
import { getSeriesOwnedColumnNames } from '../../helpers/seriesColumnSettings'
|
|
58
64
|
|
|
59
65
|
interface PreliminaryProps {
|
|
60
66
|
config: ChartConfig
|
|
@@ -70,7 +76,7 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
70
76
|
const hasComboBarSeries = isCombo && barSeriesExists
|
|
71
77
|
|
|
72
78
|
const getColumnOptions = () => {
|
|
73
|
-
return
|
|
79
|
+
return uniq(flatMap(data, keys))
|
|
74
80
|
}
|
|
75
81
|
|
|
76
82
|
const getTypeOptions = () => {
|
|
@@ -154,334 +160,525 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
154
160
|
updateConfig({ ...config, preliminaryData })
|
|
155
161
|
}
|
|
156
162
|
|
|
163
|
+
const moveColumn = (sourceIndex, destinationIndex) => {
|
|
164
|
+
const preliminaryData = config.preliminaryData ? [...config.preliminaryData] : []
|
|
165
|
+
const [movedItem] = preliminaryData.splice(sourceIndex, 1)
|
|
166
|
+
preliminaryData.splice(destinationIndex, 0, movedItem)
|
|
167
|
+
updateConfig({ ...config, preliminaryData })
|
|
168
|
+
}
|
|
169
|
+
|
|
157
170
|
return (
|
|
158
171
|
<>
|
|
159
|
-
|
|
160
|
-
config.preliminaryData
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
</Tooltip>
|
|
219
|
-
}
|
|
220
|
-
value={column}
|
|
221
|
-
initial='Select'
|
|
222
|
-
fieldName='column'
|
|
223
|
-
label='Add Data Series'
|
|
224
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
225
|
-
options={config.runtime?.seriesKeys}
|
|
226
|
-
/>
|
|
227
|
-
<TextField
|
|
228
|
-
value={value}
|
|
229
|
-
fieldName='value'
|
|
230
|
-
label='Suppressed Data Value'
|
|
231
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
232
|
-
/>
|
|
233
|
-
{(hasComboLineSeries || config.visualizationType === 'Line') && (
|
|
234
|
-
<>
|
|
235
|
-
<Select
|
|
236
|
-
tooltip={
|
|
237
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
238
|
-
<Tooltip.Target>
|
|
239
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
240
|
-
</Tooltip.Target>
|
|
241
|
-
<Tooltip.Content>
|
|
242
|
-
<p>
|
|
243
|
-
The recommended approach for presenting data is to include a footnote indicating any
|
|
244
|
-
data suppression.
|
|
245
|
-
</p>
|
|
246
|
-
</Tooltip.Content>
|
|
247
|
-
</Tooltip>
|
|
248
|
-
}
|
|
249
|
-
value={style}
|
|
250
|
-
initial='Select'
|
|
251
|
-
fieldName='style'
|
|
252
|
-
label={'suppression line style'}
|
|
253
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
254
|
-
options={getStyleOptions(type)}
|
|
255
|
-
/>
|
|
256
|
-
<CheckBox
|
|
257
|
-
value={hideLineStyle}
|
|
258
|
-
fieldName='hideLineStyle'
|
|
259
|
-
label='Hide Suppressed line Style'
|
|
260
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
261
|
-
/>
|
|
262
|
-
</>
|
|
263
|
-
)}
|
|
264
|
-
|
|
265
|
-
{(hasComboBarSeries || config.visualizationType === 'Bar') && (
|
|
266
|
-
<>
|
|
267
|
-
<Select
|
|
268
|
-
tooltip={
|
|
269
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
270
|
-
<Tooltip.Target>
|
|
271
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
272
|
-
</Tooltip.Target>
|
|
273
|
-
<Tooltip.Content>
|
|
274
|
-
<p>
|
|
275
|
-
A symbol is <i>required</i> to indicate suppressed data. We suggest "double
|
|
276
|
-
asterisks." If "double asterisks" are already used elsewhere (e.g., footnotes), please
|
|
277
|
-
select an alternative symbol from the menu to denote data suppression.
|
|
278
|
-
</p>
|
|
279
|
-
</Tooltip.Content>
|
|
280
|
-
</Tooltip>
|
|
281
|
-
}
|
|
282
|
-
value={symbol}
|
|
283
|
-
initial='Select'
|
|
284
|
-
fieldName='symbol'
|
|
285
|
-
label={config.visualizationType === 'Combo' ? 'suppression bar symbol' : 'suppression symbol'}
|
|
286
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
287
|
-
options={getSymbolOptions()}
|
|
288
|
-
/>
|
|
289
|
-
<CheckBox
|
|
290
|
-
value={hideBarSymbol}
|
|
291
|
-
fieldName='hideBarSymbol'
|
|
292
|
-
label='Hide Suppressed Bar Symbol '
|
|
293
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
294
|
-
/>
|
|
295
|
-
</>
|
|
296
|
-
)}
|
|
172
|
+
<GroupedList
|
|
173
|
+
items={config.preliminaryData}
|
|
174
|
+
label='Suppressed Data'
|
|
175
|
+
droppableId='chart-preliminary-data-order'
|
|
176
|
+
onDragEnd={({ source, destination }) => {
|
|
177
|
+
if (!destination || source.index === destination.index) return
|
|
178
|
+
moveColumn(source.index, destination.index)
|
|
179
|
+
}}
|
|
180
|
+
renderItem={(
|
|
181
|
+
{
|
|
182
|
+
displayGray,
|
|
183
|
+
circleSize,
|
|
184
|
+
column,
|
|
185
|
+
displayLegend,
|
|
186
|
+
displayTable,
|
|
187
|
+
displayTooltip,
|
|
188
|
+
label,
|
|
189
|
+
seriesKeys,
|
|
190
|
+
style,
|
|
191
|
+
symbol,
|
|
192
|
+
type,
|
|
193
|
+
value,
|
|
194
|
+
hideBarSymbol,
|
|
195
|
+
hideLineStyle
|
|
196
|
+
},
|
|
197
|
+
i
|
|
198
|
+
) => (
|
|
199
|
+
<Draggable key={`preliminaryData-${i}`} draggableId={`preliminaryData-${i}`} index={i}>
|
|
200
|
+
{(provided, snapshot) => (
|
|
201
|
+
<div
|
|
202
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
203
|
+
style={provided.draggableProps.style}
|
|
204
|
+
ref={provided.innerRef}
|
|
205
|
+
{...provided.draggableProps}
|
|
206
|
+
{...provided.dragHandleProps}
|
|
207
|
+
>
|
|
208
|
+
<Accordion allowZeroExpanded>
|
|
209
|
+
<AccordionItem className='series-item series-item--chart'>
|
|
210
|
+
<AccordionItemHeading className='series-item__title'>
|
|
211
|
+
<AccordionItemButton className='accordion__button'>
|
|
212
|
+
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
213
|
+
{type === 'suppression' ? 'Suppressed Data' : `Effect Data ${i + 1}`}
|
|
214
|
+
</AccordionItemButton>
|
|
215
|
+
</AccordionItemHeading>
|
|
216
|
+
<AccordionItemPanel>
|
|
217
|
+
<div className='series-item__panel-actions'>
|
|
218
|
+
<Button
|
|
219
|
+
type='button'
|
|
220
|
+
variant='danger'
|
|
221
|
+
size='sm'
|
|
222
|
+
className='grouped-list__remove'
|
|
223
|
+
onClick={event => {
|
|
224
|
+
event.preventDefault()
|
|
225
|
+
removeColumn(i)
|
|
226
|
+
}}
|
|
227
|
+
>
|
|
228
|
+
Remove
|
|
229
|
+
</Button>
|
|
230
|
+
</div>
|
|
297
231
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
</Tooltip.Target>
|
|
304
|
-
<Tooltip.Content>
|
|
305
|
-
<p>This label will display in the tooltip and legend.</p>
|
|
306
|
-
</Tooltip.Content>
|
|
307
|
-
</Tooltip>
|
|
308
|
-
}
|
|
309
|
-
value={label ? label : 'Suppressed'}
|
|
310
|
-
fieldName='label'
|
|
311
|
-
label='Suppressed Data Label'
|
|
312
|
-
placeholder=''
|
|
313
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
314
|
-
/>
|
|
315
|
-
<CheckBox
|
|
316
|
-
display={config.visualizationSubType === 'regular'}
|
|
317
|
-
tooltip={
|
|
318
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
319
|
-
<Tooltip.Target>
|
|
320
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
321
|
-
</Tooltip.Target>
|
|
322
|
-
<Tooltip.Content>
|
|
323
|
-
<p>
|
|
324
|
-
Deselecting the "Display In Tooltips" option prevents suppressed values from appearing in
|
|
325
|
-
tooltips.
|
|
326
|
-
</p>
|
|
327
|
-
</Tooltip.Content>
|
|
328
|
-
</Tooltip>
|
|
329
|
-
}
|
|
330
|
-
value={displayTooltip}
|
|
331
|
-
fieldName='displayTooltip'
|
|
332
|
-
label='Display in tooltips'
|
|
333
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
334
|
-
/>
|
|
335
|
-
<CheckBox
|
|
336
|
-
display={config.visualizationSubType === 'regular'}
|
|
337
|
-
tooltip={
|
|
338
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
339
|
-
<Tooltip.Target>
|
|
340
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
341
|
-
</Tooltip.Target>
|
|
342
|
-
<Tooltip.Content>
|
|
343
|
-
<p>
|
|
344
|
-
Deselecting "Display in Legend" indicates that you do not want to display suppressed data
|
|
345
|
-
in the legend.
|
|
346
|
-
</p>
|
|
347
|
-
</Tooltip.Content>
|
|
348
|
-
</Tooltip>
|
|
349
|
-
}
|
|
350
|
-
value={displayLegend}
|
|
351
|
-
fieldName='displayLegend'
|
|
352
|
-
label='Display in legend'
|
|
353
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
354
|
-
/>
|
|
355
|
-
<CheckBox
|
|
356
|
-
display={config.visualizationSubType === 'regular'}
|
|
357
|
-
tooltip={
|
|
358
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
359
|
-
<Tooltip.Target>
|
|
360
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
361
|
-
</Tooltip.Target>
|
|
362
|
-
<Tooltip.Content>
|
|
363
|
-
<p>
|
|
364
|
-
Deselecting "Display In Data Table" indicates that you do not want to display suppressed
|
|
365
|
-
data in the data table.
|
|
366
|
-
</p>
|
|
367
|
-
</Tooltip.Content>
|
|
368
|
-
</Tooltip>
|
|
369
|
-
}
|
|
370
|
-
value={displayTable}
|
|
371
|
-
fieldName='displayTable'
|
|
372
|
-
label='Display in table'
|
|
373
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
374
|
-
/>
|
|
375
|
-
<CheckBox
|
|
376
|
-
display={config.visualizationSubType === 'regular'}
|
|
377
|
-
tooltip={
|
|
378
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
379
|
-
<Tooltip.Target>
|
|
380
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
381
|
-
</Tooltip.Target>
|
|
382
|
-
<Tooltip.Content>
|
|
383
|
-
<p>Selecting this option will apply to chart, tooltip hover, legend, and data table.</p>
|
|
384
|
-
</Tooltip.Content>
|
|
385
|
-
</Tooltip>
|
|
386
|
-
}
|
|
387
|
-
value={displayGray}
|
|
388
|
-
fieldName='displayGray'
|
|
389
|
-
label='Highlight Suppressed Data In Gray'
|
|
390
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
391
|
-
/>
|
|
392
|
-
</>
|
|
393
|
-
) : (
|
|
394
|
-
<>
|
|
395
|
-
<label>
|
|
396
|
-
<span className='edit-label'>ASSOCIATE TO THESE SERIES</span>
|
|
397
|
-
<MultiSelect
|
|
398
|
-
fieldName='seriesKeys'
|
|
232
|
+
<Select
|
|
233
|
+
value={type}
|
|
234
|
+
initial={config.visualizationType == 'Bar' ? '' : 'Select'}
|
|
235
|
+
fieldName='type'
|
|
236
|
+
label='Type'
|
|
399
237
|
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
400
|
-
options={(
|
|
401
|
-
label: c,
|
|
402
|
-
value: c
|
|
403
|
-
}))}
|
|
404
|
-
selected={seriesKeys}
|
|
238
|
+
options={getTypeOptions()}
|
|
405
239
|
/>
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
240
|
+
{type === 'suppression' ? (
|
|
241
|
+
<>
|
|
242
|
+
<Select
|
|
243
|
+
tooltip={
|
|
244
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
245
|
+
<Tooltip.Target>
|
|
246
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
247
|
+
</Tooltip.Target>
|
|
248
|
+
<Tooltip.Content>
|
|
249
|
+
<p>
|
|
250
|
+
{' '}
|
|
251
|
+
Without a selected "Data Series", the suppression symbol will be applied for all
|
|
252
|
+
series in the current dataset visualization. However, choosing a specific "data
|
|
253
|
+
series" will isolate the suppression to that series.
|
|
254
|
+
</p>
|
|
255
|
+
</Tooltip.Content>
|
|
256
|
+
</Tooltip>
|
|
257
|
+
}
|
|
258
|
+
value={column}
|
|
259
|
+
initial='Select'
|
|
260
|
+
fieldName='column'
|
|
261
|
+
label='Add Data Series'
|
|
262
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
263
|
+
options={config.runtime?.seriesKeys}
|
|
264
|
+
/>
|
|
265
|
+
<TextField
|
|
266
|
+
value={value}
|
|
267
|
+
fieldName='value'
|
|
268
|
+
label='Suppressed Data Value'
|
|
269
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
270
|
+
/>
|
|
271
|
+
{(hasComboLineSeries || config.visualizationType === 'Line') && (
|
|
272
|
+
<>
|
|
273
|
+
<Select
|
|
274
|
+
tooltip={
|
|
275
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
276
|
+
<Tooltip.Target>
|
|
277
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
278
|
+
</Tooltip.Target>
|
|
279
|
+
<Tooltip.Content>
|
|
280
|
+
<p>
|
|
281
|
+
The recommended approach for presenting data is to include a footnote indicating
|
|
282
|
+
any data suppression.
|
|
283
|
+
</p>
|
|
284
|
+
</Tooltip.Content>
|
|
285
|
+
</Tooltip>
|
|
286
|
+
}
|
|
287
|
+
value={style}
|
|
288
|
+
initial='Select'
|
|
289
|
+
fieldName='style'
|
|
290
|
+
label={'suppression line style'}
|
|
291
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
292
|
+
options={getStyleOptions(type)}
|
|
293
|
+
/>
|
|
294
|
+
<CheckBox
|
|
295
|
+
value={hideLineStyle}
|
|
296
|
+
fieldName='hideLineStyle'
|
|
297
|
+
label='Hide Suppressed line Style'
|
|
298
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
299
|
+
/>
|
|
300
|
+
</>
|
|
301
|
+
)}
|
|
302
|
+
|
|
303
|
+
{(hasComboBarSeries || config.visualizationType === 'Bar') && (
|
|
304
|
+
<>
|
|
305
|
+
<Select
|
|
306
|
+
tooltip={
|
|
307
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
308
|
+
<Tooltip.Target>
|
|
309
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
310
|
+
</Tooltip.Target>
|
|
311
|
+
<Tooltip.Content>
|
|
312
|
+
<p>
|
|
313
|
+
A symbol is <i>required</i> to indicate suppressed data. We suggest "double
|
|
314
|
+
asterisks." If "double asterisks" are already used elsewhere (e.g., footnotes),
|
|
315
|
+
please select an alternative symbol from the menu to denote data suppression.
|
|
316
|
+
</p>
|
|
317
|
+
</Tooltip.Content>
|
|
318
|
+
</Tooltip>
|
|
319
|
+
}
|
|
320
|
+
value={symbol}
|
|
321
|
+
initial='Select'
|
|
322
|
+
fieldName='symbol'
|
|
323
|
+
label={
|
|
324
|
+
config.visualizationType === 'Combo' ? 'suppression bar symbol' : 'suppression symbol'
|
|
325
|
+
}
|
|
326
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
327
|
+
options={getSymbolOptions()}
|
|
328
|
+
/>
|
|
329
|
+
<CheckBox
|
|
330
|
+
value={hideBarSymbol}
|
|
331
|
+
fieldName='hideBarSymbol'
|
|
332
|
+
label='Hide Suppressed Bar Symbol '
|
|
333
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
334
|
+
/>
|
|
335
|
+
</>
|
|
336
|
+
)}
|
|
337
|
+
|
|
338
|
+
<TextField
|
|
339
|
+
tooltip={
|
|
340
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
341
|
+
<Tooltip.Target>
|
|
342
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
343
|
+
</Tooltip.Target>
|
|
344
|
+
<Tooltip.Content>
|
|
345
|
+
<p>This label will display in the tooltip and legend.</p>
|
|
346
|
+
</Tooltip.Content>
|
|
347
|
+
</Tooltip>
|
|
348
|
+
}
|
|
349
|
+
value={label ? label : 'Suppressed'}
|
|
350
|
+
fieldName='label'
|
|
351
|
+
label='Suppressed Data Label'
|
|
352
|
+
placeholder=''
|
|
353
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
354
|
+
/>
|
|
355
|
+
<CheckBox
|
|
356
|
+
display={config.visualizationSubType === 'regular'}
|
|
357
|
+
tooltip={
|
|
358
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
359
|
+
<Tooltip.Target>
|
|
360
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
361
|
+
</Tooltip.Target>
|
|
362
|
+
<Tooltip.Content>
|
|
363
|
+
<p>
|
|
364
|
+
Deselecting the "Display In Tooltips" option prevents suppressed values from
|
|
365
|
+
appearing in tooltips.
|
|
366
|
+
</p>
|
|
367
|
+
</Tooltip.Content>
|
|
368
|
+
</Tooltip>
|
|
369
|
+
}
|
|
370
|
+
value={displayTooltip}
|
|
371
|
+
fieldName='displayTooltip'
|
|
372
|
+
label='Display in tooltips'
|
|
373
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
374
|
+
/>
|
|
375
|
+
<CheckBox
|
|
376
|
+
display={config.visualizationSubType === 'regular'}
|
|
377
|
+
tooltip={
|
|
378
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
379
|
+
<Tooltip.Target>
|
|
380
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
381
|
+
</Tooltip.Target>
|
|
382
|
+
<Tooltip.Content>
|
|
383
|
+
<p>
|
|
384
|
+
Deselecting "Display in Legend" indicates that you do not want to display suppressed
|
|
385
|
+
data in the legend.
|
|
386
|
+
</p>
|
|
387
|
+
</Tooltip.Content>
|
|
388
|
+
</Tooltip>
|
|
389
|
+
}
|
|
390
|
+
value={displayLegend}
|
|
391
|
+
fieldName='displayLegend'
|
|
392
|
+
label='Display in legend'
|
|
393
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
394
|
+
/>
|
|
395
|
+
<CheckBox
|
|
396
|
+
display={config.visualizationSubType === 'regular'}
|
|
397
|
+
tooltip={
|
|
398
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
399
|
+
<Tooltip.Target>
|
|
400
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
401
|
+
</Tooltip.Target>
|
|
402
|
+
<Tooltip.Content>
|
|
403
|
+
<p>
|
|
404
|
+
Deselecting "Display In Data Table" indicates that you do not want to display
|
|
405
|
+
suppressed data in the data table.
|
|
406
|
+
</p>
|
|
407
|
+
</Tooltip.Content>
|
|
408
|
+
</Tooltip>
|
|
409
|
+
}
|
|
410
|
+
value={displayTable}
|
|
411
|
+
fieldName='displayTable'
|
|
412
|
+
label='Display in table'
|
|
413
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
414
|
+
/>
|
|
415
|
+
<CheckBox
|
|
416
|
+
display={config.visualizationSubType === 'regular'}
|
|
417
|
+
tooltip={
|
|
418
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
419
|
+
<Tooltip.Target>
|
|
420
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
421
|
+
</Tooltip.Target>
|
|
422
|
+
<Tooltip.Content>
|
|
423
|
+
<p>
|
|
424
|
+
Selecting this option will apply to chart, tooltip hover, legend, and data table.
|
|
425
|
+
</p>
|
|
426
|
+
</Tooltip.Content>
|
|
427
|
+
</Tooltip>
|
|
428
|
+
}
|
|
429
|
+
value={displayGray}
|
|
430
|
+
fieldName='displayGray'
|
|
431
|
+
label='Highlight Suppressed Data In Gray'
|
|
432
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
433
|
+
/>
|
|
434
|
+
</>
|
|
435
|
+
) : (
|
|
436
|
+
<>
|
|
437
|
+
<label>
|
|
438
|
+
<span className='edit-label'>ASSOCIATE TO THESE SERIES</span>
|
|
439
|
+
<MultiSelect
|
|
440
|
+
fieldName='seriesKeys'
|
|
441
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
442
|
+
options={(config.runtime.lineSeriesKeys ?? config.runtime?.seriesKeys).map(c => ({
|
|
443
|
+
label: c,
|
|
444
|
+
value: c
|
|
445
|
+
}))}
|
|
446
|
+
selected={seriesKeys}
|
|
447
|
+
/>
|
|
448
|
+
</label>
|
|
449
|
+
<Select
|
|
450
|
+
value={column}
|
|
451
|
+
initial='Select'
|
|
452
|
+
fieldName='column'
|
|
453
|
+
label='COLUMN WITH CONFIGURATION VALUE'
|
|
454
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
455
|
+
options={getColumnOptions()}
|
|
456
|
+
/>
|
|
457
|
+
<TextField
|
|
458
|
+
tooltip={
|
|
459
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
460
|
+
<Tooltip.Target>
|
|
461
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
462
|
+
</Tooltip.Target>
|
|
463
|
+
<Tooltip.Content>
|
|
464
|
+
<p>
|
|
465
|
+
If 'Filled Circles' is selected as the style, this field is optional, and the style
|
|
466
|
+
'Filled Circles' will apply to all points within the associated series data.
|
|
467
|
+
</p>
|
|
468
|
+
</Tooltip.Content>
|
|
469
|
+
</Tooltip>
|
|
470
|
+
}
|
|
471
|
+
value={value}
|
|
472
|
+
fieldName='value'
|
|
473
|
+
label='VALUE TO TRIGGER'
|
|
474
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
475
|
+
/>
|
|
476
|
+
<Select
|
|
477
|
+
value={style}
|
|
478
|
+
initial='Select'
|
|
479
|
+
fieldName='style'
|
|
480
|
+
label='Style'
|
|
481
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
482
|
+
options={getStyleOptions(type)}
|
|
483
|
+
/>
|
|
484
|
+
{style?.includes('Circles') && (
|
|
485
|
+
<TextField
|
|
486
|
+
className='number-narrow'
|
|
487
|
+
type='number'
|
|
488
|
+
value={circleSize}
|
|
489
|
+
fieldName='circleSize'
|
|
490
|
+
label='circle size'
|
|
491
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
492
|
+
/>
|
|
493
|
+
)}
|
|
494
|
+
{style !== 'Filled Circles' && (
|
|
495
|
+
<TextField
|
|
496
|
+
value={label}
|
|
497
|
+
fieldName='label'
|
|
498
|
+
label='Label'
|
|
499
|
+
placeholder=''
|
|
500
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
501
|
+
/>
|
|
502
|
+
)}
|
|
503
|
+
</>
|
|
504
|
+
)}
|
|
505
|
+
</AccordionItemPanel>
|
|
506
|
+
</AccordionItem>
|
|
507
|
+
</Accordion>
|
|
508
|
+
</div>
|
|
509
|
+
)}
|
|
510
|
+
</Draggable>
|
|
511
|
+
)}
|
|
512
|
+
/>
|
|
513
|
+
<Button type='button' variant='editor-primary' onClick={addColumn}>
|
|
514
|
+
{config.visualizationType === 'Line'
|
|
515
|
+
? 'Add Special Line'
|
|
516
|
+
: config.visualizationType === 'Bar'
|
|
517
|
+
? ' Add Special Bar'
|
|
518
|
+
: 'Add Special Bar/Line'}
|
|
519
|
+
</Button>
|
|
520
|
+
</>
|
|
521
|
+
)
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
interface CategoricalAxisProps {
|
|
525
|
+
config: ChartConfig
|
|
526
|
+
updateConfig: Function
|
|
527
|
+
display: boolean
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
type AxisAnchorEditorProps = {
|
|
531
|
+
axisKey: 'xAxis' | 'yAxis'
|
|
532
|
+
config: ChartConfig
|
|
533
|
+
lineOptions: { value: string; label?: string }[]
|
|
534
|
+
updateConfig: Function
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({ axisKey, config, lineOptions, updateConfig }) => {
|
|
538
|
+
const anchors = config[axisKey]?.anchors || []
|
|
539
|
+
|
|
540
|
+
const updateAnchors = (nextAnchors: Anchor[]) => {
|
|
541
|
+
updateConfig({
|
|
542
|
+
...config,
|
|
543
|
+
[axisKey]: {
|
|
544
|
+
...config[axisKey],
|
|
545
|
+
anchors: nextAnchors
|
|
546
|
+
}
|
|
547
|
+
})
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
const updateAnchorField = (index: number, field: keyof Anchor, value: string) => {
|
|
551
|
+
const copiedAnchors = [...anchors]
|
|
552
|
+
copiedAnchors[index] = {
|
|
553
|
+
...copiedAnchors[index],
|
|
554
|
+
[field]: value
|
|
555
|
+
}
|
|
556
|
+
updateAnchors(copiedAnchors)
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
const removeAnchor = (index: number) => {
|
|
560
|
+
const copiedAnchors = [...anchors]
|
|
561
|
+
copiedAnchors.splice(index, 1)
|
|
562
|
+
updateAnchors(copiedAnchors)
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const addAnchor = () => {
|
|
566
|
+
updateAnchors([...anchors, {} as Anchor])
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const reorderAnchors = (sourceIndex: number, destinationIndex: number) => {
|
|
570
|
+
const copiedAnchors = [...anchors]
|
|
571
|
+
const [movedAnchor] = copiedAnchors.splice(sourceIndex, 1)
|
|
572
|
+
copiedAnchors.splice(destinationIndex, 0, movedAnchor)
|
|
573
|
+
updateAnchors(copiedAnchors)
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return (
|
|
577
|
+
<>
|
|
578
|
+
<GroupedList
|
|
579
|
+
items={anchors}
|
|
580
|
+
label='Anchors'
|
|
581
|
+
droppableId={`${axisKey}-anchors-order`}
|
|
582
|
+
onDragEnd={({ source, destination }) => {
|
|
583
|
+
if (!destination || source.index === destination.index) return
|
|
584
|
+
reorderAnchors(source.index, destination.index)
|
|
585
|
+
}}
|
|
586
|
+
renderItem={(anchor, index) => (
|
|
587
|
+
<Draggable key={`${axisKey}-anchor-${index}`} draggableId={`${axisKey}-anchor-${index}`} index={index}>
|
|
588
|
+
{(provided, snapshot) => (
|
|
589
|
+
<div
|
|
590
|
+
ref={provided.innerRef}
|
|
591
|
+
{...provided.draggableProps}
|
|
592
|
+
{...provided.dragHandleProps}
|
|
593
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
594
|
+
style={provided.draggableProps.style}
|
|
595
|
+
>
|
|
596
|
+
<Accordion allowZeroExpanded>
|
|
597
|
+
<AccordionItem className='series-item series-item--chart'>
|
|
598
|
+
<AccordionItemHeading className='series-item__title'>
|
|
599
|
+
<AccordionItemButton className='accordion__button'>
|
|
600
|
+
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
601
|
+
{`Anchor ${index + 1}`}
|
|
602
|
+
</AccordionItemButton>
|
|
603
|
+
</AccordionItemHeading>
|
|
604
|
+
<AccordionItemPanel>
|
|
605
|
+
<div className='series-item__panel-actions'>
|
|
606
|
+
<Button
|
|
607
|
+
type='button'
|
|
608
|
+
variant='danger'
|
|
609
|
+
size='sm'
|
|
610
|
+
className='grouped-list__remove'
|
|
611
|
+
onClick={e => {
|
|
612
|
+
e.preventDefault()
|
|
613
|
+
removeAnchor(index)
|
|
614
|
+
}}
|
|
615
|
+
>
|
|
616
|
+
Remove
|
|
617
|
+
</Button>
|
|
618
|
+
</div>
|
|
619
|
+
<label>
|
|
620
|
+
<span>Anchor Value</span>
|
|
417
621
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
418
622
|
<Tooltip.Target>
|
|
419
623
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
420
624
|
</Tooltip.Target>
|
|
421
625
|
<Tooltip.Content>
|
|
422
|
-
<p>
|
|
423
|
-
If 'Filled Circles' is selected as the style, this field is optional, and the style
|
|
424
|
-
'Filled Circles' will apply to all points within the associated series data.
|
|
425
|
-
</p>
|
|
626
|
+
<p>Enter the value as its shown in the data column</p>
|
|
426
627
|
</Tooltip.Content>
|
|
427
628
|
</Tooltip>
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
label
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
)}
|
|
629
|
+
<input
|
|
630
|
+
type='text'
|
|
631
|
+
value={anchor?.value || ''}
|
|
632
|
+
onChange={e => {
|
|
633
|
+
e.preventDefault()
|
|
634
|
+
updateAnchorField(index, 'value', e.target.value)
|
|
635
|
+
}}
|
|
636
|
+
/>
|
|
637
|
+
</label>
|
|
638
|
+
|
|
639
|
+
<label>
|
|
640
|
+
<span>Anchor Color</span>
|
|
641
|
+
<input
|
|
642
|
+
type='text'
|
|
643
|
+
value={anchor?.color || ''}
|
|
644
|
+
onChange={e => {
|
|
645
|
+
e.preventDefault()
|
|
646
|
+
updateAnchorField(index, 'color', e.target.value)
|
|
647
|
+
}}
|
|
648
|
+
/>
|
|
649
|
+
</label>
|
|
650
|
+
|
|
651
|
+
<Select
|
|
652
|
+
value={anchor?.lineStyle || ''}
|
|
653
|
+
label='Anchor Line Style'
|
|
654
|
+
onChange={e => updateAnchorField(index, 'lineStyle', e.target.value)}
|
|
655
|
+
options={[
|
|
656
|
+
{ value: '', label: 'Select' },
|
|
657
|
+
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
658
|
+
]}
|
|
659
|
+
/>
|
|
660
|
+
</AccordionItemPanel>
|
|
661
|
+
</AccordionItem>
|
|
662
|
+
</Accordion>
|
|
463
663
|
</div>
|
|
464
|
-
)
|
|
465
|
-
|
|
664
|
+
)}
|
|
665
|
+
</Draggable>
|
|
466
666
|
)}
|
|
667
|
+
/>
|
|
467
668
|
|
|
468
|
-
<
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
669
|
+
<Button
|
|
670
|
+
variant='editor-primary'
|
|
671
|
+
onClick={e => {
|
|
672
|
+
e.preventDefault()
|
|
673
|
+
addAnchor()
|
|
674
|
+
}}
|
|
675
|
+
>
|
|
676
|
+
Add Anchor
|
|
677
|
+
</Button>
|
|
475
678
|
</>
|
|
476
679
|
)
|
|
477
680
|
}
|
|
478
681
|
|
|
479
|
-
interface CategoricalAxisProps {
|
|
480
|
-
config: ChartConfig
|
|
481
|
-
updateConfig: Function
|
|
482
|
-
display: boolean
|
|
483
|
-
}
|
|
484
|
-
|
|
485
682
|
const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig, display }) => {
|
|
486
683
|
const maxHeight = config?.yAxis?.maxValue
|
|
487
684
|
|
|
@@ -543,7 +740,7 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
543
740
|
return (
|
|
544
741
|
<div key={`preliminaryData-${i}`} className='edit-block'>
|
|
545
742
|
<p>Axis Category {i + 1}</p>
|
|
546
|
-
<
|
|
743
|
+
<Button
|
|
547
744
|
type='button'
|
|
548
745
|
className='btn btn-danger'
|
|
549
746
|
onClick={event => {
|
|
@@ -552,7 +749,7 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
552
749
|
}}
|
|
553
750
|
>
|
|
554
751
|
Remove
|
|
555
|
-
</
|
|
752
|
+
</Button>
|
|
556
753
|
<TextField
|
|
557
754
|
tooltip={
|
|
558
755
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
@@ -598,9 +795,9 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
598
795
|
)
|
|
599
796
|
})}
|
|
600
797
|
|
|
601
|
-
<
|
|
798
|
+
<Button type='button' variant='editor-primary' onClick={addColumn}>
|
|
602
799
|
Add Axis Category
|
|
603
|
-
</
|
|
800
|
+
</Button>
|
|
604
801
|
</>
|
|
605
802
|
)
|
|
606
803
|
}
|
|
@@ -721,7 +918,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
721
918
|
}
|
|
722
919
|
}, [config.visualizationType])
|
|
723
920
|
|
|
724
|
-
const { hasRightAxis } = useRightAxis({ config: config, yMax:
|
|
921
|
+
const { hasRightAxis } = useRightAxis({ config: config, yMax: 0, data: config.data, updateConfig })
|
|
725
922
|
|
|
726
923
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
|
727
924
|
...draggableStyle
|
|
@@ -770,6 +967,17 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
770
967
|
}
|
|
771
968
|
|
|
772
969
|
const updateField = updateFieldFactory(config, updateConfig)
|
|
970
|
+
const getAutoDetectedXAxisDateParseFormat = (dataKey = config.xAxis.dataKey, axisType = config.xAxis.type) => {
|
|
971
|
+
const hasExistingDateParseFormat =
|
|
972
|
+
typeof config.xAxis.dateParseFormat === 'string' && config.xAxis.dateParseFormat.trim() !== ''
|
|
973
|
+
|
|
974
|
+
if (hasExistingDateParseFormat || !['date', 'date-time'].includes(axisType)) {
|
|
975
|
+
return undefined
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
return getAutoDetectedDateParseFormat(config.data, dataKey)
|
|
979
|
+
}
|
|
980
|
+
|
|
773
981
|
const updateFieldDeprecated = (section, subsection, fieldName, newValue) => {
|
|
774
982
|
if (isDebug)
|
|
775
983
|
console.error(
|
|
@@ -812,6 +1020,23 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
812
1020
|
})
|
|
813
1021
|
return
|
|
814
1022
|
}
|
|
1023
|
+
|
|
1024
|
+
if (section === 'xAxis' && !truthy(subsection) && fieldName === 'dataKey') {
|
|
1025
|
+
const autoDetectedDateParseFormat = getAutoDetectedXAxisDateParseFormat(newValue)
|
|
1026
|
+
const updatedConfig = {
|
|
1027
|
+
...config,
|
|
1028
|
+
xAxis: {
|
|
1029
|
+
...config.xAxis,
|
|
1030
|
+
dataKey: newValue,
|
|
1031
|
+
...(autoDetectedDateParseFormat ? { dateParseFormat: autoDetectedDateParseFormat } : {})
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
enforceRestrictions(updatedConfig)
|
|
1036
|
+
updateConfig(updatedConfig)
|
|
1037
|
+
return
|
|
1038
|
+
}
|
|
1039
|
+
|
|
815
1040
|
if (null === section && null === subsection) {
|
|
816
1041
|
// special case that allows for updating the config object directly
|
|
817
1042
|
if (!truthy(fieldName)) console.error('fieldName is required')
|
|
@@ -935,6 +1160,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
935
1160
|
|
|
936
1161
|
// Extract column names from data with memoization (replaces getColumns)
|
|
937
1162
|
const allColumns = useDataColumns(dataSourceForColumns)
|
|
1163
|
+
const seriesOwnedColumnNames = useMemo(() => getSeriesOwnedColumnNames(config.series), [config.series])
|
|
938
1164
|
|
|
939
1165
|
// Filter out series columns and confidence key columns (except lower and upper)
|
|
940
1166
|
const filteredColumns = useMemo(() => {
|
|
@@ -1019,7 +1245,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1019
1245
|
// prettier-ignore
|
|
1020
1246
|
const {
|
|
1021
1247
|
highlightedBarValues,
|
|
1022
|
-
|
|
1248
|
+
getHighlightedSeriesValues,
|
|
1023
1249
|
handleUpdateHighlightedBar,
|
|
1024
1250
|
handleAddNewHighlightedBar,
|
|
1025
1251
|
handleRemoveHighlightedBar,
|
|
@@ -1519,46 +1745,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1519
1745
|
'Deviation Bar'
|
|
1520
1746
|
]
|
|
1521
1747
|
|
|
1522
|
-
const columnsOptions = [
|
|
1523
|
-
<option value='' key={'Select Option'}>
|
|
1524
|
-
- Select Option -
|
|
1525
|
-
</option>
|
|
1526
|
-
]
|
|
1527
|
-
|
|
1528
|
-
if (config.data && config.series) {
|
|
1529
|
-
Object.keys(config.data?.[0] || []).map(colName => {
|
|
1530
|
-
// OMIT ANY COLUMNS THAT ARE IN DATA SERIES!
|
|
1531
|
-
const found = config?.series.some(series => series.dataKey === colName)
|
|
1532
|
-
if (colName !== config.xAxis.dataKey && !found) {
|
|
1533
|
-
// if not the index then add it
|
|
1534
|
-
return columnsOptions.push(
|
|
1535
|
-
<option value={colName} key={colName}>
|
|
1536
|
-
{colName}
|
|
1537
|
-
</option>
|
|
1538
|
-
)
|
|
1539
|
-
}
|
|
1540
|
-
})
|
|
1541
|
-
}
|
|
1542
|
-
|
|
1543
|
-
// for pie charts
|
|
1544
|
-
if (!config.data && data) {
|
|
1545
|
-
if (!data[0]) return
|
|
1546
|
-
Object.keys(data[0]).map(colName => {
|
|
1547
|
-
// OMIT ANY COLUMNS THAT ARE IN DATA SERIES!
|
|
1548
|
-
const found = data.some(el => el.dataKey === colName)
|
|
1549
|
-
if (colName !== config.xAxis.dataKey && !found) {
|
|
1550
|
-
// if not the index then add it
|
|
1551
|
-
return columnsOptions.push(
|
|
1552
|
-
<option value={colName} key={colName}>
|
|
1553
|
-
{colName}
|
|
1554
|
-
</option>
|
|
1555
|
-
)
|
|
1556
|
-
}
|
|
1557
|
-
})
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
1748
|
const removeAdditionalColumn = columnName => {
|
|
1561
|
-
const newColumns =
|
|
1749
|
+
const newColumns = cloneDeep(config.columns)
|
|
1562
1750
|
|
|
1563
1751
|
delete newColumns[columnName]
|
|
1564
1752
|
|
|
@@ -1667,6 +1855,27 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1667
1855
|
const hasDynamicCategory = ![undefined, '- Select - '].includes(config.series?.[0]?.dynamicCategory)
|
|
1668
1856
|
const hasMultipleSeries = config.series?.length > 1
|
|
1669
1857
|
|
|
1858
|
+
const highlightedSeriesOptions = useMemo(() => {
|
|
1859
|
+
if (
|
|
1860
|
+
!(
|
|
1861
|
+
config.visualizationType === 'Bar' &&
|
|
1862
|
+
config.series?.length === 1 &&
|
|
1863
|
+
config.highlightedBarValues?.length > 0 &&
|
|
1864
|
+
getHighlightedSeriesValues
|
|
1865
|
+
)
|
|
1866
|
+
) {
|
|
1867
|
+
return []
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
return [...new Set(getHighlightedSeriesValues())].sort().map(option => ({ value: option, label: option }))
|
|
1871
|
+
}, [
|
|
1872
|
+
config.visualizationType,
|
|
1873
|
+
config.series?.length,
|
|
1874
|
+
config.highlightedBarValues?.length,
|
|
1875
|
+
config.data,
|
|
1876
|
+
config.xAxis.dataKey
|
|
1877
|
+
])
|
|
1878
|
+
|
|
1670
1879
|
const editorContextValues = {
|
|
1671
1880
|
addNewExclusion,
|
|
1672
1881
|
data,
|
|
@@ -1685,7 +1894,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1685
1894
|
handleUpdateHighlightedBar,
|
|
1686
1895
|
handleRemoveHighlightedBar,
|
|
1687
1896
|
isPaletteReversed: config.general?.palette?.isReversed,
|
|
1688
|
-
|
|
1897
|
+
getHighlightedSeriesValues,
|
|
1689
1898
|
handleUpdateHighlightedBorderWidth,
|
|
1690
1899
|
handleUpdateHighlightedBarColor,
|
|
1691
1900
|
setLollipopShape,
|
|
@@ -1808,49 +2017,40 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1808
2017
|
getColumns={getColumns}
|
|
1809
2018
|
handleForecastPaletteSelection={handleForecastPaletteSelection}
|
|
1810
2019
|
>
|
|
1811
|
-
<
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
onDragEnd={({ source, destination }) =>
|
|
1830
|
-
handleSeriesChange(source.index, destination.index)
|
|
2020
|
+
<GroupedList
|
|
2021
|
+
items={config.series}
|
|
2022
|
+
droppableId='chart-series-order'
|
|
2023
|
+
label={
|
|
2024
|
+
<>
|
|
2025
|
+
Displaying
|
|
2026
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2027
|
+
<Tooltip.Target>
|
|
2028
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2029
|
+
</Tooltip.Target>
|
|
2030
|
+
<Tooltip.Content>
|
|
2031
|
+
<p>
|
|
2032
|
+
A data series is a set of related data points plotted in a chart and
|
|
2033
|
+
typically represented in the chart legend.
|
|
2034
|
+
</p>
|
|
2035
|
+
</Tooltip.Content>
|
|
2036
|
+
</Tooltip>
|
|
2037
|
+
</>
|
|
1831
2038
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
/>
|
|
1848
|
-
{provided.placeholder}
|
|
1849
|
-
</ul>
|
|
1850
|
-
)
|
|
1851
|
-
}}
|
|
1852
|
-
</Droppable>
|
|
1853
|
-
</DragDropContext>
|
|
2039
|
+
onDragEnd={({ source, destination }) => {
|
|
2040
|
+
if (!destination || source.index === destination.index) return
|
|
2041
|
+
handleSeriesChange(source.index, destination.index)
|
|
2042
|
+
}}
|
|
2043
|
+
renderItem={(series, index) => (
|
|
2044
|
+
<Panels.Series.Item
|
|
2045
|
+
getItemStyle={getItemStyle}
|
|
2046
|
+
sortableItemStyles={sortableItemStyles}
|
|
2047
|
+
chartsWithOptions={chartsWithOptions}
|
|
2048
|
+
series={series}
|
|
2049
|
+
index={index}
|
|
2050
|
+
key={`series-list-${index}`}
|
|
2051
|
+
/>
|
|
2052
|
+
)}
|
|
2053
|
+
/>
|
|
1854
2054
|
</Panels.Series.Wrapper>
|
|
1855
2055
|
)}
|
|
1856
2056
|
</>
|
|
@@ -2078,38 +2278,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2078
2278
|
}
|
|
2079
2279
|
updateField={updateFieldDeprecated}
|
|
2080
2280
|
/>
|
|
2081
|
-
<TextField
|
|
2082
|
-
value={config.yAxis.size}
|
|
2083
|
-
type='number'
|
|
2084
|
-
section='yAxis'
|
|
2085
|
-
fieldName='size'
|
|
2086
|
-
label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
|
|
2087
|
-
className='number-narrow'
|
|
2088
|
-
updateField={updateFieldDeprecated}
|
|
2089
|
-
tooltip={
|
|
2090
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2091
|
-
<Tooltip.Target>
|
|
2092
|
-
<Icon
|
|
2093
|
-
display='question'
|
|
2094
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2095
|
-
/>
|
|
2096
|
-
</Tooltip.Target>
|
|
2097
|
-
<Tooltip.Content>
|
|
2098
|
-
<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>
|
|
2099
|
-
</Tooltip.Content>
|
|
2100
|
-
</Tooltip>
|
|
2101
|
-
}
|
|
2102
|
-
/>
|
|
2103
|
-
<TextField
|
|
2104
|
-
display={!visHasCategoricalAxis()}
|
|
2105
|
-
value={config.yAxis.labelOffset}
|
|
2106
|
-
section='yAxis'
|
|
2107
|
-
fieldName='labelOffset'
|
|
2108
|
-
label='Label offset'
|
|
2109
|
-
type='number'
|
|
2110
|
-
className='number-narrow'
|
|
2111
|
-
updateField={updateFieldDeprecated}
|
|
2112
|
-
/>
|
|
2113
2281
|
{config.orientation === 'horizontal' && (
|
|
2114
2282
|
<CheckBox
|
|
2115
2283
|
value={config.isResponsiveTicks}
|
|
@@ -2487,256 +2655,47 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2487
2655
|
<span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
|
|
2488
2656
|
</>
|
|
2489
2657
|
)}
|
|
2658
|
+
<TextField
|
|
2659
|
+
value={config.yAxis.smallestLeftAxisMax}
|
|
2660
|
+
section='yAxis'
|
|
2661
|
+
fieldName='smallestLeftAxisMax'
|
|
2662
|
+
type='number'
|
|
2663
|
+
label='Smallest Left Axis Maximum'
|
|
2664
|
+
placeholder='Auto'
|
|
2665
|
+
tooltip={
|
|
2666
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2667
|
+
<Tooltip.Target>
|
|
2668
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2669
|
+
</Tooltip.Target>
|
|
2670
|
+
<Tooltip.Content>
|
|
2671
|
+
<p>
|
|
2672
|
+
Example: If your data only goes up to 1, the axis might show 0, 0.2, 0.4, 0.6,
|
|
2673
|
+
0.8, 1. Setting this to 5 would make the axis show 0, 1, 2, 3, 4, 5 instead.
|
|
2674
|
+
</p>
|
|
2675
|
+
</Tooltip.Content>
|
|
2676
|
+
</Tooltip>
|
|
2677
|
+
}
|
|
2678
|
+
updateField={updateFieldDeprecated}
|
|
2679
|
+
/>
|
|
2490
2680
|
</>
|
|
2491
2681
|
)
|
|
2492
2682
|
)}
|
|
2493
2683
|
{/* start: anchors */}
|
|
2494
2684
|
{visHasAnchors() && config.orientation !== 'horizontal' && (
|
|
2495
|
-
<
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
key={`yaxis-anchors-2-${index}`}
|
|
2502
|
-
>
|
|
2503
|
-
<AccordionItemHeading className='series-item__title'>
|
|
2504
|
-
<>
|
|
2505
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
2506
|
-
Anchor {index + 1}
|
|
2507
|
-
<button
|
|
2508
|
-
className='series-list__remove'
|
|
2509
|
-
onClick={e => {
|
|
2510
|
-
e.preventDefault()
|
|
2511
|
-
const copiedAnchorGroups = [...config.yAxis.anchors]
|
|
2512
|
-
copiedAnchorGroups.splice(index, 1)
|
|
2513
|
-
updateConfig({
|
|
2514
|
-
...config,
|
|
2515
|
-
yAxis: {
|
|
2516
|
-
...config.yAxis,
|
|
2517
|
-
anchors: copiedAnchorGroups
|
|
2518
|
-
}
|
|
2519
|
-
})
|
|
2520
|
-
}}
|
|
2521
|
-
>
|
|
2522
|
-
Remove
|
|
2523
|
-
</button>
|
|
2524
|
-
</AccordionItemButton>
|
|
2525
|
-
</>
|
|
2526
|
-
</AccordionItemHeading>
|
|
2527
|
-
<AccordionItemPanel>
|
|
2528
|
-
<label>
|
|
2529
|
-
<span>Anchor Value</span>
|
|
2530
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2531
|
-
<Tooltip.Target>
|
|
2532
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2533
|
-
</Tooltip.Target>
|
|
2534
|
-
<Tooltip.Content>
|
|
2535
|
-
<p>Enter the value as its shown in the data column</p>
|
|
2536
|
-
</Tooltip.Content>
|
|
2537
|
-
</Tooltip>
|
|
2538
|
-
<input
|
|
2539
|
-
type='text'
|
|
2540
|
-
value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
|
|
2541
|
-
onChange={e => {
|
|
2542
|
-
e.preventDefault()
|
|
2543
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2544
|
-
copiedAnchors[index].value = e.target.value
|
|
2545
|
-
updateConfig({
|
|
2546
|
-
...config,
|
|
2547
|
-
yAxis: {
|
|
2548
|
-
...config.yAxis,
|
|
2549
|
-
anchors: copiedAnchors
|
|
2550
|
-
}
|
|
2551
|
-
})
|
|
2552
|
-
}}
|
|
2553
|
-
/>
|
|
2554
|
-
</label>
|
|
2555
|
-
|
|
2556
|
-
<label>
|
|
2557
|
-
<span>Anchor Color</span>
|
|
2558
|
-
<input
|
|
2559
|
-
type='text'
|
|
2560
|
-
value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
|
|
2561
|
-
onChange={e => {
|
|
2562
|
-
e.preventDefault()
|
|
2563
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2564
|
-
copiedAnchors[index].color = e.target.value
|
|
2565
|
-
updateConfig({
|
|
2566
|
-
...config,
|
|
2567
|
-
yAxis: {
|
|
2568
|
-
...config.yAxis,
|
|
2569
|
-
anchors: copiedAnchors
|
|
2570
|
-
}
|
|
2571
|
-
})
|
|
2572
|
-
}}
|
|
2573
|
-
/>
|
|
2574
|
-
</label>
|
|
2575
|
-
|
|
2576
|
-
<Select
|
|
2577
|
-
value={config.yAxis.anchors[index].lineStyle || ''}
|
|
2578
|
-
label='Anchor Line Style'
|
|
2579
|
-
onChange={e => {
|
|
2580
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2581
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
2582
|
-
updateConfig({
|
|
2583
|
-
...config,
|
|
2584
|
-
yAxis: {
|
|
2585
|
-
...config.yAxis,
|
|
2586
|
-
anchors: copiedAnchors
|
|
2587
|
-
}
|
|
2588
|
-
})
|
|
2589
|
-
}}
|
|
2590
|
-
options={[
|
|
2591
|
-
{ value: '', label: 'Select' },
|
|
2592
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
2593
|
-
]}
|
|
2594
|
-
/>
|
|
2595
|
-
</AccordionItemPanel>
|
|
2596
|
-
</AccordionItem>
|
|
2597
|
-
))}
|
|
2598
|
-
</Accordion>
|
|
2599
|
-
|
|
2600
|
-
<button
|
|
2601
|
-
className='btn btn-primary full-width'
|
|
2602
|
-
onClick={e => {
|
|
2603
|
-
e.preventDefault()
|
|
2604
|
-
const anchors = [...config.yAxis.anchors]
|
|
2605
|
-
anchors.push({} as Anchor)
|
|
2606
|
-
updateConfig({
|
|
2607
|
-
...config,
|
|
2608
|
-
yAxis: {
|
|
2609
|
-
...config.yAxis,
|
|
2610
|
-
anchors
|
|
2611
|
-
}
|
|
2612
|
-
})
|
|
2613
|
-
}}
|
|
2614
|
-
>
|
|
2615
|
-
Add Anchor
|
|
2616
|
-
</button>
|
|
2617
|
-
</div>
|
|
2685
|
+
<AxisAnchorEditor
|
|
2686
|
+
axisKey='yAxis'
|
|
2687
|
+
config={config}
|
|
2688
|
+
lineOptions={lineOptions}
|
|
2689
|
+
updateConfig={updateConfig}
|
|
2690
|
+
/>
|
|
2618
2691
|
)}
|
|
2619
2692
|
{visHasAnchors() && config.orientation === 'horizontal' && (
|
|
2620
|
-
<
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
<>
|
|
2627
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
2628
|
-
Anchor {index + 1}
|
|
2629
|
-
<button
|
|
2630
|
-
className='series-list__remove'
|
|
2631
|
-
onClick={e => {
|
|
2632
|
-
e.preventDefault()
|
|
2633
|
-
const copiedAnchorGroups = [...config.xAxis.anchors]
|
|
2634
|
-
copiedAnchorGroups.splice(index, 1)
|
|
2635
|
-
updateConfig({
|
|
2636
|
-
...config,
|
|
2637
|
-
xAxis: {
|
|
2638
|
-
...config.xAxis,
|
|
2639
|
-
anchors: copiedAnchorGroups
|
|
2640
|
-
}
|
|
2641
|
-
})
|
|
2642
|
-
}}
|
|
2643
|
-
>
|
|
2644
|
-
Remove
|
|
2645
|
-
</button>
|
|
2646
|
-
</AccordionItemButton>
|
|
2647
|
-
</>
|
|
2648
|
-
</AccordionItemHeading>
|
|
2649
|
-
<AccordionItemPanel>
|
|
2650
|
-
<label>
|
|
2651
|
-
<span>Anchor Value</span>
|
|
2652
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2653
|
-
<Tooltip.Target>
|
|
2654
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2655
|
-
</Tooltip.Target>
|
|
2656
|
-
<Tooltip.Content>
|
|
2657
|
-
<p>Enter the value as its shown in the data column</p>
|
|
2658
|
-
</Tooltip.Content>
|
|
2659
|
-
</Tooltip>
|
|
2660
|
-
<input
|
|
2661
|
-
type='text'
|
|
2662
|
-
value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
|
|
2663
|
-
onChange={e => {
|
|
2664
|
-
e.preventDefault()
|
|
2665
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2666
|
-
copiedAnchors[index].value = e.target.value
|
|
2667
|
-
updateConfig({
|
|
2668
|
-
...config,
|
|
2669
|
-
xAxis: {
|
|
2670
|
-
...config.xAxis,
|
|
2671
|
-
anchors: copiedAnchors
|
|
2672
|
-
}
|
|
2673
|
-
})
|
|
2674
|
-
}}
|
|
2675
|
-
/>
|
|
2676
|
-
</label>
|
|
2677
|
-
|
|
2678
|
-
<label>
|
|
2679
|
-
<span>Anchor Color</span>
|
|
2680
|
-
<input
|
|
2681
|
-
type='text'
|
|
2682
|
-
value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
|
|
2683
|
-
onChange={e => {
|
|
2684
|
-
e.preventDefault()
|
|
2685
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2686
|
-
copiedAnchors[index].color = e.target.value
|
|
2687
|
-
updateConfig({
|
|
2688
|
-
...config,
|
|
2689
|
-
xAxis: {
|
|
2690
|
-
...config.xAxis,
|
|
2691
|
-
anchors: copiedAnchors
|
|
2692
|
-
}
|
|
2693
|
-
})
|
|
2694
|
-
}}
|
|
2695
|
-
/>
|
|
2696
|
-
</label>
|
|
2697
|
-
|
|
2698
|
-
<Select
|
|
2699
|
-
value={config.xAxis.anchors[index].lineStyle || ''}
|
|
2700
|
-
label='Anchor Line Style'
|
|
2701
|
-
onChange={e => {
|
|
2702
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2703
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
2704
|
-
updateConfig({
|
|
2705
|
-
...config,
|
|
2706
|
-
xAxis: {
|
|
2707
|
-
...config.xAxis,
|
|
2708
|
-
anchors: copiedAnchors
|
|
2709
|
-
}
|
|
2710
|
-
})
|
|
2711
|
-
}}
|
|
2712
|
-
options={[
|
|
2713
|
-
{ value: '', label: 'Select' },
|
|
2714
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
2715
|
-
]}
|
|
2716
|
-
/>
|
|
2717
|
-
</AccordionItemPanel>
|
|
2718
|
-
</AccordionItem>
|
|
2719
|
-
))}
|
|
2720
|
-
</Accordion>
|
|
2721
|
-
|
|
2722
|
-
<button
|
|
2723
|
-
className='btn btn-primary full-width'
|
|
2724
|
-
onClick={e => {
|
|
2725
|
-
e.preventDefault()
|
|
2726
|
-
const anchors = [...config.xAxis.anchors]
|
|
2727
|
-
anchors.push({} as Anchor)
|
|
2728
|
-
updateConfig({
|
|
2729
|
-
...config,
|
|
2730
|
-
xAxis: {
|
|
2731
|
-
...config.xAxis,
|
|
2732
|
-
anchors
|
|
2733
|
-
}
|
|
2734
|
-
})
|
|
2735
|
-
}}
|
|
2736
|
-
>
|
|
2737
|
-
Add Anchor
|
|
2738
|
-
</button>
|
|
2739
|
-
</div>
|
|
2693
|
+
<AxisAnchorEditor
|
|
2694
|
+
axisKey='xAxis'
|
|
2695
|
+
config={config}
|
|
2696
|
+
lineOptions={lineOptions}
|
|
2697
|
+
updateConfig={updateConfig}
|
|
2698
|
+
/>
|
|
2740
2699
|
)}
|
|
2741
2700
|
{/* end: anchors */}
|
|
2742
2701
|
</AccordionItemPanel>
|
|
@@ -2886,7 +2845,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2886
2845
|
/>
|
|
2887
2846
|
|
|
2888
2847
|
<TextField
|
|
2889
|
-
value={config.yAxis.
|
|
2848
|
+
value={config.yAxis.rightMax}
|
|
2890
2849
|
section='yAxis'
|
|
2891
2850
|
fieldName='rightMax'
|
|
2892
2851
|
type='number'
|
|
@@ -2896,7 +2855,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2896
2855
|
/>
|
|
2897
2856
|
<span style={{ color: 'red', display: 'block' }}>{warningMsg.rightMaxMessage}</span>
|
|
2898
2857
|
<TextField
|
|
2899
|
-
value={config.yAxis.
|
|
2858
|
+
value={config.yAxis.rightMin}
|
|
2900
2859
|
section='yAxis'
|
|
2901
2860
|
fieldName='rightMin'
|
|
2902
2861
|
type='number'
|
|
@@ -2905,6 +2864,28 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2905
2864
|
updateField={updateFieldDeprecated}
|
|
2906
2865
|
/>
|
|
2907
2866
|
<span style={{ color: 'red', display: 'block' }}>{warningMsg.minMsg}</span>
|
|
2867
|
+
<TextField
|
|
2868
|
+
value={config.yAxis.smallestRightAxisMax}
|
|
2869
|
+
section='yAxis'
|
|
2870
|
+
fieldName='smallestRightAxisMax'
|
|
2871
|
+
type='number'
|
|
2872
|
+
label='Smallest Right Axis Maximum'
|
|
2873
|
+
placeholder='Auto'
|
|
2874
|
+
tooltip={
|
|
2875
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2876
|
+
<Tooltip.Target>
|
|
2877
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2878
|
+
</Tooltip.Target>
|
|
2879
|
+
<Tooltip.Content>
|
|
2880
|
+
<p>
|
|
2881
|
+
Example: If your data only goes up to 1, the axis might show 0, 0.2, 0.4, 0.6, 0.8, 1.
|
|
2882
|
+
Setting this to 5 would make the axis show 0, 1, 2, 3, 4, 5 instead.
|
|
2883
|
+
</p>
|
|
2884
|
+
</Tooltip.Content>
|
|
2885
|
+
</Tooltip>
|
|
2886
|
+
}
|
|
2887
|
+
updateField={updateFieldDeprecated}
|
|
2888
|
+
/>
|
|
2908
2889
|
</AccordionItemPanel>
|
|
2909
2890
|
</AccordionItem>
|
|
2910
2891
|
)}
|
|
@@ -2950,11 +2931,19 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2950
2931
|
section='xAxis'
|
|
2951
2932
|
fieldName='type'
|
|
2952
2933
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
2934
|
+
const autoDetectedDateParseFormat = getAutoDetectedXAxisDateParseFormat(
|
|
2935
|
+
config.xAxis.dataKey,
|
|
2936
|
+
value
|
|
2937
|
+
)
|
|
2938
|
+
|
|
2953
2939
|
updateConfig({
|
|
2954
2940
|
...config,
|
|
2955
2941
|
xAxis: {
|
|
2956
2942
|
...config.xAxis,
|
|
2957
|
-
type: value
|
|
2943
|
+
type: value,
|
|
2944
|
+
...(autoDetectedDateParseFormat
|
|
2945
|
+
? { dateParseFormat: autoDetectedDateParseFormat }
|
|
2946
|
+
: {})
|
|
2958
2947
|
}
|
|
2959
2948
|
})
|
|
2960
2949
|
}}
|
|
@@ -3576,18 +3565,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3576
3565
|
updateField={updateFieldDeprecated}
|
|
3577
3566
|
/>
|
|
3578
3567
|
)}
|
|
3579
|
-
{config.orientation === 'horizontal' && (
|
|
3580
|
-
<TextField
|
|
3581
|
-
value={config.xAxis.labelOffset}
|
|
3582
|
-
section='xAxis'
|
|
3583
|
-
fieldName='labelOffset'
|
|
3584
|
-
label='Label offset'
|
|
3585
|
-
type='number'
|
|
3586
|
-
className='number-narrow'
|
|
3587
|
-
updateField={updateFieldDeprecated}
|
|
3588
|
-
/>
|
|
3589
|
-
)}
|
|
3590
|
-
|
|
3591
3568
|
{/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
|
|
3592
3569
|
{/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateFieldDeprecated} /> */}
|
|
3593
3570
|
{(config.xAxis.type === 'continuous' || config.forestPlot.type === 'Logarithmic') && (
|
|
@@ -3726,12 +3703,12 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3726
3703
|
highlightedBarValues.map((highlightedBarValue, i) => (
|
|
3727
3704
|
<fieldset>
|
|
3728
3705
|
<div className='edit-block' key={`highlighted-bar-${i}`}>
|
|
3729
|
-
<
|
|
3706
|
+
<Button
|
|
3730
3707
|
className='btn btn-danger'
|
|
3731
3708
|
onClick={e => handleRemoveHighlightedBar(e, i)}
|
|
3732
3709
|
>
|
|
3733
3710
|
Remove
|
|
3734
|
-
</
|
|
3711
|
+
</Button>
|
|
3735
3712
|
<p>Highlighted Bar {i + 1}</p>
|
|
3736
3713
|
<Select
|
|
3737
3714
|
value={config.highlightedBarValues[i].value}
|
|
@@ -3739,11 +3716,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3739
3716
|
onChange={e => handleUpdateHighlightedBar(e, i)}
|
|
3740
3717
|
options={[
|
|
3741
3718
|
{ value: '', label: '- Select Value -' },
|
|
3742
|
-
...
|
|
3743
|
-
? [...new Set(highlightedSeriesValues)]
|
|
3744
|
-
.sort()
|
|
3745
|
-
.map(option => ({ value: option, label: option }))
|
|
3746
|
-
: [])
|
|
3719
|
+
...highlightedSeriesOptions
|
|
3747
3720
|
]}
|
|
3748
3721
|
/>
|
|
3749
3722
|
<label>
|
|
@@ -3787,12 +3760,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3787
3760
|
</div>
|
|
3788
3761
|
</fieldset>
|
|
3789
3762
|
))}
|
|
3790
|
-
<
|
|
3791
|
-
className='btn btn-primary full-width'
|
|
3792
|
-
onClick={e => handleAddNewHighlightedBar(e)}
|
|
3793
|
-
>
|
|
3763
|
+
<Button variant='editor-primary' onClick={e => handleAddNewHighlightedBar(e)}>
|
|
3794
3764
|
Add Highlighted Bar
|
|
3795
|
-
</
|
|
3765
|
+
</Button>
|
|
3796
3766
|
</>
|
|
3797
3767
|
)}
|
|
3798
3768
|
</>
|
|
@@ -3877,255 +3847,21 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3877
3847
|
|
|
3878
3848
|
{/* anchors */}
|
|
3879
3849
|
{visHasAnchors() && config.orientation !== 'horizontal' && (
|
|
3880
|
-
<
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
key={`xaxis-anchors-2-${index}`}
|
|
3887
|
-
>
|
|
3888
|
-
<AccordionItemHeading className='series-item__title'>
|
|
3889
|
-
<>
|
|
3890
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
3891
|
-
Anchor {index + 1}
|
|
3892
|
-
<button
|
|
3893
|
-
className='series-list__remove'
|
|
3894
|
-
onClick={e => {
|
|
3895
|
-
e.preventDefault()
|
|
3896
|
-
const copiedAnchorGroups = [...config.xAxis.anchors]
|
|
3897
|
-
copiedAnchorGroups.splice(index, 1)
|
|
3898
|
-
updateConfig({
|
|
3899
|
-
...config,
|
|
3900
|
-
xAxis: {
|
|
3901
|
-
...config.xAxis,
|
|
3902
|
-
anchors: copiedAnchorGroups
|
|
3903
|
-
}
|
|
3904
|
-
})
|
|
3905
|
-
}}
|
|
3906
|
-
>
|
|
3907
|
-
Remove
|
|
3908
|
-
</button>
|
|
3909
|
-
</AccordionItemButton>
|
|
3910
|
-
</>
|
|
3911
|
-
</AccordionItemHeading>
|
|
3912
|
-
<AccordionItemPanel>
|
|
3913
|
-
<label>
|
|
3914
|
-
<span>Anchor Value</span>
|
|
3915
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
3916
|
-
<Tooltip.Target>
|
|
3917
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3918
|
-
</Tooltip.Target>
|
|
3919
|
-
<Tooltip.Content>
|
|
3920
|
-
<p>Enter the value as its shown in the data column</p>
|
|
3921
|
-
</Tooltip.Content>
|
|
3922
|
-
</Tooltip>
|
|
3923
|
-
<input
|
|
3924
|
-
type='text'
|
|
3925
|
-
value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
|
|
3926
|
-
onChange={e => {
|
|
3927
|
-
e.preventDefault()
|
|
3928
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3929
|
-
copiedAnchors[index].value = e.target.value
|
|
3930
|
-
updateConfig({
|
|
3931
|
-
...config,
|
|
3932
|
-
xAxis: {
|
|
3933
|
-
...config.xAxis,
|
|
3934
|
-
anchors: copiedAnchors
|
|
3935
|
-
}
|
|
3936
|
-
})
|
|
3937
|
-
}}
|
|
3938
|
-
/>
|
|
3939
|
-
</label>
|
|
3940
|
-
|
|
3941
|
-
<label>
|
|
3942
|
-
<span>Anchor Color</span>
|
|
3943
|
-
<input
|
|
3944
|
-
type='text'
|
|
3945
|
-
value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
|
|
3946
|
-
onChange={e => {
|
|
3947
|
-
e.preventDefault()
|
|
3948
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3949
|
-
copiedAnchors[index].color = e.target.value
|
|
3950
|
-
updateConfig({
|
|
3951
|
-
...config,
|
|
3952
|
-
xAxis: {
|
|
3953
|
-
...config.xAxis,
|
|
3954
|
-
anchors: copiedAnchors
|
|
3955
|
-
}
|
|
3956
|
-
})
|
|
3957
|
-
}}
|
|
3958
|
-
/>
|
|
3959
|
-
</label>
|
|
3960
|
-
|
|
3961
|
-
<Select
|
|
3962
|
-
value={config.xAxis.anchors[index].lineStyle || ''}
|
|
3963
|
-
label='Anchor Line Style'
|
|
3964
|
-
onChange={e => {
|
|
3965
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3966
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
3967
|
-
updateConfig({
|
|
3968
|
-
...config,
|
|
3969
|
-
xAxis: {
|
|
3970
|
-
...config.xAxis,
|
|
3971
|
-
anchors: copiedAnchors
|
|
3972
|
-
}
|
|
3973
|
-
})
|
|
3974
|
-
}}
|
|
3975
|
-
options={[
|
|
3976
|
-
{ value: '', label: 'Select' },
|
|
3977
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
3978
|
-
]}
|
|
3979
|
-
/>
|
|
3980
|
-
</AccordionItemPanel>
|
|
3981
|
-
</AccordionItem>
|
|
3982
|
-
))}
|
|
3983
|
-
</Accordion>
|
|
3984
|
-
|
|
3985
|
-
<button
|
|
3986
|
-
className='btn btn-primary full-width'
|
|
3987
|
-
onClick={e => {
|
|
3988
|
-
e.preventDefault()
|
|
3989
|
-
const anchors = [...config.xAxis.anchors]
|
|
3990
|
-
anchors.push({} as Anchor)
|
|
3991
|
-
updateConfig({
|
|
3992
|
-
...config,
|
|
3993
|
-
xAxis: {
|
|
3994
|
-
...config.xAxis,
|
|
3995
|
-
anchors
|
|
3996
|
-
}
|
|
3997
|
-
})
|
|
3998
|
-
}}
|
|
3999
|
-
>
|
|
4000
|
-
Add Anchor
|
|
4001
|
-
</button>
|
|
4002
|
-
</div>
|
|
3850
|
+
<AxisAnchorEditor
|
|
3851
|
+
axisKey='xAxis'
|
|
3852
|
+
config={config}
|
|
3853
|
+
lineOptions={lineOptions}
|
|
3854
|
+
updateConfig={updateConfig}
|
|
3855
|
+
/>
|
|
4003
3856
|
)}
|
|
4004
3857
|
|
|
4005
3858
|
{visHasAnchors() && config.orientation === 'horizontal' && (
|
|
4006
|
-
<
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
key={`accordion-yaxis-anchors-${index}`}
|
|
4013
|
-
>
|
|
4014
|
-
<AccordionItemHeading className='series-item__title'>
|
|
4015
|
-
<>
|
|
4016
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
4017
|
-
Anchor {index + 1}
|
|
4018
|
-
<button
|
|
4019
|
-
className='series-list__remove'
|
|
4020
|
-
onClick={e => {
|
|
4021
|
-
e.preventDefault()
|
|
4022
|
-
const copiedAnchorGroups = [...config.yAxis.anchors]
|
|
4023
|
-
copiedAnchorGroups.splice(index, 1)
|
|
4024
|
-
updateConfig({
|
|
4025
|
-
...config,
|
|
4026
|
-
yAxis: {
|
|
4027
|
-
...config.yAxis,
|
|
4028
|
-
anchors: copiedAnchorGroups
|
|
4029
|
-
}
|
|
4030
|
-
})
|
|
4031
|
-
}}
|
|
4032
|
-
>
|
|
4033
|
-
Remove
|
|
4034
|
-
</button>
|
|
4035
|
-
</AccordionItemButton>
|
|
4036
|
-
</>
|
|
4037
|
-
</AccordionItemHeading>
|
|
4038
|
-
<AccordionItemPanel>
|
|
4039
|
-
<label>
|
|
4040
|
-
<span>Anchor Value</span>
|
|
4041
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
4042
|
-
<Tooltip.Target>
|
|
4043
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
4044
|
-
</Tooltip.Target>
|
|
4045
|
-
<Tooltip.Content>
|
|
4046
|
-
<p>Enter the value as its shown in the data column</p>
|
|
4047
|
-
</Tooltip.Content>
|
|
4048
|
-
</Tooltip>
|
|
4049
|
-
<input
|
|
4050
|
-
type='text'
|
|
4051
|
-
value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
|
|
4052
|
-
onChange={e => {
|
|
4053
|
-
e.preventDefault()
|
|
4054
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4055
|
-
copiedAnchors[index].value = e.target.value
|
|
4056
|
-
updateConfig({
|
|
4057
|
-
...config,
|
|
4058
|
-
yAxis: {
|
|
4059
|
-
...config.yAxis,
|
|
4060
|
-
anchors: copiedAnchors
|
|
4061
|
-
}
|
|
4062
|
-
})
|
|
4063
|
-
}}
|
|
4064
|
-
/>
|
|
4065
|
-
</label>
|
|
4066
|
-
|
|
4067
|
-
<label>
|
|
4068
|
-
<span>Anchor Color</span>
|
|
4069
|
-
<input
|
|
4070
|
-
type='text'
|
|
4071
|
-
value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
|
|
4072
|
-
onChange={e => {
|
|
4073
|
-
e.preventDefault()
|
|
4074
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4075
|
-
copiedAnchors[index].color = e.target.value
|
|
4076
|
-
updateConfig({
|
|
4077
|
-
...config,
|
|
4078
|
-
yAxis: {
|
|
4079
|
-
...config.yAxis,
|
|
4080
|
-
anchors: copiedAnchors
|
|
4081
|
-
}
|
|
4082
|
-
})
|
|
4083
|
-
}}
|
|
4084
|
-
/>
|
|
4085
|
-
</label>
|
|
4086
|
-
|
|
4087
|
-
<Select
|
|
4088
|
-
value={config.yAxis.anchors[index].lineStyle || ''}
|
|
4089
|
-
label='Anchor Line Style'
|
|
4090
|
-
onChange={e => {
|
|
4091
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4092
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
4093
|
-
updateConfig({
|
|
4094
|
-
...config,
|
|
4095
|
-
yAxis: {
|
|
4096
|
-
...config.yAxis,
|
|
4097
|
-
anchors: copiedAnchors
|
|
4098
|
-
}
|
|
4099
|
-
})
|
|
4100
|
-
}}
|
|
4101
|
-
options={[
|
|
4102
|
-
{ value: '', label: 'Select' },
|
|
4103
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
4104
|
-
]}
|
|
4105
|
-
/>
|
|
4106
|
-
</AccordionItemPanel>
|
|
4107
|
-
</AccordionItem>
|
|
4108
|
-
))}
|
|
4109
|
-
</Accordion>
|
|
4110
|
-
|
|
4111
|
-
<button
|
|
4112
|
-
className='btn btn-primary full-width'
|
|
4113
|
-
onClick={e => {
|
|
4114
|
-
e.preventDefault()
|
|
4115
|
-
const anchors = [...config.yAxis.anchors]
|
|
4116
|
-
anchors.push({} as Anchor)
|
|
4117
|
-
updateConfig({
|
|
4118
|
-
...config,
|
|
4119
|
-
yAxis: {
|
|
4120
|
-
...config.yAxis,
|
|
4121
|
-
anchors
|
|
4122
|
-
}
|
|
4123
|
-
})
|
|
4124
|
-
}}
|
|
4125
|
-
>
|
|
4126
|
-
Add Anchor
|
|
4127
|
-
</button>
|
|
4128
|
-
</div>
|
|
3859
|
+
<AxisAnchorEditor
|
|
3860
|
+
axisKey='yAxis'
|
|
3861
|
+
config={config}
|
|
3862
|
+
lineOptions={lineOptions}
|
|
3863
|
+
updateConfig={updateConfig}
|
|
3864
|
+
/>
|
|
4129
3865
|
)}
|
|
4130
3866
|
</AccordionItemPanel>
|
|
4131
3867
|
</AccordionItem>
|
|
@@ -4143,6 +3879,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4143
3879
|
config={config}
|
|
4144
3880
|
updateField={updateFieldDeprecated}
|
|
4145
3881
|
deleteColumn={removeAdditionalColumn}
|
|
3882
|
+
hiddenColumnNames={seriesOwnedColumnNames}
|
|
4146
3883
|
/>{' '}
|
|
4147
3884
|
</AccordionItemPanel>
|
|
4148
3885
|
</AccordionItem>
|
|
@@ -4367,7 +4104,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4367
4104
|
{config.legend.seriesHighlight &&
|
|
4368
4105
|
config.legend.seriesHighlight.map((val, i) => (
|
|
4369
4106
|
<fieldset className='edit-block' key={`${val}-${i}`}>
|
|
4370
|
-
<
|
|
4107
|
+
<Button
|
|
4371
4108
|
className='btn btn-danger'
|
|
4372
4109
|
onClick={event => {
|
|
4373
4110
|
event.preventDefault()
|
|
@@ -4380,7 +4117,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4380
4117
|
}}
|
|
4381
4118
|
>
|
|
4382
4119
|
Remove
|
|
4383
|
-
</
|
|
4120
|
+
</Button>
|
|
4384
4121
|
<Select
|
|
4385
4122
|
value={config.legend.seriesHighlight[i]}
|
|
4386
4123
|
fieldName='seriesHighlight'
|
|
@@ -4396,8 +4133,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4396
4133
|
/>
|
|
4397
4134
|
</fieldset>
|
|
4398
4135
|
))}
|
|
4399
|
-
<
|
|
4400
|
-
|
|
4136
|
+
<Button
|
|
4137
|
+
variant='editor-primary'
|
|
4401
4138
|
onClick={event => {
|
|
4402
4139
|
event.preventDefault()
|
|
4403
4140
|
const legendColumns = getLegendColumns()
|
|
@@ -4413,7 +4150,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4413
4150
|
}}
|
|
4414
4151
|
>
|
|
4415
4152
|
Add Isolate Value
|
|
4416
|
-
</
|
|
4153
|
+
</Button>
|
|
4417
4154
|
</fieldset>
|
|
4418
4155
|
)}
|
|
4419
4156
|
{/* end: isolated values */}
|
|
@@ -4600,6 +4337,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4600
4337
|
enableMarkupVariables={config.enableMarkupVariables || false}
|
|
4601
4338
|
onMarkupVariablesChange={variables => updateField(null, null, 'markupVariables', variables)}
|
|
4602
4339
|
onToggleEnable={enabled => updateField(null, null, 'enableMarkupVariables', enabled)}
|
|
4340
|
+
dataMetadata={config.dataMetadata}
|
|
4603
4341
|
/>
|
|
4604
4342
|
)}
|
|
4605
4343
|
<Panels.SmallMultiples name='Small Multiples' />
|