@cdc/chart 4.24.7 → 4.24.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cdcchart.js +40313 -37543
- package/examples/cases-year.json +13379 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +76 -15
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +5 -5
- package/index.html +17 -8
- package/package.json +2 -2
- package/src/CdcChart.tsx +383 -133
- package/src/_stories/Chart.Legend.Gradient.tsx +19 -0
- package/src/_stories/_mock/legend.gradient_mock.json +236 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +64 -11
- package/src/components/Axis/Categorical.Axis.tsx +145 -0
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +4 -3
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +1 -1
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +2 -5
- package/src/components/BarChart/components/BarChart.Vertical.tsx +17 -8
- package/src/components/BarChart/helpers/index.ts +5 -16
- package/src/components/BrushChart.tsx +205 -0
- package/src/components/EditorPanel/EditorPanel.tsx +1766 -509
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +19 -5
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +190 -37
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +43 -7
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +4 -4
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +1 -11
- package/src/components/EditorPanel/editor-panel.scss +16 -3
- package/src/components/EditorPanel/{useEditorPermissions.js → useEditorPermissions.ts} +90 -19
- package/src/components/Legend/Legend.Component.tsx +185 -193
- package/src/components/Legend/Legend.Suppression.tsx +146 -0
- package/src/components/Legend/Legend.tsx +21 -5
- package/src/components/Legend/helpers/index.ts +33 -3
- package/src/components/LegendWrapper.tsx +26 -0
- package/src/components/LineChart/LineChartProps.ts +1 -18
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +103 -0
- package/src/components/LineChart/components/LineChart.Circle.tsx +47 -8
- package/src/components/LineChart/helpers.ts +55 -11
- package/src/components/LineChart/index.tsx +113 -38
- package/src/components/LinearChart.tsx +1366 -0
- package/src/components/PieChart/PieChart.tsx +74 -17
- package/src/components/Sankey/index.tsx +22 -16
- package/src/components/Sparkline/components/SparkLine.tsx +2 -2
- package/src/data/initial-state.js +13 -3
- package/src/hooks/useLegendClasses.ts +52 -15
- package/src/hooks/useMinMax.ts +4 -4
- package/src/hooks/useScales.ts +34 -24
- package/src/hooks/useTooltip.tsx +85 -22
- package/src/scss/DataTable.scss +2 -1
- package/src/scss/main.scss +107 -14
- package/src/types/ChartConfig.ts +34 -8
- package/src/types/ChartContext.ts +5 -4
- package/examples/feature/line/line-chart.json +0 -449
- package/src/components/BrushHandle.jsx +0 -17
- package/src/components/LineChart/index.scss +0 -1
|
@@ -11,6 +11,7 @@ export const useEditorPermissions = () => {
|
|
|
11
11
|
'Area Chart',
|
|
12
12
|
'Bar',
|
|
13
13
|
'Box Plot',
|
|
14
|
+
'Bump Chart',
|
|
14
15
|
'Combo',
|
|
15
16
|
'Deviation Bar',
|
|
16
17
|
'Forecasting',
|
|
@@ -23,7 +24,19 @@ export const useEditorPermissions = () => {
|
|
|
23
24
|
'Sankey'
|
|
24
25
|
]
|
|
25
26
|
|
|
26
|
-
const headerColors = [
|
|
27
|
+
const headerColors = [
|
|
28
|
+
'theme-blue',
|
|
29
|
+
'theme-purple',
|
|
30
|
+
'theme-brown',
|
|
31
|
+
'theme-teal',
|
|
32
|
+
'theme-pink',
|
|
33
|
+
'theme-orange',
|
|
34
|
+
'theme-slate',
|
|
35
|
+
'theme-indigo',
|
|
36
|
+
'theme-cyan',
|
|
37
|
+
'theme-green',
|
|
38
|
+
'theme-amber'
|
|
39
|
+
]
|
|
27
40
|
|
|
28
41
|
const visSupportsDateCategoryAxis = () => {
|
|
29
42
|
const disabledCharts = ['Forest Plot', 'Sankey']
|
|
@@ -44,13 +57,30 @@ export const useEditorPermissions = () => {
|
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
const visHasLabelOnData = () => {
|
|
47
|
-
const disabledCharts = [
|
|
60
|
+
const disabledCharts = [
|
|
61
|
+
'Area Chart',
|
|
62
|
+
'Box Plot',
|
|
63
|
+
'Pie',
|
|
64
|
+
'Scatter Plot',
|
|
65
|
+
'Forest Plot',
|
|
66
|
+
'Spark Line',
|
|
67
|
+
'Sankey',
|
|
68
|
+
'Bump Chart'
|
|
69
|
+
]
|
|
48
70
|
if (disabledCharts.includes(visualizationType)) return false
|
|
49
71
|
return true
|
|
50
72
|
}
|
|
51
73
|
|
|
52
74
|
const visCanAnimate = () => {
|
|
53
|
-
const disabledCharts = [
|
|
75
|
+
const disabledCharts = [
|
|
76
|
+
'Area Chart',
|
|
77
|
+
'Scatter Plot',
|
|
78
|
+
'Box Plot',
|
|
79
|
+
'Forest Plot',
|
|
80
|
+
'Spark Line',
|
|
81
|
+
'Sankey',
|
|
82
|
+
'Bump Chart'
|
|
83
|
+
]
|
|
54
84
|
if (disabledCharts.includes(visualizationType)) return false
|
|
55
85
|
return true
|
|
56
86
|
}
|
|
@@ -72,7 +102,14 @@ export const useEditorPermissions = () => {
|
|
|
72
102
|
|
|
73
103
|
const visHasNumbersOnBars = () => {
|
|
74
104
|
if (visualizationType === 'Forest Plot') return false
|
|
75
|
-
if (
|
|
105
|
+
if (
|
|
106
|
+
config.orientation === 'horizontal' &&
|
|
107
|
+
(config.yAxis.labelPlacement === 'Below Bar' ||
|
|
108
|
+
config.yAxis.labelPlacement === 'On Date/Category Axis' ||
|
|
109
|
+
config.visualizationType === 'Paired Bar' ||
|
|
110
|
+
config.visualizationType === 'Deviation Bar')
|
|
111
|
+
)
|
|
112
|
+
return true
|
|
76
113
|
return false
|
|
77
114
|
}
|
|
78
115
|
|
|
@@ -104,13 +141,17 @@ export const useEditorPermissions = () => {
|
|
|
104
141
|
}
|
|
105
142
|
}
|
|
106
143
|
const visHasBrushChart = () => {
|
|
144
|
+
return false
|
|
145
|
+
if (config.xAxis.type === 'categorical') return false
|
|
107
146
|
return ['Line', 'Bar', 'Area Chart', 'Combo'].includes(visualizationType) && orientation === 'vertical'
|
|
108
147
|
}
|
|
109
148
|
|
|
110
149
|
const visHasBarBorders = () => {
|
|
111
150
|
const disabledCharts = ['Box Plot', 'Scatter Plot', 'Pie', 'Line']
|
|
112
151
|
if (disabledCharts.includes(visualizationType)) return false
|
|
113
|
-
return series?.some(
|
|
152
|
+
return series?.some(
|
|
153
|
+
series => series.type === 'Bar' || series.type === 'Paired Bar' || series.type === 'Deviation Bar'
|
|
154
|
+
)
|
|
114
155
|
}
|
|
115
156
|
|
|
116
157
|
const visHasDataCutoff = () => {
|
|
@@ -134,6 +175,9 @@ export const useEditorPermissions = () => {
|
|
|
134
175
|
const visHasLegendAxisAlign = () => {
|
|
135
176
|
return visualizationType === 'Bar' && visualizationSubType === 'stacked' && config.legend.behavior === 'isolate'
|
|
136
177
|
}
|
|
178
|
+
const visHasLegendColorCategory = () => {
|
|
179
|
+
return visualizationType === 'Bar' && visualizationSubType === 'regular' && config.series?.length === 1
|
|
180
|
+
}
|
|
137
181
|
|
|
138
182
|
const visSupportsTooltipOpacity = () => {
|
|
139
183
|
const disabledCharts = ['Spark Line', 'Sankey']
|
|
@@ -166,7 +210,7 @@ export const useEditorPermissions = () => {
|
|
|
166
210
|
}
|
|
167
211
|
|
|
168
212
|
const visSupportsDateCategoryAxisLabel = () => {
|
|
169
|
-
const disabledCharts = ['Forest Plot', 'Spark Line']
|
|
213
|
+
const disabledCharts = ['Forest Plot', 'Spark Line', 'Bump Chart']
|
|
170
214
|
if (disabledCharts.includes(visualizationType)) return false
|
|
171
215
|
return true
|
|
172
216
|
}
|
|
@@ -248,7 +292,7 @@ export const useEditorPermissions = () => {
|
|
|
248
292
|
|
|
249
293
|
// implement later
|
|
250
294
|
const visSupportsValueAxisLabels = () => {
|
|
251
|
-
const disabledCharts = ['Forest Plot']
|
|
295
|
+
const disabledCharts = ['Forest Plot', 'Bump Chart']
|
|
252
296
|
if (disabledCharts.includes(visualizationType)) return false
|
|
253
297
|
return true
|
|
254
298
|
}
|
|
@@ -271,6 +315,12 @@ export const useEditorPermissions = () => {
|
|
|
271
315
|
if (disabledCharts.includes(visualizationType)) return false
|
|
272
316
|
return true
|
|
273
317
|
}
|
|
318
|
+
const visSupportsMobileChartHeight = () => {
|
|
319
|
+
// TODO: this is a soft release. Support should eventually match visSupportsChartHeight
|
|
320
|
+
const enabledCharts = ['Bar', 'Line', 'Combo', 'Area Chart']
|
|
321
|
+
if (enabledCharts.includes(visualizationType)) return true
|
|
322
|
+
return false
|
|
323
|
+
}
|
|
274
324
|
|
|
275
325
|
const visSupportsLeftValueAxis = () => {
|
|
276
326
|
const disabledCharts = ['Spark Line', 'Sankey']
|
|
@@ -285,7 +335,7 @@ export const useEditorPermissions = () => {
|
|
|
285
335
|
}
|
|
286
336
|
|
|
287
337
|
const visSupportsDateCategoryHeight = () => {
|
|
288
|
-
const disabledCharts = ['Spark Line', 'Sankey']
|
|
338
|
+
const disabledCharts = ['Spark Line', 'Sankey', 'Bump Chart']
|
|
289
339
|
if (disabledCharts.includes(visualizationType)) return false
|
|
290
340
|
return true
|
|
291
341
|
}
|
|
@@ -295,27 +345,32 @@ export const useEditorPermissions = () => {
|
|
|
295
345
|
}
|
|
296
346
|
|
|
297
347
|
const visSupportsReactTooltip = () => {
|
|
298
|
-
if (
|
|
348
|
+
if (config.yAxis.type === 'categorical') return true
|
|
349
|
+
if (
|
|
350
|
+
['Deviation Bar', 'Box Plot', 'Scatter Plot', 'Paired Bar'].includes(visualizationType) ||
|
|
351
|
+
(visualizationType === 'Bar' && config.tooltips.singleSeries)
|
|
352
|
+
) {
|
|
299
353
|
return true
|
|
300
354
|
}
|
|
301
355
|
}
|
|
302
356
|
|
|
303
357
|
const visSupportsPreliminaryData = () => {
|
|
304
|
-
|
|
305
|
-
const lineExist = config?.series.some(item => ['Line', 'dashed-sm', 'dashed-md', 'dashed-lg'].includes(item?.type))
|
|
306
|
-
if (visualizationType === 'Line') {
|
|
307
|
-
return true
|
|
308
|
-
}
|
|
309
|
-
if (visualizationType === 'Bar' && visualizationSubType === 'regular') {
|
|
358
|
+
if (['Line', 'Bar', 'Combo'].includes(visualizationType)) {
|
|
310
359
|
return true
|
|
311
360
|
}
|
|
312
361
|
|
|
313
|
-
if (visualizationType === 'Combo') {
|
|
314
|
-
return true
|
|
315
|
-
}
|
|
316
362
|
return false
|
|
317
363
|
}
|
|
318
364
|
|
|
365
|
+
const visSupportsDynamicSeries = () => {
|
|
366
|
+
return (
|
|
367
|
+
visualizationType === 'Line' ||
|
|
368
|
+
visualizationType === 'Bar' ||
|
|
369
|
+
visualizationType === 'Scatter Plot' ||
|
|
370
|
+
visualizationType === 'Area Chart'
|
|
371
|
+
)
|
|
372
|
+
}
|
|
373
|
+
|
|
319
374
|
const visHasSingleSeriesTooltip = () => {
|
|
320
375
|
if (visualizationType === 'Bar' || visualizationType === 'Line') {
|
|
321
376
|
return true
|
|
@@ -326,6 +381,18 @@ export const useEditorPermissions = () => {
|
|
|
326
381
|
return false
|
|
327
382
|
}
|
|
328
383
|
|
|
384
|
+
const visHasCategoricalAxis = () => {
|
|
385
|
+
if (
|
|
386
|
+
(visualizationType === 'Line' ||
|
|
387
|
+
visualizationType === 'Bar' ||
|
|
388
|
+
visualizationType === 'Combo' ||
|
|
389
|
+
visualizationType === 'Area Chart') &&
|
|
390
|
+
config.yAxis.type === 'categorical' &&
|
|
391
|
+
orientation === 'vertical'
|
|
392
|
+
)
|
|
393
|
+
return true
|
|
394
|
+
}
|
|
395
|
+
|
|
329
396
|
return {
|
|
330
397
|
enabledChartTypes,
|
|
331
398
|
headerColors,
|
|
@@ -337,12 +404,14 @@ export const useEditorPermissions = () => {
|
|
|
337
404
|
visHasDataSuppression,
|
|
338
405
|
visHasLegend,
|
|
339
406
|
visHasLegendAxisAlign,
|
|
407
|
+
visHasLegendColorCategory,
|
|
340
408
|
visHasBrushChart,
|
|
341
409
|
visHasNumbersOnBars,
|
|
342
410
|
visHasaAdditionalLabelsOnBars,
|
|
343
411
|
visSupportsBarSpace,
|
|
344
412
|
visSupportsBarThickness,
|
|
345
413
|
visSupportsChartHeight,
|
|
414
|
+
visSupportsMobileChartHeight,
|
|
346
415
|
visSupportsDateCategoryAxis,
|
|
347
416
|
visSupportsDateCategoryAxisLabel,
|
|
348
417
|
visSupportsDateCategoryAxisLine,
|
|
@@ -372,6 +441,8 @@ export const useEditorPermissions = () => {
|
|
|
372
441
|
visSupportsReactTooltip,
|
|
373
442
|
visSupportsValueAxisMax,
|
|
374
443
|
visSupportsValueAxisMin,
|
|
375
|
-
|
|
444
|
+
visSupportsDynamicSeries,
|
|
445
|
+
visHasSingleSeriesTooltip,
|
|
446
|
+
visHasCategoricalAxis
|
|
376
447
|
}
|
|
377
448
|
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import parse from 'html-react-parser'
|
|
2
2
|
import { LegendOrdinal, LegendItem, LegendLabel } from '@visx/legend'
|
|
3
|
-
import
|
|
3
|
+
import LegendShape from '@cdc/core/components/LegendShape'
|
|
4
4
|
import Button from '@cdc/core/components/elements/Button'
|
|
5
5
|
import useLegendClasses from '../../hooks/useLegendClasses'
|
|
6
6
|
import { useHighlightedBars } from '../../hooks/useHighlightedBars'
|
|
7
7
|
import { handleLineType } from '../../helpers/handleLineType'
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
import { getMarginTop, getGradientConfig, getMarginBottom } from './helpers/index'
|
|
9
10
|
import { Line } from '@visx/shape'
|
|
10
11
|
import { Label } from '../../types/Label'
|
|
11
12
|
import { ChartConfig } from '../../types/ChartConfig'
|
|
12
13
|
import { ColorScale } from '../../types/ChartContext'
|
|
13
14
|
import { forwardRef } from 'react'
|
|
15
|
+
import LegendSuppression from './Legend.Suppression'
|
|
16
|
+
import LegendGradient from '@cdc/core/components/Legend/Legend.Gradient'
|
|
17
|
+
import { DimensionsType } from '@cdc/core/types/Dimensions'
|
|
14
18
|
|
|
15
19
|
export interface LegendProps {
|
|
16
20
|
colorScale: ColorScale
|
|
@@ -22,209 +26,197 @@ export interface LegendProps {
|
|
|
22
26
|
ref: React.Ref<() => void>
|
|
23
27
|
seriesHighlight: string[]
|
|
24
28
|
skipId: string
|
|
29
|
+
dimensions: DimensionsType // for responsive width legend
|
|
30
|
+
getTextWidth: (text: string, font: string) => string
|
|
25
31
|
}
|
|
26
32
|
|
|
27
33
|
/* eslint-disable jsx-a11y/no-noninteractive-tabindex, jsx-a11y/no-static-element-interactions */
|
|
28
|
-
const Legend: React.FC<LegendProps> = forwardRef(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
const Legend: React.FC<LegendProps> = forwardRef(
|
|
35
|
+
(
|
|
36
|
+
{
|
|
37
|
+
config,
|
|
38
|
+
colorScale,
|
|
39
|
+
seriesHighlight,
|
|
40
|
+
highlight,
|
|
41
|
+
highlightReset,
|
|
42
|
+
currentViewport,
|
|
43
|
+
formatLabels,
|
|
44
|
+
skipId = 'legend',
|
|
45
|
+
dimensions,
|
|
46
|
+
getTextWidth
|
|
47
|
+
},
|
|
48
|
+
ref
|
|
49
|
+
) => {
|
|
50
|
+
const { innerClasses, containerClasses } = useLegendClasses(config)
|
|
51
|
+
const { runtime, legend } = config
|
|
52
|
+
|
|
53
|
+
const isBottomOrSmallViewport =
|
|
54
|
+
legend?.position === 'bottom' || (['sm', 'xs', 'xxs'].includes(currentViewport) && !legend.hide)
|
|
55
|
+
|
|
56
|
+
const legendClasses = {
|
|
57
|
+
marginBottom: getMarginBottom(isBottomOrSmallViewport, config),
|
|
58
|
+
|
|
59
|
+
marginTop:
|
|
60
|
+
isBottomOrSmallViewport && config.orientation === 'horizontal'
|
|
61
|
+
? `${config.yAxis.label && config.isResponsiveTicks ? config.dynamicMarginTop : config.runtime.xAxis.size}px`
|
|
62
|
+
: getMarginTop(isBottomOrSmallViewport, config.brush.active, legend)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const { HighLightedBarUtils } = useHighlightedBars(config)
|
|
66
|
+
let highLightedLegendItems = HighLightedBarUtils.findDuplicates(config.highlightedBarValues)
|
|
67
|
+
if (!legend) return null
|
|
68
|
+
return (
|
|
69
|
+
<aside
|
|
70
|
+
ref={ref}
|
|
71
|
+
style={legendClasses}
|
|
72
|
+
id={skipId || 'legend'}
|
|
73
|
+
className={containerClasses.join(' ')}
|
|
74
|
+
role='region'
|
|
75
|
+
aria-label='legend'
|
|
76
|
+
tabIndex={0}
|
|
77
|
+
>
|
|
78
|
+
{legend.label && <h3>{parse(legend.label)}</h3>}
|
|
79
|
+
{legend.description && <p>{parse(legend.description)}</p>}
|
|
80
|
+
<LegendGradient
|
|
81
|
+
getTextWidth={getTextWidth}
|
|
82
|
+
config={config}
|
|
83
|
+
{...getGradientConfig(config, formatLabels, colorScale)}
|
|
84
|
+
dimensions={dimensions}
|
|
85
|
+
currentViewport={currentViewport}
|
|
86
|
+
/>
|
|
87
|
+
|
|
88
|
+
<LegendOrdinal scale={colorScale} itemDirection='row' labelMargin='0 20px 0 0' shapeMargin='0 10px 0'>
|
|
89
|
+
{labels => {
|
|
90
|
+
return (
|
|
91
|
+
<>
|
|
92
|
+
<div className={innerClasses.join(' ')}>
|
|
93
|
+
{formatLabels(labels as Label[]).map((label, i) => {
|
|
94
|
+
let className = ['legend-item', `legend-text--${label.text.replace(' ', '').toLowerCase()}`]
|
|
95
|
+
let itemName = label.datum
|
|
96
|
+
|
|
97
|
+
// Filter excluded data keys from legend
|
|
98
|
+
if (config.exclusions.active && config.exclusions.keys?.includes(itemName)) {
|
|
99
|
+
return null
|
|
100
|
+
}
|
|
48
101
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
<>
|
|
53
|
-
<div className={innerClasses.join(' ')}>
|
|
54
|
-
{formatLabels(labels as Label[]).map((label, i) => {
|
|
55
|
-
let className = ['legend-item', `legend-text--${label.text.replace(' ', '').toLowerCase()}`]
|
|
56
|
-
let itemName = label.datum
|
|
102
|
+
if (runtime.seriesLabels) {
|
|
103
|
+
let index = config.runtime.seriesLabelsAll.indexOf(itemName)
|
|
104
|
+
itemName = config.runtime.seriesKeys[index]
|
|
57
105
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
106
|
+
if (runtime?.forecastingSeriesKeys?.length > 0) {
|
|
107
|
+
itemName = label.text
|
|
108
|
+
}
|
|
109
|
+
}
|
|
62
110
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
111
|
+
if (seriesHighlight.length > 0 && false === seriesHighlight.includes(itemName)) {
|
|
112
|
+
className.push('inactive')
|
|
113
|
+
}
|
|
66
114
|
|
|
67
|
-
if (
|
|
68
|
-
|
|
115
|
+
if (config.legend.style === 'gradient') {
|
|
116
|
+
return <></>
|
|
69
117
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<LegendItem
|
|
121
|
+
className={className.join(' ')}
|
|
122
|
+
tabIndex={0}
|
|
123
|
+
key={`legend-quantile-${i}`}
|
|
124
|
+
onKeyDown={e => {
|
|
125
|
+
if (e.key === 'Enter') {
|
|
126
|
+
e.preventDefault()
|
|
127
|
+
highlight(label)
|
|
128
|
+
}
|
|
129
|
+
}}
|
|
130
|
+
onClick={e => {
|
|
83
131
|
e.preventDefault()
|
|
84
132
|
highlight(label)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
133
|
+
}}
|
|
134
|
+
role='button'
|
|
135
|
+
>
|
|
136
|
+
<div>
|
|
137
|
+
{config.visualizationType === 'Line' && config.legend.style === 'lines' ? (
|
|
138
|
+
<svg width={40} height={20}>
|
|
139
|
+
<Line
|
|
140
|
+
from={{ x: 10, y: 10 }}
|
|
141
|
+
to={{ x: 40, y: 10 }}
|
|
142
|
+
stroke={label.value}
|
|
143
|
+
strokeWidth={2}
|
|
144
|
+
strokeDasharray={handleLineType(config.series[i]?.type ? config.series[i]?.type : '')}
|
|
145
|
+
/>
|
|
146
|
+
</svg>
|
|
147
|
+
) : (
|
|
148
|
+
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
149
|
+
<LegendShape
|
|
150
|
+
shape={config.legend.style === 'boxes' ? 'square' : 'circle'}
|
|
151
|
+
viewport={currentViewport}
|
|
152
|
+
margin='0'
|
|
153
|
+
fill={label.value}
|
|
154
|
+
display={true}
|
|
155
|
+
/>
|
|
156
|
+
</div>
|
|
157
|
+
)}
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
<LegendLabel align='left' margin='0 0 0 4px'>
|
|
161
|
+
{label.text}
|
|
162
|
+
</LegendLabel>
|
|
163
|
+
</LegendItem>
|
|
164
|
+
)
|
|
165
|
+
})}
|
|
166
|
+
|
|
167
|
+
{highLightedLegendItems.map((bar, i) => {
|
|
168
|
+
// if duplicates only return first item
|
|
169
|
+
let className = 'legend-item'
|
|
170
|
+
let itemName = bar.legendLabel
|
|
171
|
+
|
|
172
|
+
if (!itemName) return false
|
|
173
|
+
if (seriesHighlight.length > 0 && false === seriesHighlight.includes(itemName)) {
|
|
174
|
+
className += ' inactive'
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<LegendItem
|
|
179
|
+
className={className}
|
|
180
|
+
tabIndex={0}
|
|
181
|
+
key={`legend-quantile-${i}`}
|
|
182
|
+
onKeyDown={e => {
|
|
183
|
+
if (e.key === 'Enter') {
|
|
184
|
+
e.preventDefault()
|
|
185
|
+
highlight(bar.legendLabel)
|
|
186
|
+
}
|
|
187
|
+
}}
|
|
188
|
+
onClick={e => {
|
|
128
189
|
e.preventDefault()
|
|
129
190
|
highlight(bar.legendLabel)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
{config?.preliminaryData?.some(pd => pd.label && pd.type === 'effect' && pd.style === 'Open Circles') && ['Line', 'Combo'].includes(config.visualizationType) && (
|
|
148
|
-
<>
|
|
149
|
-
<hr></hr>
|
|
150
|
-
<div className={config.legend.singleRow && isBottomOrSmallViewport ? 'legend-container__inner bottom single-row' : ''}>
|
|
151
|
-
{config?.preliminaryData?.map((pd, index) => {
|
|
152
|
-
return (
|
|
153
|
-
<>
|
|
154
|
-
{pd.label && pd.type === 'effect' && pd.style && (
|
|
155
|
-
<div key={index} className='legend-preliminary'>
|
|
156
|
-
<span className={pd.symbol}>{pd.lineCode}</span>
|
|
157
|
-
<p> {pd.label}</p>
|
|
158
|
-
</div>
|
|
159
|
-
)}
|
|
160
|
-
</>
|
|
161
|
-
)
|
|
162
|
-
})}
|
|
163
|
-
</div>
|
|
164
|
-
</>
|
|
165
|
-
)}
|
|
166
|
-
{!config.legend.hideSuppressedLabels &&
|
|
167
|
-
config?.preliminaryData?.some(pd => pd.label && pd.displayLegend && pd.type === 'suppression' && pd.value && (pd?.style || pd.symbol)) &&
|
|
168
|
-
((config.visualizationType === 'Bar' && config.visualizationSubType === 'regular') || config.visualizationType === 'Line' || config.visualizationType === 'Combo') && (
|
|
169
|
-
<>
|
|
170
|
-
<hr></hr>
|
|
171
|
-
<div className={config.legend.singleRow && isBottomOrSmallViewport ? 'legend-container__inner bottom single-row' : ''}>
|
|
172
|
-
{config?.preliminaryData?.map(
|
|
173
|
-
(pd, index) =>
|
|
174
|
-
pd.displayLegend &&
|
|
175
|
-
pd.type === 'suppression' && (
|
|
176
|
-
<>
|
|
177
|
-
{config.visualizationType === 'Bar' && (
|
|
178
|
-
<>
|
|
179
|
-
<div key={index + 'Bar'} className={`legend-preliminary ${pd.symbol}`}>
|
|
180
|
-
<span className={pd.symbol}>{pd.iconCode}</span>
|
|
181
|
-
<p className={pd.type}>{pd.label}</p>
|
|
182
|
-
</div>
|
|
183
|
-
</>
|
|
184
|
-
)}
|
|
185
|
-
{config.visualizationType === 'Line' && (
|
|
186
|
-
<>
|
|
187
|
-
<div key={index + 'Line'} className={`legend-preliminary `}>
|
|
188
|
-
<span>{pd.lineCode}</span>
|
|
189
|
-
<p className={pd.type}>{pd.label}</p>
|
|
190
|
-
</div>
|
|
191
|
-
</>
|
|
192
|
-
)}
|
|
193
|
-
{config.visualizationType === 'Combo' && (
|
|
194
|
-
<>
|
|
195
|
-
{pd.symbol && pd.iconCode && (
|
|
196
|
-
<div key={index + 'Combo'} className={`legend-preliminary ${pd.symbol}`}>
|
|
197
|
-
<span className={pd.symbol}>{pd.iconCode}</span>
|
|
198
|
-
<p className={pd.type}>{pd.label}</p>
|
|
199
|
-
</div>
|
|
200
|
-
)}
|
|
201
|
-
|
|
202
|
-
{pd.style && pd.lineCode && (
|
|
203
|
-
<div key={index + 'Combo'} className='legend-preliminary'>
|
|
204
|
-
<span>{pd.lineCode}</span>
|
|
205
|
-
<p>{pd.label}</p>
|
|
206
|
-
</div>
|
|
207
|
-
)}
|
|
208
|
-
</>
|
|
209
|
-
)}
|
|
210
|
-
</>
|
|
211
|
-
)
|
|
212
|
-
)}
|
|
213
|
-
</div>
|
|
214
|
-
</>
|
|
215
|
-
)}
|
|
191
|
+
}}
|
|
192
|
+
>
|
|
193
|
+
<LegendShape
|
|
194
|
+
shape={config.legend.style === 'boxes' ? 'square' : 'circle'}
|
|
195
|
+
style={{ borderRadius: '0px' }}
|
|
196
|
+
fill='transparent'
|
|
197
|
+
borderColor={bar.color ? bar.color : `rgba(255, 102, 1)`}
|
|
198
|
+
/>{' '}
|
|
199
|
+
<LegendLabel align='left' margin='0 0 0 4px'>
|
|
200
|
+
{bar.legendLabel ? bar.legendLabel : bar.value}
|
|
201
|
+
</LegendLabel>
|
|
202
|
+
</LegendItem>
|
|
203
|
+
)
|
|
204
|
+
})}
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<LegendSuppression config={config} isBottomOrSmallViewport={isBottomOrSmallViewport} />
|
|
216
208
|
</>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
209
|
+
)
|
|
210
|
+
}}
|
|
211
|
+
</LegendOrdinal>
|
|
212
|
+
{seriesHighlight.length > 0 && (
|
|
213
|
+
<Button onClick={labels => highlightReset(labels)} style={{ marginTop: '1rem' }}>
|
|
214
|
+
Reset
|
|
215
|
+
</Button>
|
|
216
|
+
)}
|
|
217
|
+
</aside>
|
|
218
|
+
)
|
|
219
|
+
}
|
|
220
|
+
)
|
|
229
221
|
|
|
230
222
|
export default Legend
|