@cdc/chart 4.24.3 → 4.24.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/cdcchart.js +34377 -33726
  2. package/examples/feature/line/line-chart.json +361 -37
  3. package/examples/region-issue.json +2065 -0
  4. package/examples/test.json +5409 -0
  5. package/index.html +13 -11
  6. package/package.json +2 -2
  7. package/src/CdcChart.tsx +159 -89
  8. package/src/_stories/Chart.stories.tsx +8 -0
  9. package/src/_stories/_mock/bar-chart-suppressed.json +474 -0
  10. package/src/components/AreaChart/components/AreaChart.jsx +2 -2
  11. package/src/components/BarChart/components/BarChart.Horizontal.tsx +61 -63
  12. package/src/components/BarChart/components/BarChart.Vertical.tsx +79 -94
  13. package/src/components/DeviationBar.jsx +4 -2
  14. package/src/components/EditorPanel/EditorPanel.tsx +1580 -1924
  15. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +19 -2
  16. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +0 -1
  17. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +4 -5
  18. package/src/components/EditorPanel/editor-panel.scss +0 -724
  19. package/src/components/EditorPanel/useEditorPermissions.js +4 -1
  20. package/src/components/Legend/Legend.Component.tsx +82 -58
  21. package/src/components/Legend/Legend.tsx +5 -1
  22. package/src/components/LineChart/LineChartProps.ts +13 -6
  23. package/src/components/LineChart/components/LineChart.Circle.tsx +22 -11
  24. package/src/components/LineChart/helpers.ts +134 -10
  25. package/src/components/LineChart/index.tsx +69 -42
  26. package/src/components/LinearChart.jsx +156 -139
  27. package/src/components/ZoomBrush.tsx +40 -21
  28. package/src/data/initial-state.js +4 -4
  29. package/src/hooks/useBarChart.js +47 -22
  30. package/src/hooks/useMinMax.ts +21 -2
  31. package/src/hooks/useScales.ts +33 -1
  32. package/src/hooks/useTooltip.tsx +11 -11
  33. package/src/scss/main.scss +80 -5
  34. package/src/types/ChartConfig.ts +3 -13
  35. package/src/types/ChartContext.ts +4 -0
  36. package/src/_stories/ChartLine.preliminary.tsx +0 -19
  37. package/src/_stories/ChartSuppress.stories.tsx +0 -19
  38. package/src/_stories/_mock/suppress_mock.json +0 -911
  39. package/src/helpers/computeMarginBottom.ts +0 -56
@@ -1,23 +1,29 @@
1
1
  import React, { useContext } from 'react'
2
+
3
+ // Local context and hooks
2
4
  import ConfigContext from '../../../ConfigContext'
3
5
  import { useBarChart } from '../../../hooks/useBarChart'
6
+ import { useHighlightedBars } from '../../../hooks/useHighlightedBars'
7
+
8
+ // VisX library imports
4
9
  import { Group } from '@visx/group'
5
10
  import { Text } from '@visx/text'
6
11
  import { BarGroup } from '@visx/shape'
7
- import { useHighlightedBars } from '../../../hooks/useHighlightedBars'
8
- import { FaStar } from 'react-icons/fa'
12
+
13
+ // CDC core components and helpers
9
14
  import { getContrastColor } from '@cdc/core/helpers/cove/accessibility'
15
+ import createBarElement from '@cdc/core/components/createBarElement'
10
16
 
11
- // third party
17
+ // Third party libraries
12
18
  import chroma from 'chroma-js'
19
+
20
+ // Local context and types
13
21
  import BarChartContext, { BarChartContextValues } from './context'
14
22
  import { ChartContext } from '../../../types/ChartContext'
15
23
 
16
- import createBarElement from '@cdc/core/components/createBarElement'
17
-
18
24
  export const BarChartHorizontal = () => {
19
25
  const { xScale, yScale, yMax, seriesScale } = useContext<BarChartContextValues>(BarChartContext)
20
- const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter, isNumber, getTextWidth, getYAxisData, getXAxisData } = useContext<ChartContext>(ConfigContext)
26
+ const { transformedData: data, tableData, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter, isNumber, getTextWidth, getYAxisData, getXAxisData } = useContext<ChartContext>(ConfigContext)
21
27
  const {
22
28
  isHorizontal,
23
29
  barBorderWidth,
@@ -31,32 +37,22 @@ export const BarChartHorizontal = () => {
31
37
  lollipopShapeSize,
32
38
  getHighlightedBarColorByValue,
33
39
  getHighlightedBarByValue,
34
- generateIconSize,
35
40
  getAdditionalColumn,
36
41
  hoveredBar,
37
42
  onMouseLeaveBar,
38
- onMouseOverBar
43
+ onMouseOverBar,
44
+ composeSuppressionBars
39
45
  } = useBarChart()
40
46
 
41
47
  const { HighLightedBarUtils } = useHighlightedBars(config)
42
- const getIcon = (bar, barWidth) => {
43
- let icon = null
44
- const iconSize = generateIconSize(barWidth)
45
- config.suppressedData?.forEach(d => {
46
- if (bar.key === d.column && String(bar.value) === String(d.value) && d.icon) {
47
- icon = <FaStar color='#000' size={iconSize} />
48
- // icon = <BarIcon color='#000' size={fontSize[config.fontSize] / 1.7} />
49
- }
50
- })
51
- return icon
52
- }
48
+
53
49
  return (
54
50
  config.visualizationSubType !== 'stacked' &&
55
51
  config.visualizationType === 'Bar' &&
56
52
  config.orientation === 'horizontal' && (
57
53
  <Group>
58
54
  <BarGroup
59
- data={data}
55
+ data={config.preliminaryData?.some(pd => pd.value && pd.type === 'suppression') ? tableData : data}
60
56
  keys={config.runtime.barSeriesKeys || config.runtime.seriesKeys}
61
57
  height={yMax}
62
58
  x0={d => d[config.runtime.originalXAxis.dataKey]}
@@ -72,30 +68,32 @@ export const BarChartHorizontal = () => {
72
68
  <Group className={`bar-group-${barGroup.index}-${barGroup.x0}--${index} ${config.orientation}`} key={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`} id={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`} top={barGroup.y}>
73
69
  {barGroup.bars.map((bar, index) => {
74
70
  const scaleVal = config.useLogScale ? 0.1 : 0
71
+ const { suppresedBarHeight: suppresedBarWidth, getIconSize, getIconPadding, getVerticalAnchor, isSuppressed } = composeSuppressionBars({ bar })
75
72
 
76
73
  let highlightedBarValues = config.highlightedBarValues.map(item => item.value).filter(item => item !== ('' || undefined))
77
74
  highlightedBarValues = config.xAxis.type === 'date' ? HighLightedBarUtils.formatDates(highlightedBarValues) : highlightedBarValues
78
75
  let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
79
76
  let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
80
77
  let barHeight = config.barHeight
78
+ let numbericBarHeight = parseInt(!config.isLollipopChart ? barHeight : lollipopBarWidth)
79
+ if (isNaN(numbericBarHeight)) {
80
+ numbericBarHeight = 25
81
+ }
81
82
  let barY = bar.value >= 0 && isNumber(bar.value) ? bar.y : yScale(scaleVal)
82
- const barXBase = bar.value < 0 ? Math.abs(xScale(bar.value)) : xScale(scaleVal)
83
83
  const barWidthHorizontal = Math.abs(xScale(bar.value) - xScale(scaleVal))
84
- const suppresedBarWidth = 25
84
+ // const suppresedBarWidth = config.xAxis.showSuppressedLine ? 4 : 0
85
85
  const isPositiveBar = bar.value >= 0 && isNumber(bar.value)
86
- let barWidth = bar.value && config.suppressedData.some(({ column, value }) => bar.key === column && bar.value === value) ? suppresedBarWidth : barWidthHorizontal
87
-
88
- const supprssedBarX = isPositiveBar ? xScale(0) : xScale(scaleVal) - suppresedBarWidth
89
- const barX = config.suppressedData.some(d => bar.key === d.column && String(bar.value) === String(d.value)) ? supprssedBarX : barXBase
86
+ let barWidth = isSuppressed ? suppresedBarWidth : barWidthHorizontal
87
+ const barX = bar.value < 0 ? Math.abs(xScale(bar.value)) : xScale(scaleVal)
90
88
  const yAxisValue = formatNumber(bar.value, 'left')
91
89
  const xAxisValue = config.runtime[section].type === 'date' ? formatDate(parseDate(data[barGroup.index][config.runtime.originalXAxis.dataKey])) : data[barGroup.index][config.runtime.originalXAxis.dataKey]
92
90
 
93
91
  const barPosition = !isPositiveBar ? 'below' : 'above'
94
- const barValueLabel = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? '' : yAxisValue
92
+ const barValueLabel = isSuppressed ? '' : yAxisValue
95
93
 
96
94
  // check if bar text/value string fits into each bars.
97
95
  let textWidth = getTextWidth(xAxisValue, `normal ${fontSize[config.fontSize]}px sans-serif`)
98
- let textFits = textWidth < barWidthHorizontal - 5 // minus padding 5
96
+ let textFits = Number(textWidth) < barWidthHorizontal - 5 // minus padding 5
99
97
 
100
98
  // control text position
101
99
  let textAnchor = textFits ? 'end' : 'start'
@@ -131,28 +129,17 @@ export const BarChartHorizontal = () => {
131
129
  barColor = assignColorsToValues(barGroups.length, barGroup.index, barColor) // Color code by category
132
130
  const isRegularLollipopColor = config.isLollipopChart && config.lollipopColorStyle === 'regular'
133
131
  const isTwoToneLollipopColor = config.isLollipopChart && config.lollipopColorStyle === 'two-tone'
134
- const isHighlightedBar = highlightedBarValues?.includes(yAxisValue)
135
- const highlightedBarColor = getHighlightedBarColorByValue(yAxisValue)
136
- const highlightedBar = getHighlightedBarByValue(yAxisValue)
132
+ const isHighlightedBar = highlightedBarValues?.includes(xAxisValue)
133
+ const highlightedBarColor = getHighlightedBarColorByValue(xAxisValue)
134
+ const highlightedBar = getHighlightedBarByValue(xAxisValue)
137
135
  const borderColor = isHighlightedBar ? highlightedBarColor : config.barHasBorder === 'true' ? '#000' : 'transparent'
138
136
  const borderWidth = isHighlightedBar ? highlightedBar.borderWidth : config.isLollipopChart ? 0 : config.barHasBorder === 'true' ? barBorderWidth : 0
139
- const displaylollipopShape = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? 'none' : 'block'
137
+ const displaylollipopShape = isSuppressed ? 'none' : 'block'
140
138
  // update label color
141
139
  if (barColor && labelColor && textFits) {
142
140
  labelColor = getContrastColor('#000', barColor)
143
141
  }
144
- const getTop = () => {
145
- if (Number(barHeight) < 20) return -4
146
- if (Number(barHeight) < 25) return -1
147
- if (Number(barHeight) < 30) return 2
148
- if (Number(barHeight) < 35) return 4
149
- if (Number(barHeight) < 40) return 5
150
- if (Number(barHeight) < 50) return 9
151
- if (Number(barHeight) < 60) return 10
152
- else {
153
- return 12
154
- }
155
- }
142
+
156
143
  const background = () => {
157
144
  if (isRegularLollipopColor) return barColor
158
145
  if (isTwoToneLollipopColor) return chroma(barColor).brighten(1)
@@ -160,6 +147,8 @@ export const BarChartHorizontal = () => {
160
147
  return barColor
161
148
  }
162
149
 
150
+ const iconPadding = symbol => (symbol === 'Asterisk' ? '3px' : symbol === 'Double Asterisks' ? '4px' : '12px')
151
+
163
152
  return (
164
153
  <Group key={`${barGroup.index}--${index}`}>
165
154
  <Group key={`bar-sub-group-${barGroup.index}-${barGroup.x0}-${barY}--${index}`}>
@@ -172,7 +161,7 @@ export const BarChartHorizontal = () => {
172
161
  borderStyle: 'solid',
173
162
  borderWidth: `${borderWidth}px`,
174
163
  width: barWidth,
175
- height: !config.isLollipopChart ? barHeight : lollipopBarWidth,
164
+ height: numbericBarHeight,
176
165
  x: barX,
177
166
  y: barHeight * bar.index,
178
167
  onMouseOver: () => onMouseOverBar(xAxisValue, bar.key),
@@ -192,24 +181,33 @@ export const BarChartHorizontal = () => {
192
181
  display: displayBar ? 'block' : 'none'
193
182
  }
194
183
  })}
195
- <g
196
- transform={`translate(${barX},${barHeight * bar.index})`}
197
- onMouseOver={() => onMouseOverBar(xAxisValue, bar.key)}
198
- onMouseLeave={onMouseLeaveBar}
199
- opacity={transparentBar ? 0.2 : 1}
200
- display={displayBar ? 'block' : 'none'}
201
- data-tooltip-html={tooltip}
202
- data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
203
- onClick={e => {
204
- e.preventDefault()
205
- if (setSharedFilter) {
206
- bar[config.xAxis.dataKey] = yAxisValue
207
- setSharedFilter(config.uid, bar)
208
- }
209
- }}
210
- >
211
- {getIcon(bar, barWidth)}
212
- </g>
184
+ {config.preliminaryData?.map((pd, index) => {
185
+ // check if user selected column
186
+ const selectedSuppressionColumn = !pd.column || pd.column === bar.key
187
+ // compare entered suppressed value with data value
188
+ const isValueMatch = String(pd.value) === String(tableData[barGroup.index][bar.key]) && pd.value !== ''
189
+ const isSuppressed = isValueMatch && selectedSuppressionColumn
190
+ if (!isSuppressed || barHeight < 10 || !config.xAxis.showSuppressedSymbol) {
191
+ return
192
+ }
193
+ return (
194
+ <Text // prettier-ignore
195
+ key={index}
196
+ fontSize={getIconSize(pd.symbol, barHeight)}
197
+ angle={90}
198
+ display={displayBar ? 'block' : 'none'}
199
+ opacity={transparentBar ? 0.5 : 1}
200
+ x={barX}
201
+ y={config.barHeight / 2 + config.barHeight * bar.index}
202
+ fill={'#000'}
203
+ dx={iconPadding(pd.symbol)}
204
+ verticalAnchor={getVerticalAnchor(pd.symbol)}
205
+ textAnchor={'middle'}
206
+ >
207
+ {pd.iconCode}
208
+ </Text>
209
+ )
210
+ })}
213
211
 
214
212
  {!config.isLollipopChart && displayNumbersOnBar && (
215
213
  <Text // prettier-ignore
@@ -1,72 +1,47 @@
1
1
  import React, { useContext, useState } from 'react'
2
+ // Local contexts
2
3
  import ConfigContext from '../../../ConfigContext'
3
- import { type ChartContext } from '../../../types/ChartContext'
4
+ import BarChartContext, { type BarChartContextValues } from './context'
5
+ // Local hooks
4
6
  import { useBarChart } from '../../../hooks/useBarChart'
7
+ import { useHighlightedBars } from '../../../hooks/useHighlightedBars'
8
+ // VisX library imports
5
9
  import { Group } from '@visx/group'
6
10
  import { Text } from '@visx/text'
7
11
  import { BarGroup } from '@visx/shape'
8
- import { useHighlightedBars } from '../../../hooks/useHighlightedBars'
9
- import { FaStar } from 'react-icons/fa'
10
- import Regions from './../../Regions'
12
+ // Local components
13
+ import Regions from '../../Regions'
14
+ // CDC core components and helpers
11
15
  import { isDateScale } from '@cdc/core/helpers/cove/date'
12
-
13
16
  import createBarElement from '@cdc/core/components/createBarElement'
14
-
15
- // third party
17
+ // Third party libraries
16
18
  import chroma from 'chroma-js'
17
- import BarChartContext, { type BarChartContextValues } from './context'
19
+ // Types
20
+ import { type ChartContext } from '../../../types/ChartContext'
18
21
 
19
22
  export const BarChartVertical = () => {
20
23
  const { xScale, yScale, xMax, yMax, seriesScale } = useContext<BarChartContextValues>(BarChartContext)
21
24
 
22
25
  const [barWidth, setBarWidth] = useState(0)
23
26
  const [totalBarsInGroup, setTotalBarsInGroup] = useState(0)
24
-
25
27
  // prettier-ignore
26
- const {
27
- applyRadius,
28
- assignColorsToValues,
29
- barBorderWidth,
30
- generateIconSize,
31
- getAdditionalColumn,
32
- getHighlightedBarByValue,
33
- getHighlightedBarColorByValue,
34
- lollipopBarWidth,
35
- lollipopShapeSize,
36
- onMouseLeaveBar,
37
- onMouseOverBar,
38
- section
39
- } = useBarChart()
28
+ const { assignColorsToValues, barBorderWidth, getAdditionalColumn, getHighlightedBarByValue, getHighlightedBarColorByValue, lollipopBarWidth, lollipopShapeSize, onMouseLeaveBar, onMouseOverBar, section, composeSuppressionBars, shouldSuppress } = useBarChart()
40
29
 
41
30
  // prettier-ignore
42
- const {
43
- colorScale,
44
- config,
45
- dashboardConfig,
46
- formatDate,
47
- formatNumber,
48
- getXAxisData,
49
- getYAxisData,
50
- isNumber,
51
- parseDate,
52
- seriesHighlight,
53
- setSharedFilter,
54
- transformedData,
55
- } = useContext<ChartContext>(ConfigContext)
56
-
31
+ const { colorScale, config, dashboardConfig, tableData, formatDate, formatNumber, getXAxisData, getYAxisData, isNumber, parseDate, seriesHighlight, setSharedFilter, transformedData, brushConfig, } = useContext<ChartContext>(ConfigContext)
57
32
  const { HighLightedBarUtils } = useHighlightedBars(config)
58
- const data = config.brush.active && config.brush.data?.length ? config.brush.data : transformedData
59
-
60
- const getIcon = (bar, barWidth) => {
61
- let icon = null
62
- const iconSize = generateIconSize(barWidth)
63
- config.suppressedData?.forEach(d => {
64
- if (bar.key === d.column && String(bar.value) === String(d.value) && d.icon) {
65
- icon = <FaStar color='#000' size={iconSize} />
66
- }
67
- })
68
- return icon
33
+ let data = transformedData
34
+ // check if user add suppression
35
+ const isSuppressionActive = config.preliminaryData.some(pd => pd.value && pd.type === 'suppression')
36
+ // if suppression active use table data (filtere | excluded) but non cleaned
37
+ if (isSuppressionActive) {
38
+ data = tableData
39
+ }
40
+ // if brush active use brush data (filtered|excluded) not cleaned
41
+ if (brushConfig.data.length) {
42
+ data = brushConfig.data
69
43
  }
44
+
70
45
  return (
71
46
  config.visualizationSubType !== 'stacked' &&
72
47
  (config.visualizationType === 'Bar' || config.visualizationType === 'Combo') &&
@@ -91,16 +66,15 @@ export const BarChartVertical = () => {
91
66
  return barGroups.map((barGroup, index) => (
92
67
  <Group className={`bar-group-${barGroup.index}-${barGroup.x0}--${index} ${config.orientation}`} key={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`} id={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`} left={barGroup.x0}>
93
68
  {barGroup.bars.map((bar, index) => {
69
+ const { suppresedBarHeight, getIconSize, getIconPadding, getVerticalAnchor, isSuppressed } = composeSuppressionBars({ bar })
94
70
  const scaleVal = config.useLogScale ? 0.1 : 0
95
- const suppresedBarHeight = 20
96
71
  let highlightedBarValues = config.highlightedBarValues.map(item => item.value).filter(item => item !== ('' || undefined))
97
72
  highlightedBarValues = config.xAxis.type === 'date' ? HighLightedBarUtils.formatDates(highlightedBarValues) : highlightedBarValues
98
- let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
99
- let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
100
- let barHeightBase = Math.abs(yScale(bar.value) - yScale(scaleVal))
101
- let barYBase = bar.value >= 0 && isNumber(bar.value) ? bar.y : yScale(0)
102
- const supprssedBarY = bar.value >= 0 && isNumber(bar.value) ? yScale(scaleVal) - suppresedBarHeight : yScale(0)
103
- const barY = config.suppressedData.some(d => bar.key === d.column && String(bar.value) === String(d.value)) ? supprssedBarY : barYBase
73
+ const transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
74
+ const displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
75
+ const barHeightBase = Math.abs(yScale(bar.value) - yScale(scaleVal))
76
+ const barYBase = bar.value >= 0 && isNumber(bar.value) ? bar.y : yScale(0)
77
+ const barY = isSuppressed ? yScale(scaleVal) - suppresedBarHeight : barYBase
104
78
 
105
79
  let barGroupWidth = seriesScale.range()[1]
106
80
 
@@ -108,9 +82,8 @@ export const BarChartVertical = () => {
108
82
  let barX = bar.x + (config.isLollipopChart ? (barGroupWidth / barGroup.bars.length - lollipopBarWidth) / 2 : 0) - (config.xAxis.type === 'date-time' ? barGroupWidth / 2 : 0)
109
83
  setBarWidth(barWidth)
110
84
  setTotalBarsInGroup(barGroup.bars.length)
111
-
112
- let yAxisValue = formatNumber(bar.value, 'left')
113
- let xAxisValue = config.runtime[section].type === 'date' ? formatDate(parseDate(data[barGroup.index][config.runtime.originalXAxis.dataKey])) : data[barGroup.index][config.runtime.originalXAxis.dataKey]
85
+ const yAxisValue = formatNumber(/[a-zA-Z]/.test(String(bar.value)) ? '' : bar.value, 'left')
86
+ const xAxisValue = config.runtime[section].type === 'date' ? formatDate(parseDate(data[barGroup.index][config.runtime.originalXAxis.dataKey])) : data[barGroup.index][config.runtime.originalXAxis.dataKey]
114
87
 
115
88
  // create new Index for bars with negative values
116
89
  const newIndex = bar.value < 0 ? -1 : index
@@ -138,10 +111,10 @@ export const BarChartVertical = () => {
138
111
  const highlightedBar = getHighlightedBarByValue(xAxisValue)
139
112
  const borderColor = isHighlightedBar ? highlightedBarColor : config.barHasBorder === 'true' ? '#000' : 'transparent'
140
113
  const borderWidth = isHighlightedBar ? highlightedBar.borderWidth : config.isLollipopChart ? 0 : config.barHasBorder === 'true' ? barBorderWidth : 0
141
- const barValueLabel = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? '' : yAxisValue
142
- let barHeight = config.suppressedData.some(d => bar.key === d.column && String(bar.value) === String(d.value)) ? suppresedBarHeight : barHeightBase
143
- const displaylollipopShape = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? 'none' : 'block'
114
+ const barValueLabel = isSuppressed ? '' : yAxisValue
115
+ const barHeight = isSuppressed ? suppresedBarHeight : barHeightBase
144
116
 
117
+ const displaylollipopShape = isSuppressed ? 'none' : 'block'
145
118
  const getBarBackgroundColor = (barColor: string, filteredOutColor?: string): string => {
146
119
  let _barColor = barColor
147
120
  let _filteredOutColor = filteredOutColor || '#f2f2f2'
@@ -151,21 +124,23 @@ export const BarChartVertical = () => {
151
124
  * color the bar that is using the filter with barColor and
152
125
  * color the filteredOut (typically gray) bars with the filteredOutColor
153
126
  */
154
- if (dashboardConfig && dashboardConfig.dashboard.sharedFilters) {
127
+ if (dashboardConfig && dashboardConfig.dashboard.sharedFilters?.length !== 0) {
155
128
  const { sharedFilters } = dashboardConfig.dashboard
156
129
 
157
- _barColor = sharedFilters.map(_sharedFilter => {
158
- if (_sharedFilter.setBy === config.uid) {
159
- // If the current filter is the reset filter item.
160
- if (_sharedFilter.resetLabel === _sharedFilter.active) return barColor
161
- // If the current filter is the bars
162
- if (_sharedFilter.active === transformedData[barGroup.index][config.xAxis.dataKey]) return barColor
163
- return _filteredOutColor
164
- } else {
165
- // If the setBy isn't the config.uid return the original barColor
166
- return barColor
167
- }
168
- })[0]
130
+ _barColor = sharedFilters
131
+ ? sharedFilters.map(_sharedFilter => {
132
+ if (_sharedFilter.setBy === config.uid) {
133
+ // If the current filter is the reset filter item.
134
+ if (_sharedFilter.resetLabel === _sharedFilter.active) return colorScale(config.runtime.seriesLabels[bar.key])
135
+ // If the current filter is the bars
136
+ if (_sharedFilter.active === transformedData[barGroup.index][config.xAxis.dataKey]) return colorScale(config.runtime.seriesLabels[bar.key])
137
+ return _filteredOutColor
138
+ } else {
139
+ // If the setBy isn't the config.uid return the original barColor
140
+ return colorScale(config.runtime.seriesLabels[bar.key])
141
+ }
142
+ })[0]
143
+ : colorScale(config.runtime.seriesLabels[bar.key])
169
144
 
170
145
  if (isRegularLollipopColor) _barColor = barColor
171
146
  if (isTwoToneLollipopColor) _barColor = chroma(barColor).brighten(1)
@@ -188,7 +163,7 @@ export const BarChartVertical = () => {
188
163
  config: config,
189
164
  index: newIndex,
190
165
  id: `barGroup${barGroup.index}`,
191
- background: getBarBackgroundColor(barColor),
166
+ background: getBarBackgroundColor(colorScale(config.runtime.seriesLabels[bar.key])),
192
167
  borderColor,
193
168
  borderStyle: 'solid',
194
169
  borderWidth: `${borderWidth}px`,
@@ -214,24 +189,34 @@ export const BarChartVertical = () => {
214
189
  cursor: dashboardConfig ? 'pointer' : 'default'
215
190
  }
216
191
  })}
217
- <g
218
- transform={`translate(${barX},${yMax - suppresedBarHeight})`}
219
- onMouseOver={() => onMouseOverBar(xAxisValue, bar.key)}
220
- onMouseLeave={onMouseLeaveBar}
221
- opacity={transparentBar ? 0.2 : 1}
222
- display={displayBar ? 'block' : 'none'}
223
- data-tooltip-html={tooltip}
224
- data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
225
- onClick={e => {
226
- e.preventDefault()
227
- if (setSharedFilter) {
228
- bar[config.xAxis.dataKey] = xAxisValue
229
- setSharedFilter(config.uid, bar)
230
- }
231
- }}
232
- >
233
- {getIcon(bar, barWidth)}
234
- </g>
192
+ {config.preliminaryData.map((pd, index) => {
193
+ // check if user selected column
194
+ const selectedSuppressionColumn = !pd.column || pd.column === bar.key
195
+ // compare entered suppressed value with data value
196
+ const isValueMatch = String(pd.value) === String(bar.value) && pd.value !== ''
197
+ let isSuppressed = isValueMatch && selectedSuppressionColumn
198
+
199
+ if (!isSuppressed || barWidth < 10 || !config.xAxis.showSuppressedSymbol) {
200
+ return
201
+ }
202
+
203
+ return (
204
+ <Text // prettier-ignore
205
+ key={index}
206
+ dy={getIconPadding(pd.symbol)}
207
+ display={displayBar ? 'block' : 'none'}
208
+ opacity={transparentBar ? 0.5 : 1}
209
+ x={barX + barWidth / 2}
210
+ y={barY}
211
+ verticalAnchor={getVerticalAnchor(pd.symbol)}
212
+ fill={labelColor}
213
+ textAnchor='middle'
214
+ fontSize={`${getIconSize(pd.symbol, barWidth)}px`}
215
+ >
216
+ {pd.iconCode}
217
+ </Text>
218
+ )
219
+ })}
235
220
 
236
221
  <Text // prettier-ignore
237
222
  display={config.labels && displayBar ? 'block' : 'none'}
@@ -82,7 +82,8 @@ export default function DeviationBar({ height, xScale }) {
82
82
  useEffect(() => {
83
83
  const handleResize = () => {
84
84
  setWindowWidth(window.innerWidth)
85
- barRefs.current.forEach(bar => {
85
+ barRefs.current?.forEach(bar => {
86
+ if (!bar || !bar.style) return
86
87
  bar.style.transition = 'none'
87
88
  bar.style.transform = 'translate(0) scale(1)'
88
89
  })
@@ -104,7 +105,8 @@ export default function DeviationBar({ height, xScale }) {
104
105
  }, [entry?.isIntersecting, config.animate]) // eslint-disable-line
105
106
 
106
107
  useEffect(() => {
107
- barRefs.current.forEach((bar, i) => {
108
+ barRefs.current?.forEach((bar, i) => {
109
+ if (!bar || !bar.style) return
108
110
  if (config.animate) {
109
111
  const normalizedTarget = (target / maxVal) * 100
110
112
  bar.style.opacity = '0'