@cdc/chart 4.26.7 → 4.26.10
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 +502 -368
- package/dist/cdcchart-CYc-Kayd.es.js +22488 -0
- package/dist/cdcchart-DCKn8NmI.es.js +20695 -0
- package/dist/cdcchart-Dyui9nk_.es.js +45828 -0
- package/dist/cdcchart.js +4 -97406
- package/examples/__data__/vega-remote-data.json +6 -0
- package/examples/dendrogram.json +18 -0
- package/examples/feature/bar/bar-chart-race-annual-change.json +68 -0
- package/examples/feature/heatmap/average-age-categorical.json +2 -2
- package/examples/feature/heatmap/calendar-heatmap.json +2 -2
- package/examples/feature/heatmap/cell-values-bottom-axis.json +2 -2
- package/examples/feature/heatmap/sparse-aggregation.json +2 -2
- package/examples/feature/line/line-chart-race.json +50 -0
- package/examples/feature/sankey/sankey-example-data.json +40 -1441
- package/examples/feature/sankey/sankey_chart_data.csv +9 -20
- package/examples/network.json +31 -0
- package/examples/private/box-plot.json +573 -0
- package/examples/private/custom-color-issue.json +625 -0
- package/examples/private/custom-colors.json +522 -0
- package/examples/private/cutoff.json +10750 -0
- package/examples/private/overlay-legend.json +485 -0
- package/examples/private/pie-test.json +469 -0
- package/examples/vega-remote.json +22 -0
- package/package.json +11 -5
- package/src/CdcChartComponent.tsx +405 -208
- package/src/_stories/Chart.BarRace.stories.tsx +443 -0
- package/src/_stories/Chart.BoxPlotNumericSort.stories.tsx +189 -0
- package/src/_stories/Chart.BoxPlotStatsParity.stories.tsx +207 -0
- package/src/_stories/Chart.ColorDistribution.stories.tsx +299 -0
- package/src/_stories/Chart.DataCutoff.stories.tsx +147 -0
- package/src/_stories/Chart.DataTableDownloadFilename.stories.tsx +60 -0
- package/src/_stories/Chart.Dendrogram.stories.tsx +373 -0
- package/src/_stories/Chart.Forecast.CILegend.stories.tsx +236 -0
- package/src/_stories/Chart.HeatMap.stories.tsx +170 -4
- package/src/_stories/Chart.Legend.AxisAlign.stories.tsx +119 -0
- package/src/_stories/Chart.LineRace.stories.tsx +149 -0
- package/src/_stories/Chart.Network.stories.tsx +432 -0
- package/src/_stories/Chart.PaletteConversion.Editor.stories.tsx +208 -0
- package/src/_stories/Chart.Patterns.smoke.stories.tsx +31 -0
- package/src/_stories/Chart.PercentageValue.stories.tsx +311 -0
- package/src/_stories/Chart.PieLabels.stories.tsx +4 -2
- package/src/_stories/Chart.RankByValueMutation.stories.tsx +206 -0
- package/src/_stories/Chart.RequiredFields.stories.tsx +681 -0
- package/src/_stories/Chart.Sankey.stories.tsx +417 -0
- package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +47 -0
- package/src/_stories/Chart.SmallMultiplesNumericTileOrder.stories.tsx +137 -0
- package/src/_stories/Chart.TooltipSeriesLabels.stories.tsx +43 -0
- package/src/_stories/Chart.VegaRemoteData.stories.tsx +31 -0
- package/src/_stories/ChartAnnotation.Editor.stories.tsx +78 -0
- package/src/_stories/ChartAxisTitles.smoke.stories.tsx +48 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +499 -57
- package/src/_stories/ChartBrush.Editor.stories.tsx +46 -67
- package/src/_stories/ChartBrush.Regression.stories.tsx +135 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +33 -3
- package/src/_stories/ChartLine.EffectCompatibility.stories.tsx +120 -0
- package/src/_stories/_mock/annotation_event-line_mock.json +2 -2
- package/src/_stories/_mock/editor-test-configs.json +20 -10
- package/src/_stories/_mock/editor-test-datasets.json +38 -42
- package/src/_stories/_mock/heatmap-average-age-categorical.json +2 -2
- package/src/_stories/_mock/heatmap.json +2 -2
- package/src/_stories/_mock/legend-axis-align-stacked-bar.json +125 -0
- package/src/_stories/_mock/sankey_mock.json +23 -27
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +52 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +639 -139
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +44 -4
- package/src/components/Annotations/components/AnnotationDropdown.tsx +10 -32
- package/src/components/Annotations/helpers/resolveAnnotationLayout.ts +212 -0
- package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +612 -19
- package/src/components/Annotations/tests/AnnotationDropdown.test.tsx +50 -0
- package/src/components/Annotations/tests/resolveAnnotationLayout.test.ts +203 -0
- package/src/components/Axis/BottomAxis.tsx +1 -1
- package/src/components/Axis/Categorical.Axis.tsx +3 -3
- package/src/components/Axis/RightAxis.tsx +21 -13
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +38 -6
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +12 -3
- package/src/components/BarChart/components/BarChart.StackedVertical.test.ts +28 -0
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +29 -25
- package/src/components/BarChart/components/BarChart.Vertical.tsx +37 -26
- package/src/components/BarChart/components/PortionPatternOverlay.tsx +61 -0
- package/src/components/BarChart/components/context.tsx +6 -0
- package/src/components/BarChart/helpers/getPatternUrl.ts +2 -5
- package/src/components/BarChart/helpers/index.ts +8 -0
- package/src/components/BarChart/helpers/portionPattern.ts +243 -0
- package/src/components/BarChart/helpers/tests/addMinimumBarHeights.test.ts +42 -0
- package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +13 -0
- package/src/components/BarChart/helpers/tests/portionPattern.test.ts +280 -0
- package/src/components/BarChart/helpers/tests/useBarChart.test.tsx +104 -0
- package/src/components/BarChart/helpers/useBarChart.ts +60 -59
- package/src/components/BarChartRace/BarChartRace.test.tsx +199 -0
- package/src/components/BarChartRace/BarChartRace.tsx +230 -0
- package/src/components/BarChartRace/BarChartRaceFallback.test.tsx +61 -0
- package/src/components/BarChartRace/BarChartRaceFallback.tsx +48 -0
- package/src/components/BarChartRace/bar-chart-race.css +160 -0
- package/src/components/BarChartRace/helpers.test.ts +114 -0
- package/src/components/BarChartRace/helpers.ts +185 -0
- package/src/components/BarChartRace/index.ts +3 -0
- package/src/components/BoxPlot/helpers/index.ts +11 -82
- package/src/components/Brush/BrushSelector.tsx +9 -23
- package/src/components/Brush/MiniChartPreview.tsx +33 -1
- package/src/components/Dendrogram/components/Dendrogram.tsx +374 -0
- package/src/components/Dendrogram/dendrogram.css +113 -0
- package/src/components/Dendrogram/helpers/layoutDendrogram.test.ts +95 -0
- package/src/components/Dendrogram/helpers/layoutDendrogram.ts +56 -0
- package/src/components/Dendrogram/helpers/prepareDendrogramData.test.ts +135 -0
- package/src/components/Dendrogram/helpers/prepareDendrogramData.ts +166 -0
- package/src/components/Dendrogram/helpers/resolveDendrogramLabels.test.ts +196 -0
- package/src/components/Dendrogram/helpers/resolveDendrogramLabels.ts +418 -0
- package/src/components/Dendrogram/index.tsx +1 -0
- package/src/components/Dendrogram/types/index.ts +66 -0
- package/src/components/EditorPanel/EditorPanel.tsx +1005 -760
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +50 -5
- package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.css +10 -0
- package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.tsx +211 -0
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +19 -8
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +88 -54
- package/src/components/EditorPanel/components/Panels/Panel.Network.css +9 -0
- package/src/components/EditorPanel/components/Panels/Panel.Network.tsx +202 -0
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +233 -33
- package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +6 -1
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +89 -105
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +2 -2
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +8 -66
- package/src/components/EditorPanel/components/Panels/RacingControls.test.tsx +131 -0
- package/src/components/EditorPanel/components/Panels/RacingControls.tsx +185 -0
- package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +2 -2
- package/src/components/EditorPanel/components/Panels/index.tsx +4 -0
- package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +20 -7
- package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +25 -2
- package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +2 -1
- package/src/components/EditorPanel/useEditorPermissions.test.tsx +62 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +70 -24
- package/src/components/Forecasting/Forecasting.tsx +15 -6
- package/src/components/HeatMap/components/HeatMap.tsx +511 -178
- package/src/components/HeatMap/heatmap.constants.ts +7 -3
- package/src/components/HeatMap/heatmap.css +101 -2
- package/src/components/HeatMap/helpers/layout.ts +80 -0
- package/src/components/HeatMap/tests/HeatMap.test.tsx +339 -16
- package/src/components/HeatMap/tests/helpers.test.ts +79 -0
- package/src/components/Legend/Legend.Component.tsx +110 -90
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +7 -0
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +47 -34
- package/src/components/Legend/helpers/createFormatLabels.test.ts +226 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +45 -51
- package/src/components/LineChart/components/LineChart.Circle.tsx +3 -3
- package/src/components/LineChart/helpers.test.ts +126 -38
- package/src/components/LineChart/helpers.ts +9 -4
- package/src/components/LineChart/index.tsx +69 -24
- package/src/components/LineChart/tests/LineChart.test.tsx +630 -0
- package/src/components/LineChartRace/LineChartRace.test.tsx +275 -0
- package/src/components/LineChartRace/LineChartRace.tsx +134 -0
- package/src/components/LineChartRace/LineChartRaceFallback.tsx +28 -0
- package/src/components/LineChartRace/helpers.test.ts +88 -0
- package/src/components/LineChartRace/helpers.ts +157 -0
- package/src/components/LineChartRace/index.ts +3 -0
- package/src/components/LineChartRace/line-chart-race.css +16 -0
- package/src/components/LinearChart/ValueAxisAnchors.tsx +58 -0
- package/src/components/LinearChart/VisualizationRenderer.tsx +18 -23
- package/src/components/LinearChart/tests/LinearChart.test.tsx +412 -13
- package/src/components/LinearChart/tests/VisualizationRenderer.test.tsx +141 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +2 -1
- package/src/components/LinearChart.tsx +81 -51
- package/src/components/Network/components/Network.tsx +372 -0
- package/src/components/Network/helpers/layoutNetwork.test.ts +68 -0
- package/src/components/Network/helpers/layoutNetwork.ts +87 -0
- package/src/components/Network/helpers/prepareNetworkData.test.ts +116 -0
- package/src/components/Network/helpers/prepareNetworkData.ts +101 -0
- package/src/components/Network/helpers/resolveNetworkLabels.test.ts +112 -0
- package/src/components/Network/helpers/resolveNetworkLabels.ts +206 -0
- package/src/components/Network/index.tsx +3 -0
- package/src/components/Network/network.css +107 -0
- package/src/components/Network/types/index.ts +56 -0
- package/src/components/PairedBarChart.jsx +5 -10
- package/src/components/PairedBarChart.test.tsx +71 -0
- package/src/components/PieChart/PieChart.tsx +9 -8
- package/src/components/RacingChartRenderer.tsx +44 -0
- package/src/components/Regions/components/Regions.test.tsx +179 -0
- package/src/components/Regions/components/Regions.tsx +104 -69
- package/src/components/Regions/index.tsx +2 -3
- package/src/components/Sankey/components/Sankey.tsx +264 -437
- package/src/components/Sankey/helpers/getSankeyTooltip.ts +12 -0
- package/src/components/Sankey/helpers/prepareSankeyData.test.ts +71 -0
- package/src/components/Sankey/helpers/prepareSankeyData.ts +90 -0
- package/src/components/Sankey/sankey.scss +57 -116
- package/src/components/Sankey/types/index.ts +41 -4
- package/src/components/ScatterPlot/ScatterPlot.jsx +28 -4
- package/src/components/ScatterPlot/ScatterPlot.test.tsx +60 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +12 -12
- package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +7 -5
- package/src/components/raceTiming.ts +18 -0
- package/src/data/initial-state.js +77 -31
- package/src/helpers/applyChartTypeContract.ts +71 -0
- package/src/helpers/axisLabelFontSize.ts +2 -2
- package/src/helpers/boxPlotStats.ts +60 -0
- package/src/helpers/bumpChartTooltip.ts +2 -1
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.test.ts +37 -0
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +3 -2
- package/src/helpers/calculateRightYAxisWidth.ts +60 -0
- package/src/helpers/colorAssignmentHelpers.ts +2 -2
- package/src/helpers/createNewChartConfig.ts +56 -0
- package/src/helpers/dataDrivenYAxisCategories.ts +18 -0
- package/src/helpers/forecastLegend.ts +88 -0
- package/src/helpers/getBoxPlotConfig.ts +18 -37
- package/src/helpers/getChartTypeDefaultPalette.ts +29 -0
- package/src/helpers/getColorCodeCategoryColorMap.ts +26 -0
- package/src/helpers/getColorScale.ts +31 -22
- package/src/helpers/getDynamicYAxisCategories.ts +69 -0
- package/src/helpers/getMinMax.ts +9 -7
- package/src/helpers/getNewRuntime.ts +5 -2
- package/src/helpers/getStackedSeriesMax.ts +51 -0
- package/src/helpers/getV21ChartDistributionColors.ts +57 -0
- package/src/helpers/handleRankByValue.ts +15 -15
- package/src/helpers/seriesColumnSettings.ts +10 -0
- package/src/helpers/sizeHelpers.ts +4 -3
- package/src/helpers/smallMultiplesHelpers.ts +10 -13
- package/src/helpers/tests/applyChartTypeContract.test.ts +37 -0
- package/src/helpers/tests/boxPlotStats.test.ts +31 -0
- package/src/helpers/tests/bumpChartTooltip.test.ts +29 -0
- package/src/helpers/tests/calculateRightYAxisWidth.test.ts +105 -0
- package/src/helpers/tests/countNumOfTicks.test.ts +11 -0
- package/src/helpers/tests/createNewChartConfig.test.ts +182 -0
- package/src/helpers/tests/getBoxPlotConfig.test.ts +70 -0
- package/src/helpers/tests/getColorCodeCategoryColorMap.test.ts +113 -0
- package/src/helpers/tests/getColorScale.test.ts +226 -1
- package/src/helpers/tests/getDynamicYAxisCategories.test.ts +61 -0
- package/src/helpers/tests/getMinMax.test.ts +41 -0
- package/src/helpers/tests/getStackedSeriesMax.test.ts +26 -0
- package/src/helpers/tests/handleRankByValue.test.ts +55 -37
- package/src/helpers/tests/seriesColumnSettings.test.ts +23 -0
- package/src/helpers/tests/smallMultiplesHelpers.test.ts +37 -1
- package/src/helpers/tests/tooltipHelpers.test.ts +80 -0
- package/src/helpers/tooltipHelpers.ts +16 -0
- package/src/hooks/tests/useTooltip.test.tsx +353 -1
- package/src/hooks/usePrefersReducedMotion.ts +22 -0
- package/src/hooks/useReduceData.ts +4 -36
- package/src/hooks/useScales.ts +15 -0
- package/src/hooks/useTooltip.tsx +95 -64
- package/src/scss/main.scss +74 -2
- package/src/store/chart.reducer.ts +4 -3
- package/src/test/CdcChart.dataTable.test.tsx +490 -16
- package/src/test/CdcChart.dendrogram.test.tsx +277 -0
- package/src/test/CdcChart.finalization.test.tsx +143 -0
- package/src/test/CdcChart.network.test.tsx +271 -0
- package/src/types/ChartConfig.ts +91 -54
- package/src/types/ChartContext.ts +5 -0
- package/src/types/Horizon.ts +1 -1
- package/LICENSE +0 -201
- package/dist/cdcchart-BWVIUcAF.es.js +0 -4802
- package/src/_stories/Chart.Sankey.smoke.stories.tsx +0 -62
- package/src/components/Sankey/components/ColumnList.tsx +0 -19
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +0 -34
- package/src/components/Sankey/useSankeyAlert.tsx +0 -60
- package/src/data/legacy-defaults.ts +0 -18
- package/src/helpers/ensureSpecialChartAxisTypes.ts +0 -11
- package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +0 -30
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
// @cdc/core
|
|
14
14
|
import { EditorPanel as BaseEditorPanel } from '@cdc/core/components/EditorPanel/EditorPanel'
|
|
15
15
|
import AdvancedEditor from '@cdc/core/components/AdvancedEditor'
|
|
16
|
+
import ModernStylesAction from '@cdc/core/components/EditorPanel/ModernStylesAction'
|
|
16
17
|
import Icon from '@cdc/core/components/ui/Icon'
|
|
17
18
|
import ColumnsEditor from '@cdc/core/components/EditorPanel/ColumnsEditor'
|
|
18
19
|
import CustomSortOrder from '@cdc/core/components/EditorPanel/CustomSortOrder'
|
|
@@ -30,7 +31,7 @@ import { useDataColumns } from '@cdc/core/hooks/useDataColumns'
|
|
|
30
31
|
|
|
31
32
|
// chart components
|
|
32
33
|
import Panels from './components/Panels'
|
|
33
|
-
import PaletteConversionModal from '@cdc/core/components/PaletteConversionModal'
|
|
34
|
+
import PaletteConversionModal, { V21_PALETTE_CONVERSION_MESSAGE } from '@cdc/core/components/PaletteConversionModal'
|
|
34
35
|
|
|
35
36
|
// cdc additional
|
|
36
37
|
import { useEditorPermissions } from './useEditorPermissions'
|
|
@@ -64,7 +65,9 @@ import { getSeriesOwnedColumnNames } from '../../helpers/seriesColumnSettings'
|
|
|
64
65
|
import { getOrderedCategoryValues } from '../../helpers/categoryOrder'
|
|
65
66
|
import {
|
|
66
67
|
HEATMAP_CONFIG_DEFAULTS,
|
|
68
|
+
MAX_HEATMAP_COLUMN_WIDTH,
|
|
67
69
|
MAX_HEATMAP_COLOR_BUCKETS,
|
|
70
|
+
MIN_HEATMAP_COLUMN_WIDTH,
|
|
68
71
|
MIN_HEATMAP_COLOR_BUCKETS
|
|
69
72
|
} from '../HeatMap/heatmap.constants'
|
|
70
73
|
|
|
@@ -129,6 +132,7 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
129
132
|
let preliminaryData = config.preliminaryData ? [...config.preliminaryData] : []
|
|
130
133
|
const defaultValues = {
|
|
131
134
|
type: defaultType,
|
|
135
|
+
lineEffectScope: 'outgoing',
|
|
132
136
|
seriesKeys: [],
|
|
133
137
|
label: 'Suppressed',
|
|
134
138
|
column: '',
|
|
@@ -157,7 +161,10 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
157
161
|
preliminaryData = [...config.preliminaryData]
|
|
158
162
|
}
|
|
159
163
|
|
|
160
|
-
preliminaryData[i][fieldName]
|
|
164
|
+
preliminaryData[i] = { ...preliminaryData[i], [fieldName]: value }
|
|
165
|
+
if (fieldName === 'lineEffectScope' && value === '') {
|
|
166
|
+
delete preliminaryData[i].lineEffectScope
|
|
167
|
+
}
|
|
161
168
|
if (fieldName === 'symbol') {
|
|
162
169
|
preliminaryData[i]['iconCode'] = symbolCodes[value]
|
|
163
170
|
}
|
|
@@ -200,6 +207,7 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
200
207
|
value,
|
|
201
208
|
hideBarSymbol,
|
|
202
209
|
hideLineStyle,
|
|
210
|
+
lineEffectScope,
|
|
203
211
|
weight
|
|
204
212
|
},
|
|
205
213
|
i
|
|
@@ -509,6 +517,34 @@ const PreliminaryData: React.FC<PreliminaryProps> = ({ config, updateConfig, dat
|
|
|
509
517
|
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
510
518
|
/>
|
|
511
519
|
)}
|
|
520
|
+
{style && !style.includes('Circles') && (
|
|
521
|
+
<Select
|
|
522
|
+
display={config.visualizationType === 'Line' || hasComboLineSeries}
|
|
523
|
+
id={`line-effect-scope-${i}`}
|
|
524
|
+
value={lineEffectScope === 'outgoing' ? 'outgoing' : ''}
|
|
525
|
+
fieldName='lineEffectScope'
|
|
526
|
+
label='Apply style to'
|
|
527
|
+
aria-label='Apply style to'
|
|
528
|
+
tooltip={
|
|
529
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
530
|
+
<Tooltip.Target>
|
|
531
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
532
|
+
</Tooltip.Target>
|
|
533
|
+
<Tooltip.Content>
|
|
534
|
+
<p>
|
|
535
|
+
A matching data point styles either the segment after it or both segments before
|
|
536
|
+
and after it.
|
|
537
|
+
</p>
|
|
538
|
+
</Tooltip.Content>
|
|
539
|
+
</Tooltip>
|
|
540
|
+
}
|
|
541
|
+
updateField={(_, __, fieldName, value) => update(fieldName, value, i)}
|
|
542
|
+
options={[
|
|
543
|
+
{ label: 'Segment after point', value: 'outgoing' },
|
|
544
|
+
{ label: 'Both adjacent segments', value: '' }
|
|
545
|
+
]}
|
|
546
|
+
/>
|
|
547
|
+
)}
|
|
512
548
|
{style && !style.includes('Circles') && (
|
|
513
549
|
<TextField
|
|
514
550
|
type='number'
|
|
@@ -559,20 +595,27 @@ interface CategoricalAxisProps {
|
|
|
559
595
|
|
|
560
596
|
type AxisAnchorEditorProps = {
|
|
561
597
|
axisKey: 'xAxis' | 'yAxis'
|
|
598
|
+
anchorField?: 'anchors' | 'rightAnchors'
|
|
562
599
|
config: ChartConfig
|
|
563
600
|
lineOptions: { value: string; label?: string }[]
|
|
564
601
|
updateConfig: Function
|
|
565
602
|
}
|
|
566
603
|
|
|
567
|
-
const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({
|
|
568
|
-
|
|
604
|
+
const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({
|
|
605
|
+
axisKey,
|
|
606
|
+
anchorField = 'anchors',
|
|
607
|
+
config,
|
|
608
|
+
lineOptions,
|
|
609
|
+
updateConfig
|
|
610
|
+
}) => {
|
|
611
|
+
const anchors = config[axisKey]?.[anchorField] || []
|
|
569
612
|
|
|
570
613
|
const updateAnchors = (nextAnchors: Anchor[]) => {
|
|
571
614
|
updateConfig({
|
|
572
615
|
...config,
|
|
573
616
|
[axisKey]: {
|
|
574
617
|
...config[axisKey],
|
|
575
|
-
|
|
618
|
+
[anchorField]: nextAnchors
|
|
576
619
|
}
|
|
577
620
|
})
|
|
578
621
|
}
|
|
@@ -608,13 +651,17 @@ const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({ axisKey, config, li
|
|
|
608
651
|
<GroupedList
|
|
609
652
|
items={anchors}
|
|
610
653
|
label='Anchors'
|
|
611
|
-
droppableId={`${axisKey}-
|
|
654
|
+
droppableId={`${axisKey}-${anchorField}-order`}
|
|
612
655
|
onDragEnd={({ source, destination }) => {
|
|
613
656
|
if (!destination || source.index === destination.index) return
|
|
614
657
|
reorderAnchors(source.index, destination.index)
|
|
615
658
|
}}
|
|
616
659
|
renderItem={(anchor, index) => (
|
|
617
|
-
<Draggable
|
|
660
|
+
<Draggable
|
|
661
|
+
key={`${axisKey}-${anchorField}-anchor-${index}`}
|
|
662
|
+
draggableId={`${axisKey}-${anchorField}-anchor-${index}`}
|
|
663
|
+
index={index}
|
|
664
|
+
>
|
|
618
665
|
{(provided, snapshot) => (
|
|
619
666
|
<div
|
|
620
667
|
ref={provided.innerRef}
|
|
@@ -710,6 +757,38 @@ const AxisAnchorEditor: React.FC<AxisAnchorEditorProps> = ({ axisKey, config, li
|
|
|
710
757
|
}
|
|
711
758
|
|
|
712
759
|
const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig, display }) => {
|
|
760
|
+
const dataDrivenCategories = config.yAxis.dataDrivenCategories
|
|
761
|
+
const isDataDriven =
|
|
762
|
+
config.yAxis.categoryMode === 'data-driven' || (config.yAxis.categoryMode === undefined && !!dataDrivenCategories)
|
|
763
|
+
|
|
764
|
+
const updateDynamicCategories = (updates: Record<string, any>) => {
|
|
765
|
+
updateConfig({
|
|
766
|
+
...config,
|
|
767
|
+
yAxis: {
|
|
768
|
+
...config.yAxis,
|
|
769
|
+
dataDrivenCategories: { ...dataDrivenCategories, ...updates }
|
|
770
|
+
}
|
|
771
|
+
})
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
const updateDynamicCategory = (index: number, fieldName: string, value: string) => {
|
|
775
|
+
const categories = [...(dataDrivenCategories?.categories || [])]
|
|
776
|
+
categories[index] = { ...categories[index], [fieldName]: value }
|
|
777
|
+
updateDynamicCategories({ categories })
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
const addDynamicCategory = () => {
|
|
781
|
+
const categories = [...(dataDrivenCategories?.categories || [])]
|
|
782
|
+
categories.push({ label: `Category ${categories.length + 1}`, upperBoundKey: '', color: '#c9c9c9' })
|
|
783
|
+
updateDynamicCategories({ categories })
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
const removeDynamicCategory = (index: number) => {
|
|
787
|
+
const categories = [...(dataDrivenCategories?.categories || [])]
|
|
788
|
+
categories.splice(index, 1)
|
|
789
|
+
updateDynamicCategories({ categories })
|
|
790
|
+
}
|
|
791
|
+
|
|
713
792
|
const maxHeight = config?.yAxis?.maxValue
|
|
714
793
|
|
|
715
794
|
const totalEnteredHeight =
|
|
@@ -763,6 +842,44 @@ const CategoricalAxis: React.FC<CategoricalAxisProps> = ({ config, updateConfig,
|
|
|
763
842
|
return <></>
|
|
764
843
|
}
|
|
765
844
|
|
|
845
|
+
if (isDataDriven && dataDrivenCategories) {
|
|
846
|
+
return (
|
|
847
|
+
<div className='edit-block'>
|
|
848
|
+
<p>Data-Driven Category Axis</p>
|
|
849
|
+
<p>Thresholds are read from the current filtered data. The last category defines the axis maximum.</p>
|
|
850
|
+
{dataDrivenCategories.categories?.map((category, index) => (
|
|
851
|
+
<div key={category.upperBoundKey || category.label || 'unnamed-category'} className='edit-block'>
|
|
852
|
+
<p>Data-Driven Category {index + 1}</p>
|
|
853
|
+
<Button type='button' className='btn btn-danger' onClick={() => removeDynamicCategory(index)}>
|
|
854
|
+
Remove
|
|
855
|
+
</Button>
|
|
856
|
+
<TextField
|
|
857
|
+
value={category.label}
|
|
858
|
+
fieldName='label'
|
|
859
|
+
label='Category Label'
|
|
860
|
+
updateField={(_, __, fieldName, value) => updateDynamicCategory(index, fieldName, value)}
|
|
861
|
+
/>
|
|
862
|
+
<TextField
|
|
863
|
+
value={category.upperBoundKey}
|
|
864
|
+
fieldName='upperBoundKey'
|
|
865
|
+
label='Upper-Bound Column'
|
|
866
|
+
updateField={(_, __, fieldName, value) => updateDynamicCategory(index, fieldName, value)}
|
|
867
|
+
/>
|
|
868
|
+
<TextField
|
|
869
|
+
value={category.color}
|
|
870
|
+
fieldName='color'
|
|
871
|
+
label='Color'
|
|
872
|
+
updateField={(_, __, fieldName, value) => updateDynamicCategory(index, fieldName, value)}
|
|
873
|
+
/>
|
|
874
|
+
</div>
|
|
875
|
+
))}
|
|
876
|
+
<Button type='button' variant='editor-primary' onClick={addDynamicCategory}>
|
|
877
|
+
Add Data-Driven Category
|
|
878
|
+
</Button>
|
|
879
|
+
</div>
|
|
880
|
+
)
|
|
881
|
+
}
|
|
882
|
+
|
|
766
883
|
return (
|
|
767
884
|
<>
|
|
768
885
|
{config.yAxis.type === 'categorical' &&
|
|
@@ -859,7 +976,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
859
976
|
handleShowAll,
|
|
860
977
|
dimensions
|
|
861
978
|
} = useContext<ChartContext>(ConfigContext)
|
|
862
|
-
|
|
979
|
+
const isBarRace = config.visualizationType === 'Bar' && config.visualizationSubType === 'racing'
|
|
863
980
|
const { minValue, maxValue, existPositiveValue, isAllLine } = useReduceData(config, unfilteredData)
|
|
864
981
|
const properties = {
|
|
865
982
|
data,
|
|
@@ -921,7 +1038,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
921
1038
|
...series,
|
|
922
1039
|
type:
|
|
923
1040
|
config.visualizationType === 'Combo' ? 'Bar' : config.visualizationType ? config.visualizationType : 'Bar',
|
|
924
|
-
axis: 'Left'
|
|
1041
|
+
axis: 'Left',
|
|
1042
|
+
tooltip: series.tooltip ?? true
|
|
925
1043
|
}
|
|
926
1044
|
})
|
|
927
1045
|
}
|
|
@@ -985,13 +1103,19 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
985
1103
|
if (isDateScale(updatedConfig.xAxis) && !updatedConfig.xAxis.padding) {
|
|
986
1104
|
updatedConfig.xAxis.padding = 0
|
|
987
1105
|
}
|
|
1106
|
+
if (isDateScale(updatedConfig.xAxis) && updatedConfig.xAxis.dataKey && !updatedConfig.table.defaultSort?.column) {
|
|
1107
|
+
updatedConfig.table.defaultSort = {
|
|
1108
|
+
column: updatedConfig.xAxis.dataKey,
|
|
1109
|
+
sortDirection: 'desc'
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
988
1112
|
// Default Radar charts to a taller height
|
|
989
1113
|
if (updatedConfig.visualizationType === 'Radar' && updatedConfig.heights?.vertical <= 400) {
|
|
990
1114
|
updatedConfig.heights.vertical = 400
|
|
991
1115
|
}
|
|
992
1116
|
// DEV-8008 - Remove Bar styling when Line is converted to Bar
|
|
993
1117
|
if (updatedConfig.visualizationType === 'Line') {
|
|
994
|
-
updatedConfig.visualizationSubType = 'regular'
|
|
1118
|
+
if (updatedConfig.visualizationSubType !== 'racing') updatedConfig.visualizationSubType = 'regular'
|
|
995
1119
|
updatedConfig.barStyle = 'flat'
|
|
996
1120
|
updatedConfig.isLollipopChart = false
|
|
997
1121
|
}
|
|
@@ -1143,7 +1267,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1143
1267
|
}
|
|
1144
1268
|
|
|
1145
1269
|
const addNewExclusion = exclusionKey => {
|
|
1146
|
-
let newExclusion = [...config.exclusions
|
|
1270
|
+
let newExclusion = [...(config.exclusions?.keys ?? [])]
|
|
1147
1271
|
newExclusion.push(exclusionKey)
|
|
1148
1272
|
|
|
1149
1273
|
let payload = { ...config.exclusions, keys: newExclusion }
|
|
@@ -1152,7 +1276,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1152
1276
|
|
|
1153
1277
|
const removeExclusion = excludeValue => {
|
|
1154
1278
|
let exclusionsIndex = -1
|
|
1155
|
-
let exclusions = [...config.exclusions
|
|
1279
|
+
let exclusions = [...(config.exclusions?.keys ?? [])]
|
|
1156
1280
|
|
|
1157
1281
|
for (let i = 0; i < exclusions.length; i++) {
|
|
1158
1282
|
if (exclusions[i] === excludeValue) {
|
|
@@ -1167,10 +1291,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1167
1291
|
let newExclusions = { ...config.exclusions, keys: exclusions }
|
|
1168
1292
|
let newExclusionsPayload = { ...config, exclusions: newExclusions }
|
|
1169
1293
|
|
|
1170
|
-
if (exclusions.length === 0) {
|
|
1171
|
-
delete newExclusionsPayload.exclusions.keys
|
|
1172
|
-
}
|
|
1173
|
-
|
|
1174
1294
|
updateConfig(newExclusionsPayload)
|
|
1175
1295
|
}
|
|
1176
1296
|
}
|
|
@@ -1355,34 +1475,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1355
1475
|
handleUpdateHighlightedBorderWidth
|
|
1356
1476
|
} = useHighlightedBars(config, updateConfig)
|
|
1357
1477
|
|
|
1358
|
-
// when the orientation changes, swap x and y axis anchors
|
|
1359
|
-
useEffect(() => {
|
|
1360
|
-
const prevXAnchors = config.xAxis.anchors.length > 0 ? config.xAxis.anchors : []
|
|
1361
|
-
const prevYAnchors = config.yAxis.anchors.length > 0 ? config.yAxis.anchors : []
|
|
1362
|
-
|
|
1363
|
-
updateConfig({
|
|
1364
|
-
...config,
|
|
1365
|
-
xAxis: {
|
|
1366
|
-
...config.xAxis,
|
|
1367
|
-
anchors: prevYAnchors
|
|
1368
|
-
},
|
|
1369
|
-
yAxis: {
|
|
1370
|
-
...config.yAxis,
|
|
1371
|
-
anchors: prevXAnchors
|
|
1372
|
-
}
|
|
1373
|
-
})
|
|
1374
|
-
}, [config.orientation])
|
|
1375
|
-
|
|
1376
|
-
// Set paired bars to be horizontal, even though that option doesn't display
|
|
1377
|
-
useEffect(() => {
|
|
1378
|
-
if (config.visualizationType === 'Paired Bar') {
|
|
1379
|
-
updateConfig({
|
|
1380
|
-
...config,
|
|
1381
|
-
orientation: 'horizontal'
|
|
1382
|
-
})
|
|
1383
|
-
}
|
|
1384
|
-
}, []) // eslint-disable-line
|
|
1385
|
-
|
|
1386
1478
|
useEffect(() => {
|
|
1387
1479
|
if (config.orientation === 'horizontal') {
|
|
1388
1480
|
updateConfig({
|
|
@@ -1392,15 +1484,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1392
1484
|
}
|
|
1393
1485
|
}, [config.isLollipopChart, config.lollipopShape]) // eslint-disable-line
|
|
1394
1486
|
|
|
1395
|
-
/// temporary force orientation untill we support Vartical deviaton bar
|
|
1396
|
-
useEffect(() => {
|
|
1397
|
-
if (config.visualizationType === 'Deviation Bar') {
|
|
1398
|
-
updateConfig({ ...config, orientation: 'horizontal' })
|
|
1399
|
-
}
|
|
1400
|
-
}, [config.visualizationType])
|
|
1401
|
-
|
|
1402
1487
|
const ExclusionsList = useCallback(() => {
|
|
1403
|
-
const exclusions = [...config.exclusions
|
|
1488
|
+
const exclusions = [...(config.exclusions?.keys ?? [])]
|
|
1404
1489
|
return (
|
|
1405
1490
|
<ul className='series-list'>
|
|
1406
1491
|
{exclusions.map((exclusion, index) => {
|
|
@@ -1463,6 +1548,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1463
1548
|
|
|
1464
1549
|
// Check if it's a v1 palette configuration
|
|
1465
1550
|
const isV1PaletteConfig = isV1Palette(config)
|
|
1551
|
+
const shouldUpgradePalette = USE_V2_MIGRATION && (isV1PaletteConfig || config.general?.palette?.version === '2.0')
|
|
1466
1552
|
|
|
1467
1553
|
const executeSelection = () => {
|
|
1468
1554
|
const _newConfig = cloneConfig(config)
|
|
@@ -1478,14 +1564,14 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1478
1564
|
// V2 migration logic
|
|
1479
1565
|
const migratedName = palette ? migratePaletteWithMap(palette, paletteMigrationMap, false) : undefined
|
|
1480
1566
|
_newConfig.general.palette.name = migratedName
|
|
1481
|
-
if (
|
|
1482
|
-
_newConfig.general.palette.version = '2.
|
|
1567
|
+
if (shouldUpgradePalette) {
|
|
1568
|
+
_newConfig.general.palette.version = '2.1'
|
|
1483
1569
|
}
|
|
1484
1570
|
}
|
|
1485
1571
|
updateConfig(_newConfig)
|
|
1486
1572
|
}
|
|
1487
1573
|
|
|
1488
|
-
if (
|
|
1574
|
+
if (shouldUpgradePalette) {
|
|
1489
1575
|
setPendingPaletteSelection({ palette, action: executeSelection, type: 'general' })
|
|
1490
1576
|
setShowConversionModal(true)
|
|
1491
1577
|
} else {
|
|
@@ -1539,7 +1625,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1539
1625
|
if (!_newConfig.general.palette) {
|
|
1540
1626
|
_newConfig.general.palette = {}
|
|
1541
1627
|
}
|
|
1542
|
-
_newConfig.general.palette.version = '2.
|
|
1628
|
+
_newConfig.general.palette.version = '2.1'
|
|
1543
1629
|
|
|
1544
1630
|
// Create backup for rollback functionality (consistent with standard format)
|
|
1545
1631
|
if (!_newConfig.general.palette.backups) {
|
|
@@ -1595,7 +1681,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1595
1681
|
if (!_newConfig.general.palette) {
|
|
1596
1682
|
_newConfig.general.palette = {}
|
|
1597
1683
|
}
|
|
1598
|
-
_newConfig.general.palette.version = '2.
|
|
1684
|
+
_newConfig.general.palette.version = '2.1'
|
|
1599
1685
|
|
|
1600
1686
|
// Forecast-specific migration map for v1 → v2 palette names (all lowercase-hyphen format)
|
|
1601
1687
|
const forecastPaletteMigrationMap: Record<string, string> = {
|
|
@@ -1720,15 +1806,14 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
1720
1806
|
_newConfig.general.palette.name = palette
|
|
1721
1807
|
}
|
|
1722
1808
|
|
|
1723
|
-
//
|
|
1809
|
+
// Keep the current palette version
|
|
1724
1810
|
if (!_newConfig.general) {
|
|
1725
1811
|
_newConfig.general = {}
|
|
1726
1812
|
}
|
|
1727
1813
|
if (!_newConfig.general.palette) {
|
|
1728
1814
|
_newConfig.general.palette = {}
|
|
1729
1815
|
}
|
|
1730
|
-
_newConfig.general.palette.version = '1.0'
|
|
1731
|
-
|
|
1816
|
+
_newConfig.general.palette.version = config.general?.palette?.version || '1.0'
|
|
1732
1817
|
updateConfig(_newConfig)
|
|
1733
1818
|
}
|
|
1734
1819
|
setShowConversionModal(false)
|
|
@@ -2048,6 +2133,25 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2048
2133
|
label='Show Cell Values'
|
|
2049
2134
|
updateField={updateFieldDeprecated}
|
|
2050
2135
|
/>
|
|
2136
|
+
<CheckBox
|
|
2137
|
+
value={Boolean(config.heatmap?.horizontalScroll ?? HEATMAP_CONFIG_DEFAULTS.horizontalScroll)}
|
|
2138
|
+
section='heatmap'
|
|
2139
|
+
fieldName='horizontalScroll'
|
|
2140
|
+
label='Enable Horizontal Scrolling'
|
|
2141
|
+
updateField={updateFieldDeprecated}
|
|
2142
|
+
/>
|
|
2143
|
+
{Boolean(config.heatmap?.horizontalScroll ?? HEATMAP_CONFIG_DEFAULTS.horizontalScroll) && (
|
|
2144
|
+
<TextField
|
|
2145
|
+
value={config.heatmap?.minColumnWidth ?? HEATMAP_CONFIG_DEFAULTS.minColumnWidth}
|
|
2146
|
+
type='number'
|
|
2147
|
+
min={MIN_HEATMAP_COLUMN_WIDTH}
|
|
2148
|
+
max={MAX_HEATMAP_COLUMN_WIDTH}
|
|
2149
|
+
section='heatmap'
|
|
2150
|
+
fieldName='minColumnWidth'
|
|
2151
|
+
label='Minimum Column Width'
|
|
2152
|
+
updateField={updateFieldDeprecated}
|
|
2153
|
+
/>
|
|
2154
|
+
)}
|
|
2051
2155
|
<TextField
|
|
2052
2156
|
value={config.heatmap?.cellPadding ?? HEATMAP_CONFIG_DEFAULTS.cellPadding}
|
|
2053
2157
|
type='number'
|
|
@@ -2056,6 +2160,14 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2056
2160
|
fieldName='cellPadding'
|
|
2057
2161
|
label='Cell Padding'
|
|
2058
2162
|
updateField={updateFieldDeprecated}
|
|
2163
|
+
tooltip={
|
|
2164
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
2165
|
+
<Tooltip.Target>
|
|
2166
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2167
|
+
</Tooltip.Target>
|
|
2168
|
+
<Tooltip.Content>To adjust cell height, use Chart Height in the General panel.</Tooltip.Content>
|
|
2169
|
+
</Tooltip>
|
|
2170
|
+
}
|
|
2059
2171
|
/>
|
|
2060
2172
|
<TextField
|
|
2061
2173
|
value={config.heatmap?.rowLabelGap ?? HEATMAP_CONFIG_DEFAULTS.rowLabelGap}
|
|
@@ -2121,16 +2233,21 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2121
2233
|
<Panels.General name='General' />
|
|
2122
2234
|
<Panels.ForestPlot name='Forest Plot Settings' />
|
|
2123
2235
|
<Panels.Sankey name='Sankey' />
|
|
2236
|
+
<Panels.Network name='Network' />
|
|
2237
|
+
<Panels.Dendrogram name='Dendrogram' />
|
|
2124
2238
|
{config.visualizationType !== 'Pie' &&
|
|
2125
2239
|
config.visualizationType !== 'Forest Plot' &&
|
|
2126
|
-
|
|
2240
|
+
!['Sankey', 'Network', 'Dendrogram'].includes(config.visualizationType) && (
|
|
2127
2241
|
<AccordionItem>
|
|
2128
2242
|
<AccordionItemHeading>
|
|
2129
|
-
<AccordionItemButton>
|
|
2243
|
+
<AccordionItemButton data-required-field-section='data-series'>
|
|
2130
2244
|
Data Series{' '}
|
|
2131
2245
|
{(!config.series ||
|
|
2132
2246
|
config.series.length === 0 ||
|
|
2133
|
-
(config.
|
|
2247
|
+
(config.isLollipopChart && config.series.length !== 1) ||
|
|
2248
|
+
(config.visualizationType === 'Radar' && config.series.length < 3) ||
|
|
2249
|
+
(config.visualizationType === 'Deviation Bar' && config.series.length !== 1) ||
|
|
2250
|
+
(config.visualizationType === 'Paired Bar' && config.series.length !== 2)) &&
|
|
2134
2251
|
!config.dynamicSeries &&
|
|
2135
2252
|
config.visualizationType !== 'HeatMap' && (
|
|
2136
2253
|
<WarningImage width='25' className='warning-icon' />
|
|
@@ -2180,25 +2297,31 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2180
2297
|
{(!config.series || config.series.length === 0) &&
|
|
2181
2298
|
!config.dynamicSeries &&
|
|
2182
2299
|
config.visualizationType !== 'Paired Bar' &&
|
|
2183
|
-
config.visualizationType !== '
|
|
2184
|
-
|
|
2185
|
-
|
|
2300
|
+
config.visualizationType !== 'Deviation Bar' &&
|
|
2301
|
+
config.visualizationType !== 'HeatMap' &&
|
|
2302
|
+
!config.isLollipopChart && <p className='warning'>At least one series is required</p>}
|
|
2303
|
+
{config.isLollipopChart && config.series?.length !== 1 && (
|
|
2304
|
+
<p className='warning'>Select exactly one data series for a lollipop chart.</p>
|
|
2305
|
+
)}
|
|
2306
|
+
{config.visualizationType === 'Deviation Bar' && config.series?.length !== 1 && (
|
|
2307
|
+
<p className='warning'>Select exactly one data series for a deviation bar chart.</p>
|
|
2308
|
+
)}
|
|
2186
2309
|
{(!config.series || config.series.length === 0) &&
|
|
2187
2310
|
!config.dynamicSeries &&
|
|
2188
2311
|
config.visualizationType === 'HeatMap' && (
|
|
2189
2312
|
<p className='warning'>At least one series is required</p>
|
|
2190
2313
|
)}
|
|
2191
|
-
{
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
)}
|
|
2314
|
+
{config.series?.length !== 2 && config.visualizationType === 'Paired Bar' && (
|
|
2315
|
+
<p className='warning'>
|
|
2316
|
+
Select two data series for paired bar chart (e.g., Male and Female).
|
|
2317
|
+
</p>
|
|
2318
|
+
)}
|
|
2197
2319
|
<>
|
|
2198
2320
|
<Select
|
|
2199
2321
|
fieldName='visualizationType'
|
|
2200
2322
|
label='Add Data Series'
|
|
2201
2323
|
aria-label='Add Data Series'
|
|
2324
|
+
data-required-field-control='data-series'
|
|
2202
2325
|
initial='Select'
|
|
2203
2326
|
onChange={e => {
|
|
2204
2327
|
if (e.target.value !== '' && e.target.value !== 'Select') {
|
|
@@ -2305,7 +2428,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2305
2428
|
{visSupportsLeftValueAxis() && (
|
|
2306
2429
|
<AccordionItem>
|
|
2307
2430
|
<AccordionItemHeading>
|
|
2308
|
-
<AccordionItemButton
|
|
2431
|
+
<AccordionItemButton
|
|
2432
|
+
data-required-field-section={config.visualizationType === 'Pie' ? 'pie-data-column' : undefined}
|
|
2433
|
+
>
|
|
2309
2434
|
{config.visualizationType === 'Pie'
|
|
2310
2435
|
? 'Data Format'
|
|
2311
2436
|
: config.orientation === 'vertical'
|
|
@@ -2324,6 +2449,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2324
2449
|
section='yAxis'
|
|
2325
2450
|
fieldName='dataKey'
|
|
2326
2451
|
label='Data Column'
|
|
2452
|
+
data-required-field-control='pie-data-column'
|
|
2327
2453
|
initial='Select'
|
|
2328
2454
|
required={true}
|
|
2329
2455
|
updateField={updateFieldDeprecated}
|
|
@@ -2440,29 +2566,57 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2440
2566
|
/>
|
|
2441
2567
|
</>
|
|
2442
2568
|
)}
|
|
2443
|
-
{config.visualizationType !== 'Pie' && config.visualizationType !== 'HeatMap' && (
|
|
2569
|
+
{!isBarRace && config.visualizationType !== 'Pie' && config.visualizationType !== 'HeatMap' && (
|
|
2444
2570
|
<>
|
|
2445
2571
|
<Select
|
|
2446
2572
|
label='Axis Type'
|
|
2447
|
-
value={
|
|
2573
|
+
value={
|
|
2574
|
+
config.yAxis.type === 'categorical' &&
|
|
2575
|
+
(config.yAxis.categoryMode === 'data-driven' ||
|
|
2576
|
+
(config.yAxis.categoryMode === undefined && config.yAxis.dataDrivenCategories))
|
|
2577
|
+
? 'categorical-data-driven'
|
|
2578
|
+
: config.yAxis.type
|
|
2579
|
+
}
|
|
2448
2580
|
options={[
|
|
2449
2581
|
{ value: 'linear', label: 'Numeric (Linear Scale)' },
|
|
2450
2582
|
...(config.visualizationSubType !== 'stacked'
|
|
2451
2583
|
? [{ value: 'logarithmic', label: 'Numeric (Logarithmic Scale)' }]
|
|
2452
2584
|
: []),
|
|
2453
2585
|
...(config.orientation !== 'horizontal'
|
|
2454
|
-
? [
|
|
2586
|
+
? [
|
|
2587
|
+
{ value: 'categorical', label: 'Categorical' },
|
|
2588
|
+
{ value: 'categorical-data-driven', label: 'Categorical (Data-Driven)' }
|
|
2589
|
+
]
|
|
2455
2590
|
: [])
|
|
2456
2591
|
]}
|
|
2457
2592
|
section='yAxis'
|
|
2458
2593
|
fieldName='type'
|
|
2459
2594
|
updateField={(_section, _subsection, _fieldName, value) => {
|
|
2595
|
+
const isDataDriven = value === 'categorical-data-driven'
|
|
2596
|
+
const isCategorical = value === 'categorical' || isDataDriven
|
|
2597
|
+
const nextYAxis = {
|
|
2598
|
+
...config.yAxis,
|
|
2599
|
+
type: isCategorical ? 'categorical' : value
|
|
2600
|
+
}
|
|
2601
|
+
|
|
2602
|
+
if (isDataDriven) {
|
|
2603
|
+
nextYAxis.categoryMode = 'data-driven'
|
|
2604
|
+
nextYAxis.dataDrivenCategories = config.yAxis.dataDrivenCategories || {
|
|
2605
|
+
categories: [],
|
|
2606
|
+
manualCategories: config.yAxis.categories || []
|
|
2607
|
+
}
|
|
2608
|
+
nextYAxis.categories = []
|
|
2609
|
+
} else if (isCategorical) {
|
|
2610
|
+
nextYAxis.categoryMode = 'manual'
|
|
2611
|
+
nextYAxis.categories =
|
|
2612
|
+
config.yAxis.dataDrivenCategories?.manualCategories || config.yAxis.categories || []
|
|
2613
|
+
} else {
|
|
2614
|
+
delete nextYAxis.categoryMode
|
|
2615
|
+
}
|
|
2616
|
+
|
|
2460
2617
|
updateConfig({
|
|
2461
2618
|
...config,
|
|
2462
|
-
yAxis:
|
|
2463
|
-
...config.yAxis,
|
|
2464
|
-
type: value
|
|
2465
|
-
}
|
|
2619
|
+
yAxis: nextYAxis
|
|
2466
2620
|
})
|
|
2467
2621
|
}}
|
|
2468
2622
|
tooltip={
|
|
@@ -2471,8 +2625,8 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2471
2625
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2472
2626
|
</Tooltip.Target>
|
|
2473
2627
|
<Tooltip.Content>
|
|
2474
|
-
Select
|
|
2475
|
-
|
|
2628
|
+
Select a numeric scale, 'Categorical' for manually sized categories, or 'Categorical
|
|
2629
|
+
(Data-Driven)' to size categories from threshold columns in the current data.
|
|
2476
2630
|
</Tooltip.Content>
|
|
2477
2631
|
</Tooltip>
|
|
2478
2632
|
}
|
|
@@ -2491,20 +2645,28 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2491
2645
|
fieldName='label'
|
|
2492
2646
|
label='Label'
|
|
2493
2647
|
updateField={updateFieldDeprecated}
|
|
2494
|
-
maxLength={
|
|
2648
|
+
maxLength={
|
|
2649
|
+
config.orientation === 'horizontal' || config.yAxis.titlePlacement === 'side'
|
|
2650
|
+
? 35
|
|
2651
|
+
: undefined
|
|
2652
|
+
}
|
|
2495
2653
|
tooltip={
|
|
2496
2654
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
2497
2655
|
<Tooltip.Target>
|
|
2498
2656
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2499
2657
|
</Tooltip.Target>
|
|
2500
2658
|
<Tooltip.Content>
|
|
2501
|
-
<p>
|
|
2659
|
+
<p>
|
|
2660
|
+
{config.orientation === 'horizontal'
|
|
2661
|
+
? '35 character limit'
|
|
2662
|
+
: '35 character limit when Label Placement is Side'}
|
|
2663
|
+
</p>
|
|
2502
2664
|
</Tooltip.Content>
|
|
2503
2665
|
</Tooltip>
|
|
2504
2666
|
}
|
|
2505
2667
|
/>
|
|
2506
2668
|
<Select
|
|
2507
|
-
display={!visHasCategoricalAxis()}
|
|
2669
|
+
display={config.orientation !== 'horizontal' && !visHasCategoricalAxis()}
|
|
2508
2670
|
value={config.yAxis.titlePlacement}
|
|
2509
2671
|
section='yAxis'
|
|
2510
2672
|
fieldName='titlePlacement'
|
|
@@ -2667,7 +2829,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2667
2829
|
}
|
|
2668
2830
|
/>
|
|
2669
2831
|
<CheckBox
|
|
2670
|
-
display={!visHasCategoricalAxis()}
|
|
2832
|
+
display={!isBarRace && !visHasCategoricalAxis()}
|
|
2671
2833
|
value={config.dataFormat.abbreviated}
|
|
2672
2834
|
section='dataFormat'
|
|
2673
2835
|
fieldName='abbreviated'
|
|
@@ -2795,255 +2957,82 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
2795
2957
|
}
|
|
2796
2958
|
/>
|
|
2797
2959
|
</div>
|
|
2798
|
-
{
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
fieldName='hideAxis'
|
|
2805
|
-
label='Hide Axis'
|
|
2806
|
-
updateField={updateFieldDeprecated}
|
|
2807
|
-
/>
|
|
2808
|
-
)}
|
|
2809
|
-
{visSupportsValueAxisLabels() && (
|
|
2810
|
-
<CheckBox
|
|
2811
|
-
value={config.xAxis.hideLabel}
|
|
2812
|
-
section='xAxis'
|
|
2813
|
-
fieldName='hideLabel'
|
|
2814
|
-
label='Hide Tick Labels'
|
|
2815
|
-
updateField={updateFieldDeprecated}
|
|
2816
|
-
/>
|
|
2817
|
-
)}
|
|
2818
|
-
{visSupportsValueAxisTicks() && (
|
|
2819
|
-
<CheckBox
|
|
2820
|
-
value={config.xAxis.hideTicks}
|
|
2821
|
-
section='xAxis'
|
|
2822
|
-
fieldName='hideTicks'
|
|
2823
|
-
label='Hide Ticks'
|
|
2824
|
-
updateField={updateFieldDeprecated}
|
|
2825
|
-
/>
|
|
2826
|
-
)}
|
|
2827
|
-
<div className='axis-domain-group'>
|
|
2828
|
-
<span className='axis-domain-group__title'>Value Axis Domain</span>
|
|
2829
|
-
<div className='axis-domain-group__row'>
|
|
2830
|
-
{visSupportsValueAxisMax() && (
|
|
2831
|
-
<div className='axis-domain-group__field'>
|
|
2832
|
-
<TextField
|
|
2833
|
-
value={config.xAxis.max}
|
|
2834
|
-
section='xAxis'
|
|
2835
|
-
fieldName='max'
|
|
2836
|
-
label='axis max value'
|
|
2837
|
-
type='number'
|
|
2838
|
-
placeholder='Auto'
|
|
2839
|
-
className='axis-domain-number'
|
|
2840
|
-
updateField={updateFieldDeprecated}
|
|
2841
|
-
/>
|
|
2842
|
-
<span className='axis-domain-warning'>{warningMsg.maxMsg}</span>
|
|
2843
|
-
</div>
|
|
2844
|
-
)}
|
|
2845
|
-
{visSupportsValueAxisMin() && (
|
|
2846
|
-
<div className='axis-domain-group__field'>
|
|
2847
|
-
<TextField
|
|
2848
|
-
value={config.xAxis.min}
|
|
2849
|
-
section='xAxis'
|
|
2850
|
-
fieldName='min'
|
|
2851
|
-
type='number'
|
|
2852
|
-
label='axis min value'
|
|
2853
|
-
placeholder='Auto'
|
|
2854
|
-
className='axis-domain-number'
|
|
2855
|
-
updateField={updateFieldDeprecated}
|
|
2856
|
-
/>
|
|
2857
|
-
<span className='axis-domain-warning'>{warningMsg.minMsg}</span>
|
|
2858
|
-
</div>
|
|
2859
|
-
)}
|
|
2860
|
-
</div>
|
|
2861
|
-
{config.visualizationType === 'Deviation Bar' && (
|
|
2862
|
-
<TextField
|
|
2863
|
-
value={config.xAxis.target}
|
|
2960
|
+
{!isBarRace &&
|
|
2961
|
+
(config.orientation === 'horizontal' ? ( // horizontal - x is vertical y is horizontal
|
|
2962
|
+
<>
|
|
2963
|
+
{visSupportsValueAxisLine() && (
|
|
2964
|
+
<CheckBox
|
|
2965
|
+
value={config.xAxis.hideAxis}
|
|
2864
2966
|
section='xAxis'
|
|
2865
|
-
fieldName='
|
|
2866
|
-
|
|
2867
|
-
label='Deviation point'
|
|
2868
|
-
placeholder='Auto'
|
|
2869
|
-
className='axis-domain-number'
|
|
2870
|
-
updateField={updateFieldDeprecated}
|
|
2871
|
-
/>
|
|
2872
|
-
)}
|
|
2873
|
-
<TextField
|
|
2874
|
-
value={config.yAxis.smallestLeftAxisMax}
|
|
2875
|
-
section='yAxis'
|
|
2876
|
-
fieldName='smallestLeftAxisMax'
|
|
2877
|
-
type='number'
|
|
2878
|
-
label='Smallest axis maximum'
|
|
2879
|
-
placeholder='Auto'
|
|
2880
|
-
className='axis-domain-number'
|
|
2881
|
-
tooltip={
|
|
2882
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2883
|
-
<Tooltip.Target>
|
|
2884
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2885
|
-
</Tooltip.Target>
|
|
2886
|
-
<Tooltip.Content>
|
|
2887
|
-
<p>
|
|
2888
|
-
Example: If your data only goes up to 1, the axis might show 0, 0.2, 0.4, 0.6,
|
|
2889
|
-
0.8, 1. Setting this to 5 would make the axis show 0, 1, 2, 3, 4, 5 instead.
|
|
2890
|
-
</p>
|
|
2891
|
-
</Tooltip.Content>
|
|
2892
|
-
</Tooltip>
|
|
2893
|
-
}
|
|
2894
|
-
updateField={updateFieldDeprecated}
|
|
2895
|
-
/>
|
|
2896
|
-
{visSupportsAutoMaxStrategy() && (
|
|
2897
|
-
<Select
|
|
2898
|
-
value={config.yAxis.autoMaxStrategy || 'default'}
|
|
2899
|
-
section='yAxis'
|
|
2900
|
-
fieldName='autoMaxStrategy'
|
|
2901
|
-
label='Automatic max strategy'
|
|
2902
|
-
updateField={updateFieldDeprecated}
|
|
2903
|
-
options={[
|
|
2904
|
-
{ value: 'default', label: 'Default' },
|
|
2905
|
-
{ value: 'clean-top-tick', label: 'Clean top tick' }
|
|
2906
|
-
]}
|
|
2907
|
-
tooltip={
|
|
2908
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2909
|
-
<Tooltip.Target>
|
|
2910
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2911
|
-
</Tooltip.Target>
|
|
2912
|
-
<Tooltip.Content>
|
|
2913
|
-
{config.visualizationType === 'Combo' ? (
|
|
2914
|
-
<p>
|
|
2915
|
-
Clean top tick rounds automatic left and right axis maximums up to cleaner
|
|
2916
|
-
tick steps before axis padding is applied.
|
|
2917
|
-
</p>
|
|
2918
|
-
) : (
|
|
2919
|
-
<p>
|
|
2920
|
-
Clean top tick rounds the automatic value axis maximum up to a cleaner tick
|
|
2921
|
-
step before axis padding is applied.
|
|
2922
|
-
</p>
|
|
2923
|
-
)}
|
|
2924
|
-
</Tooltip.Content>
|
|
2925
|
-
</Tooltip>
|
|
2926
|
-
}
|
|
2927
|
-
/>
|
|
2928
|
-
)}
|
|
2929
|
-
{visSupportsFilterDomainBehavior() && (
|
|
2930
|
-
<Select
|
|
2931
|
-
value={config.yAxis.filterDomainBehavior || 'dynamic'}
|
|
2932
|
-
section='yAxis'
|
|
2933
|
-
fieldName='filterDomainBehavior'
|
|
2934
|
-
label='Filter Domain Behavior'
|
|
2967
|
+
fieldName='hideAxis'
|
|
2968
|
+
label='Hide Axis'
|
|
2935
2969
|
updateField={updateFieldDeprecated}
|
|
2936
|
-
options={[
|
|
2937
|
-
{ value: 'dynamic', label: 'Dynamic' },
|
|
2938
|
-
{ value: 'stable', label: 'Stable' }
|
|
2939
|
-
]}
|
|
2940
|
-
tooltip={
|
|
2941
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
2942
|
-
<Tooltip.Target>
|
|
2943
|
-
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
2944
|
-
</Tooltip.Target>
|
|
2945
|
-
<Tooltip.Content>
|
|
2946
|
-
{config.visualizationType === 'Combo' ? (
|
|
2947
|
-
<p>
|
|
2948
|
-
Dynamic rescales the value axes to the currently filtered data. Stable keeps
|
|
2949
|
-
the left and right axes based on the full eligible dataset while still
|
|
2950
|
-
rendering filtered rows.
|
|
2951
|
-
</p>
|
|
2952
|
-
) : (
|
|
2953
|
-
<p>
|
|
2954
|
-
Dynamic rescales the value axis to the currently filtered data. Stable keeps
|
|
2955
|
-
the value axis based on the full eligible dataset while still rendering
|
|
2956
|
-
filtered rows.
|
|
2957
|
-
</p>
|
|
2958
|
-
)}
|
|
2959
|
-
</Tooltip.Content>
|
|
2960
|
-
</Tooltip>
|
|
2961
|
-
}
|
|
2962
2970
|
/>
|
|
2963
2971
|
)}
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
<TextField
|
|
2968
|
-
value={config.xAxis.targetLabel || 'Target'}
|
|
2972
|
+
{visSupportsValueAxisLabels() && (
|
|
2973
|
+
<CheckBox
|
|
2974
|
+
value={config.xAxis.hideLabel}
|
|
2969
2975
|
section='xAxis'
|
|
2970
|
-
fieldName='
|
|
2971
|
-
|
|
2972
|
-
label='Deviation point Label'
|
|
2976
|
+
fieldName='hideLabel'
|
|
2977
|
+
label='Hide Tick Labels'
|
|
2973
2978
|
updateField={updateFieldDeprecated}
|
|
2974
2979
|
/>
|
|
2980
|
+
)}
|
|
2981
|
+
{visSupportsValueAxisTicks() && (
|
|
2975
2982
|
<CheckBox
|
|
2976
|
-
value={config.xAxis.
|
|
2983
|
+
value={config.xAxis.hideTicks}
|
|
2977
2984
|
section='xAxis'
|
|
2978
|
-
fieldName='
|
|
2979
|
-
label='
|
|
2985
|
+
fieldName='hideTicks'
|
|
2986
|
+
label='Hide Ticks'
|
|
2980
2987
|
updateField={updateFieldDeprecated}
|
|
2981
2988
|
/>
|
|
2982
|
-
|
|
2983
|
-
)}
|
|
2984
|
-
</>
|
|
2985
|
-
) : (
|
|
2986
|
-
config.visualizationType !== 'Pie' &&
|
|
2987
|
-
config.visualizationType !== 'HeatMap' && (
|
|
2988
|
-
<>
|
|
2989
|
-
<CheckBox
|
|
2990
|
-
display={!visHasCategoricalAxis()}
|
|
2991
|
-
value={config.yAxis.hideAxis}
|
|
2992
|
-
section='yAxis'
|
|
2993
|
-
fieldName='hideAxis'
|
|
2994
|
-
label='Hide Axis'
|
|
2995
|
-
updateField={updateFieldDeprecated}
|
|
2996
|
-
/>
|
|
2997
|
-
<CheckBox
|
|
2998
|
-
display={!visHasCategoricalAxis()}
|
|
2999
|
-
value={config.yAxis.hideLabel}
|
|
3000
|
-
section='yAxis'
|
|
3001
|
-
fieldName='hideLabel'
|
|
3002
|
-
label='Hide Tick Labels'
|
|
3003
|
-
updateField={updateFieldDeprecated}
|
|
3004
|
-
/>
|
|
3005
|
-
<CheckBox
|
|
3006
|
-
display={!visHasCategoricalAxis()}
|
|
3007
|
-
value={config.yAxis.hideTicks}
|
|
3008
|
-
section='yAxis'
|
|
3009
|
-
fieldName='hideTicks'
|
|
3010
|
-
label='Hide Ticks'
|
|
3011
|
-
updateField={updateFieldDeprecated}
|
|
3012
|
-
/>
|
|
3013
|
-
|
|
2989
|
+
)}
|
|
3014
2990
|
<div className='axis-domain-group'>
|
|
3015
2991
|
<span className='axis-domain-group__title'>Value Axis Domain</span>
|
|
3016
2992
|
<div className='axis-domain-group__row'>
|
|
3017
|
-
|
|
3018
|
-
<
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
</
|
|
3045
|
-
|
|
2993
|
+
{visSupportsValueAxisMax() && (
|
|
2994
|
+
<div className='axis-domain-group__field'>
|
|
2995
|
+
<TextField
|
|
2996
|
+
value={config.xAxis.max}
|
|
2997
|
+
section='xAxis'
|
|
2998
|
+
fieldName='max'
|
|
2999
|
+
label='axis max value'
|
|
3000
|
+
type='number'
|
|
3001
|
+
placeholder='Auto'
|
|
3002
|
+
className='axis-domain-number'
|
|
3003
|
+
updateField={updateFieldDeprecated}
|
|
3004
|
+
/>
|
|
3005
|
+
<span className='axis-domain-warning'>{warningMsg.maxMsg}</span>
|
|
3006
|
+
</div>
|
|
3007
|
+
)}
|
|
3008
|
+
{visSupportsValueAxisMin() && (
|
|
3009
|
+
<div className='axis-domain-group__field'>
|
|
3010
|
+
<TextField
|
|
3011
|
+
value={config.xAxis.min}
|
|
3012
|
+
section='xAxis'
|
|
3013
|
+
fieldName='min'
|
|
3014
|
+
type='number'
|
|
3015
|
+
label='axis min value'
|
|
3016
|
+
placeholder='Auto'
|
|
3017
|
+
className='axis-domain-number'
|
|
3018
|
+
updateField={updateFieldDeprecated}
|
|
3019
|
+
/>
|
|
3020
|
+
<span className='axis-domain-warning'>{warningMsg.minMsg}</span>
|
|
3021
|
+
</div>
|
|
3022
|
+
)}
|
|
3046
3023
|
</div>
|
|
3024
|
+
{config.visualizationType === 'Deviation Bar' && (
|
|
3025
|
+
<TextField
|
|
3026
|
+
value={config.xAxis.target}
|
|
3027
|
+
section='xAxis'
|
|
3028
|
+
fieldName='target'
|
|
3029
|
+
type='number'
|
|
3030
|
+
label='Deviation point'
|
|
3031
|
+
placeholder='Auto'
|
|
3032
|
+
className='axis-domain-number'
|
|
3033
|
+
updateField={updateFieldDeprecated}
|
|
3034
|
+
/>
|
|
3035
|
+
)}
|
|
3047
3036
|
<TextField
|
|
3048
3037
|
value={config.yAxis.smallestLeftAxisMax}
|
|
3049
3038
|
section='yAxis'
|
|
@@ -3135,30 +3124,203 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3135
3124
|
}
|
|
3136
3125
|
/>
|
|
3137
3126
|
)}
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
section='yAxis'
|
|
3142
|
-
fieldName='enablePadding'
|
|
3143
|
-
label='Add Padding to Value Axis Scale'
|
|
3144
|
-
updateField={updateFieldDeprecated}
|
|
3145
|
-
/>
|
|
3146
|
-
)}
|
|
3147
|
-
{config.yAxis.enablePadding && visSupportsYPadding() && (
|
|
3127
|
+
</div>
|
|
3128
|
+
{config.visualizationType === 'Deviation Bar' && (
|
|
3129
|
+
<>
|
|
3148
3130
|
<TextField
|
|
3149
|
-
|
|
3131
|
+
value={config.xAxis.targetLabel || 'Target'}
|
|
3132
|
+
section='xAxis'
|
|
3133
|
+
fieldName='targetLabel'
|
|
3134
|
+
type='text'
|
|
3135
|
+
label='Deviation point Label'
|
|
3136
|
+
updateField={updateFieldDeprecated}
|
|
3137
|
+
/>
|
|
3138
|
+
<CheckBox
|
|
3139
|
+
value={config.xAxis.showTargetLabel}
|
|
3140
|
+
section='xAxis'
|
|
3141
|
+
fieldName='showTargetLabel'
|
|
3142
|
+
label='Show Deviation point label'
|
|
3143
|
+
updateField={updateFieldDeprecated}
|
|
3144
|
+
/>
|
|
3145
|
+
</>
|
|
3146
|
+
)}
|
|
3147
|
+
</>
|
|
3148
|
+
) : (
|
|
3149
|
+
config.visualizationType !== 'Pie' &&
|
|
3150
|
+
config.visualizationType !== 'HeatMap' && (
|
|
3151
|
+
<>
|
|
3152
|
+
<CheckBox
|
|
3153
|
+
value={config.yAxis.hideAxis}
|
|
3154
|
+
section='yAxis'
|
|
3155
|
+
fieldName='hideAxis'
|
|
3156
|
+
label='Hide Axis'
|
|
3157
|
+
updateField={updateFieldDeprecated}
|
|
3158
|
+
/>
|
|
3159
|
+
<CheckBox
|
|
3160
|
+
display={!visHasCategoricalAxis()}
|
|
3161
|
+
value={config.yAxis.hideLabel}
|
|
3162
|
+
section='yAxis'
|
|
3163
|
+
fieldName='hideLabel'
|
|
3164
|
+
label='Hide Tick Labels'
|
|
3165
|
+
updateField={updateFieldDeprecated}
|
|
3166
|
+
/>
|
|
3167
|
+
<CheckBox
|
|
3168
|
+
display={!visHasCategoricalAxis()}
|
|
3169
|
+
value={config.yAxis.hideTicks}
|
|
3170
|
+
section='yAxis'
|
|
3171
|
+
fieldName='hideTicks'
|
|
3172
|
+
label='Hide Ticks'
|
|
3173
|
+
updateField={updateFieldDeprecated}
|
|
3174
|
+
/>
|
|
3175
|
+
|
|
3176
|
+
<div className='axis-domain-group'>
|
|
3177
|
+
<span className='axis-domain-group__title'>Value Axis Domain</span>
|
|
3178
|
+
<div className='axis-domain-group__row'>
|
|
3179
|
+
<div className='axis-domain-group__field'>
|
|
3180
|
+
<TextField
|
|
3181
|
+
value={config.yAxis.max}
|
|
3182
|
+
section='yAxis'
|
|
3183
|
+
fieldName='max'
|
|
3184
|
+
type='number'
|
|
3185
|
+
label='axis max value'
|
|
3186
|
+
placeholder='Auto'
|
|
3187
|
+
className='axis-domain-number'
|
|
3188
|
+
updateField={updateFieldDeprecated}
|
|
3189
|
+
/>
|
|
3190
|
+
<span className='axis-domain-warning'>{warningMsg.maxMsg}</span>
|
|
3191
|
+
</div>
|
|
3192
|
+
{config.visualizationType !== 'Area Chart' &&
|
|
3193
|
+
config.visualizationSubType !== 'stacked' && (
|
|
3194
|
+
<div className='axis-domain-group__field'>
|
|
3195
|
+
<TextField
|
|
3196
|
+
value={config.yAxis.min}
|
|
3197
|
+
section='yAxis'
|
|
3198
|
+
fieldName='min'
|
|
3199
|
+
type='number'
|
|
3200
|
+
label='axis min value'
|
|
3201
|
+
placeholder='Auto'
|
|
3202
|
+
className='axis-domain-number'
|
|
3203
|
+
updateField={updateFieldDeprecated}
|
|
3204
|
+
/>
|
|
3205
|
+
<span className='axis-domain-warning'>{warningMsg.minMsg}</span>
|
|
3206
|
+
</div>
|
|
3207
|
+
)}
|
|
3208
|
+
</div>
|
|
3209
|
+
<TextField
|
|
3210
|
+
value={config.yAxis.smallestLeftAxisMax}
|
|
3150
3211
|
section='yAxis'
|
|
3151
|
-
fieldName='
|
|
3152
|
-
|
|
3212
|
+
fieldName='smallestLeftAxisMax'
|
|
3213
|
+
type='number'
|
|
3214
|
+
label='Smallest axis maximum'
|
|
3215
|
+
placeholder='Auto'
|
|
3153
3216
|
className='axis-domain-number'
|
|
3217
|
+
tooltip={
|
|
3218
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
3219
|
+
<Tooltip.Target>
|
|
3220
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3221
|
+
</Tooltip.Target>
|
|
3222
|
+
<Tooltip.Content>
|
|
3223
|
+
<p>
|
|
3224
|
+
Example: If your data only goes up to 1, the axis might show 0, 0.2, 0.4, 0.6,
|
|
3225
|
+
0.8, 1. Setting this to 5 would make the axis show 0, 1, 2, 3, 4, 5 instead.
|
|
3226
|
+
</p>
|
|
3227
|
+
</Tooltip.Content>
|
|
3228
|
+
</Tooltip>
|
|
3229
|
+
}
|
|
3154
3230
|
updateField={updateFieldDeprecated}
|
|
3155
|
-
value={config.yAxis.scalePadding}
|
|
3156
3231
|
/>
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3232
|
+
{visSupportsAutoMaxStrategy() && (
|
|
3233
|
+
<Select
|
|
3234
|
+
value={config.yAxis.autoMaxStrategy || 'default'}
|
|
3235
|
+
section='yAxis'
|
|
3236
|
+
fieldName='autoMaxStrategy'
|
|
3237
|
+
label='Automatic max strategy'
|
|
3238
|
+
updateField={updateFieldDeprecated}
|
|
3239
|
+
options={[
|
|
3240
|
+
{ value: 'default', label: 'Default' },
|
|
3241
|
+
{ value: 'clean-top-tick', label: 'Clean top tick' }
|
|
3242
|
+
]}
|
|
3243
|
+
tooltip={
|
|
3244
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
3245
|
+
<Tooltip.Target>
|
|
3246
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3247
|
+
</Tooltip.Target>
|
|
3248
|
+
<Tooltip.Content>
|
|
3249
|
+
{config.visualizationType === 'Combo' ? (
|
|
3250
|
+
<p>
|
|
3251
|
+
Clean top tick rounds automatic left and right axis maximums up to cleaner
|
|
3252
|
+
tick steps before axis padding is applied.
|
|
3253
|
+
</p>
|
|
3254
|
+
) : (
|
|
3255
|
+
<p>
|
|
3256
|
+
Clean top tick rounds the automatic value axis maximum up to a cleaner
|
|
3257
|
+
tick step before axis padding is applied.
|
|
3258
|
+
</p>
|
|
3259
|
+
)}
|
|
3260
|
+
</Tooltip.Content>
|
|
3261
|
+
</Tooltip>
|
|
3262
|
+
}
|
|
3263
|
+
/>
|
|
3264
|
+
)}
|
|
3265
|
+
{visSupportsFilterDomainBehavior() && (
|
|
3266
|
+
<Select
|
|
3267
|
+
value={config.yAxis.filterDomainBehavior || 'dynamic'}
|
|
3268
|
+
section='yAxis'
|
|
3269
|
+
fieldName='filterDomainBehavior'
|
|
3270
|
+
label='Filter Domain Behavior'
|
|
3271
|
+
updateField={updateFieldDeprecated}
|
|
3272
|
+
options={[
|
|
3273
|
+
{ value: 'dynamic', label: 'Dynamic' },
|
|
3274
|
+
{ value: 'stable', label: 'Stable' }
|
|
3275
|
+
]}
|
|
3276
|
+
tooltip={
|
|
3277
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
3278
|
+
<Tooltip.Target>
|
|
3279
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3280
|
+
</Tooltip.Target>
|
|
3281
|
+
<Tooltip.Content>
|
|
3282
|
+
{config.visualizationType === 'Combo' ? (
|
|
3283
|
+
<p>
|
|
3284
|
+
Dynamic rescales the value axes to the currently filtered data. Stable
|
|
3285
|
+
keeps the left and right axes based on the full eligible dataset while
|
|
3286
|
+
still rendering filtered rows.
|
|
3287
|
+
</p>
|
|
3288
|
+
) : (
|
|
3289
|
+
<p>
|
|
3290
|
+
Dynamic rescales the value axis to the currently filtered data. Stable
|
|
3291
|
+
keeps the value axis based on the full eligible dataset while still
|
|
3292
|
+
rendering filtered rows.
|
|
3293
|
+
</p>
|
|
3294
|
+
)}
|
|
3295
|
+
</Tooltip.Content>
|
|
3296
|
+
</Tooltip>
|
|
3297
|
+
}
|
|
3298
|
+
/>
|
|
3299
|
+
)}
|
|
3300
|
+
{visSupportsYPadding() && (
|
|
3301
|
+
<CheckBox
|
|
3302
|
+
value={config.yAxis.enablePadding}
|
|
3303
|
+
section='yAxis'
|
|
3304
|
+
fieldName='enablePadding'
|
|
3305
|
+
label='Add Padding to Value Axis Scale'
|
|
3306
|
+
updateField={updateFieldDeprecated}
|
|
3307
|
+
/>
|
|
3308
|
+
)}
|
|
3309
|
+
{config.yAxis.enablePadding && visSupportsYPadding() && (
|
|
3310
|
+
<TextField
|
|
3311
|
+
type='number'
|
|
3312
|
+
section='yAxis'
|
|
3313
|
+
fieldName='scalePadding'
|
|
3314
|
+
label='Padding Percentage'
|
|
3315
|
+
className='axis-domain-number'
|
|
3316
|
+
updateField={updateFieldDeprecated}
|
|
3317
|
+
value={config.yAxis.scalePadding}
|
|
3318
|
+
/>
|
|
3319
|
+
)}
|
|
3320
|
+
</div>
|
|
3321
|
+
</>
|
|
3322
|
+
)
|
|
3323
|
+
))}
|
|
3162
3324
|
{/* start: anchors */}
|
|
3163
3325
|
{visHasAnchors() && config.orientation !== 'horizontal' && (
|
|
3164
3326
|
<AxisAnchorEditor
|
|
@@ -3193,18 +3355,29 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3193
3355
|
fieldName='rightLabel'
|
|
3194
3356
|
label='Label'
|
|
3195
3357
|
updateField={updateFieldDeprecated}
|
|
3196
|
-
maxLength={35}
|
|
3358
|
+
maxLength={config.yAxis.rightTitlePlacement === 'side' ? 35 : undefined}
|
|
3197
3359
|
tooltip={
|
|
3198
3360
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
3199
3361
|
<Tooltip.Target>
|
|
3200
3362
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3201
3363
|
</Tooltip.Target>
|
|
3202
3364
|
<Tooltip.Content>
|
|
3203
|
-
<p>35 character limit</p>
|
|
3365
|
+
<p>35 character limit when Label Placement is Side</p>
|
|
3204
3366
|
</Tooltip.Content>
|
|
3205
3367
|
</Tooltip>
|
|
3206
3368
|
}
|
|
3207
3369
|
/>
|
|
3370
|
+
<Select
|
|
3371
|
+
value={config.yAxis.rightTitlePlacement || 'top'}
|
|
3372
|
+
section='yAxis'
|
|
3373
|
+
fieldName='rightTitlePlacement'
|
|
3374
|
+
label='Label Placement'
|
|
3375
|
+
updateField={updateField}
|
|
3376
|
+
options={[
|
|
3377
|
+
{ value: 'side', label: 'Side' },
|
|
3378
|
+
{ value: 'top', label: 'Top' }
|
|
3379
|
+
]}
|
|
3380
|
+
/>
|
|
3208
3381
|
<TextField
|
|
3209
3382
|
value={config.yAxis.rightNumTicks}
|
|
3210
3383
|
placeholder='Auto'
|
|
@@ -3215,24 +3388,6 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3215
3388
|
className='number-narrow'
|
|
3216
3389
|
updateField={updateFieldDeprecated}
|
|
3217
3390
|
/>
|
|
3218
|
-
<TextField
|
|
3219
|
-
value={config.yAxis.rightAxisSize}
|
|
3220
|
-
type='number'
|
|
3221
|
-
section='yAxis'
|
|
3222
|
-
fieldName='rightAxisSize'
|
|
3223
|
-
label='Size (Width)'
|
|
3224
|
-
className='number-narrow'
|
|
3225
|
-
updateField={updateFieldDeprecated}
|
|
3226
|
-
/>
|
|
3227
|
-
<TextField
|
|
3228
|
-
value={config.yAxis.rightLabelOffsetSize}
|
|
3229
|
-
type='number'
|
|
3230
|
-
section='yAxis'
|
|
3231
|
-
fieldName='rightLabelOffsetSize'
|
|
3232
|
-
label='Label Offset'
|
|
3233
|
-
className='number-narrow'
|
|
3234
|
-
updateField={updateFieldDeprecated}
|
|
3235
|
-
/>
|
|
3236
3391
|
|
|
3237
3392
|
<span className='divider-heading'>Number Formatting</span>
|
|
3238
3393
|
<CheckBox
|
|
@@ -3377,13 +3532,24 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3377
3532
|
updateField={updateFieldDeprecated}
|
|
3378
3533
|
/>
|
|
3379
3534
|
</div>
|
|
3535
|
+
<AxisAnchorEditor
|
|
3536
|
+
axisKey='yAxis'
|
|
3537
|
+
anchorField='rightAnchors'
|
|
3538
|
+
config={config}
|
|
3539
|
+
lineOptions={lineOptions}
|
|
3540
|
+
updateConfig={updateConfig}
|
|
3541
|
+
/>
|
|
3380
3542
|
</AccordionItemPanel>
|
|
3381
3543
|
</AccordionItem>
|
|
3382
3544
|
)}
|
|
3383
3545
|
{visSupportsDateCategoryAxis() && (
|
|
3384
3546
|
<AccordionItem>
|
|
3385
3547
|
<AccordionItemHeading>
|
|
3386
|
-
<AccordionItemButton
|
|
3548
|
+
<AccordionItemButton
|
|
3549
|
+
data-required-field-section={
|
|
3550
|
+
config.visualizationType === 'Pie' ? 'pie-segments' : 'date-category-axis'
|
|
3551
|
+
}
|
|
3552
|
+
>
|
|
3387
3553
|
{config.visualizationType === 'Pie' ? 'Segments' : 'Date/Category Axis'}
|
|
3388
3554
|
{!config.xAxis.dataKey && <WarningImage width='25' className='warning-icon' />}
|
|
3389
3555
|
</AccordionItemButton>
|
|
@@ -3394,6 +3560,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3394
3560
|
{config.visualizationType !== 'Forest Plot' && (
|
|
3395
3561
|
<>
|
|
3396
3562
|
<Select
|
|
3563
|
+
display={!isBarRace}
|
|
3397
3564
|
label='Data Scaling Type'
|
|
3398
3565
|
tooltip={
|
|
3399
3566
|
<Tooltip style={{ textTransform: 'none', display: 'inline-block' }}>
|
|
@@ -3442,13 +3609,15 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3442
3609
|
})
|
|
3443
3610
|
}}
|
|
3444
3611
|
/>
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3612
|
+
{config.visualizationType !== 'HeatMap' && !isBarRace && (
|
|
3613
|
+
<CheckBox
|
|
3614
|
+
value={config.xAxis.manual}
|
|
3615
|
+
section='xAxis'
|
|
3616
|
+
fieldName='manual'
|
|
3617
|
+
label='Manual Ticks'
|
|
3618
|
+
updateField={updateFieldDeprecated}
|
|
3619
|
+
/>
|
|
3620
|
+
)}
|
|
3452
3621
|
<CheckBox
|
|
3453
3622
|
display={config.xAxis.type !== 'categorical'}
|
|
3454
3623
|
value={config.xAxis.sortByRecentDate}
|
|
@@ -3490,6 +3659,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3490
3659
|
section='xAxis'
|
|
3491
3660
|
fieldName='dataKey'
|
|
3492
3661
|
label='Data Key'
|
|
3662
|
+
data-required-field-control='date-category-axis'
|
|
3493
3663
|
initial='Select'
|
|
3494
3664
|
required={true}
|
|
3495
3665
|
updateField={updateFieldDeprecated}
|
|
@@ -3516,6 +3686,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3516
3686
|
section='xAxis'
|
|
3517
3687
|
fieldName='dataKey'
|
|
3518
3688
|
label='Segment Labels'
|
|
3689
|
+
data-required-field-control='pie-segments'
|
|
3519
3690
|
initial='Select'
|
|
3520
3691
|
required={true}
|
|
3521
3692
|
updateField={updateFieldDeprecated}
|
|
@@ -3546,18 +3717,38 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3546
3717
|
fieldName='label'
|
|
3547
3718
|
label='Label'
|
|
3548
3719
|
updateField={updateFieldDeprecated}
|
|
3549
|
-
maxLength={
|
|
3720
|
+
maxLength={
|
|
3721
|
+
config.orientation === 'horizontal' && config.yAxis.titlePlacement === 'top'
|
|
3722
|
+
? undefined
|
|
3723
|
+
: 35
|
|
3724
|
+
}
|
|
3550
3725
|
tooltip={
|
|
3551
3726
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
3552
3727
|
<Tooltip.Target>
|
|
3553
3728
|
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
3554
3729
|
</Tooltip.Target>
|
|
3555
3730
|
<Tooltip.Content>
|
|
3556
|
-
<p>
|
|
3731
|
+
<p>
|
|
3732
|
+
{config.orientation === 'horizontal'
|
|
3733
|
+
? '35 character limit when Label Placement is Side'
|
|
3734
|
+
: '35 character limit'}
|
|
3735
|
+
</p>
|
|
3557
3736
|
</Tooltip.Content>
|
|
3558
3737
|
</Tooltip>
|
|
3559
3738
|
}
|
|
3560
3739
|
/>
|
|
3740
|
+
<Select
|
|
3741
|
+
display={config.orientation === 'horizontal' && !isBarRace}
|
|
3742
|
+
value={config.yAxis.titlePlacement}
|
|
3743
|
+
section='yAxis'
|
|
3744
|
+
fieldName='titlePlacement'
|
|
3745
|
+
label='Label Placement'
|
|
3746
|
+
updateField={updateField}
|
|
3747
|
+
options={[
|
|
3748
|
+
{ value: 'side', label: 'Side' },
|
|
3749
|
+
{ value: 'top', label: 'Top' }
|
|
3750
|
+
]}
|
|
3751
|
+
/>
|
|
3561
3752
|
{config.visualizationType === 'HeatMap' && (
|
|
3562
3753
|
<Select
|
|
3563
3754
|
value={config.heatmap?.xAxisPosition ?? HEATMAP_CONFIG_DEFAULTS.xAxisPosition}
|
|
@@ -3778,6 +3969,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3778
3969
|
updateField={updateFieldDeprecated}
|
|
3779
3970
|
/>
|
|
3780
3971
|
<CheckBox
|
|
3972
|
+
display={!isBarRace}
|
|
3781
3973
|
value={config.xAxis.showYearsOnce}
|
|
3782
3974
|
section='xAxis'
|
|
3783
3975
|
fieldName='showYearsOnce'
|
|
@@ -3800,7 +3992,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3800
3992
|
}
|
|
3801
3993
|
updateField={updateFieldDeprecated}
|
|
3802
3994
|
/>
|
|
3803
|
-
{visHasBrushChart() && (
|
|
3995
|
+
{visHasBrushChart() && config.visualizationSubType !== 'racing' && (
|
|
3804
3996
|
<>
|
|
3805
3997
|
<CheckBox
|
|
3806
3998
|
value={config.xAxis.brushActive}
|
|
@@ -3828,6 +4020,14 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3828
4020
|
/>
|
|
3829
4021
|
{config.xAxis.brushActive && (
|
|
3830
4022
|
<>
|
|
4023
|
+
<CheckBox
|
|
4024
|
+
value={config.xAxis.brushHideHatching === true}
|
|
4025
|
+
section='xAxis'
|
|
4026
|
+
fieldName='brushHideHatching'
|
|
4027
|
+
label='Hide diagonal hatching'
|
|
4028
|
+
className='ms-4'
|
|
4029
|
+
updateField={updateFieldDeprecated}
|
|
4030
|
+
/>
|
|
3831
4031
|
<CheckBox
|
|
3832
4032
|
value={!!config.xAxis.brushDynamicYAxis}
|
|
3833
4033
|
section='xAxis'
|
|
@@ -3900,7 +4100,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3900
4100
|
<>
|
|
3901
4101
|
{config.xAxis.type === 'categorical' && (
|
|
3902
4102
|
<>
|
|
3903
|
-
{config.exclusions
|
|
4103
|
+
{(config.exclusions?.keys?.length ?? 0) > 0 && (
|
|
3904
4104
|
<>
|
|
3905
4105
|
<fieldset>
|
|
3906
4106
|
<legend className='edit-label'>Excluded Keys</legend>
|
|
@@ -3948,6 +4148,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
3948
4148
|
)}
|
|
3949
4149
|
|
|
3950
4150
|
{visSupportsDateCategoryNumTicks() &&
|
|
4151
|
+
config.visualizationType !== 'HeatMap' &&
|
|
3951
4152
|
config.xAxis.type !== 'date-time' &&
|
|
3952
4153
|
config.xAxis.manual && (
|
|
3953
4154
|
<>
|
|
@@ -4022,7 +4223,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4022
4223
|
</>
|
|
4023
4224
|
)}
|
|
4024
4225
|
{visSupportsDateCategoryNumTicks() &&
|
|
4025
|
-
(config.
|
|
4226
|
+
(config.visualizationType === 'HeatMap' ||
|
|
4227
|
+
config.xAxis.type === 'date-time' ||
|
|
4228
|
+
!config.xAxis.manual) && (
|
|
4026
4229
|
<>
|
|
4027
4230
|
<TextField
|
|
4028
4231
|
value={config.xAxis.numTicks}
|
|
@@ -4048,9 +4251,10 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4048
4251
|
</Tooltip.Target>
|
|
4049
4252
|
<Tooltip.Content>
|
|
4050
4253
|
<p>
|
|
4051
|
-
|
|
4052
|
-
may change the exact number of ticks used.
|
|
4053
|
-
|
|
4254
|
+
Approximate number of ticks. Other factors such as space available and data
|
|
4255
|
+
may change the exact number of ticks used.
|
|
4256
|
+
{config.visualizationType !== 'HeatMap' &&
|
|
4257
|
+
' To enforce an exact number of ticks, check "Manual Ticks" above.'}
|
|
4054
4258
|
</p>
|
|
4055
4259
|
</Tooltip.Content>
|
|
4056
4260
|
</Tooltip>
|
|
@@ -4336,7 +4540,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4336
4540
|
/>
|
|
4337
4541
|
{config.exclusions.active && (
|
|
4338
4542
|
<>
|
|
4339
|
-
{config.exclusions
|
|
4543
|
+
{(config.exclusions?.keys?.length ?? 0) > 0 && (
|
|
4340
4544
|
<>
|
|
4341
4545
|
<fieldset>
|
|
4342
4546
|
<legend className='edit-label'>Excluded Keys</legend>
|
|
@@ -4411,7 +4615,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4411
4615
|
<Panels.Regions name='Regions' />
|
|
4412
4616
|
|
|
4413
4617
|
{/* Columns */}
|
|
4414
|
-
{
|
|
4618
|
+
{!['Box Plot', 'Sankey'].includes(config.visualizationType) && (
|
|
4415
4619
|
<AccordionItem>
|
|
4416
4620
|
<AccordionItemHeading>
|
|
4417
4621
|
<AccordionItemButton>Columns</AccordionItemButton>
|
|
@@ -4435,421 +4639,456 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4435
4639
|
<AccordionItemButton>Legend</AccordionItemButton>
|
|
4436
4640
|
</AccordionItemHeading>
|
|
4437
4641
|
<AccordionItemPanel>
|
|
4438
|
-
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
fieldName='position'
|
|
4442
|
-
label='Position'
|
|
4443
|
-
updateField={updateFieldDeprecated}
|
|
4444
|
-
options={
|
|
4445
|
-
config.visualizationType === 'HeatMap'
|
|
4446
|
-
? config.legend.style === 'gradient'
|
|
4447
|
-
? ['bottom', 'top']
|
|
4448
|
-
: ['right', 'left', 'bottom', 'top']
|
|
4449
|
-
: config.visualizationType === 'Warming Stripes'
|
|
4450
|
-
? ['bottom']
|
|
4451
|
-
: ['right', 'left', 'bottom', 'top']
|
|
4452
|
-
}
|
|
4453
|
-
/>
|
|
4454
|
-
{(config.legend.position === 'left' ||
|
|
4455
|
-
config.legend.position === 'right' ||
|
|
4456
|
-
!config.legend.position) &&
|
|
4457
|
-
config.legend.style === 'gradient' && (
|
|
4458
|
-
<span style={{ color: 'red', fontSize: '14px' }}>
|
|
4459
|
-
Position must be set to top or bottom to use gradient style.
|
|
4460
|
-
</span>
|
|
4461
|
-
)}
|
|
4462
|
-
|
|
4463
|
-
<Select
|
|
4464
|
-
tooltip={
|
|
4465
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
4466
|
-
<Tooltip.Target>
|
|
4467
|
-
<Icon
|
|
4468
|
-
display='question'
|
|
4469
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4470
|
-
/>
|
|
4471
|
-
</Tooltip.Target>
|
|
4472
|
-
<Tooltip.Content>
|
|
4473
|
-
<p>
|
|
4474
|
-
If using gradient style, limit the legend to five items for better mobile visibility,
|
|
4475
|
-
and position the legend at the top or bottom.
|
|
4476
|
-
</p>
|
|
4477
|
-
</Tooltip.Content>
|
|
4478
|
-
</Tooltip>
|
|
4479
|
-
}
|
|
4480
|
-
display={!config.legend.hide}
|
|
4481
|
-
value={config.legend.style}
|
|
4482
|
-
section='legend'
|
|
4483
|
-
fieldName='style'
|
|
4484
|
-
label='Legend Style'
|
|
4485
|
-
updateField={updateFieldDeprecated}
|
|
4486
|
-
options={getLegendStyleOptions('style')}
|
|
4487
|
-
/>
|
|
4488
|
-
|
|
4489
|
-
{config.visualizationType !== 'Warming Stripes' && config.visualizationType !== 'HeatMap' && (
|
|
4490
|
-
<Select
|
|
4491
|
-
value={config.legend.groupBy}
|
|
4642
|
+
{config.visualizationType === 'Network' ? (
|
|
4643
|
+
<CheckBox
|
|
4644
|
+
value={config.legend.hide ? true : false}
|
|
4492
4645
|
section='legend'
|
|
4493
|
-
fieldName='
|
|
4494
|
-
|
|
4495
|
-
label='Legend Group By:'
|
|
4646
|
+
fieldName='hide'
|
|
4647
|
+
label='Hide Legend'
|
|
4496
4648
|
updateField={updateFieldDeprecated}
|
|
4497
|
-
|
|
4649
|
+
tooltip={
|
|
4650
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4651
|
+
<Tooltip.Target>
|
|
4652
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
4653
|
+
</Tooltip.Target>
|
|
4654
|
+
<Tooltip.Content>
|
|
4655
|
+
<p>With a single-series chart, consider hiding the legend to reduce visual clutter.</p>
|
|
4656
|
+
</Tooltip.Content>
|
|
4657
|
+
</Tooltip>
|
|
4658
|
+
}
|
|
4498
4659
|
/>
|
|
4499
|
-
)
|
|
4660
|
+
) : (
|
|
4661
|
+
<>
|
|
4662
|
+
<Select
|
|
4663
|
+
value={config.legend?.position}
|
|
4664
|
+
section='legend'
|
|
4665
|
+
fieldName='position'
|
|
4666
|
+
label='Position'
|
|
4667
|
+
updateField={updateFieldDeprecated}
|
|
4668
|
+
options={
|
|
4669
|
+
config.visualizationType === 'HeatMap'
|
|
4670
|
+
? config.legend.style === 'gradient'
|
|
4671
|
+
? ['bottom', 'top']
|
|
4672
|
+
: ['right', 'left', 'bottom', 'top']
|
|
4673
|
+
: config.visualizationType === 'Warming Stripes'
|
|
4674
|
+
? ['bottom']
|
|
4675
|
+
: ['right', 'left', 'bottom', 'top']
|
|
4676
|
+
}
|
|
4677
|
+
/>
|
|
4678
|
+
{(config.legend.position === 'left' ||
|
|
4679
|
+
config.legend.position === 'right' ||
|
|
4680
|
+
!config.legend.position) &&
|
|
4681
|
+
config.legend.style === 'gradient' && (
|
|
4682
|
+
<span style={{ color: 'red', fontSize: '14px' }}>
|
|
4683
|
+
Position must be set to top or bottom to use gradient style.
|
|
4684
|
+
</span>
|
|
4685
|
+
)}
|
|
4500
4686
|
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4687
|
+
<Select
|
|
4688
|
+
tooltip={
|
|
4689
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4690
|
+
<Tooltip.Target>
|
|
4691
|
+
<Icon
|
|
4692
|
+
display='question'
|
|
4693
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4694
|
+
/>
|
|
4695
|
+
</Tooltip.Target>
|
|
4696
|
+
<Tooltip.Content>
|
|
4697
|
+
<p>
|
|
4698
|
+
If using gradient style, limit the legend to five items for better mobile
|
|
4699
|
+
visibility, and position the legend at the top or bottom.
|
|
4700
|
+
</p>
|
|
4701
|
+
</Tooltip.Content>
|
|
4702
|
+
</Tooltip>
|
|
4703
|
+
}
|
|
4704
|
+
display={!config.legend.hide}
|
|
4705
|
+
value={config.legend.style}
|
|
4706
|
+
section='legend'
|
|
4707
|
+
fieldName='style'
|
|
4708
|
+
label='Legend Style'
|
|
4709
|
+
updateField={updateFieldDeprecated}
|
|
4710
|
+
options={getLegendStyleOptions('style')}
|
|
4711
|
+
/>
|
|
4522
4712
|
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
config.visualizationType !== 'HeatMap' &&
|
|
4535
|
-
config.legend.style === 'gradient' &&
|
|
4536
|
-
!config.legend.hide
|
|
4537
|
-
}
|
|
4538
|
-
className='number-narrow'
|
|
4539
|
-
type='number'
|
|
4540
|
-
value={config.legend.tickRotation}
|
|
4541
|
-
section='legend'
|
|
4542
|
-
fieldName='tickRotation'
|
|
4543
|
-
label='Tick Rotation (Degrees)'
|
|
4544
|
-
updateField={updateFieldDeprecated}
|
|
4545
|
-
/>
|
|
4713
|
+
{config.visualizationType !== 'Warming Stripes' && config.visualizationType !== 'HeatMap' && (
|
|
4714
|
+
<Select
|
|
4715
|
+
value={config.legend.groupBy}
|
|
4716
|
+
section='legend'
|
|
4717
|
+
fieldName='groupBy'
|
|
4718
|
+
initial='Select'
|
|
4719
|
+
label='Legend Group By:'
|
|
4720
|
+
updateField={updateFieldDeprecated}
|
|
4721
|
+
options={getLegendStyleOptions('groupBy')}
|
|
4722
|
+
/>
|
|
4723
|
+
)}
|
|
4546
4724
|
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
indicating "suppressed" data in the Data Series Panel.
|
|
4569
|
-
</p>
|
|
4570
|
-
</Tooltip.Content>
|
|
4571
|
-
</Tooltip>
|
|
4572
|
-
}
|
|
4573
|
-
/>
|
|
4574
|
-
<CheckBox
|
|
4575
|
-
display={
|
|
4576
|
-
config.visualizationType !== 'Radar' &&
|
|
4577
|
-
config.preliminaryData?.some(pd => pd.label && pd.type === 'suppression' && pd.value)
|
|
4578
|
-
}
|
|
4579
|
-
value={config.legend.hideSuppressionLink}
|
|
4580
|
-
section='legend'
|
|
4581
|
-
fieldName='hideSuppressionLink'
|
|
4582
|
-
label='Hide Suppression Definition Link'
|
|
4583
|
-
updateField={updateFieldDeprecated}
|
|
4584
|
-
tooltip={
|
|
4585
|
-
<Tooltip style={{ textTransform: 'none' }}>
|
|
4586
|
-
<Tooltip.Target>
|
|
4587
|
-
<Icon
|
|
4588
|
-
display='question'
|
|
4589
|
-
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4590
|
-
/>
|
|
4591
|
-
</Tooltip.Target>
|
|
4592
|
-
<Tooltip.Content>
|
|
4593
|
-
<p>Selecting this option will hide the suppression definition link from display.</p>
|
|
4594
|
-
</Tooltip.Content>
|
|
4595
|
-
</Tooltip>
|
|
4596
|
-
}
|
|
4597
|
-
/>
|
|
4725
|
+
<CheckBox
|
|
4726
|
+
tooltip={
|
|
4727
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4728
|
+
<Tooltip.Target>
|
|
4729
|
+
<Icon
|
|
4730
|
+
display='question'
|
|
4731
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4732
|
+
/>
|
|
4733
|
+
</Tooltip.Target>
|
|
4734
|
+
<Tooltip.Content>
|
|
4735
|
+
<p>Choose option Shapes in Line Datapoint Symbols to display.</p>
|
|
4736
|
+
</Tooltip.Content>
|
|
4737
|
+
</Tooltip>
|
|
4738
|
+
}
|
|
4739
|
+
display={!config.legend.hide && config.legend.style === 'lines'}
|
|
4740
|
+
value={config.legend.hasShape}
|
|
4741
|
+
section='legend'
|
|
4742
|
+
fieldName='hasShape'
|
|
4743
|
+
label='Shapes'
|
|
4744
|
+
updateField={updateFieldDeprecated}
|
|
4745
|
+
/>
|
|
4598
4746
|
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4747
|
+
<Select
|
|
4748
|
+
display={!config.legend.hide && config.legend.style === 'gradient'}
|
|
4749
|
+
value={config.legend.subStyle}
|
|
4750
|
+
section='legend'
|
|
4751
|
+
fieldName='subStyle'
|
|
4752
|
+
label='Gradient Style'
|
|
4753
|
+
updateField={updateFieldDeprecated}
|
|
4754
|
+
options={getLegendStyleOptions('subStyle')}
|
|
4755
|
+
/>
|
|
4756
|
+
<TextField
|
|
4757
|
+
display={
|
|
4758
|
+
config.visualizationType !== 'HeatMap' &&
|
|
4759
|
+
config.legend.style === 'gradient' &&
|
|
4760
|
+
!config.legend.hide
|
|
4761
|
+
}
|
|
4762
|
+
className='number-narrow'
|
|
4763
|
+
type='number'
|
|
4764
|
+
value={config.legend.tickRotation}
|
|
4765
|
+
section='legend'
|
|
4766
|
+
fieldName='tickRotation'
|
|
4767
|
+
label='Tick Rotation (Degrees)'
|
|
4768
|
+
updateField={updateFieldDeprecated}
|
|
4769
|
+
/>
|
|
4608
4770
|
|
|
4609
|
-
|
|
4610
|
-
|
|
4611
|
-
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
|
|
4620
|
-
<CheckBox
|
|
4621
|
-
value={config.legend.axisAlign}
|
|
4622
|
-
fieldName='axisAlign'
|
|
4623
|
-
section='legend'
|
|
4624
|
-
label='Align to Axis on Isolate'
|
|
4625
|
-
updateField={updateFieldDeprecated}
|
|
4626
|
-
/>
|
|
4627
|
-
)}
|
|
4628
|
-
{config.legend.behavior === 'highlight' && config.tooltips.singleSeries && (
|
|
4629
|
-
<CheckBox
|
|
4630
|
-
value={config.legend.highlightOnHover}
|
|
4631
|
-
section='legend'
|
|
4632
|
-
fieldName='highlightOnHover'
|
|
4633
|
-
label='HIGHLIGHT DATA SERIES ON HOVER'
|
|
4634
|
-
updateField={updateFieldDeprecated}
|
|
4635
|
-
/>
|
|
4636
|
-
)}
|
|
4637
|
-
{/* start: isolated values */}
|
|
4638
|
-
{visHasSelectableLegendValues && config.legend.behavior === 'isolate' && !colorCodeByCategory && (
|
|
4639
|
-
<fieldset className='primary-fieldset edit-block' key={'additional-highlight-values'}>
|
|
4640
|
-
<label>
|
|
4641
|
-
<span className='edit-label'>
|
|
4642
|
-
Isolate Data Series
|
|
4771
|
+
<CheckBox
|
|
4772
|
+
display={
|
|
4773
|
+
config.visualizationType !== 'Radar' &&
|
|
4774
|
+
config.preliminaryData?.some(pd => pd.label && pd.type === 'suppression' && pd.value)
|
|
4775
|
+
}
|
|
4776
|
+
value={config.legend.hideSuppressedLabels}
|
|
4777
|
+
section='legend'
|
|
4778
|
+
fieldName='hideSuppressedLabels'
|
|
4779
|
+
label='Hide Suppressed Labels'
|
|
4780
|
+
updateField={updateFieldDeprecated}
|
|
4781
|
+
tooltip={
|
|
4643
4782
|
<Tooltip style={{ textTransform: 'none' }}>
|
|
4644
4783
|
<Tooltip.Target>
|
|
4645
|
-
<Icon
|
|
4784
|
+
<Icon
|
|
4785
|
+
display='question'
|
|
4786
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4787
|
+
/>
|
|
4646
4788
|
</Tooltip.Target>
|
|
4647
4789
|
<Tooltip.Content>
|
|
4648
4790
|
<p>
|
|
4649
|
-
|
|
4650
|
-
|
|
4791
|
+
Hiding suppressed labels will not override the 'Special Class' assigned to line
|
|
4792
|
+
chart indicating "suppressed" data in the Data Series Panel.
|
|
4651
4793
|
</p>
|
|
4652
4794
|
</Tooltip.Content>
|
|
4653
4795
|
</Tooltip>
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4796
|
+
}
|
|
4797
|
+
/>
|
|
4798
|
+
<CheckBox
|
|
4799
|
+
display={
|
|
4800
|
+
config.visualizationType !== 'Radar' &&
|
|
4801
|
+
config.preliminaryData?.some(pd => pd.label && pd.type === 'suppression' && pd.value)
|
|
4802
|
+
}
|
|
4803
|
+
value={config.legend.hideSuppressionLink}
|
|
4804
|
+
section='legend'
|
|
4805
|
+
fieldName='hideSuppressionLink'
|
|
4806
|
+
label='Hide Suppression Definition Link'
|
|
4807
|
+
updateField={updateFieldDeprecated}
|
|
4808
|
+
tooltip={
|
|
4809
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4810
|
+
<Tooltip.Target>
|
|
4811
|
+
<Icon
|
|
4812
|
+
display='question'
|
|
4813
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4814
|
+
/>
|
|
4815
|
+
</Tooltip.Target>
|
|
4816
|
+
<Tooltip.Content>
|
|
4817
|
+
<p>Selecting this option will hide the suppression definition link from display.</p>
|
|
4818
|
+
</Tooltip.Content>
|
|
4819
|
+
</Tooltip>
|
|
4820
|
+
}
|
|
4821
|
+
/>
|
|
4822
|
+
|
|
4823
|
+
<Select
|
|
4824
|
+
display={visSupportsClickingLegend() && (hasDynamicCategory || hasMultipleSeries)}
|
|
4825
|
+
value={config.legend.behavior}
|
|
4826
|
+
section='legend'
|
|
4827
|
+
fieldName='behavior'
|
|
4828
|
+
label='Legend Behavior (When clicked)'
|
|
4829
|
+
updateField={(...[section, , fieldName, value]) =>
|
|
4830
|
+
updateBehavior(section, fieldName, value)
|
|
4831
|
+
}
|
|
4832
|
+
options={['highlight', 'isolate']}
|
|
4833
|
+
/>
|
|
4834
|
+
|
|
4835
|
+
<Select
|
|
4836
|
+
display={visHasLegendColorCategory()}
|
|
4837
|
+
value={config.legend.colorCode}
|
|
4838
|
+
section='legend'
|
|
4839
|
+
fieldName='colorCode'
|
|
4840
|
+
label='Color code by category'
|
|
4841
|
+
initial='Select'
|
|
4842
|
+
updateField={updateFieldDeprecated}
|
|
4843
|
+
options={getDataValueOptions(data)}
|
|
4844
|
+
/>
|
|
4845
|
+
{visHasLegendAxisAlign() && (
|
|
4846
|
+
<CheckBox
|
|
4847
|
+
value={config.legend.axisAlign}
|
|
4848
|
+
fieldName='axisAlign'
|
|
4849
|
+
section='legend'
|
|
4850
|
+
label='Align to Axis on Isolate'
|
|
4851
|
+
updateField={updateFieldDeprecated}
|
|
4852
|
+
/>
|
|
4853
|
+
)}
|
|
4854
|
+
{config.legend.behavior === 'highlight' && config.tooltips.singleSeries && (
|
|
4855
|
+
<CheckBox
|
|
4856
|
+
value={config.legend.highlightOnHover}
|
|
4857
|
+
section='legend'
|
|
4858
|
+
fieldName='highlightOnHover'
|
|
4859
|
+
label='HIGHLIGHT DATA SERIES ON HOVER'
|
|
4860
|
+
updateField={updateFieldDeprecated}
|
|
4861
|
+
/>
|
|
4862
|
+
)}
|
|
4863
|
+
{/* start: isolated values */}
|
|
4864
|
+
{visHasSelectableLegendValues &&
|
|
4865
|
+
config.legend.behavior === 'isolate' &&
|
|
4866
|
+
!colorCodeByCategory && (
|
|
4867
|
+
<fieldset className='primary-fieldset edit-block' key={'additional-highlight-values'}>
|
|
4868
|
+
<label>
|
|
4869
|
+
<span className='edit-label'>
|
|
4870
|
+
Isolate Data Series
|
|
4871
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4872
|
+
<Tooltip.Target>
|
|
4873
|
+
<Icon display='question' style={{ marginLeft: '0.5rem' }} />
|
|
4874
|
+
</Tooltip.Target>
|
|
4875
|
+
<Tooltip.Content>
|
|
4876
|
+
<p>
|
|
4877
|
+
You can choose data series that are shown on load. Others will be added when
|
|
4878
|
+
the user clicks on them in the legend.
|
|
4879
|
+
</p>
|
|
4880
|
+
</Tooltip.Content>
|
|
4881
|
+
</Tooltip>
|
|
4882
|
+
</span>
|
|
4883
|
+
</label>
|
|
4884
|
+
{config.legend.seriesHighlight &&
|
|
4885
|
+
config.legend.seriesHighlight.map((val, i) => (
|
|
4886
|
+
<fieldset className='edit-block' key={`${val}-${i}`}>
|
|
4887
|
+
<Button
|
|
4888
|
+
className='btn btn-danger'
|
|
4889
|
+
onClick={event => {
|
|
4890
|
+
event.preventDefault()
|
|
4891
|
+
const updatedSeriesHighlight = [...config.legend.seriesHighlight]
|
|
4892
|
+
updatedSeriesHighlight.splice(i, 1)
|
|
4893
|
+
updateFieldDeprecated(
|
|
4894
|
+
'legend',
|
|
4895
|
+
null,
|
|
4896
|
+
'seriesHighlight',
|
|
4897
|
+
updatedSeriesHighlight
|
|
4898
|
+
)
|
|
4899
|
+
if (!updatedSeriesHighlight.length) {
|
|
4900
|
+
handleShowAll()
|
|
4901
|
+
}
|
|
4902
|
+
}}
|
|
4903
|
+
>
|
|
4904
|
+
Remove
|
|
4905
|
+
</Button>
|
|
4906
|
+
<Select
|
|
4907
|
+
value={config.legend.seriesHighlight[i]}
|
|
4908
|
+
fieldName='seriesHighlight'
|
|
4909
|
+
label='Isolate Value'
|
|
4910
|
+
onChange={e => {
|
|
4911
|
+
const updatedSeriesHighlight = [...config.legend.seriesHighlight]
|
|
4912
|
+
if (!updatedSeriesHighlight.includes(e.target.value)) {
|
|
4913
|
+
updatedSeriesHighlight[i] = e.target.value
|
|
4914
|
+
updateSeriesIsolateValues([...updatedSeriesHighlight])
|
|
4915
|
+
}
|
|
4916
|
+
}}
|
|
4917
|
+
options={getLegendColumns()}
|
|
4918
|
+
/>
|
|
4919
|
+
</fieldset>
|
|
4920
|
+
))}
|
|
4659
4921
|
<Button
|
|
4660
|
-
|
|
4922
|
+
variant='editor-primary'
|
|
4661
4923
|
onClick={event => {
|
|
4662
4924
|
event.preventDefault()
|
|
4925
|
+
const legendColumns = getLegendColumns()
|
|
4663
4926
|
const updatedSeriesHighlight = [...config.legend.seriesHighlight]
|
|
4664
|
-
updatedSeriesHighlight.
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4927
|
+
const seriesLength = updatedSeriesHighlight.length
|
|
4928
|
+
if (seriesLength < legendColumns.length) {
|
|
4929
|
+
const [newSeriesHighlight] = legendColumns.filter(
|
|
4930
|
+
d => !updatedSeriesHighlight.includes(d)
|
|
4931
|
+
)
|
|
4932
|
+
updatedSeriesHighlight.push(newSeriesHighlight)
|
|
4933
|
+
updateSeriesIsolateValues([...updatedSeriesHighlight])
|
|
4668
4934
|
}
|
|
4669
4935
|
}}
|
|
4670
4936
|
>
|
|
4671
|
-
|
|
4937
|
+
Add Isolate Value
|
|
4672
4938
|
</Button>
|
|
4673
|
-
<Select
|
|
4674
|
-
value={config.legend.seriesHighlight[i]}
|
|
4675
|
-
fieldName='seriesHighlight'
|
|
4676
|
-
label='Isolate Value'
|
|
4677
|
-
onChange={e => {
|
|
4678
|
-
const updatedSeriesHighlight = [...config.legend.seriesHighlight]
|
|
4679
|
-
if (!updatedSeriesHighlight.includes(e.target.value)) {
|
|
4680
|
-
updatedSeriesHighlight[i] = e.target.value
|
|
4681
|
-
updateSeriesIsolateValues([...updatedSeriesHighlight])
|
|
4682
|
-
}
|
|
4683
|
-
}}
|
|
4684
|
-
options={getLegendColumns()}
|
|
4685
|
-
/>
|
|
4686
4939
|
</fieldset>
|
|
4687
|
-
)
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4940
|
+
)}
|
|
4941
|
+
{/* end: isolated values */}
|
|
4942
|
+
<CheckBox
|
|
4943
|
+
display={!config.legend.hide && config.legend.style !== 'gradient'}
|
|
4944
|
+
value={config.legend.reverseLabelOrder}
|
|
4945
|
+
section='legend'
|
|
4946
|
+
fieldName='reverseLabelOrder'
|
|
4947
|
+
label='Reverse Labels'
|
|
4948
|
+
updateField={updateFieldDeprecated}
|
|
4949
|
+
/>
|
|
4950
|
+
{config.visualizationType !== 'Warming Stripes' && (
|
|
4951
|
+
<CheckBox
|
|
4952
|
+
display={!config.legend.hide}
|
|
4953
|
+
value={
|
|
4954
|
+
['left', 'right'].includes(config.legend.position)
|
|
4955
|
+
? config.legend.hideBorder.side
|
|
4956
|
+
: config.legend.hideBorder.topBottom
|
|
4701
4957
|
}
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
!['left', 'right'].includes(config.legend.position) &&
|
|
4749
|
-
config.legend.style !== 'gradient'
|
|
4750
|
-
}
|
|
4751
|
-
value={config.legend.singleRow}
|
|
4752
|
-
section='legend'
|
|
4753
|
-
fieldName='singleRow'
|
|
4754
|
-
label='Single Row Legend'
|
|
4755
|
-
updateField={updateFieldDeprecated}
|
|
4756
|
-
/>
|
|
4757
|
-
<CheckBox
|
|
4758
|
-
display={
|
|
4759
|
-
['bottom', 'top'].includes(config.legend.position) &&
|
|
4760
|
-
!config.legend.hide &&
|
|
4761
|
-
config.legend.style !== 'gradient' &&
|
|
4762
|
-
!config.legend.singleRow &&
|
|
4763
|
-
!config.legend.singleRow
|
|
4764
|
-
}
|
|
4765
|
-
value={config.legend.verticalSorted}
|
|
4766
|
-
section='legend'
|
|
4767
|
-
fieldName='verticalSorted'
|
|
4768
|
-
label='Vertical sorted Legend'
|
|
4769
|
-
updateField={updateFieldDeprecated}
|
|
4770
|
-
/>
|
|
4958
|
+
section='legend'
|
|
4959
|
+
subsection='hideBorder'
|
|
4960
|
+
fieldName={['left', 'right'].includes(config.legend.position) ? 'side' : 'topBottom'}
|
|
4961
|
+
label='Hide Legend Box'
|
|
4962
|
+
updateField={updateFieldDeprecated}
|
|
4963
|
+
tooltip={
|
|
4964
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
4965
|
+
<Tooltip.Target>
|
|
4966
|
+
<Icon
|
|
4967
|
+
display='question'
|
|
4968
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
4969
|
+
/>
|
|
4970
|
+
</Tooltip.Target>
|
|
4971
|
+
<Tooltip.Content>
|
|
4972
|
+
<p>Default option for top and bottom legends is ‘No Box.’.</p>
|
|
4973
|
+
</Tooltip.Content>
|
|
4974
|
+
</Tooltip>
|
|
4975
|
+
}
|
|
4976
|
+
/>
|
|
4977
|
+
)}
|
|
4978
|
+
<CheckBox
|
|
4979
|
+
display={
|
|
4980
|
+
!config.legend.hide &&
|
|
4981
|
+
!['left', 'right'].includes(config.legend.position) &&
|
|
4982
|
+
config.legend.style !== 'gradient'
|
|
4983
|
+
}
|
|
4984
|
+
value={config.legend.singleRow}
|
|
4985
|
+
section='legend'
|
|
4986
|
+
fieldName='singleRow'
|
|
4987
|
+
label='Single Row Legend'
|
|
4988
|
+
updateField={updateFieldDeprecated}
|
|
4989
|
+
/>
|
|
4990
|
+
<CheckBox
|
|
4991
|
+
display={
|
|
4992
|
+
['bottom', 'top'].includes(config.legend.position) &&
|
|
4993
|
+
!config.legend.hide &&
|
|
4994
|
+
config.legend.style !== 'gradient' &&
|
|
4995
|
+
!config.legend.singleRow &&
|
|
4996
|
+
!config.legend.singleRow
|
|
4997
|
+
}
|
|
4998
|
+
value={config.legend.verticalSorted}
|
|
4999
|
+
section='legend'
|
|
5000
|
+
fieldName='verticalSorted'
|
|
5001
|
+
label='Vertical sorted Legend'
|
|
5002
|
+
updateField={updateFieldDeprecated}
|
|
5003
|
+
/>
|
|
4771
5004
|
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
5005
|
+
{config.visualizationType !== 'Warming Stripes' && (
|
|
5006
|
+
<CheckBox
|
|
5007
|
+
value={config.legend.hide ? true : false}
|
|
5008
|
+
section='legend'
|
|
5009
|
+
fieldName='hide'
|
|
5010
|
+
label='Hide Legend'
|
|
5011
|
+
updateField={updateFieldDeprecated}
|
|
5012
|
+
tooltip={
|
|
5013
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
5014
|
+
<Tooltip.Target>
|
|
5015
|
+
<Icon
|
|
5016
|
+
display='question'
|
|
5017
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
5018
|
+
/>
|
|
5019
|
+
</Tooltip.Target>
|
|
5020
|
+
<Tooltip.Content>
|
|
5021
|
+
<p>
|
|
5022
|
+
With a single-series chart, consider hiding the legend to reduce visual clutter.
|
|
5023
|
+
</p>
|
|
5024
|
+
</Tooltip.Content>
|
|
5025
|
+
</Tooltip>
|
|
5026
|
+
}
|
|
5027
|
+
/>
|
|
5028
|
+
)}
|
|
5029
|
+
<TextField
|
|
5030
|
+
value={config.legend.label}
|
|
5031
|
+
section='legend'
|
|
5032
|
+
fieldName='label'
|
|
5033
|
+
label='Title'
|
|
5034
|
+
updateField={updateFieldDeprecated}
|
|
5035
|
+
/>
|
|
5036
|
+
<TextField
|
|
5037
|
+
type='textarea'
|
|
5038
|
+
value={config.legend.description}
|
|
5039
|
+
updateField={updateFieldDeprecated}
|
|
5040
|
+
section='legend'
|
|
5041
|
+
fieldName='description'
|
|
5042
|
+
label='Legend Description'
|
|
5043
|
+
/>
|
|
4809
5044
|
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
5045
|
+
{config.visualizationType !== 'Warming Stripes' && (
|
|
5046
|
+
<CheckBox
|
|
5047
|
+
value={config.legend.unified}
|
|
5048
|
+
section='legend'
|
|
5049
|
+
fieldName='unified'
|
|
5050
|
+
label='Unified Legend'
|
|
5051
|
+
updateField={updateFieldDeprecated}
|
|
5052
|
+
tooltip={
|
|
5053
|
+
<Tooltip style={{ textTransform: 'none' }}>
|
|
5054
|
+
<Tooltip.Target>
|
|
5055
|
+
<Icon
|
|
5056
|
+
display='question'
|
|
5057
|
+
style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }}
|
|
5058
|
+
/>
|
|
5059
|
+
</Tooltip.Target>
|
|
5060
|
+
<Tooltip.Content>
|
|
5061
|
+
<p>
|
|
5062
|
+
For a chart with filters, check this option if you want the legend to contain an
|
|
5063
|
+
item for every series in the data set, including those that are filtered.
|
|
5064
|
+
</p>
|
|
5065
|
+
</Tooltip.Content>
|
|
5066
|
+
</Tooltip>
|
|
5067
|
+
}
|
|
5068
|
+
/>
|
|
5069
|
+
)}
|
|
5070
|
+
</>
|
|
4834
5071
|
)}
|
|
4835
5072
|
</AccordionItemPanel>
|
|
4836
5073
|
</AccordionItem>
|
|
4837
5074
|
)}
|
|
4838
5075
|
{visSupportsFilters() && (
|
|
4839
5076
|
<>
|
|
4840
|
-
|
|
4841
|
-
<
|
|
4842
|
-
<
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
<
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
5077
|
+
{!isBarRace && (
|
|
5078
|
+
<AccordionItem>
|
|
5079
|
+
<AccordionItemHeading>
|
|
5080
|
+
<AccordionItemButton>Filters</AccordionItemButton>
|
|
5081
|
+
</AccordionItemHeading>
|
|
5082
|
+
<AccordionItemPanel>
|
|
5083
|
+
<VizFilterEditor
|
|
5084
|
+
config={config}
|
|
5085
|
+
updateField={updateField}
|
|
5086
|
+
rawData={rawData}
|
|
5087
|
+
hasFootnotes={isDashboard}
|
|
5088
|
+
/>
|
|
5089
|
+
</AccordionItemPanel>
|
|
5090
|
+
</AccordionItem>
|
|
5091
|
+
)}
|
|
4853
5092
|
<AccordionItem>
|
|
4854
5093
|
<AccordionItemHeading>
|
|
4855
5094
|
<AccordionItemButton>Footnotes</AccordionItemButton>
|
|
@@ -4861,7 +5100,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4861
5100
|
</>
|
|
4862
5101
|
)}
|
|
4863
5102
|
<Panels.Visual name='Visual' />
|
|
4864
|
-
|
|
5103
|
+
{!isBarRace && !['Network', 'Dendrogram'].includes(config.visualizationType) && (
|
|
5104
|
+
<Panels.PatternSettings name='PatternSettings' />
|
|
5105
|
+
)}
|
|
4865
5106
|
{/* Spark Line has no data table */}
|
|
4866
5107
|
{config.visualizationType !== 'Spark Line' && (
|
|
4867
5108
|
<AccordionItem>
|
|
@@ -4879,7 +5120,9 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4879
5120
|
</AccordionItemPanel>
|
|
4880
5121
|
</AccordionItem>
|
|
4881
5122
|
)}
|
|
4882
|
-
|
|
5123
|
+
{!isBarRace && !['Network', 'Dendrogram'].includes(config.visualizationType) && (
|
|
5124
|
+
<Panels.Annotate name='Text Annotations' />
|
|
5125
|
+
)}
|
|
4883
5126
|
{/* {(config.visualizationType === 'Bar' || config.visualizationType === 'Line') && <Panels.DateHighlighting name='Date Highlighting' />} */}
|
|
4884
5127
|
{config.visualizationType !== 'Radar' && (
|
|
4885
5128
|
<PanelMarkup
|
|
@@ -4894,6 +5137,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4894
5137
|
)}
|
|
4895
5138
|
<Panels.SmallMultiples name='Small Multiples' />
|
|
4896
5139
|
</Accordion>
|
|
5140
|
+
{!isDashboard && <ModernStylesAction />}
|
|
4897
5141
|
{config.type !== 'Spark Line' && (
|
|
4898
5142
|
<AdvancedEditor
|
|
4899
5143
|
loadConfig={updateConfig}
|
|
@@ -4913,6 +5157,7 @@ const EditorPanel: React.FC<ChartEditorPanelProps> = ({ datasets }) => {
|
|
|
4913
5157
|
onCancel={handleConversionCancel}
|
|
4914
5158
|
onReturnToV1={handleReturnToV1}
|
|
4915
5159
|
paletteName={pendingPaletteSelection?.palette}
|
|
5160
|
+
message={config.general?.palette?.version === '2.0' ? V21_PALETTE_CONVERSION_MESSAGE : undefined}
|
|
4916
5161
|
/>
|
|
4917
5162
|
)}
|
|
4918
5163
|
</EditorPanelContext.Provider>
|