@cdc/chart 4.26.3 → 4.26.5
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 +489 -0
- package/README.md +42 -17
- package/dist/cdcchart.js +39024 -36587
- package/examples/feature/bar/additional-column-tooltip.json +3 -3
- package/examples/feature/deviation/planet-deviation-config.json +2 -2
- package/examples/feature/heatmap/average-age-categorical.json +313 -0
- package/examples/feature/heatmap/calendar-heatmap.json +134 -0
- package/examples/feature/heatmap/cell-values-bottom-axis.json +181 -0
- package/examples/feature/heatmap/sparse-aggregation.json +158 -0
- package/examples/feature/paired-bar/paired-bar-example.json +2 -2
- 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 +1 -1
- package/examples/minimal-example.json +24 -0
- package/examples/private/bump-chart.json +1116 -0
- package/examples/private/test-123.json +624 -0
- package/examples/private/test2.json +35012 -0
- package/package.json +5 -4
- package/src/CdcChartComponent.tsx +144 -60
- package/src/_stories/Chart.AltText.stories.tsx +136 -0
- package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
- package/src/_stories/Chart.HeatMap.stories.tsx +187 -0
- package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
- package/src/_stories/Chart.Sankey.smoke.stories.tsx +62 -0
- package/src/_stories/Chart.SmallMultiples.smoke.stories.tsx +108 -0
- package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +12 -0
- package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
- package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +13 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +151 -85
- package/src/_stories/ChartBrush.Interaction.stories.tsx +112 -0
- package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +13 -4
- package/src/_stories/ChartEditor.Editor.stories.tsx +23 -0
- package/src/_stories/ChartLine.DashedDates.smoke.stories.tsx +23 -0
- package/src/_stories/_mock/alt_text_metadata.json +38 -0
- package/src/_stories/_mock/heatmap-average-age-categorical.json +315 -0
- package/src/_stories/_mock/heatmap.json +156 -0
- package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
- package/src/_stories/_mock/paired-bar-abbr.json +1 -1
- package/src/_stories/_mock/paired-bar.json +1 -1
- package/src/_stories/_mock/reported_pertussis_cases.json +1643 -0
- package/src/_stories/_mock/sankey_mock.json +78 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +1 -1
- package/src/components/Annotations/components/AnnotationDraggable.tsx +2 -2
- package/src/components/Annotations/components/AnnotationDropdown.tsx +5 -2
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
- package/src/components/Axis/BottomAxis.tsx +1 -1
- package/src/components/Axis/LeftAxis.tsx +15 -14
- package/src/components/Axis/LeftAxisGridlines.tsx +14 -13
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +9 -5
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +9 -5
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +9 -5
- package/src/components/BarChart/components/BarChart.Vertical.tsx +9 -6
- package/src/components/BarChart/components/BarChart.tsx +2 -6
- package/src/components/BarChart/helpers/useBarChart.ts +1 -1
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
- package/src/components/Brush/BrushSelector.tsx +88 -187
- package/src/components/Brush/brushInteraction.ts +22 -0
- package/src/components/Brush/tests/brushInteraction.test.ts +38 -0
- package/src/components/EditorPanel/EditorPanel.tsx +946 -960
- package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +229 -165
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +105 -13
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +169 -116
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +159 -109
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +14 -28
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +1 -1
- package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +57 -0
- package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +56 -0
- package/src/components/EditorPanel/useEditorPermissions.test.tsx +70 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +32 -21
- package/src/components/Forecasting/Forecasting.tsx +2 -2
- package/src/components/HeatMap/components/HeatMap.tsx +762 -0
- package/src/components/HeatMap/components/HeatMapGradientLegend.tsx +114 -0
- package/src/components/HeatMap/heatmap.constants.ts +13 -0
- package/src/components/HeatMap/heatmap.css +71 -0
- package/src/components/HeatMap/helpers/index.ts +261 -0
- package/src/components/HeatMap/index.tsx +5 -0
- package/src/components/HeatMap/tests/HeatMap.test.tsx +1040 -0
- package/src/components/HeatMap/tests/helpers.test.ts +167 -0
- 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 +5 -0
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
- 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 +22 -24
- package/src/components/LineChart/helpers.test.ts +345 -0
- package/src/components/LineChart/helpers.ts +15 -5
- package/src/components/LineChart/index.tsx +18 -5
- package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
- package/src/components/LinearChart/tests/LinearChart.test.tsx +228 -7
- package/src/components/LinearChart/tests/mockConfigContext.ts +1 -0
- package/src/components/LinearChart.tsx +155 -77
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/PieChart/PieChart.tsx +15 -10
- package/src/components/RadarChart/RadarChart.tsx +3 -1
- package/src/components/Regions/components/Regions.tsx +199 -35
- package/src/components/Sankey/components/Sankey.tsx +7 -3
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +7 -6
- package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +31 -3
- package/src/components/SmallMultiples/SmallMultiples.css +12 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +15 -9
- package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +152 -0
- package/src/components/Sparkline/components/SparkLine.tsx +5 -10
- package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +1 -1
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +2 -2
- package/src/data/initial-state.js +12 -0
- package/src/helpers/axisLabelFontSize.ts +8 -0
- package/src/helpers/bumpChartTooltip.ts +54 -0
- package/src/helpers/calculateLeftYAxisWidth.ts +197 -0
- package/src/helpers/ensureSpecialChartAxisTypes.ts +11 -0
- package/src/helpers/getMinMax.ts +2 -3
- package/src/helpers/getYAxisAutoPadding.ts +8 -6
- package/src/helpers/getYAxisAutoPaddingMode.ts +17 -0
- package/src/helpers/handleChartAriaLabels.ts +23 -10
- package/src/helpers/seriesHighlight.ts +26 -0
- package/src/helpers/tests/axisLabelFontSize.test.ts +15 -0
- package/src/helpers/tests/bumpChartTooltip.test.ts +75 -0
- package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +30 -0
- package/src/helpers/tests/getYAxisAutoPadding.test.ts +37 -0
- package/src/helpers/tests/getYAxisAutoPaddingMode.test.ts +90 -0
- package/src/helpers/tests/handleChartAriaLabels.test.ts +71 -0
- package/src/helpers/tests/seriesHighlight.test.ts +61 -0
- package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
- package/src/helpers/tooltipHelpers.ts +176 -0
- package/src/hooks/tests/useScales.test.tsx +105 -0
- package/src/hooks/useHighlightedBars.ts +9 -16
- package/src/hooks/useProgrammaticTooltip.ts +16 -2
- package/src/hooks/useScales.ts +19 -9
- package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
- package/src/hooks/useTooltip.tsx +167 -38
- package/src/index.jsx +5 -2
- package/src/scss/main.scss +32 -49
- package/src/test/CdcChart.test.jsx +24 -0
- package/src/types/ChartConfig.ts +19 -0
- package/src/types/ChartContext.ts +2 -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/src/_stories/Chart.SmallMultiples.stories.tsx +0 -63
- /package/examples/{data → __data__}/data-with-metadata.json +0 -0
- /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.CustomColors.stories.tsx → Chart.CustomColors.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Defaults.stories.tsx → Chart.Defaults.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/{Chart.SmallestLeftAxisMax.stories.tsx → Chart.SmallestLeftAxisMax.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/{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/{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'
|
|
@@ -59,6 +61,11 @@ import { paletteMigrationMap, twoColorPaletteMigrationMap } from '@cdc/core/help
|
|
|
59
61
|
import { isV1Palette, migratePaletteWithMap } from '@cdc/core/helpers/palettes/utils'
|
|
60
62
|
import { USE_V2_MIGRATION } from '@cdc/core/helpers/constants'
|
|
61
63
|
import { getSeriesOwnedColumnNames } from '../../helpers/seriesColumnSettings'
|
|
64
|
+
import {
|
|
65
|
+
HEATMAP_CONFIG_DEFAULTS,
|
|
66
|
+
MAX_HEATMAP_COLOR_BUCKETS,
|
|
67
|
+
MIN_HEATMAP_COLOR_BUCKETS
|
|
68
|
+
} from '../HeatMap/heatmap.constants'
|
|
62
69
|
|
|
63
70
|
interface PreliminaryProps {
|
|
64
71
|
config: ChartConfig
|
|
@@ -158,324 +165,363 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
158
165
|
updateConfig({ ...config, preliminaryData })
|
|
159
166
|
}
|
|
160
167
|
|
|
168
|
+
const moveColumn = (sourceIndex, destinationIndex) => {
|
|
169
|
+
const preliminaryData = config.preliminaryData ? [...config.preliminaryData] : []
|
|
170
|
+
const [movedItem] = preliminaryData.splice(sourceIndex, 1)
|
|
171
|
+
preliminaryData.splice(destinationIndex, 0, movedItem)
|
|
172
|
+
updateConfig({ ...config, preliminaryData })
|
|
173
|
+
}
|
|
174
|
+
|
|
161
175
|
return (
|
|
162
176
|
<>
|
|
163
|
-
|
|
164
|
-
config.preliminaryData
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
</Tooltip>
|
|
223
|
-
}
|
|
224
|
-
value={column}
|
|
225
|
-
initial='Select'
|
|
226
|
-
fieldName='column'
|
|
227
|
-
label='Add Data Series'
|
|
228
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
229
|
-
options={config.runtime?.seriesKeys}
|
|
230
|
-
/>
|
|
231
|
-
<TextField
|
|
232
|
-
value={value}
|
|
233
|
-
fieldName='value'
|
|
234
|
-
label='Suppressed Data Value'
|
|
235
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
236
|
-
/>
|
|
237
|
-
{(hasComboLineSeries || config.visualizationType === 'Line') && (
|
|
238
|
-
<>
|
|
239
|
-
<Select
|
|
240
|
-
tooltip={
|
|
241
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
242
|
-
<Tooltip.Target>
|
|
243
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
244
|
-
</Tooltip.Target>
|
|
245
|
-
<Tooltip.Content>
|
|
246
|
-
<p>
|
|
247
|
-
The recommended approach for presenting data is to include a footnote indicating any
|
|
248
|
-
data suppression.
|
|
249
|
-
</p>
|
|
250
|
-
</Tooltip.Content>
|
|
251
|
-
</Tooltip>
|
|
252
|
-
}
|
|
253
|
-
value={style}
|
|
254
|
-
initial='Select'
|
|
255
|
-
fieldName='style'
|
|
256
|
-
label={'suppression line style'}
|
|
257
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
258
|
-
options={getStyleOptions(type)}
|
|
259
|
-
/>
|
|
260
|
-
<CheckBox
|
|
261
|
-
value={hideLineStyle}
|
|
262
|
-
fieldName='hideLineStyle'
|
|
263
|
-
label='Hide Suppressed line Style'
|
|
264
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
265
|
-
/>
|
|
266
|
-
</>
|
|
267
|
-
)}
|
|
268
|
-
|
|
269
|
-
{(hasComboBarSeries || config.visualizationType === 'Bar') && (
|
|
270
|
-
<>
|
|
271
|
-
<Select
|
|
272
|
-
tooltip={
|
|
273
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
274
|
-
<Tooltip.Target>
|
|
275
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
276
|
-
</Tooltip.Target>
|
|
277
|
-
<Tooltip.Content>
|
|
278
|
-
<p>
|
|
279
|
-
A symbol is <i>required</i> to indicate suppressed data. We suggest "double
|
|
280
|
-
asterisks." If "double asterisks" are already used elsewhere (e.g., footnotes), please
|
|
281
|
-
select an alternative symbol from the menu to denote data suppression.
|
|
282
|
-
</p>
|
|
283
|
-
</Tooltip.Content>
|
|
284
|
-
</Tooltip>
|
|
285
|
-
}
|
|
286
|
-
value={symbol}
|
|
287
|
-
initial='Select'
|
|
288
|
-
fieldName='symbol'
|
|
289
|
-
label={config.visualizationType === 'Combo' ? 'suppression bar symbol' : 'suppression symbol'}
|
|
290
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
291
|
-
options={getSymbolOptions()}
|
|
292
|
-
/>
|
|
293
|
-
<CheckBox
|
|
294
|
-
value={hideBarSymbol}
|
|
295
|
-
fieldName='hideBarSymbol'
|
|
296
|
-
label='Hide Suppressed Bar Symbol '
|
|
297
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
298
|
-
/>
|
|
299
|
-
</>
|
|
300
|
-
)}
|
|
177
|
+
<GroupedList
|
|
178
|
+
items={config.preliminaryData}
|
|
179
|
+
label='Suppressed Data'
|
|
180
|
+
droppableId='chart-preliminary-data-order'
|
|
181
|
+
onDragEnd={({ source, destination }) => {
|
|
182
|
+
if (!destination || source.index === destination.index) return
|
|
183
|
+
moveColumn(source.index, destination.index)
|
|
184
|
+
}}
|
|
185
|
+
renderItem={(
|
|
186
|
+
{
|
|
187
|
+
displayGray,
|
|
188
|
+
circleSize,
|
|
189
|
+
column,
|
|
190
|
+
displayLegend,
|
|
191
|
+
displayTable,
|
|
192
|
+
displayTooltip,
|
|
193
|
+
label,
|
|
194
|
+
seriesKeys,
|
|
195
|
+
style,
|
|
196
|
+
symbol,
|
|
197
|
+
type,
|
|
198
|
+
value,
|
|
199
|
+
hideBarSymbol,
|
|
200
|
+
hideLineStyle
|
|
201
|
+
},
|
|
202
|
+
i
|
|
203
|
+
) => (
|
|
204
|
+
<Draggable key={`preliminaryData-${i}`} draggableId={`preliminaryData-${i}`} index={i}>
|
|
205
|
+
{(provided, snapshot) => (
|
|
206
|
+
<div
|
|
207
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
208
|
+
style={provided.draggableProps.style}
|
|
209
|
+
ref={provided.innerRef}
|
|
210
|
+
{...provided.draggableProps}
|
|
211
|
+
{...provided.dragHandleProps}
|
|
212
|
+
>
|
|
213
|
+
<Accordion allowZeroExpanded>
|
|
214
|
+
<AccordionItem className='series-item series-item--chart'>
|
|
215
|
+
<AccordionItemHeading className='series-item__title'>
|
|
216
|
+
<AccordionItemButton className='accordion__button'>
|
|
217
|
+
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
218
|
+
{type === 'suppression' ? 'Suppressed Data' : `Effect Data ${i + 1}`}
|
|
219
|
+
</AccordionItemButton>
|
|
220
|
+
</AccordionItemHeading>
|
|
221
|
+
<AccordionItemPanel>
|
|
222
|
+
<div className='series-item__panel-actions'>
|
|
223
|
+
<Button
|
|
224
|
+
type='button'
|
|
225
|
+
variant='danger'
|
|
226
|
+
size='sm'
|
|
227
|
+
className='grouped-list__remove'
|
|
228
|
+
onClick={event => {
|
|
229
|
+
event.preventDefault()
|
|
230
|
+
removeColumn(i)
|
|
231
|
+
}}
|
|
232
|
+
>
|
|
233
|
+
Remove
|
|
234
|
+
</Button>
|
|
235
|
+
</div>
|
|
301
236
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
</Tooltip.Target>
|
|
308
|
-
<Tooltip.Content>
|
|
309
|
-
<p>This label will display in the tooltip and legend.</p>
|
|
310
|
-
</Tooltip.Content>
|
|
311
|
-
</Tooltip>
|
|
312
|
-
}
|
|
313
|
-
value={label ? label : 'Suppressed'}
|
|
314
|
-
fieldName='label'
|
|
315
|
-
label='Suppressed Data Label'
|
|
316
|
-
placeholder=''
|
|
317
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
318
|
-
/>
|
|
319
|
-
<CheckBox
|
|
320
|
-
display={config.visualizationSubType === 'regular'}
|
|
321
|
-
tooltip={
|
|
322
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
323
|
-
<Tooltip.Target>
|
|
324
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
325
|
-
</Tooltip.Target>
|
|
326
|
-
<Tooltip.Content>
|
|
327
|
-
<p>
|
|
328
|
-
Deselecting the "Display In Tooltips" option prevents suppressed values from appearing in
|
|
329
|
-
tooltips.
|
|
330
|
-
</p>
|
|
331
|
-
</Tooltip.Content>
|
|
332
|
-
</Tooltip>
|
|
333
|
-
}
|
|
334
|
-
value={displayTooltip}
|
|
335
|
-
fieldName='displayTooltip'
|
|
336
|
-
label='Display in tooltips'
|
|
337
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
338
|
-
/>
|
|
339
|
-
<CheckBox
|
|
340
|
-
display={config.visualizationSubType === 'regular'}
|
|
341
|
-
tooltip={
|
|
342
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
343
|
-
<Tooltip.Target>
|
|
344
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
345
|
-
</Tooltip.Target>
|
|
346
|
-
<Tooltip.Content>
|
|
347
|
-
<p>
|
|
348
|
-
Deselecting "Display in Legend" indicates that you do not want to display suppressed data
|
|
349
|
-
in the legend.
|
|
350
|
-
</p>
|
|
351
|
-
</Tooltip.Content>
|
|
352
|
-
</Tooltip>
|
|
353
|
-
}
|
|
354
|
-
value={displayLegend}
|
|
355
|
-
fieldName='displayLegend'
|
|
356
|
-
label='Display in legend'
|
|
357
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
358
|
-
/>
|
|
359
|
-
<CheckBox
|
|
360
|
-
display={config.visualizationSubType === 'regular'}
|
|
361
|
-
tooltip={
|
|
362
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
363
|
-
<Tooltip.Target>
|
|
364
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
365
|
-
</Tooltip.Target>
|
|
366
|
-
<Tooltip.Content>
|
|
367
|
-
<p>
|
|
368
|
-
Deselecting "Display In Data Table" indicates that you do not want to display suppressed
|
|
369
|
-
data in the data table.
|
|
370
|
-
</p>
|
|
371
|
-
</Tooltip.Content>
|
|
372
|
-
</Tooltip>
|
|
373
|
-
}
|
|
374
|
-
value={displayTable}
|
|
375
|
-
fieldName='displayTable'
|
|
376
|
-
label='Display in table'
|
|
377
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
378
|
-
/>
|
|
379
|
-
<CheckBox
|
|
380
|
-
display={config.visualizationSubType === 'regular'}
|
|
381
|
-
tooltip={
|
|
382
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
383
|
-
<Tooltip.Target>
|
|
384
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
385
|
-
</Tooltip.Target>
|
|
386
|
-
<Tooltip.Content>
|
|
387
|
-
<p>Selecting this option will apply to chart, tooltip hover, legend, and data table.</p>
|
|
388
|
-
</Tooltip.Content>
|
|
389
|
-
</Tooltip>
|
|
390
|
-
}
|
|
391
|
-
value={displayGray}
|
|
392
|
-
fieldName='displayGray'
|
|
393
|
-
label='Highlight Suppressed Data In Gray'
|
|
394
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
395
|
-
/>
|
|
396
|
-
</>
|
|
397
|
-
) : (
|
|
398
|
-
<>
|
|
399
|
-
<label>
|
|
400
|
-
<span className='edit-label'>ASSOCIATE TO THESE SERIES</span>
|
|
401
|
-
<MultiSelect
|
|
402
|
-
fieldName='seriesKeys'
|
|
403
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
404
|
-
options={(config.runtime.lineSeriesKeys ?? config.runtime?.seriesKeys).map(c => ({
|
|
405
|
-
label: c,
|
|
406
|
-
value: c
|
|
407
|
-
}))}
|
|
408
|
-
selected={seriesKeys}
|
|
409
|
-
/>
|
|
410
|
-
</label>
|
|
411
|
-
<Select
|
|
412
|
-
value={column}
|
|
413
|
-
initial='Select'
|
|
414
|
-
fieldName='column'
|
|
415
|
-
label='COLUMN WITH CONFIGURATION VALUE'
|
|
416
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
417
|
-
options={getColumnOptions()}
|
|
418
|
-
/>
|
|
419
|
-
<TextField
|
|
420
|
-
tooltip={
|
|
421
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
422
|
-
<Tooltip.Target>
|
|
423
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
424
|
-
</Tooltip.Target>
|
|
425
|
-
<Tooltip.Content>
|
|
426
|
-
<p>
|
|
427
|
-
If 'Filled Circles' is selected as the style, this field is optional, and the style
|
|
428
|
-
'Filled Circles' will apply to all points within the associated series data.
|
|
429
|
-
</p>
|
|
430
|
-
</Tooltip.Content>
|
|
431
|
-
</Tooltip>
|
|
432
|
-
}
|
|
433
|
-
value={value}
|
|
434
|
-
fieldName='value'
|
|
435
|
-
label='VALUE TO TRIGGER'
|
|
436
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
437
|
-
/>
|
|
438
|
-
<Select
|
|
439
|
-
value={style}
|
|
440
|
-
initial='Select'
|
|
441
|
-
fieldName='style'
|
|
442
|
-
label='Style'
|
|
443
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
444
|
-
options={getStyleOptions(type)}
|
|
445
|
-
/>
|
|
446
|
-
{style.includes('Circles') && (
|
|
447
|
-
<TextField
|
|
448
|
-
className='number-narrow'
|
|
449
|
-
type='number'
|
|
450
|
-
value={circleSize}
|
|
451
|
-
fieldName='circleSize'
|
|
452
|
-
label='circle size'
|
|
453
|
-
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
454
|
-
/>
|
|
455
|
-
)}
|
|
456
|
-
{style !== 'Filled Circles' && (
|
|
457
|
-
<TextField
|
|
458
|
-
value={label}
|
|
459
|
-
fieldName='label'
|
|
460
|
-
label='Label'
|
|
461
|
-
placeholder=''
|
|
237
|
+
<Select
|
|
238
|
+
value={type}
|
|
239
|
+
initial={config.visualizationType == 'Bar' ? '' : 'Select'}
|
|
240
|
+
fieldName='type'
|
|
241
|
+
label='Type'
|
|
462
242
|
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
243
|
+
options={getTypeOptions()}
|
|
463
244
|
/>
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
245
|
+
{type === 'suppression' ? (
|
|
246
|
+
<>
|
|
247
|
+
<Select
|
|
248
|
+
tooltip={
|
|
249
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
250
|
+
<Tooltip.Target>
|
|
251
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
252
|
+
</Tooltip.Target>
|
|
253
|
+
<Tooltip.Content>
|
|
254
|
+
<p>
|
|
255
|
+
{' '}
|
|
256
|
+
Without a selected "Data Series", the suppression symbol will be applied for all
|
|
257
|
+
series in the current dataset visualization. However, choosing a specific "data
|
|
258
|
+
series" will isolate the suppression to that series.
|
|
259
|
+
</p>
|
|
260
|
+
</Tooltip.Content>
|
|
261
|
+
</Tooltip>
|
|
262
|
+
}
|
|
263
|
+
value={column}
|
|
264
|
+
initial='Select'
|
|
265
|
+
fieldName='column'
|
|
266
|
+
label='Add Data Series'
|
|
267
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
268
|
+
options={config.runtime?.seriesKeys}
|
|
269
|
+
/>
|
|
270
|
+
<TextField
|
|
271
|
+
value={value}
|
|
272
|
+
fieldName='value'
|
|
273
|
+
label='Suppressed Data Value'
|
|
274
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
275
|
+
/>
|
|
276
|
+
{(hasComboLineSeries || config.visualizationType === 'Line') && (
|
|
277
|
+
<>
|
|
278
|
+
<Select
|
|
279
|
+
tooltip={
|
|
280
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
281
|
+
<Tooltip.Target>
|
|
282
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
283
|
+
</Tooltip.Target>
|
|
284
|
+
<Tooltip.Content>
|
|
285
|
+
<p>
|
|
286
|
+
The recommended approach for presenting data is to include a footnote indicating
|
|
287
|
+
any data suppression.
|
|
288
|
+
</p>
|
|
289
|
+
</Tooltip.Content>
|
|
290
|
+
</Tooltip>
|
|
291
|
+
}
|
|
292
|
+
value={style}
|
|
293
|
+
initial='Select'
|
|
294
|
+
fieldName='style'
|
|
295
|
+
label={'suppression line style'}
|
|
296
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
297
|
+
options={getStyleOptions(type)}
|
|
298
|
+
/>
|
|
299
|
+
<CheckBox
|
|
300
|
+
value={hideLineStyle}
|
|
301
|
+
fieldName='hideLineStyle'
|
|
302
|
+
label='Hide Suppressed line Style'
|
|
303
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
304
|
+
/>
|
|
305
|
+
</>
|
|
306
|
+
)}
|
|
307
|
+
|
|
308
|
+
{(hasComboBarSeries || config.visualizationType === 'Bar') && (
|
|
309
|
+
<>
|
|
310
|
+
<Select
|
|
311
|
+
tooltip={
|
|
312
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
313
|
+
<Tooltip.Target>
|
|
314
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
315
|
+
</Tooltip.Target>
|
|
316
|
+
<Tooltip.Content>
|
|
317
|
+
<p>
|
|
318
|
+
A symbol is <i>required</i> to indicate suppressed data. We suggest "double
|
|
319
|
+
asterisks." If "double asterisks" are already used elsewhere (e.g., footnotes),
|
|
320
|
+
please select an alternative symbol from the menu to denote data suppression.
|
|
321
|
+
</p>
|
|
322
|
+
</Tooltip.Content>
|
|
323
|
+
</Tooltip>
|
|
324
|
+
}
|
|
325
|
+
value={symbol}
|
|
326
|
+
initial='Select'
|
|
327
|
+
fieldName='symbol'
|
|
328
|
+
label={
|
|
329
|
+
config.visualizationType === 'Combo' ? 'suppression bar symbol' : 'suppression symbol'
|
|
330
|
+
}
|
|
331
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
332
|
+
options={getSymbolOptions()}
|
|
333
|
+
/>
|
|
334
|
+
<CheckBox
|
|
335
|
+
value={hideBarSymbol}
|
|
336
|
+
fieldName='hideBarSymbol'
|
|
337
|
+
label='Hide Suppressed Bar Symbol '
|
|
338
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
339
|
+
/>
|
|
340
|
+
</>
|
|
341
|
+
)}
|
|
342
|
+
|
|
343
|
+
<TextField
|
|
344
|
+
tooltip={
|
|
345
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
346
|
+
<Tooltip.Target>
|
|
347
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
348
|
+
</Tooltip.Target>
|
|
349
|
+
<Tooltip.Content>
|
|
350
|
+
<p>This label will display in the tooltip and legend.</p>
|
|
351
|
+
</Tooltip.Content>
|
|
352
|
+
</Tooltip>
|
|
353
|
+
}
|
|
354
|
+
value={label ? label : 'Suppressed'}
|
|
355
|
+
fieldName='label'
|
|
356
|
+
label='Suppressed Data Label'
|
|
357
|
+
placeholder=''
|
|
358
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
359
|
+
/>
|
|
360
|
+
<CheckBox
|
|
361
|
+
display={config.visualizationSubType === 'regular'}
|
|
362
|
+
tooltip={
|
|
363
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
364
|
+
<Tooltip.Target>
|
|
365
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
366
|
+
</Tooltip.Target>
|
|
367
|
+
<Tooltip.Content>
|
|
368
|
+
<p>
|
|
369
|
+
Deselecting the "Display In Tooltips" option prevents suppressed values from
|
|
370
|
+
appearing in tooltips.
|
|
371
|
+
</p>
|
|
372
|
+
</Tooltip.Content>
|
|
373
|
+
</Tooltip>
|
|
374
|
+
}
|
|
375
|
+
value={displayTooltip}
|
|
376
|
+
fieldName='displayTooltip'
|
|
377
|
+
label='Display in tooltips'
|
|
378
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
379
|
+
/>
|
|
380
|
+
<CheckBox
|
|
381
|
+
display={config.visualizationSubType === 'regular'}
|
|
382
|
+
tooltip={
|
|
383
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
384
|
+
<Tooltip.Target>
|
|
385
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
386
|
+
</Tooltip.Target>
|
|
387
|
+
<Tooltip.Content>
|
|
388
|
+
<p>
|
|
389
|
+
Deselecting "Display in Legend" indicates that you do not want to display suppressed
|
|
390
|
+
data in the legend.
|
|
391
|
+
</p>
|
|
392
|
+
</Tooltip.Content>
|
|
393
|
+
</Tooltip>
|
|
394
|
+
}
|
|
395
|
+
value={displayLegend}
|
|
396
|
+
fieldName='displayLegend'
|
|
397
|
+
label='Display in legend'
|
|
398
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
399
|
+
/>
|
|
400
|
+
<CheckBox
|
|
401
|
+
display={config.visualizationSubType === 'regular'}
|
|
402
|
+
tooltip={
|
|
403
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
404
|
+
<Tooltip.Target>
|
|
405
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
406
|
+
</Tooltip.Target>
|
|
407
|
+
<Tooltip.Content>
|
|
408
|
+
<p>
|
|
409
|
+
Deselecting "Display In Data Table" indicates that you do not want to display
|
|
410
|
+
suppressed data in the data table.
|
|
411
|
+
</p>
|
|
412
|
+
</Tooltip.Content>
|
|
413
|
+
</Tooltip>
|
|
414
|
+
}
|
|
415
|
+
value={displayTable}
|
|
416
|
+
fieldName='displayTable'
|
|
417
|
+
label='Display in table'
|
|
418
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
419
|
+
/>
|
|
420
|
+
<CheckBox
|
|
421
|
+
display={config.visualizationSubType === 'regular'}
|
|
422
|
+
tooltip={
|
|
423
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
424
|
+
<Tooltip.Target>
|
|
425
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
426
|
+
</Tooltip.Target>
|
|
427
|
+
<Tooltip.Content>
|
|
428
|
+
<p>
|
|
429
|
+
Selecting this option will apply to chart, tooltip hover, legend, and data table.
|
|
430
|
+
</p>
|
|
431
|
+
</Tooltip.Content>
|
|
432
|
+
</Tooltip>
|
|
433
|
+
}
|
|
434
|
+
value={displayGray}
|
|
435
|
+
fieldName='displayGray'
|
|
436
|
+
label='Highlight Suppressed Data In Gray'
|
|
437
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
438
|
+
/>
|
|
439
|
+
</>
|
|
440
|
+
) : (
|
|
441
|
+
<>
|
|
442
|
+
<label>
|
|
443
|
+
<span className='edit-label'>ASSOCIATE TO THESE SERIES</span>
|
|
444
|
+
<MultiSelect
|
|
445
|
+
fieldName='seriesKeys'
|
|
446
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
447
|
+
options={(config.runtime.lineSeriesKeys ?? config.runtime?.seriesKeys).map(c => ({
|
|
448
|
+
label: c,
|
|
449
|
+
value: c
|
|
450
|
+
}))}
|
|
451
|
+
selected={seriesKeys}
|
|
452
|
+
/>
|
|
453
|
+
</label>
|
|
454
|
+
<Select
|
|
455
|
+
value={column}
|
|
456
|
+
initial='Select'
|
|
457
|
+
fieldName='column'
|
|
458
|
+
label='COLUMN WITH CONFIGURATION VALUE'
|
|
459
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
460
|
+
options={getColumnOptions()}
|
|
461
|
+
/>
|
|
462
|
+
<TextField
|
|
463
|
+
tooltip={
|
|
464
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
465
|
+
<Tooltip.Target>
|
|
466
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
467
|
+
</Tooltip.Target>
|
|
468
|
+
<Tooltip.Content>
|
|
469
|
+
<p>
|
|
470
|
+
If 'Filled Circles' is selected as the style, this field is optional, and the style
|
|
471
|
+
'Filled Circles' will apply to all points within the associated series data.
|
|
472
|
+
</p>
|
|
473
|
+
</Tooltip.Content>
|
|
474
|
+
</Tooltip>
|
|
475
|
+
}
|
|
476
|
+
value={value}
|
|
477
|
+
fieldName='value'
|
|
478
|
+
label='VALUE TO TRIGGER'
|
|
479
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
480
|
+
/>
|
|
481
|
+
<Select
|
|
482
|
+
value={style}
|
|
483
|
+
initial='Select'
|
|
484
|
+
fieldName='style'
|
|
485
|
+
label='Style'
|
|
486
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
487
|
+
options={getStyleOptions(type)}
|
|
488
|
+
/>
|
|
489
|
+
{style?.includes('Circles') && (
|
|
490
|
+
<TextField
|
|
491
|
+
className='number-narrow'
|
|
492
|
+
type='number'
|
|
493
|
+
value={circleSize}
|
|
494
|
+
fieldName='circleSize'
|
|
495
|
+
label='circle size'
|
|
496
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
497
|
+
/>
|
|
498
|
+
)}
|
|
499
|
+
{style !== 'Filled Circles' && (
|
|
500
|
+
<TextField
|
|
501
|
+
value={label}
|
|
502
|
+
fieldName='label'
|
|
503
|
+
label='Label'
|
|
504
|
+
placeholder=''
|
|
505
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
506
|
+
/>
|
|
507
|
+
)}
|
|
508
|
+
</>
|
|
509
|
+
)}
|
|
510
|
+
</AccordionItemPanel>
|
|
511
|
+
</AccordionItem>
|
|
512
|
+
</Accordion>
|
|
467
513
|
</div>
|
|
468
|
-
)
|
|
469
|
-
|
|
514
|
+
)}
|
|
515
|
+
</Draggable>
|
|
470
516
|
)}
|
|
471
|
-
|
|
472
|
-
<
|
|
517
|
+
/>
|
|
518
|
+
<Button type='button' variant='editor-primary' onClick={addColumn}>
|
|
473
519
|
{config.visualizationType === 'Line'
|
|
474
520
|
? 'Add Special Line'
|
|
475
521
|
: config.visualizationType === 'Bar'
|
|
476
522
|
? ' Add Special Bar'
|
|
477
523
|
: 'Add Special Bar/Line'}
|
|
478
|
-
</
|
|
524
|
+
</Button>
|
|
479
525
|
</>
|
|
480
526
|
)
|
|
481
527
|
}
|
|
@@ -486,6 +532,158 @@ interface CategoricalAxisProps {
|
|
|
486
532
|
display: boolean
|
|
487
533
|
}
|
|
488
534
|
|
|
535
|
+
type AxisAnchorEditorProps = {
|
|
536
|
+
axisKey: 'xAxis' | 'yAxis'
|
|
537
|
+
config: ChartConfig
|
|
538
|
+
lineOptions: { value: string; label?: string }[]
|
|
539
|
+
updateConfig: Function
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({ axisKey, config, lineOptions, updateConfig }) => {
|
|
543
|
+
const anchors = config[axisKey]?.anchors || []
|
|
544
|
+
|
|
545
|
+
const updateAnchors = (nextAnchors: Anchor[]) => {
|
|
546
|
+
updateConfig({
|
|
547
|
+
...config,
|
|
548
|
+
[axisKey]: {
|
|
549
|
+
...config[axisKey],
|
|
550
|
+
anchors: nextAnchors
|
|
551
|
+
}
|
|
552
|
+
})
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
const updateAnchorField = (index: number, field: keyof Anchor, value: string) => {
|
|
556
|
+
const copiedAnchors = [...anchors]
|
|
557
|
+
copiedAnchors[index] = {
|
|
558
|
+
...copiedAnchors[index],
|
|
559
|
+
[field]: value
|
|
560
|
+
}
|
|
561
|
+
updateAnchors(copiedAnchors)
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const removeAnchor = (index: number) => {
|
|
565
|
+
const copiedAnchors = [...anchors]
|
|
566
|
+
copiedAnchors.splice(index, 1)
|
|
567
|
+
updateAnchors(copiedAnchors)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
const addAnchor = () => {
|
|
571
|
+
updateAnchors([...anchors, {} as Anchor])
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const reorderAnchors = (sourceIndex: number, destinationIndex: number) => {
|
|
575
|
+
const copiedAnchors = [...anchors]
|
|
576
|
+
const [movedAnchor] = copiedAnchors.splice(sourceIndex, 1)
|
|
577
|
+
copiedAnchors.splice(destinationIndex, 0, movedAnchor)
|
|
578
|
+
updateAnchors(copiedAnchors)
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
return (
|
|
582
|
+
<>
|
|
583
|
+
<GroupedList
|
|
584
|
+
items={anchors}
|
|
585
|
+
label='Anchors'
|
|
586
|
+
droppableId={`${axisKey}-anchors-order`}
|
|
587
|
+
onDragEnd={({ source, destination }) => {
|
|
588
|
+
if (!destination || source.index === destination.index) return
|
|
589
|
+
reorderAnchors(source.index, destination.index)
|
|
590
|
+
}}
|
|
591
|
+
renderItem={(anchor, index) => (
|
|
592
|
+
<Draggable key={`${axisKey}-anchor-${index}`} draggableId={`${axisKey}-anchor-${index}`} index={index}>
|
|
593
|
+
{(provided, snapshot) => (
|
|
594
|
+
<div
|
|
595
|
+
ref={provided.innerRef}
|
|
596
|
+
{...provided.draggableProps}
|
|
597
|
+
{...provided.dragHandleProps}
|
|
598
|
+
className={snapshot.isDragging ? 'currently-dragging' : ''}
|
|
599
|
+
style={provided.draggableProps.style}
|
|
600
|
+
>
|
|
601
|
+
<Accordion allowZeroExpanded>
|
|
602
|
+
<AccordionItem className='series-item series-item--chart'>
|
|
603
|
+
<AccordionItemHeading className='series-item__title'>
|
|
604
|
+
<AccordionItemButton className='accordion__button'>
|
|
605
|
+
<Icon display='move' size={15} style={{ cursor: 'default' }} />
|
|
606
|
+
{`Anchor ${index + 1}`}
|
|
607
|
+
</AccordionItemButton>
|
|
608
|
+
</AccordionItemHeading>
|
|
609
|
+
<AccordionItemPanel>
|
|
610
|
+
<div className='series-item__panel-actions'>
|
|
611
|
+
<Button
|
|
612
|
+
type='button'
|
|
613
|
+
variant='danger'
|
|
614
|
+
size='sm'
|
|
615
|
+
className='grouped-list__remove'
|
|
616
|
+
onClick={e => {
|
|
617
|
+
e.preventDefault()
|
|
618
|
+
removeAnchor(index)
|
|
619
|
+
}}
|
|
620
|
+
>
|
|
621
|
+
Remove
|
|
622
|
+
</Button>
|
|
623
|
+
</div>
|
|
624
|
+
<label>
|
|
625
|
+
<span>Anchor Value</span>
|
|
626
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
627
|
+
<Tooltip.Target>
|
|
628
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
629
|
+
</Tooltip.Target>
|
|
630
|
+
<Tooltip.Content>
|
|
631
|
+
<p>Enter the value as its shown in the data column</p>
|
|
632
|
+
</Tooltip.Content>
|
|
633
|
+
</Tooltip>
|
|
634
|
+
<input
|
|
635
|
+
type='text'
|
|
636
|
+
value={anchor?.value || ''}
|
|
637
|
+
onChange={e => {
|
|
638
|
+
e.preventDefault()
|
|
639
|
+
updateAnchorField(index, 'value', e.target.value)
|
|
640
|
+
}}
|
|
641
|
+
/>
|
|
642
|
+
</label>
|
|
643
|
+
|
|
644
|
+
<label>
|
|
645
|
+
<span>Anchor Color</span>
|
|
646
|
+
<input
|
|
647
|
+
type='text'
|
|
648
|
+
value={anchor?.color || ''}
|
|
649
|
+
onChange={e => {
|
|
650
|
+
e.preventDefault()
|
|
651
|
+
updateAnchorField(index, 'color', e.target.value)
|
|
652
|
+
}}
|
|
653
|
+
/>
|
|
654
|
+
</label>
|
|
655
|
+
|
|
656
|
+
<Select
|
|
657
|
+
value={anchor?.lineStyle || ''}
|
|
658
|
+
label='Anchor Line Style'
|
|
659
|
+
onChange={e => updateAnchorField(index, 'lineStyle', e.target.value)}
|
|
660
|
+
options={[
|
|
661
|
+
{ value: '', label: 'Select' },
|
|
662
|
+
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
663
|
+
]}
|
|
664
|
+
/>
|
|
665
|
+
</AccordionItemPanel>
|
|
666
|
+
</AccordionItem>
|
|
667
|
+
</Accordion>
|
|
668
|
+
</div>
|
|
669
|
+
)}
|
|
670
|
+
</Draggable>
|
|
671
|
+
)}
|
|
672
|
+
/>
|
|
673
|
+
|
|
674
|
+
<Button
|
|
675
|
+
variant='editor-primary'
|
|
676
|
+
onClick={e => {
|
|
677
|
+
e.preventDefault()
|
|
678
|
+
addAnchor()
|
|
679
|
+
}}
|
|
680
|
+
>
|
|
681
|
+
Add Anchor
|
|
682
|
+
</Button>
|
|
683
|
+
</>
|
|
684
|
+
)
|
|
685
|
+
}
|
|
686
|
+
|
|
489
687
|
const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig, display }) => {
|
|
490
688
|
const maxHeight = config?.yAxis?.maxValue
|
|
491
689
|
|
|
@@ -547,7 +745,7 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
547
745
|
return (
|
|
548
746
|
<div key={`preliminaryData-${i}`} className='edit-block'>
|
|
549
747
|
<p>Axis Category {i + 1}</p>
|
|
550
|
-
<
|
|
748
|
+
<Button
|
|
551
749
|
type='button'
|
|
552
750
|
className='btn btn-danger'
|
|
553
751
|
onClick={event => {
|
|
@@ -556,7 +754,7 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
556
754
|
}}
|
|
557
755
|
>
|
|
558
756
|
Remove
|
|
559
|
-
</
|
|
757
|
+
</Button>
|
|
560
758
|
<TextField
|
|
561
759
|
tooltip={
|
|
562
760
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
@@ -602,9 +800,9 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
602
800
|
)
|
|
603
801
|
})}
|
|
604
802
|
|
|
605
|
-
<
|
|
803
|
+
<Button type='button' variant='editor-primary' onClick={addColumn}>
|
|
606
804
|
Add Axis Category
|
|
607
|
-
</
|
|
805
|
+
</Button>
|
|
608
806
|
</>
|
|
609
807
|
)
|
|
610
808
|
}
|
|
@@ -725,7 +923,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
725
923
|
}
|
|
726
924
|
}, [config.visualizationType])
|
|
727
925
|
|
|
728
|
-
const { hasRightAxis } = useRightAxis({ config: config, yMax:
|
|
926
|
+
const { hasRightAxis } = useRightAxis({ config: config, yMax: 0, data: config.data, updateConfig })
|
|
729
927
|
|
|
730
928
|
const getItemStyle = (isDragging, draggableStyle) => ({
|
|
731
929
|
...draggableStyle
|
|
@@ -774,6 +972,17 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
774
972
|
}
|
|
775
973
|
|
|
776
974
|
const updateField = updateFieldFactory(config, updateConfig)
|
|
975
|
+
const getAutoDetectedXAxisDateParseFormat = (dataKey = config.xAxis.dataKey, axisType = config.xAxis.type) => {
|
|
976
|
+
const hasExistingDateParseFormat =
|
|
977
|
+
typeof config.xAxis.dateParseFormat === 'string' && config.xAxis.dateParseFormat.trim() !== ''
|
|
978
|
+
|
|
979
|
+
if (hasExistingDateParseFormat || !['date', 'date-time'].includes(axisType)) {
|
|
980
|
+
return undefined
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
return getAutoDetectedDateParseFormat(config.data, dataKey)
|
|
984
|
+
}
|
|
985
|
+
|
|
777
986
|
const updateFieldDeprecated = (section, subsection, fieldName, newValue) => {
|
|
778
987
|
if (isDebug)
|
|
779
988
|
console.error(
|
|
@@ -816,6 +1025,23 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
816
1025
|
})
|
|
817
1026
|
return
|
|
818
1027
|
}
|
|
1028
|
+
|
|
1029
|
+
if (section === 'xAxis' && !truthy(subsection) && fieldName === 'dataKey') {
|
|
1030
|
+
const autoDetectedDateParseFormat = getAutoDetectedXAxisDateParseFormat(newValue)
|
|
1031
|
+
const updatedConfig = {
|
|
1032
|
+
...config,
|
|
1033
|
+
xAxis: {
|
|
1034
|
+
...config.xAxis,
|
|
1035
|
+
dataKey: newValue,
|
|
1036
|
+
...(autoDetectedDateParseFormat ? { dateParseFormat: autoDetectedDateParseFormat } : {})
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
enforceRestrictions(updatedConfig)
|
|
1041
|
+
updateConfig(updatedConfig)
|
|
1042
|
+
return
|
|
1043
|
+
}
|
|
1044
|
+
|
|
819
1045
|
if (null === section && null === subsection) {
|
|
820
1046
|
// special case that allows for updating the config object directly
|
|
821
1047
|
if (!truthy(fieldName)) console.error('fieldName is required')
|
|
@@ -968,12 +1194,23 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
968
1194
|
return filter ? filteredColumns : allColumns
|
|
969
1195
|
}
|
|
970
1196
|
|
|
1197
|
+
const isHeatMap = config.visualizationType === 'HeatMap'
|
|
1198
|
+
const heatMapOwnedColumnNames = useMemo(
|
|
1199
|
+
() => [config.xAxis?.dataKey, ...(config.series || []).map(series => series.dataKey)].filter(Boolean),
|
|
1200
|
+
[config.xAxis?.dataKey, config.series]
|
|
1201
|
+
)
|
|
1202
|
+
|
|
971
1203
|
const getLegendStyleOptions = (option: 'style' | 'subStyle' | 'shapes' | 'groupBy'): string[] => {
|
|
972
1204
|
const options: string[] = []
|
|
973
1205
|
|
|
974
1206
|
switch (option) {
|
|
975
1207
|
case 'style':
|
|
976
1208
|
options.push('circles', 'boxes')
|
|
1209
|
+
if (config.visualizationType === 'HeatMap') {
|
|
1210
|
+
if (!['right', 'left'].includes(config.legend.position) && config.legend.position) {
|
|
1211
|
+
options.push('gradient')
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
977
1214
|
if (
|
|
978
1215
|
config.visualizationType === 'Bar' &&
|
|
979
1216
|
(!['right', 'left'].includes(config.legend.position) || !config.legend.position)
|
|
@@ -1024,7 +1261,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1024
1261
|
// prettier-ignore
|
|
1025
1262
|
const {
|
|
1026
1263
|
highlightedBarValues,
|
|
1027
|
-
|
|
1264
|
+
getHighlightedSeriesValues,
|
|
1028
1265
|
handleUpdateHighlightedBar,
|
|
1029
1266
|
handleAddNewHighlightedBar,
|
|
1030
1267
|
handleRemoveHighlightedBar,
|
|
@@ -1117,6 +1354,15 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1117
1354
|
if (config.isLollipopChart && config?.series?.length === 0) {
|
|
1118
1355
|
config.runtime.editorErrorMessage = 'Add a data series'
|
|
1119
1356
|
}
|
|
1357
|
+
if (config.visualizationType === 'HeatMap') {
|
|
1358
|
+
const missingMappings = [
|
|
1359
|
+
!config.xAxis?.dataKey && 'Date/Category Axis',
|
|
1360
|
+
(!config.series || config.series.length === 0) && 'Data Series'
|
|
1361
|
+
].filter(Boolean)
|
|
1362
|
+
|
|
1363
|
+
config.runtime.editorErrorMessage =
|
|
1364
|
+
missingMappings.length > 0 ? `${missingMappings.join(', ')} must be set for heatmaps.` : ''
|
|
1365
|
+
}
|
|
1120
1366
|
|
|
1121
1367
|
const section = config.orientation === 'horizontal' ? 'xAxis' : 'yAxis'
|
|
1122
1368
|
const [warningMsg, setWarningMsg] = useState({ maxMsg: '', minMsg: '', rightMaxMessage: '', minMsgRight: '' })
|
|
@@ -1516,6 +1762,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1516
1762
|
'Bump Chart',
|
|
1517
1763
|
'Area Chart',
|
|
1518
1764
|
'Combo',
|
|
1765
|
+
'HeatMap',
|
|
1519
1766
|
'Line',
|
|
1520
1767
|
'Bar',
|
|
1521
1768
|
'Forecasting',
|
|
@@ -1634,6 +1881,27 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1634
1881
|
const hasDynamicCategory = ![undefined, '- Select - '].includes(config.series?.[0]?.dynamicCategory)
|
|
1635
1882
|
const hasMultipleSeries = config.series?.length > 1
|
|
1636
1883
|
|
|
1884
|
+
const highlightedSeriesOptions = useMemo(() => {
|
|
1885
|
+
if (
|
|
1886
|
+
!(
|
|
1887
|
+
config.visualizationType === 'Bar' &&
|
|
1888
|
+
config.series?.length === 1 &&
|
|
1889
|
+
config.highlightedBarValues?.length > 0 &&
|
|
1890
|
+
getHighlightedSeriesValues
|
|
1891
|
+
)
|
|
1892
|
+
) {
|
|
1893
|
+
return []
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1896
|
+
return [...new Set(getHighlightedSeriesValues())].sort().map(option => ({ value: option, label: option }))
|
|
1897
|
+
}, [
|
|
1898
|
+
config.visualizationType,
|
|
1899
|
+
config.series?.length,
|
|
1900
|
+
config.highlightedBarValues?.length,
|
|
1901
|
+
config.data,
|
|
1902
|
+
config.xAxis.dataKey
|
|
1903
|
+
])
|
|
1904
|
+
|
|
1637
1905
|
const editorContextValues = {
|
|
1638
1906
|
addNewExclusion,
|
|
1639
1907
|
data,
|
|
@@ -1652,7 +1920,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1652
1920
|
handleUpdateHighlightedBar,
|
|
1653
1921
|
handleRemoveHighlightedBar,
|
|
1654
1922
|
isPaletteReversed: config.general?.palette?.isReversed,
|
|
1655
|
-
|
|
1923
|
+
getHighlightedSeriesValues,
|
|
1656
1924
|
handleUpdateHighlightedBorderWidth,
|
|
1657
1925
|
handleUpdateHighlightedBarColor,
|
|
1658
1926
|
setLollipopShape,
|
|
@@ -1678,6 +1946,76 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1678
1946
|
return strippedState
|
|
1679
1947
|
}
|
|
1680
1948
|
|
|
1949
|
+
const renderHeatMapSettingsAccordion = () => {
|
|
1950
|
+
if (config.visualizationType !== 'HeatMap') return null
|
|
1951
|
+
|
|
1952
|
+
return (
|
|
1953
|
+
<AccordionItem>
|
|
1954
|
+
<AccordionItemHeading>
|
|
1955
|
+
<AccordionItemButton>HeatMap Settings</AccordionItemButton>
|
|
1956
|
+
</AccordionItemHeading>
|
|
1957
|
+
<AccordionItemPanel>
|
|
1958
|
+
<p className='helper-text'>Selected data series columns provide the heatmap cell values.</p>
|
|
1959
|
+
<CheckBox
|
|
1960
|
+
value={Boolean(config.heatmap?.showCellValues ?? HEATMAP_CONFIG_DEFAULTS.showCellValues)}
|
|
1961
|
+
section='heatmap'
|
|
1962
|
+
fieldName='showCellValues'
|
|
1963
|
+
label='Show Cell Values'
|
|
1964
|
+
updateField={updateFieldDeprecated}
|
|
1965
|
+
/>
|
|
1966
|
+
<TextField
|
|
1967
|
+
value={config.heatmap?.cellPadding ?? HEATMAP_CONFIG_DEFAULTS.cellPadding}
|
|
1968
|
+
type='number'
|
|
1969
|
+
min={0}
|
|
1970
|
+
section='heatmap'
|
|
1971
|
+
fieldName='cellPadding'
|
|
1972
|
+
label='Cell Padding'
|
|
1973
|
+
updateField={updateFieldDeprecated}
|
|
1974
|
+
/>
|
|
1975
|
+
<TextField
|
|
1976
|
+
value={config.heatmap?.rowLabelGap ?? HEATMAP_CONFIG_DEFAULTS.rowLabelGap}
|
|
1977
|
+
type='number'
|
|
1978
|
+
min={0}
|
|
1979
|
+
section='heatmap'
|
|
1980
|
+
fieldName='rowLabelGap'
|
|
1981
|
+
label='Row Label Gap'
|
|
1982
|
+
updateField={updateFieldDeprecated}
|
|
1983
|
+
/>
|
|
1984
|
+
<TextField
|
|
1985
|
+
value={config.heatmap?.columnLabelGap ?? HEATMAP_CONFIG_DEFAULTS.columnLabelGap}
|
|
1986
|
+
type='number'
|
|
1987
|
+
min={0}
|
|
1988
|
+
section='heatmap'
|
|
1989
|
+
fieldName='columnLabelGap'
|
|
1990
|
+
label='Column Label Gap'
|
|
1991
|
+
updateField={updateFieldDeprecated}
|
|
1992
|
+
/>
|
|
1993
|
+
<TextField
|
|
1994
|
+
value={config.heatmap?.colorBucketCount ?? HEATMAP_CONFIG_DEFAULTS.colorBucketCount}
|
|
1995
|
+
type='number'
|
|
1996
|
+
min={MIN_HEATMAP_COLOR_BUCKETS}
|
|
1997
|
+
max={MAX_HEATMAP_COLOR_BUCKETS}
|
|
1998
|
+
step={1}
|
|
1999
|
+
section='heatmap'
|
|
2000
|
+
fieldName='colorBucketCount'
|
|
2001
|
+
label='Data Grouping'
|
|
2002
|
+
updateField={updateFieldDeprecated}
|
|
2003
|
+
tooltip={
|
|
2004
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2005
|
+
<Tooltip.Target>
|
|
2006
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2007
|
+
</Tooltip.Target>
|
|
2008
|
+
<Tooltip.Content>
|
|
2009
|
+
Choose the number of value groups used to color the heatmap. Values are limited to 1-9.
|
|
2010
|
+
</Tooltip.Content>
|
|
2011
|
+
</Tooltip>
|
|
2012
|
+
}
|
|
2013
|
+
/>
|
|
2014
|
+
</AccordionItemPanel>
|
|
2015
|
+
</AccordionItem>
|
|
2016
|
+
)
|
|
2017
|
+
}
|
|
2018
|
+
|
|
1681
2019
|
return (
|
|
1682
2020
|
<EditorPanelContext.Provider value={editorContextValues}>
|
|
1683
2021
|
<BaseEditorPanel
|
|
@@ -1708,7 +2046,10 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1708
2046
|
{(!config.series ||
|
|
1709
2047
|
config.series.length === 0 ||
|
|
1710
2048
|
(config.visualizationType === 'Paired Bar' && config.series.length < 2)) &&
|
|
1711
|
-
!config.dynamicSeries &&
|
|
2049
|
+
!config.dynamicSeries &&
|
|
2050
|
+
config.visualizationType !== 'HeatMap' && (
|
|
2051
|
+
<WarningImage width='25' className='warning-icon' />
|
|
2052
|
+
)}
|
|
1712
2053
|
</AccordionItemButton>
|
|
1713
2054
|
</AccordionItemHeading>
|
|
1714
2055
|
<AccordionItemPanel>
|
|
@@ -1745,9 +2086,21 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1745
2086
|
)}
|
|
1746
2087
|
{(!visSupportsDynamicSeries() || !config.dynamicSeries) && (
|
|
1747
2088
|
<>
|
|
2089
|
+
{config.visualizationType === 'HeatMap' && (
|
|
2090
|
+
<p className='helper-text'>
|
|
2091
|
+
Add one or more data series to create heatmap rows. Each selected series becomes a row
|
|
2092
|
+
in the heatmap, while the Date/Category Axis provides the columns.
|
|
2093
|
+
</p>
|
|
2094
|
+
)}
|
|
2095
|
+
{(!config.series || config.series.length === 0) &&
|
|
2096
|
+
!config.dynamicSeries &&
|
|
2097
|
+
config.visualizationType !== 'Paired Bar' &&
|
|
2098
|
+
config.visualizationType !== 'HeatMap' && (
|
|
2099
|
+
<p className='warning'>At least one series is required</p>
|
|
2100
|
+
)}
|
|
1748
2101
|
{(!config.series || config.series.length === 0) &&
|
|
1749
2102
|
!config.dynamicSeries &&
|
|
1750
|
-
config.visualizationType
|
|
2103
|
+
config.visualizationType === 'HeatMap' && (
|
|
1751
2104
|
<p className='warning'>At least one series is required</p>
|
|
1752
2105
|
)}
|
|
1753
2106
|
{(!config.series || config.series.length === 0 || config.series.length < 2) &&
|
|
@@ -1768,56 +2121,54 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1768
2121
|
}
|
|
1769
2122
|
e.target.value = ''
|
|
1770
2123
|
}}
|
|
1771
|
-
options={getColumns()}
|
|
2124
|
+
options={getColumns().filter(column => column !== config.xAxis?.dataKey)}
|
|
1772
2125
|
/>
|
|
1773
2126
|
{config.series && config.series.length !== 0 && (
|
|
1774
2127
|
<Panels.Series.Wrapper
|
|
1775
2128
|
getColumns={getColumns}
|
|
1776
2129
|
handleForecastPaletteSelection={handleForecastPaletteSelection}
|
|
1777
2130
|
>
|
|
1778
|
-
<
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
2131
|
+
<GroupedList
|
|
2132
|
+
items={config.series}
|
|
2133
|
+
droppableId='chart-series-order'
|
|
2134
|
+
label={
|
|
2135
|
+
<>
|
|
2136
|
+
{config.visualizationType === 'HeatMap' ? 'Displaying Rows' : 'Displaying'}
|
|
2137
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2138
|
+
<Tooltip.Target>
|
|
2139
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2140
|
+
</Tooltip.Target>
|
|
2141
|
+
<Tooltip.Content>
|
|
2142
|
+
{config.visualizationType === 'HeatMap' ? (
|
|
2143
|
+
<p>
|
|
2144
|
+
Each selected data series becomes a row in the heatmap. Reorder these
|
|
2145
|
+
entries to change the row order shown in the visualization.
|
|
2146
|
+
</p>
|
|
2147
|
+
) : (
|
|
2148
|
+
<p>
|
|
2149
|
+
A data series is a set of related data points plotted in a chart and
|
|
2150
|
+
typically represented in the chart legend.
|
|
2151
|
+
</p>
|
|
2152
|
+
)}
|
|
2153
|
+
</Tooltip.Content>
|
|
2154
|
+
</Tooltip>
|
|
2155
|
+
</>
|
|
1798
2156
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
/>
|
|
1815
|
-
{provided.placeholder}
|
|
1816
|
-
</ul>
|
|
1817
|
-
)
|
|
1818
|
-
}}
|
|
1819
|
-
</Droppable>
|
|
1820
|
-
</DragDropContext>
|
|
2157
|
+
onDragEnd={({ source, destination }) => {
|
|
2158
|
+
if (!destination || source.index === destination.index) return
|
|
2159
|
+
handleSeriesChange(source.index, destination.index)
|
|
2160
|
+
}}
|
|
2161
|
+
renderItem={(series, index) => (
|
|
2162
|
+
<Panels.Series.Item
|
|
2163
|
+
getItemStyle={getItemStyle}
|
|
2164
|
+
sortableItemStyles={sortableItemStyles}
|
|
2165
|
+
chartsWithOptions={chartsWithOptions}
|
|
2166
|
+
series={series}
|
|
2167
|
+
index={index}
|
|
2168
|
+
key={`series-list-${index}`}
|
|
2169
|
+
/>
|
|
2170
|
+
)}
|
|
2171
|
+
/>
|
|
1821
2172
|
</Panels.Series.Wrapper>
|
|
1822
2173
|
)}
|
|
1823
2174
|
</>
|
|
@@ -1875,9 +2226,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1875
2226
|
: config.orientation === 'vertical'
|
|
1876
2227
|
? 'Left Value Axis'
|
|
1877
2228
|
: 'Value Axis'}
|
|
1878
|
-
{config.visualizationType === 'Pie' && !config.yAxis.dataKey
|
|
2229
|
+
{config.visualizationType === 'Pie' && !config.yAxis.dataKey ? (
|
|
1879
2230
|
<WarningImage width='25' className='warning-icon' />
|
|
1880
|
-
)}
|
|
2231
|
+
) : null}
|
|
1881
2232
|
</AccordionItemButton>
|
|
1882
2233
|
</AccordionItemHeading>
|
|
1883
2234
|
<AccordionItemPanel>
|
|
@@ -1904,28 +2255,107 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1904
2255
|
}
|
|
1905
2256
|
/>
|
|
1906
2257
|
<TextField
|
|
1907
|
-
value={config.yAxis.label}
|
|
2258
|
+
value={config.yAxis.label}
|
|
2259
|
+
section='yAxis'
|
|
2260
|
+
fieldName='label'
|
|
2261
|
+
label='Data Label'
|
|
2262
|
+
updateField={updateFieldDeprecated}
|
|
2263
|
+
maxLength={35}
|
|
2264
|
+
tooltip={
|
|
2265
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2266
|
+
<Tooltip.Target>
|
|
2267
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2268
|
+
</Tooltip.Target>
|
|
2269
|
+
<Tooltip.Content>
|
|
2270
|
+
<p>
|
|
2271
|
+
Override the data column name shown in tooltips and data table (35 character limit)
|
|
2272
|
+
</p>
|
|
2273
|
+
</Tooltip.Content>
|
|
2274
|
+
</Tooltip>
|
|
2275
|
+
}
|
|
2276
|
+
/>
|
|
2277
|
+
</>
|
|
2278
|
+
)}
|
|
2279
|
+
{config.visualizationType === 'HeatMap' && (
|
|
2280
|
+
<>
|
|
2281
|
+
<TextField
|
|
2282
|
+
value={config.yAxis.label}
|
|
2283
|
+
section='yAxis'
|
|
2284
|
+
fieldName='label'
|
|
2285
|
+
label='Label'
|
|
2286
|
+
updateField={updateFieldDeprecated}
|
|
2287
|
+
maxLength={35}
|
|
2288
|
+
tooltip={
|
|
2289
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2290
|
+
<Tooltip.Target>
|
|
2291
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2292
|
+
</Tooltip.Target>
|
|
2293
|
+
<Tooltip.Content>
|
|
2294
|
+
<p>35 character limit</p>
|
|
2295
|
+
</Tooltip.Content>
|
|
2296
|
+
</Tooltip>
|
|
2297
|
+
}
|
|
2298
|
+
/>
|
|
2299
|
+
<Select
|
|
2300
|
+
value={config.yAxis.titlePlacement || 'side'}
|
|
2301
|
+
section='yAxis'
|
|
2302
|
+
fieldName='titlePlacement'
|
|
2303
|
+
label='Label Placement'
|
|
2304
|
+
updateField={updateFieldDeprecated}
|
|
2305
|
+
options={[
|
|
2306
|
+
{ value: 'side', label: 'Side' },
|
|
2307
|
+
{ value: 'top', label: 'Top' }
|
|
2308
|
+
]}
|
|
2309
|
+
/>
|
|
2310
|
+
<TextField
|
|
2311
|
+
value={config.yAxis.size}
|
|
2312
|
+
type='number'
|
|
1908
2313
|
section='yAxis'
|
|
1909
|
-
fieldName='
|
|
1910
|
-
label='
|
|
2314
|
+
fieldName='size'
|
|
2315
|
+
label='Size (Width)'
|
|
2316
|
+
className='number-narrow'
|
|
1911
2317
|
updateField={updateFieldDeprecated}
|
|
1912
|
-
maxLength={35}
|
|
1913
2318
|
tooltip={
|
|
1914
2319
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1915
2320
|
<Tooltip.Target>
|
|
1916
|
-
<Icon
|
|
2321
|
+
<Icon
|
|
2322
|
+
display='question'
|
|
2323
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2324
|
+
/>
|
|
1917
2325
|
</Tooltip.Target>
|
|
1918
2326
|
<Tooltip.Content>
|
|
1919
|
-
<p>
|
|
1920
|
-
Override the data column name shown in tooltips and data table (35 character limit)
|
|
1921
|
-
</p>
|
|
2327
|
+
<p>Increase the size if month labels are crowded or overlap the chart area.</p>
|
|
1922
2328
|
</Tooltip.Content>
|
|
1923
2329
|
</Tooltip>
|
|
1924
2330
|
}
|
|
1925
2331
|
/>
|
|
2332
|
+
<CheckBox
|
|
2333
|
+
value={config.yAxis.hideAxis}
|
|
2334
|
+
section='yAxis'
|
|
2335
|
+
fieldName='hideAxis'
|
|
2336
|
+
label='Hide Axis'
|
|
2337
|
+
updateField={updateFieldDeprecated}
|
|
2338
|
+
/>
|
|
2339
|
+
<CheckBox
|
|
2340
|
+
value={config.yAxis.hideTicks}
|
|
2341
|
+
section='yAxis'
|
|
2342
|
+
fieldName='hideTicks'
|
|
2343
|
+
label='Hide Ticks'
|
|
2344
|
+
updateField={updateFieldDeprecated}
|
|
2345
|
+
/>
|
|
2346
|
+
<TextField
|
|
2347
|
+
value={config.yAxis.tickRotation || 0}
|
|
2348
|
+
type='number'
|
|
2349
|
+
min={0}
|
|
2350
|
+
section='yAxis'
|
|
2351
|
+
fieldName='tickRotation'
|
|
2352
|
+
label='Tick rotation (Degrees)'
|
|
2353
|
+
className='number-narrow'
|
|
2354
|
+
updateField={updateFieldDeprecated}
|
|
2355
|
+
/>
|
|
1926
2356
|
</>
|
|
1927
2357
|
)}
|
|
1928
|
-
{config.visualizationType !== 'Pie' && (
|
|
2358
|
+
{config.visualizationType !== 'Pie' && config.visualizationType !== 'HeatMap' && (
|
|
1929
2359
|
<>
|
|
1930
2360
|
<Select
|
|
1931
2361
|
label='Axis Type'
|
|
@@ -1976,18 +2406,30 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1976
2406
|
fieldName='label'
|
|
1977
2407
|
label='Label'
|
|
1978
2408
|
updateField={updateFieldDeprecated}
|
|
1979
|
-
maxLength={35}
|
|
2409
|
+
maxLength={config.yAxis.titlePlacement === 'side' ? 35 : undefined}
|
|
1980
2410
|
tooltip={
|
|
1981
2411
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
1982
2412
|
<Tooltip.Target>
|
|
1983
2413
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
1984
2414
|
</Tooltip.Target>
|
|
1985
2415
|
<Tooltip.Content>
|
|
1986
|
-
<p>35 character limit</p>
|
|
2416
|
+
<p>35 character limit when Label Placement is Side</p>
|
|
1987
2417
|
</Tooltip.Content>
|
|
1988
2418
|
</Tooltip>
|
|
1989
2419
|
}
|
|
1990
2420
|
/>
|
|
2421
|
+
<Select
|
|
2422
|
+
display={!visHasCategoricalAxis()}
|
|
2423
|
+
value={config.yAxis.titlePlacement}
|
|
2424
|
+
section='yAxis'
|
|
2425
|
+
fieldName='titlePlacement'
|
|
2426
|
+
label='Label Placement'
|
|
2427
|
+
updateField={updateField}
|
|
2428
|
+
options={[
|
|
2429
|
+
{ value: 'side', label: 'Side' },
|
|
2430
|
+
{ value: 'top', label: 'Top' }
|
|
2431
|
+
]}
|
|
2432
|
+
/>
|
|
1991
2433
|
<TextField
|
|
1992
2434
|
display={!visHasCategoricalAxis()}
|
|
1993
2435
|
value={config.yAxis.inlineLabel}
|
|
@@ -2045,38 +2487,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2045
2487
|
}
|
|
2046
2488
|
updateField={updateFieldDeprecated}
|
|
2047
2489
|
/>
|
|
2048
|
-
<TextField
|
|
2049
|
-
value={config.yAxis.size}
|
|
2050
|
-
type='number'
|
|
2051
|
-
section='yAxis'
|
|
2052
|
-
fieldName='size'
|
|
2053
|
-
label={config.orientation === 'horizontal' ? 'Size (Height)' : 'Size (Width)'}
|
|
2054
|
-
className='number-narrow'
|
|
2055
|
-
updateField={updateFieldDeprecated}
|
|
2056
|
-
tooltip={
|
|
2057
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2058
|
-
<Tooltip.Target>
|
|
2059
|
-
<Icon
|
|
2060
|
-
display='question'
|
|
2061
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
2062
|
-
/>
|
|
2063
|
-
</Tooltip.Target>
|
|
2064
|
-
<Tooltip.Content>
|
|
2065
|
-
<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>
|
|
2066
|
-
</Tooltip.Content>
|
|
2067
|
-
</Tooltip>
|
|
2068
|
-
}
|
|
2069
|
-
/>
|
|
2070
|
-
<TextField
|
|
2071
|
-
display={!visHasCategoricalAxis()}
|
|
2072
|
-
value={config.yAxis.labelOffset}
|
|
2073
|
-
section='yAxis'
|
|
2074
|
-
fieldName='labelOffset'
|
|
2075
|
-
label='Label offset'
|
|
2076
|
-
type='number'
|
|
2077
|
-
className='number-narrow'
|
|
2078
|
-
updateField={updateFieldDeprecated}
|
|
2079
|
-
/>
|
|
2080
2490
|
{config.orientation === 'horizontal' && (
|
|
2081
2491
|
<CheckBox
|
|
2082
2492
|
value={config.isResponsiveTicks}
|
|
@@ -2403,7 +2813,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2403
2813
|
)}
|
|
2404
2814
|
</>
|
|
2405
2815
|
) : (
|
|
2406
|
-
config.visualizationType !== 'Pie' &&
|
|
2816
|
+
config.visualizationType !== 'Pie' &&
|
|
2817
|
+
config.visualizationType !== 'HeatMap' && (
|
|
2407
2818
|
<>
|
|
2408
2819
|
<CheckBox
|
|
2409
2820
|
display={!visHasCategoricalAxis()}
|
|
@@ -2481,251 +2892,20 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2481
2892
|
)}
|
|
2482
2893
|
{/* start: anchors */}
|
|
2483
2894
|
{visHasAnchors() && config.orientation !== 'horizontal' && (
|
|
2484
|
-
<
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
key={`yaxis-anchors-2-${index}`}
|
|
2491
|
-
>
|
|
2492
|
-
<AccordionItemHeading className='series-item__title'>
|
|
2493
|
-
<>
|
|
2494
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
2495
|
-
Anchor {index + 1}
|
|
2496
|
-
<button
|
|
2497
|
-
className='series-list__remove'
|
|
2498
|
-
onClick={e => {
|
|
2499
|
-
e.preventDefault()
|
|
2500
|
-
const copiedAnchorGroups = [...config.yAxis.anchors]
|
|
2501
|
-
copiedAnchorGroups.splice(index, 1)
|
|
2502
|
-
updateConfig({
|
|
2503
|
-
...config,
|
|
2504
|
-
yAxis: {
|
|
2505
|
-
...config.yAxis,
|
|
2506
|
-
anchors: copiedAnchorGroups
|
|
2507
|
-
}
|
|
2508
|
-
})
|
|
2509
|
-
}}
|
|
2510
|
-
>
|
|
2511
|
-
Remove
|
|
2512
|
-
</button>
|
|
2513
|
-
</AccordionItemButton>
|
|
2514
|
-
</>
|
|
2515
|
-
</AccordionItemHeading>
|
|
2516
|
-
<AccordionItemPanel>
|
|
2517
|
-
<label>
|
|
2518
|
-
<span>Anchor Value</span>
|
|
2519
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2520
|
-
<Tooltip.Target>
|
|
2521
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2522
|
-
</Tooltip.Target>
|
|
2523
|
-
<Tooltip.Content>
|
|
2524
|
-
<p>Enter the value as its shown in the data column</p>
|
|
2525
|
-
</Tooltip.Content>
|
|
2526
|
-
</Tooltip>
|
|
2527
|
-
<input
|
|
2528
|
-
type='text'
|
|
2529
|
-
value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
|
|
2530
|
-
onChange={e => {
|
|
2531
|
-
e.preventDefault()
|
|
2532
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2533
|
-
copiedAnchors[index].value = e.target.value
|
|
2534
|
-
updateConfig({
|
|
2535
|
-
...config,
|
|
2536
|
-
yAxis: {
|
|
2537
|
-
...config.yAxis,
|
|
2538
|
-
anchors: copiedAnchors
|
|
2539
|
-
}
|
|
2540
|
-
})
|
|
2541
|
-
}}
|
|
2542
|
-
/>
|
|
2543
|
-
</label>
|
|
2544
|
-
|
|
2545
|
-
<label>
|
|
2546
|
-
<span>Anchor Color</span>
|
|
2547
|
-
<input
|
|
2548
|
-
type='text'
|
|
2549
|
-
value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
|
|
2550
|
-
onChange={e => {
|
|
2551
|
-
e.preventDefault()
|
|
2552
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2553
|
-
copiedAnchors[index].color = e.target.value
|
|
2554
|
-
updateConfig({
|
|
2555
|
-
...config,
|
|
2556
|
-
yAxis: {
|
|
2557
|
-
...config.yAxis,
|
|
2558
|
-
anchors: copiedAnchors
|
|
2559
|
-
}
|
|
2560
|
-
})
|
|
2561
|
-
}}
|
|
2562
|
-
/>
|
|
2563
|
-
</label>
|
|
2564
|
-
|
|
2565
|
-
<Select
|
|
2566
|
-
value={config.yAxis.anchors[index].lineStyle || ''}
|
|
2567
|
-
label='Anchor Line Style'
|
|
2568
|
-
onChange={e => {
|
|
2569
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
2570
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
2571
|
-
updateConfig({
|
|
2572
|
-
...config,
|
|
2573
|
-
yAxis: {
|
|
2574
|
-
...config.yAxis,
|
|
2575
|
-
anchors: copiedAnchors
|
|
2576
|
-
}
|
|
2577
|
-
})
|
|
2578
|
-
}}
|
|
2579
|
-
options={[
|
|
2580
|
-
{ value: '', label: 'Select' },
|
|
2581
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
2582
|
-
]}
|
|
2583
|
-
/>
|
|
2584
|
-
</AccordionItemPanel>
|
|
2585
|
-
</AccordionItem>
|
|
2586
|
-
))}
|
|
2587
|
-
</Accordion>
|
|
2588
|
-
|
|
2589
|
-
<button
|
|
2590
|
-
className='btn btn-primary full-width'
|
|
2591
|
-
onClick={e => {
|
|
2592
|
-
e.preventDefault()
|
|
2593
|
-
const anchors = [...config.yAxis.anchors]
|
|
2594
|
-
anchors.push({} as Anchor)
|
|
2595
|
-
updateConfig({
|
|
2596
|
-
...config,
|
|
2597
|
-
yAxis: {
|
|
2598
|
-
...config.yAxis,
|
|
2599
|
-
anchors
|
|
2600
|
-
}
|
|
2601
|
-
})
|
|
2602
|
-
}}
|
|
2603
|
-
>
|
|
2604
|
-
Add Anchor
|
|
2605
|
-
</button>
|
|
2606
|
-
</div>
|
|
2895
|
+
<AxisAnchorEditor
|
|
2896
|
+
axisKey='yAxis'
|
|
2897
|
+
config={config}
|
|
2898
|
+
lineOptions={lineOptions}
|
|
2899
|
+
updateConfig={updateConfig}
|
|
2900
|
+
/>
|
|
2607
2901
|
)}
|
|
2608
2902
|
{visHasAnchors() && config.orientation === 'horizontal' && (
|
|
2609
|
-
<
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
<>
|
|
2616
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
2617
|
-
Anchor {index + 1}
|
|
2618
|
-
<button
|
|
2619
|
-
className='series-list__remove'
|
|
2620
|
-
onClick={e => {
|
|
2621
|
-
e.preventDefault()
|
|
2622
|
-
const copiedAnchorGroups = [...config.xAxis.anchors]
|
|
2623
|
-
copiedAnchorGroups.splice(index, 1)
|
|
2624
|
-
updateConfig({
|
|
2625
|
-
...config,
|
|
2626
|
-
xAxis: {
|
|
2627
|
-
...config.xAxis,
|
|
2628
|
-
anchors: copiedAnchorGroups
|
|
2629
|
-
}
|
|
2630
|
-
})
|
|
2631
|
-
}}
|
|
2632
|
-
>
|
|
2633
|
-
Remove
|
|
2634
|
-
</button>
|
|
2635
|
-
</AccordionItemButton>
|
|
2636
|
-
</>
|
|
2637
|
-
</AccordionItemHeading>
|
|
2638
|
-
<AccordionItemPanel>
|
|
2639
|
-
<label>
|
|
2640
|
-
<span>Anchor Value</span>
|
|
2641
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2642
|
-
<Tooltip.Target>
|
|
2643
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2644
|
-
</Tooltip.Target>
|
|
2645
|
-
<Tooltip.Content>
|
|
2646
|
-
<p>Enter the value as its shown in the data column</p>
|
|
2647
|
-
</Tooltip.Content>
|
|
2648
|
-
</Tooltip>
|
|
2649
|
-
<input
|
|
2650
|
-
type='text'
|
|
2651
|
-
value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
|
|
2652
|
-
onChange={e => {
|
|
2653
|
-
e.preventDefault()
|
|
2654
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2655
|
-
copiedAnchors[index].value = e.target.value
|
|
2656
|
-
updateConfig({
|
|
2657
|
-
...config,
|
|
2658
|
-
xAxis: {
|
|
2659
|
-
...config.xAxis,
|
|
2660
|
-
anchors: copiedAnchors
|
|
2661
|
-
}
|
|
2662
|
-
})
|
|
2663
|
-
}}
|
|
2664
|
-
/>
|
|
2665
|
-
</label>
|
|
2666
|
-
|
|
2667
|
-
<label>
|
|
2668
|
-
<span>Anchor Color</span>
|
|
2669
|
-
<input
|
|
2670
|
-
type='text'
|
|
2671
|
-
value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
|
|
2672
|
-
onChange={e => {
|
|
2673
|
-
e.preventDefault()
|
|
2674
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2675
|
-
copiedAnchors[index].color = e.target.value
|
|
2676
|
-
updateConfig({
|
|
2677
|
-
...config,
|
|
2678
|
-
xAxis: {
|
|
2679
|
-
...config.xAxis,
|
|
2680
|
-
anchors: copiedAnchors
|
|
2681
|
-
}
|
|
2682
|
-
})
|
|
2683
|
-
}}
|
|
2684
|
-
/>
|
|
2685
|
-
</label>
|
|
2686
|
-
|
|
2687
|
-
<Select
|
|
2688
|
-
value={config.xAxis.anchors[index].lineStyle || ''}
|
|
2689
|
-
label='Anchor Line Style'
|
|
2690
|
-
onChange={e => {
|
|
2691
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
2692
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
2693
|
-
updateConfig({
|
|
2694
|
-
...config,
|
|
2695
|
-
xAxis: {
|
|
2696
|
-
...config.xAxis,
|
|
2697
|
-
anchors: copiedAnchors
|
|
2698
|
-
}
|
|
2699
|
-
})
|
|
2700
|
-
}}
|
|
2701
|
-
options={[
|
|
2702
|
-
{ value: '', label: 'Select' },
|
|
2703
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
2704
|
-
]}
|
|
2705
|
-
/>
|
|
2706
|
-
</AccordionItemPanel>
|
|
2707
|
-
</AccordionItem>
|
|
2708
|
-
))}
|
|
2709
|
-
</Accordion>
|
|
2710
|
-
|
|
2711
|
-
<button
|
|
2712
|
-
className='btn btn-primary full-width'
|
|
2713
|
-
onClick={e => {
|
|
2714
|
-
e.preventDefault()
|
|
2715
|
-
const anchors = [...config.xAxis.anchors]
|
|
2716
|
-
anchors.push({} as Anchor)
|
|
2717
|
-
updateConfig({
|
|
2718
|
-
...config,
|
|
2719
|
-
xAxis: {
|
|
2720
|
-
...config.xAxis,
|
|
2721
|
-
anchors
|
|
2722
|
-
}
|
|
2723
|
-
})
|
|
2724
|
-
}}
|
|
2725
|
-
>
|
|
2726
|
-
Add Anchor
|
|
2727
|
-
</button>
|
|
2728
|
-
</div>
|
|
2903
|
+
<AxisAnchorEditor
|
|
2904
|
+
axisKey='xAxis'
|
|
2905
|
+
config={config}
|
|
2906
|
+
lineOptions={lineOptions}
|
|
2907
|
+
updateConfig={updateConfig}
|
|
2908
|
+
/>
|
|
2729
2909
|
)}
|
|
2730
2910
|
{/* end: anchors */}
|
|
2731
2911
|
</AccordionItemPanel>
|
|
@@ -2961,11 +3141,19 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2961
3141
|
section='xAxis'
|
|
2962
3142
|
fieldName='type'
|
|
2963
3143
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
3144
|
+
const autoDetectedDateParseFormat = getAutoDetectedXAxisDateParseFormat(
|
|
3145
|
+
config.xAxis.dataKey,
|
|
3146
|
+
value
|
|
3147
|
+
)
|
|
3148
|
+
|
|
2964
3149
|
updateConfig({
|
|
2965
3150
|
...config,
|
|
2966
3151
|
xAxis: {
|
|
2967
3152
|
...config.xAxis,
|
|
2968
|
-
type: value
|
|
3153
|
+
type: value,
|
|
3154
|
+
...(autoDetectedDateParseFormat
|
|
3155
|
+
? { dateParseFormat: autoDetectedDateParseFormat }
|
|
3156
|
+
: {})
|
|
2969
3157
|
}
|
|
2970
3158
|
})
|
|
2971
3159
|
}}
|
|
@@ -3082,6 +3270,16 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3082
3270
|
</Tooltip>
|
|
3083
3271
|
}
|
|
3084
3272
|
/>
|
|
3273
|
+
{config.visualizationType === 'HeatMap' && (
|
|
3274
|
+
<Select
|
|
3275
|
+
value={config.heatmap?.xAxisPosition ?? HEATMAP_CONFIG_DEFAULTS.xAxisPosition}
|
|
3276
|
+
section='heatmap'
|
|
3277
|
+
fieldName='xAxisPosition'
|
|
3278
|
+
label='X-Axis Position'
|
|
3279
|
+
updateField={updateFieldDeprecated}
|
|
3280
|
+
options={['top', 'bottom']}
|
|
3281
|
+
/>
|
|
3282
|
+
)}
|
|
3085
3283
|
|
|
3086
3284
|
{config.xAxis.type === 'continuous' && (
|
|
3087
3285
|
<>
|
|
@@ -3341,38 +3539,71 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3341
3539
|
}
|
|
3342
3540
|
/>
|
|
3343
3541
|
{config.xAxis.brushActive && (
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3542
|
+
<>
|
|
3543
|
+
<CheckBox
|
|
3544
|
+
value={!!config.xAxis.brushDynamicYAxis}
|
|
3545
|
+
section='xAxis'
|
|
3546
|
+
fieldName='brushDynamicYAxis'
|
|
3547
|
+
label='Dynamic Y-Axis'
|
|
3548
|
+
className='ms-4'
|
|
3549
|
+
updateField={updateFieldDeprecated}
|
|
3550
|
+
tooltip={
|
|
3551
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
3552
|
+
<Tooltip.Target>
|
|
3553
|
+
<Icon
|
|
3554
|
+
display='question'
|
|
3555
|
+
style={{
|
|
3556
|
+
marginLeft: '0.5rem',
|
|
3557
|
+
display: 'inline-block',
|
|
3558
|
+
whiteSpace: 'nowrap'
|
|
3559
|
+
}}
|
|
3560
|
+
/>
|
|
3561
|
+
</Tooltip.Target>
|
|
3562
|
+
<Tooltip.Content>
|
|
3563
|
+
<p>
|
|
3564
|
+
When enabled, the Y-axis rescales to fit only the data visible in the
|
|
3565
|
+
current brush selection. When disabled, the Y-axis shows the full data
|
|
3566
|
+
range.
|
|
3567
|
+
</p>
|
|
3568
|
+
</Tooltip.Content>
|
|
3569
|
+
</Tooltip>
|
|
3570
|
+
}
|
|
3571
|
+
/>
|
|
3572
|
+
<div className='ms-4 mt-2'>
|
|
3573
|
+
<TextField
|
|
3574
|
+
value={config.xAxis.brushDefaultRecentDateCount ?? ''}
|
|
3575
|
+
placeholder='Default (35%)'
|
|
3576
|
+
type='number'
|
|
3577
|
+
min={1}
|
|
3578
|
+
section='xAxis'
|
|
3579
|
+
fieldName='brushDefaultRecentDateCount'
|
|
3580
|
+
label='Show Last X Dates by Default'
|
|
3581
|
+
className='number-narrow'
|
|
3582
|
+
updateField={updateFieldDeprecated}
|
|
3583
|
+
tooltip={
|
|
3584
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
3585
|
+
<Tooltip.Target>
|
|
3586
|
+
<Icon
|
|
3587
|
+
display='question'
|
|
3588
|
+
style={{
|
|
3589
|
+
marginLeft: '0.5rem',
|
|
3590
|
+
display: 'inline-block',
|
|
3591
|
+
whiteSpace: 'nowrap'
|
|
3592
|
+
}}
|
|
3593
|
+
/>
|
|
3594
|
+
</Tooltip.Target>
|
|
3595
|
+
<Tooltip.Content>
|
|
3596
|
+
<p>
|
|
3597
|
+
When set, the brush slider will initially select this many recent data
|
|
3598
|
+
points instead of the default 35%. Leave empty to use the default
|
|
3599
|
+
percentage-based selection.
|
|
3600
|
+
</p>
|
|
3601
|
+
</Tooltip.Content>
|
|
3602
|
+
</Tooltip>
|
|
3603
|
+
}
|
|
3604
|
+
/>
|
|
3605
|
+
</div>
|
|
3606
|
+
</>
|
|
3376
3607
|
)}
|
|
3377
3608
|
</>
|
|
3378
3609
|
)}
|
|
@@ -3587,18 +3818,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3587
3818
|
updateField={updateFieldDeprecated}
|
|
3588
3819
|
/>
|
|
3589
3820
|
)}
|
|
3590
|
-
{config.orientation === 'horizontal' && (
|
|
3591
|
-
<TextField
|
|
3592
|
-
value={config.xAxis.labelOffset}
|
|
3593
|
-
section='xAxis'
|
|
3594
|
-
fieldName='labelOffset'
|
|
3595
|
-
label='Label offset'
|
|
3596
|
-
type='number'
|
|
3597
|
-
className='number-narrow'
|
|
3598
|
-
updateField={updateFieldDeprecated}
|
|
3599
|
-
/>
|
|
3600
|
-
)}
|
|
3601
|
-
|
|
3602
3821
|
{/* Hiding this for now, not interested in moving the axis lines away from chart comp. right now. */}
|
|
3603
3822
|
{/* <TextField value={config.xAxis.axisPadding} type='number' max={10} min={0} section='xAxis' fieldName='axisPadding' label={'Axis Padding'} className='number-narrow' updateField={updateFieldDeprecated} /> */}
|
|
3604
3823
|
{(config.xAxis.type === 'continuous' || config.forestPlot.type === 'Logarithmic') && (
|
|
@@ -3737,12 +3956,12 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3737
3956
|
highlightedBarValues.map((highlightedBarValue, i) => (
|
|
3738
3957
|
<fieldset>
|
|
3739
3958
|
<div className='edit-block' key={`highlighted-bar-${i}`}>
|
|
3740
|
-
<
|
|
3959
|
+
<Button
|
|
3741
3960
|
className='btn btn-danger'
|
|
3742
3961
|
onClick={e => handleRemoveHighlightedBar(e, i)}
|
|
3743
3962
|
>
|
|
3744
3963
|
Remove
|
|
3745
|
-
</
|
|
3964
|
+
</Button>
|
|
3746
3965
|
<p>Highlighted Bar {i + 1}</p>
|
|
3747
3966
|
<Select
|
|
3748
3967
|
value={config.highlightedBarValues[i].value}
|
|
@@ -3750,11 +3969,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3750
3969
|
onChange={e => handleUpdateHighlightedBar(e, i)}
|
|
3751
3970
|
options={[
|
|
3752
3971
|
{ value: '', label: '- Select Value -' },
|
|
3753
|
-
...
|
|
3754
|
-
? [...new Set(highlightedSeriesValues)]
|
|
3755
|
-
.sort()
|
|
3756
|
-
.map(option => ({ value: option, label: option }))
|
|
3757
|
-
: [])
|
|
3972
|
+
...highlightedSeriesOptions
|
|
3758
3973
|
]}
|
|
3759
3974
|
/>
|
|
3760
3975
|
<label>
|
|
@@ -3798,12 +4013,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3798
4013
|
</div>
|
|
3799
4014
|
</fieldset>
|
|
3800
4015
|
))}
|
|
3801
|
-
<
|
|
3802
|
-
className='btn btn-primary full-width'
|
|
3803
|
-
onClick={e => handleAddNewHighlightedBar(e)}
|
|
3804
|
-
>
|
|
4016
|
+
<Button variant='editor-primary' onClick={e => handleAddNewHighlightedBar(e)}>
|
|
3805
4017
|
Add Highlighted Bar
|
|
3806
|
-
</
|
|
4018
|
+
</Button>
|
|
3807
4019
|
</>
|
|
3808
4020
|
)}
|
|
3809
4021
|
</>
|
|
@@ -3888,259 +4100,26 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3888
4100
|
|
|
3889
4101
|
{/* anchors */}
|
|
3890
4102
|
{visHasAnchors() && config.orientation !== 'horizontal' && (
|
|
3891
|
-
<
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
key={`xaxis-anchors-2-${index}`}
|
|
3898
|
-
>
|
|
3899
|
-
<AccordionItemHeading className='series-item__title'>
|
|
3900
|
-
<>
|
|
3901
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
3902
|
-
Anchor {index + 1}
|
|
3903
|
-
<button
|
|
3904
|
-
className='series-list__remove'
|
|
3905
|
-
onClick={e => {
|
|
3906
|
-
e.preventDefault()
|
|
3907
|
-
const copiedAnchorGroups = [...config.xAxis.anchors]
|
|
3908
|
-
copiedAnchorGroups.splice(index, 1)
|
|
3909
|
-
updateConfig({
|
|
3910
|
-
...config,
|
|
3911
|
-
xAxis: {
|
|
3912
|
-
...config.xAxis,
|
|
3913
|
-
anchors: copiedAnchorGroups
|
|
3914
|
-
}
|
|
3915
|
-
})
|
|
3916
|
-
}}
|
|
3917
|
-
>
|
|
3918
|
-
Remove
|
|
3919
|
-
</button>
|
|
3920
|
-
</AccordionItemButton>
|
|
3921
|
-
</>
|
|
3922
|
-
</AccordionItemHeading>
|
|
3923
|
-
<AccordionItemPanel>
|
|
3924
|
-
<label>
|
|
3925
|
-
<span>Anchor Value</span>
|
|
3926
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
3927
|
-
<Tooltip.Target>
|
|
3928
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3929
|
-
</Tooltip.Target>
|
|
3930
|
-
<Tooltip.Content>
|
|
3931
|
-
<p>Enter the value as its shown in the data column</p>
|
|
3932
|
-
</Tooltip.Content>
|
|
3933
|
-
</Tooltip>
|
|
3934
|
-
<input
|
|
3935
|
-
type='text'
|
|
3936
|
-
value={config.xAxis.anchors[index].value ? config.xAxis.anchors[index].value : ''}
|
|
3937
|
-
onChange={e => {
|
|
3938
|
-
e.preventDefault()
|
|
3939
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3940
|
-
copiedAnchors[index].value = e.target.value
|
|
3941
|
-
updateConfig({
|
|
3942
|
-
...config,
|
|
3943
|
-
xAxis: {
|
|
3944
|
-
...config.xAxis,
|
|
3945
|
-
anchors: copiedAnchors
|
|
3946
|
-
}
|
|
3947
|
-
})
|
|
3948
|
-
}}
|
|
3949
|
-
/>
|
|
3950
|
-
</label>
|
|
3951
|
-
|
|
3952
|
-
<label>
|
|
3953
|
-
<span>Anchor Color</span>
|
|
3954
|
-
<input
|
|
3955
|
-
type='text'
|
|
3956
|
-
value={config.xAxis.anchors[index].color ? config.xAxis.anchors[index].color : ''}
|
|
3957
|
-
onChange={e => {
|
|
3958
|
-
e.preventDefault()
|
|
3959
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3960
|
-
copiedAnchors[index].color = e.target.value
|
|
3961
|
-
updateConfig({
|
|
3962
|
-
...config,
|
|
3963
|
-
xAxis: {
|
|
3964
|
-
...config.xAxis,
|
|
3965
|
-
anchors: copiedAnchors
|
|
3966
|
-
}
|
|
3967
|
-
})
|
|
3968
|
-
}}
|
|
3969
|
-
/>
|
|
3970
|
-
</label>
|
|
3971
|
-
|
|
3972
|
-
<Select
|
|
3973
|
-
value={config.xAxis.anchors[index].lineStyle || ''}
|
|
3974
|
-
label='Anchor Line Style'
|
|
3975
|
-
onChange={e => {
|
|
3976
|
-
const copiedAnchors = [...config.xAxis.anchors]
|
|
3977
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
3978
|
-
updateConfig({
|
|
3979
|
-
...config,
|
|
3980
|
-
xAxis: {
|
|
3981
|
-
...config.xAxis,
|
|
3982
|
-
anchors: copiedAnchors
|
|
3983
|
-
}
|
|
3984
|
-
})
|
|
3985
|
-
}}
|
|
3986
|
-
options={[
|
|
3987
|
-
{ value: '', label: 'Select' },
|
|
3988
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
3989
|
-
]}
|
|
3990
|
-
/>
|
|
3991
|
-
</AccordionItemPanel>
|
|
3992
|
-
</AccordionItem>
|
|
3993
|
-
))}
|
|
3994
|
-
</Accordion>
|
|
3995
|
-
|
|
3996
|
-
<button
|
|
3997
|
-
className='btn btn-primary full-width'
|
|
3998
|
-
onClick={e => {
|
|
3999
|
-
e.preventDefault()
|
|
4000
|
-
const anchors = [...config.xAxis.anchors]
|
|
4001
|
-
anchors.push({} as Anchor)
|
|
4002
|
-
updateConfig({
|
|
4003
|
-
...config,
|
|
4004
|
-
xAxis: {
|
|
4005
|
-
...config.xAxis,
|
|
4006
|
-
anchors
|
|
4007
|
-
}
|
|
4008
|
-
})
|
|
4009
|
-
}}
|
|
4010
|
-
>
|
|
4011
|
-
Add Anchor
|
|
4012
|
-
</button>
|
|
4013
|
-
</div>
|
|
4103
|
+
<AxisAnchorEditor
|
|
4104
|
+
axisKey='xAxis'
|
|
4105
|
+
config={config}
|
|
4106
|
+
lineOptions={lineOptions}
|
|
4107
|
+
updateConfig={updateConfig}
|
|
4108
|
+
/>
|
|
4014
4109
|
)}
|
|
4015
4110
|
|
|
4016
4111
|
{visHasAnchors() && config.orientation === 'horizontal' && (
|
|
4017
|
-
<
|
|
4018
|
-
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
4023
|
-
key={`accordion-yaxis-anchors-${index}`}
|
|
4024
|
-
>
|
|
4025
|
-
<AccordionItemHeading className='series-item__title'>
|
|
4026
|
-
<>
|
|
4027
|
-
<AccordionItemButton className={'accordion__button accordion__button'}>
|
|
4028
|
-
Anchor {index + 1}
|
|
4029
|
-
<button
|
|
4030
|
-
className='series-list__remove'
|
|
4031
|
-
onClick={e => {
|
|
4032
|
-
e.preventDefault()
|
|
4033
|
-
const copiedAnchorGroups = [...config.yAxis.anchors]
|
|
4034
|
-
copiedAnchorGroups.splice(index, 1)
|
|
4035
|
-
updateConfig({
|
|
4036
|
-
...config,
|
|
4037
|
-
yAxis: {
|
|
4038
|
-
...config.yAxis,
|
|
4039
|
-
anchors: copiedAnchorGroups
|
|
4040
|
-
}
|
|
4041
|
-
})
|
|
4042
|
-
}}
|
|
4043
|
-
>
|
|
4044
|
-
Remove
|
|
4045
|
-
</button>
|
|
4046
|
-
</AccordionItemButton>
|
|
4047
|
-
</>
|
|
4048
|
-
</AccordionItemHeading>
|
|
4049
|
-
<AccordionItemPanel>
|
|
4050
|
-
<label>
|
|
4051
|
-
<span>Anchor Value</span>
|
|
4052
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
4053
|
-
<Tooltip.Target>
|
|
4054
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
4055
|
-
</Tooltip.Target>
|
|
4056
|
-
<Tooltip.Content>
|
|
4057
|
-
<p>Enter the value as its shown in the data column</p>
|
|
4058
|
-
</Tooltip.Content>
|
|
4059
|
-
</Tooltip>
|
|
4060
|
-
<input
|
|
4061
|
-
type='text'
|
|
4062
|
-
value={config.yAxis.anchors[index].value ? config.yAxis.anchors[index].value : ''}
|
|
4063
|
-
onChange={e => {
|
|
4064
|
-
e.preventDefault()
|
|
4065
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4066
|
-
copiedAnchors[index].value = e.target.value
|
|
4067
|
-
updateConfig({
|
|
4068
|
-
...config,
|
|
4069
|
-
yAxis: {
|
|
4070
|
-
...config.yAxis,
|
|
4071
|
-
anchors: copiedAnchors
|
|
4072
|
-
}
|
|
4073
|
-
})
|
|
4074
|
-
}}
|
|
4075
|
-
/>
|
|
4076
|
-
</label>
|
|
4077
|
-
|
|
4078
|
-
<label>
|
|
4079
|
-
<span>Anchor Color</span>
|
|
4080
|
-
<input
|
|
4081
|
-
type='text'
|
|
4082
|
-
value={config.yAxis.anchors[index].color ? config.yAxis.anchors[index].color : ''}
|
|
4083
|
-
onChange={e => {
|
|
4084
|
-
e.preventDefault()
|
|
4085
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4086
|
-
copiedAnchors[index].color = e.target.value
|
|
4087
|
-
updateConfig({
|
|
4088
|
-
...config,
|
|
4089
|
-
yAxis: {
|
|
4090
|
-
...config.yAxis,
|
|
4091
|
-
anchors: copiedAnchors
|
|
4092
|
-
}
|
|
4093
|
-
})
|
|
4094
|
-
}}
|
|
4095
|
-
/>
|
|
4096
|
-
</label>
|
|
4097
|
-
|
|
4098
|
-
<Select
|
|
4099
|
-
value={config.yAxis.anchors[index].lineStyle || ''}
|
|
4100
|
-
label='Anchor Line Style'
|
|
4101
|
-
onChange={e => {
|
|
4102
|
-
const copiedAnchors = [...config.yAxis.anchors]
|
|
4103
|
-
copiedAnchors[index].lineStyle = e.target.value
|
|
4104
|
-
updateConfig({
|
|
4105
|
-
...config,
|
|
4106
|
-
yAxis: {
|
|
4107
|
-
...config.yAxis,
|
|
4108
|
-
anchors: copiedAnchors
|
|
4109
|
-
}
|
|
4110
|
-
})
|
|
4111
|
-
}}
|
|
4112
|
-
options={[
|
|
4113
|
-
{ value: '', label: 'Select' },
|
|
4114
|
-
...lineOptions.map(line => ({ value: line.value, label: line.value }))
|
|
4115
|
-
]}
|
|
4116
|
-
/>
|
|
4117
|
-
</AccordionItemPanel>
|
|
4118
|
-
</AccordionItem>
|
|
4119
|
-
))}
|
|
4120
|
-
</Accordion>
|
|
4121
|
-
|
|
4122
|
-
<button
|
|
4123
|
-
className='btn btn-primary full-width'
|
|
4124
|
-
onClick={e => {
|
|
4125
|
-
e.preventDefault()
|
|
4126
|
-
const anchors = [...config.yAxis.anchors]
|
|
4127
|
-
anchors.push({} as Anchor)
|
|
4128
|
-
updateConfig({
|
|
4129
|
-
...config,
|
|
4130
|
-
yAxis: {
|
|
4131
|
-
...config.yAxis,
|
|
4132
|
-
anchors
|
|
4133
|
-
}
|
|
4134
|
-
})
|
|
4135
|
-
}}
|
|
4136
|
-
>
|
|
4137
|
-
Add Anchor
|
|
4138
|
-
</button>
|
|
4139
|
-
</div>
|
|
4112
|
+
<AxisAnchorEditor
|
|
4113
|
+
axisKey='yAxis'
|
|
4114
|
+
config={config}
|
|
4115
|
+
lineOptions={lineOptions}
|
|
4116
|
+
updateConfig={updateConfig}
|
|
4117
|
+
/>
|
|
4140
4118
|
)}
|
|
4141
4119
|
</AccordionItemPanel>
|
|
4142
4120
|
</AccordionItem>
|
|
4143
4121
|
)}
|
|
4122
|
+
{renderHeatMapSettingsAccordion()}
|
|
4144
4123
|
<Panels.Regions name='Regions' />
|
|
4145
4124
|
|
|
4146
4125
|
{/* Columns */}
|
|
@@ -4154,7 +4133,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4154
4133
|
config={config}
|
|
4155
4134
|
updateField={updateFieldDeprecated}
|
|
4156
4135
|
deleteColumn={removeAdditionalColumn}
|
|
4157
|
-
hiddenColumnNames={
|
|
4136
|
+
hiddenColumnNames={
|
|
4137
|
+
isHeatMap ? [...seriesOwnedColumnNames, ...heatMapOwnedColumnNames] : seriesOwnedColumnNames
|
|
4138
|
+
}
|
|
4158
4139
|
/>{' '}
|
|
4159
4140
|
</AccordionItemPanel>
|
|
4160
4141
|
</AccordionItem>
|
|
@@ -4173,7 +4154,11 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4173
4154
|
label='Position'
|
|
4174
4155
|
updateField={updateFieldDeprecated}
|
|
4175
4156
|
options={
|
|
4176
|
-
config.visualizationType === '
|
|
4157
|
+
config.visualizationType === 'HeatMap'
|
|
4158
|
+
? config.legend.style === 'gradient'
|
|
4159
|
+
? ['bottom', 'top']
|
|
4160
|
+
: ['right', 'left', 'bottom', 'top']
|
|
4161
|
+
: config.visualizationType === 'Warming Stripes'
|
|
4177
4162
|
? ['bottom']
|
|
4178
4163
|
: ['right', 'left', 'bottom', 'top']
|
|
4179
4164
|
}
|
|
@@ -4213,7 +4198,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4213
4198
|
options={getLegendStyleOptions('style')}
|
|
4214
4199
|
/>
|
|
4215
4200
|
|
|
4216
|
-
{config.visualizationType !== 'Warming Stripes' && (
|
|
4201
|
+
{config.visualizationType !== 'Warming Stripes' && config.visualizationType !== 'HeatMap' && (
|
|
4217
4202
|
<Select
|
|
4218
4203
|
value={config.legend.groupBy}
|
|
4219
4204
|
section='legend'
|
|
@@ -4379,7 +4364,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4379
4364
|
{config.legend.seriesHighlight &&
|
|
4380
4365
|
config.legend.seriesHighlight.map((val, i) => (
|
|
4381
4366
|
<fieldset className='edit-block' key={`${val}-${i}`}>
|
|
4382
|
-
<
|
|
4367
|
+
<Button
|
|
4383
4368
|
className='btn btn-danger'
|
|
4384
4369
|
onClick={event => {
|
|
4385
4370
|
event.preventDefault()
|
|
@@ -4392,7 +4377,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4392
4377
|
}}
|
|
4393
4378
|
>
|
|
4394
4379
|
Remove
|
|
4395
|
-
</
|
|
4380
|
+
</Button>
|
|
4396
4381
|
<Select
|
|
4397
4382
|
value={config.legend.seriesHighlight[i]}
|
|
4398
4383
|
fieldName='seriesHighlight'
|
|
@@ -4408,8 +4393,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4408
4393
|
/>
|
|
4409
4394
|
</fieldset>
|
|
4410
4395
|
))}
|
|
4411
|
-
<
|
|
4412
|
-
|
|
4396
|
+
<Button
|
|
4397
|
+
variant='editor-primary'
|
|
4413
4398
|
onClick={event => {
|
|
4414
4399
|
event.preventDefault()
|
|
4415
4400
|
const legendColumns = getLegendColumns()
|
|
@@ -4425,7 +4410,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4425
4410
|
}}
|
|
4426
4411
|
>
|
|
4427
4412
|
Add Isolate Value
|
|
4428
|
-
</
|
|
4413
|
+
</Button>
|
|
4429
4414
|
</fieldset>
|
|
4430
4415
|
)}
|
|
4431
4416
|
{/* end: isolated values */}
|
|
@@ -4622,6 +4607,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4622
4607
|
loadConfig={updateConfig}
|
|
4623
4608
|
config={config}
|
|
4624
4609
|
convertStateToConfig={chartConvertStateToConfig}
|
|
4610
|
+
defaultExpanded={config.visualizationType === 'HeatMap'}
|
|
4625
4611
|
/>
|
|
4626
4612
|
)}
|
|
4627
4613
|
</>
|