@cdc/chart 4.23.10 → 4.23.11
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 +30989 -29057
- package/examples/feature/bar/example-bar-chart.json +1 -46
- package/examples/feature/bar/lollipop.json +156 -0
- package/examples/feature/combo/planet-combo-example-config.json +99 -9
- package/examples/feature/dev-4261.json +399 -0
- package/examples/feature/forest-plot/{broken.json → linear.json} +55 -50
- package/examples/feature/forest-plot/logarithmic.json +306 -0
- package/examples/feature/line/line-points.json +340 -0
- package/examples/feature/regions/index.json +462 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +181 -48
- package/examples/sparkline-multilple.json +846 -0
- package/index.html +10 -6
- package/package.json +3 -3
- package/src/CdcChart.tsx +75 -63
- package/src/_stories/Chart.stories.tsx +188 -0
- package/src/_stories/Chart.tooltip.stories.tsx +305 -0
- package/src/_stories/ChartBrush.stories.tsx +19 -0
- package/src/_stories/ChartSuppress.stories.tsx +19 -0
- package/src/_stories/_mock/brush_mock.json +393 -0
- package/src/_stories/_mock/suppress_mock.json +911 -0
- package/src/components/AreaChart.Stacked.jsx +4 -5
- package/src/components/AreaChart.jsx +6 -35
- package/src/components/{BarChart.Horizontal.jsx → BarChart.Horizontal.tsx} +106 -29
- package/src/components/{BarChart.StackedHorizontal.jsx → BarChart.StackedHorizontal.tsx} +22 -17
- package/src/components/{BarChart.StackedVertical.jsx → BarChart.StackedVertical.tsx} +22 -26
- package/src/components/{BarChart.Vertical.jsx → BarChart.Vertical.tsx} +175 -31
- package/src/components/BarChart.jsx +1 -1
- package/src/components/DeviationBar.jsx +4 -3
- package/src/components/EditorPanel.jsx +176 -50
- package/src/components/ForestPlot/ForestPlotProps.ts +11 -0
- package/src/components/ForestPlot/Readme.md +0 -0
- package/src/components/ForestPlot/index.scss +1 -0
- package/src/components/{ForestPlot.jsx → ForestPlot/index.tsx} +51 -31
- package/src/components/ForestPlotSettings.jsx +162 -113
- package/src/components/Legend.jsx +36 -3
- package/src/components/{LineChart.Circle.tsx → LineChart/LineChart.Circle.tsx} +26 -29
- package/src/components/LineChart/LineChartProps.ts +17 -0
- package/src/components/LineChart/index.scss +1 -0
- package/src/components/{LineChart.tsx → LineChart/index.tsx} +64 -35
- package/src/components/LinearChart.jsx +120 -60
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/Series.jsx +22 -3
- package/src/components/ZoomBrush.tsx +168 -0
- package/src/data/initial-state.js +27 -12
- package/src/hooks/useBarChart.js +71 -7
- package/src/hooks/useColorScale.ts +50 -0
- package/src/hooks/useEditorPermissions.js +22 -4
- package/src/hooks/{useMinMax.js → useMinMax.ts} +75 -23
- package/src/hooks/{useRightAxis.js → useRightAxis.ts} +10 -2
- package/src/hooks/{useScales.js → useScales.ts} +64 -17
- package/src/hooks/useTooltip.jsx +68 -41
- package/src/scss/main.scss +3 -35
- package/src/types/ChartConfig.ts +43 -0
- package/src/types/ChartContext.ts +38 -0
- package/src/types/ChartProps.ts +7 -0
- package/src/types/ForestPlot.ts +60 -0
|
@@ -1,20 +1,44 @@
|
|
|
1
|
-
import React, { useContext } from 'react'
|
|
1
|
+
import React, { useContext, useState } from 'react'
|
|
2
2
|
import ConfigContext from '../ConfigContext'
|
|
3
3
|
import { useBarChart } from '../hooks/useBarChart'
|
|
4
4
|
import { Group } from '@visx/group'
|
|
5
5
|
import { Text } from '@visx/text'
|
|
6
6
|
import { BarGroup } from '@visx/shape'
|
|
7
7
|
import { useHighlightedBars } from '../hooks/useHighlightedBars'
|
|
8
|
+
import { FaStar } from 'react-icons/fa'
|
|
8
9
|
|
|
9
10
|
// third party
|
|
10
11
|
import chroma from 'chroma-js'
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
import { type BarChartProps } from '../types/ChartProps'
|
|
14
|
+
|
|
15
|
+
export const BarChartVertical = (props: BarChartProps) => {
|
|
13
16
|
const { xScale, yScale, xMax, yMax, seriesScale } = props
|
|
14
|
-
|
|
15
|
-
const
|
|
17
|
+
|
|
18
|
+
const [barWidth, setBarWidth] = useState(0)
|
|
19
|
+
const [totalBarsInGroup, setTotalBarsInGroup] = useState(0)
|
|
20
|
+
|
|
21
|
+
const { barBorderWidth, hasMultipleSeries, applyRadius, updateBars, assignColorsToValues, section, lollipopBarWidth, lollipopShapeSize, getHighlightedBarColorByValue, getHighlightedBarByValue, generateIconSize, getAdditionalColumn, hoveredBar, onMouseOverBar, onMouseLeaveBar } = useBarChart()
|
|
22
|
+
|
|
23
|
+
// CONTEXT VALUES
|
|
24
|
+
// prettier-ignore
|
|
25
|
+
const { colorScale, config, formatDate, formatNumber, getXAxisData, getYAxisData, isNumber, parseDate, seriesHighlight, setSharedFilter, transformedData, dashboardConfig, setSeriesHighlight } = useContext(ConfigContext)
|
|
26
|
+
|
|
27
|
+
const { runtime } = config
|
|
28
|
+
|
|
16
29
|
const { HighLightedBarUtils } = useHighlightedBars(config)
|
|
30
|
+
const data = config.brush.active && config.brush.data?.length ? config.brush.data : transformedData
|
|
17
31
|
|
|
32
|
+
const getIcon = (bar, barWidth) => {
|
|
33
|
+
let icon = null
|
|
34
|
+
const iconSize = generateIconSize(barWidth)
|
|
35
|
+
config.suppressedData?.forEach(d => {
|
|
36
|
+
if (bar.key === d.column && String(bar.value) === String(d.value) && d.icon) {
|
|
37
|
+
icon = <FaStar color='#000' size={iconSize} />
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
return icon
|
|
41
|
+
}
|
|
18
42
|
return (
|
|
19
43
|
config.visualizationSubType !== 'stacked' &&
|
|
20
44
|
(config.visualizationType === 'Bar' || config.visualizationType === 'Combo') &&
|
|
@@ -33,16 +57,20 @@ export const BarChartVertical = props => {
|
|
|
33
57
|
}}
|
|
34
58
|
>
|
|
35
59
|
{barGroups => {
|
|
36
|
-
return
|
|
60
|
+
return barGroups.map((barGroup, index) => (
|
|
37
61
|
<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={(xMax / barGroups.length) * barGroup.index}>
|
|
38
62
|
{barGroup.bars.map((bar, index) => {
|
|
39
63
|
const scaleVal = config.useLogScale ? 0.1 : 0
|
|
64
|
+
const suppresedBarHeight = 20
|
|
40
65
|
let highlightedBarValues = config.highlightedBarValues.map(item => item.value).filter(item => item !== ('' || undefined))
|
|
41
66
|
highlightedBarValues = config.xAxis.type === 'date' ? HighLightedBarUtils.formatDates(highlightedBarValues) : highlightedBarValues
|
|
42
67
|
let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
|
|
43
68
|
let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
|
|
44
|
-
let
|
|
45
|
-
let
|
|
69
|
+
let barHeightBase = Math.abs(yScale(bar.value) - yScale(scaleVal))
|
|
70
|
+
let barYBase = bar.value >= 0 && isNumber(bar.value) ? bar.y : yScale(0)
|
|
71
|
+
const supprssedBarY = bar.value >= 0 && isNumber(bar.value) ? yScale(scaleVal) - suppresedBarHeight : yScale(0)
|
|
72
|
+
const barY = config.suppressedData.some(d => bar.key === d.column && String(bar.value) === String(d.value)) ? supprssedBarY : barYBase
|
|
73
|
+
|
|
46
74
|
let barGroupWidth = (xMax / barGroups.length) * (config.barThickness || 0.8)
|
|
47
75
|
let offset = ((xMax / barGroups.length) * (1 - (config.barThickness || 0.8))) / 2
|
|
48
76
|
// configure left side offset of lollipop bars
|
|
@@ -51,6 +79,8 @@ export const BarChartVertical = props => {
|
|
|
51
79
|
}
|
|
52
80
|
|
|
53
81
|
let barWidth = config.isLollipopChart ? lollipopBarWidth : barGroupWidth / barGroup.bars.length
|
|
82
|
+
setBarWidth(barWidth)
|
|
83
|
+
setTotalBarsInGroup(barGroup.bars.length)
|
|
54
84
|
|
|
55
85
|
let yAxisValue = formatNumber(bar.value, 'left')
|
|
56
86
|
let xAxisValue = config.runtime[section].type === 'date' ? formatDate(parseDate(data[barGroup.index][config.runtime.originalXAxis.dataKey])) : data[barGroup.index][config.runtime.originalXAxis.dataKey]
|
|
@@ -58,18 +88,15 @@ export const BarChartVertical = props => {
|
|
|
58
88
|
// create new Index for bars with negative values
|
|
59
89
|
const newIndex = bar.value < 0 ? -1 : index
|
|
60
90
|
const borderRadius = applyRadius(newIndex)
|
|
61
|
-
|
|
62
|
-
|
|
91
|
+
// tooltips
|
|
92
|
+
const additionalColTooltip = getAdditionalColumn(hoveredBar)
|
|
63
93
|
let xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${xAxisValue}` : xAxisValue
|
|
64
|
-
|
|
65
|
-
if (!hasMultipleSeries) {
|
|
66
|
-
yAxisTooltip = config.isLegendValue ? `${bar.key}: ${yAxisValue}` : config.runtime.yAxis.label ? `${config.runtime.yAxis.label}: ${yAxisValue}` : yAxisValue
|
|
67
|
-
}
|
|
94
|
+
const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${yAxisValue}`
|
|
68
95
|
|
|
69
96
|
const tooltip = `<ul>
|
|
70
|
-
|
|
71
|
-
<li class="tooltip-
|
|
72
|
-
|
|
97
|
+
<li class="tooltip-heading">${xAxisTooltip}</li>
|
|
98
|
+
<li class="tooltip-body ">${tooltipBody}</li>
|
|
99
|
+
<li class="tooltip-body ">${additionalColTooltip}</li>
|
|
73
100
|
</li></ul>`
|
|
74
101
|
|
|
75
102
|
// configure colors
|
|
@@ -84,19 +111,76 @@ export const BarChartVertical = props => {
|
|
|
84
111
|
const highlightedBar = getHighlightedBarByValue(xAxisValue)
|
|
85
112
|
const borderColor = isHighlightedBar ? highlightedBarColor : config.barHasBorder === 'true' ? '#000' : 'transparent'
|
|
86
113
|
const borderWidth = isHighlightedBar ? highlightedBar.borderWidth : config.isLollipopChart ? 0 : config.barHasBorder === 'true' ? barBorderWidth : 0
|
|
114
|
+
const barValueLabel = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? '' : yAxisValue
|
|
115
|
+
let barHeight = config.suppressedData.some(d => bar.key === d.column && String(bar.value) === String(d.value)) ? suppresedBarHeight : barHeightBase
|
|
116
|
+
const displaylollipopShape = config.suppressedData.some(d => bar.key === d.column && bar.value === d.value) ? 'none' : 'block'
|
|
117
|
+
|
|
118
|
+
const getBarBackgroundColor = (barColor: string, filteredOutColor?: string): string => {
|
|
119
|
+
let _barColor = barColor
|
|
120
|
+
let _filteredOutColor = filteredOutColor || '#f2f2f2'
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* If this is a dashboard using a setBy column on the bars
|
|
124
|
+
* color the bar that is using the filter with barColor and
|
|
125
|
+
* color the filteredOut (typically gray) bars with the filteredOutColor
|
|
126
|
+
*/
|
|
127
|
+
if (dashboardConfig && dashboardConfig.dashboard.sharedFilters) {
|
|
128
|
+
const { sharedFilters } = dashboardConfig.dashboard
|
|
129
|
+
|
|
130
|
+
_barColor = sharedFilters.map(_sharedFilter => {
|
|
131
|
+
if (_sharedFilter.setBy === config.uid) {
|
|
132
|
+
// If the current filter is the reset filter item.
|
|
133
|
+
if (_sharedFilter.resetLabel === _sharedFilter.active) return barColor
|
|
134
|
+
// If the current filter is the bars
|
|
135
|
+
if (_sharedFilter.active === transformedData[barGroup.index][config.xAxis.dataKey]) return barColor
|
|
136
|
+
return _filteredOutColor
|
|
137
|
+
} else {
|
|
138
|
+
// If the setBy isn't the config.uid return the original barColor
|
|
139
|
+
return barColor
|
|
140
|
+
}
|
|
141
|
+
})[0]
|
|
142
|
+
|
|
143
|
+
if (isRegularLollipopColor) _barColor = barColor
|
|
144
|
+
if (isTwoToneLollipopColor) _barColor = chroma(barColor).brighten(1)
|
|
145
|
+
if (isHighlightedBar) _barColor = 'transparent'
|
|
146
|
+
return _barColor
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// if this is a two tone lollipop slightly lighten the bar.
|
|
150
|
+
if (isTwoToneLollipopColor) _barColor = chroma(barColor).brighten(1)
|
|
151
|
+
|
|
152
|
+
// if we're highlighting a bar make it invisible since it gets a border
|
|
153
|
+
if (isHighlightedBar) _barColor = 'transparent'
|
|
154
|
+
return _barColor
|
|
155
|
+
}
|
|
87
156
|
|
|
88
|
-
const
|
|
89
|
-
if (
|
|
90
|
-
if (
|
|
91
|
-
if (
|
|
92
|
-
return
|
|
157
|
+
const getLeft = () => {
|
|
158
|
+
if (barWidth < 50 && barWidth > 15) return barWidth / 2.5
|
|
159
|
+
if (barWidth < 15 && barWidth > 5) return barWidth / 6
|
|
160
|
+
if (barWidth < 5) return 0
|
|
161
|
+
return barWidth / 2
|
|
93
162
|
}
|
|
163
|
+
const iconStyle: { [key: string]: any } = {
|
|
164
|
+
position: 'absolute',
|
|
165
|
+
top: bar.value >= 0 && isNumber(bar.value) ? -suppresedBarHeight : undefined,
|
|
166
|
+
bottom: bar.value >= 0 && isNumber(bar.value) ? undefined : `-${suppresedBarHeight}px`,
|
|
167
|
+
left: getLeft()
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (config.isLollipopChart) {
|
|
171
|
+
iconStyle.left = 0
|
|
172
|
+
iconStyle.transform = `translateX(0)`
|
|
173
|
+
}
|
|
174
|
+
|
|
94
175
|
const finalStyle = {
|
|
95
|
-
background:
|
|
176
|
+
background: getBarBackgroundColor(barColor),
|
|
96
177
|
borderColor,
|
|
97
178
|
borderStyle: 'solid',
|
|
98
|
-
borderWidth
|
|
99
|
-
|
|
179
|
+
borderWidth: `${borderWidth}px`,
|
|
180
|
+
width: barWidth,
|
|
181
|
+
height: barHeight,
|
|
182
|
+
...borderRadius,
|
|
183
|
+
cursor: dashboardConfig ? 'pointer' : 'default'
|
|
100
184
|
}
|
|
101
185
|
|
|
102
186
|
return (
|
|
@@ -104,22 +188,24 @@ export const BarChartVertical = props => {
|
|
|
104
188
|
{/* This feels gross but inline transition was not working well*/}
|
|
105
189
|
<style>
|
|
106
190
|
{`
|
|
107
|
-
.linear #barGroup${barGroup.index},
|
|
108
|
-
.Combo #barGroup${barGroup.index} {
|
|
191
|
+
.linear #barGroup${barGroup.index} div,
|
|
192
|
+
.Combo #barGroup${barGroup.index} div {
|
|
109
193
|
transform-origin: 0 ${barY + barHeight}px;
|
|
110
194
|
}
|
|
111
195
|
`}
|
|
112
196
|
</style>
|
|
113
197
|
<Group key={`bar-sub-group-${barGroup.index}-${barGroup.x0}-${barY}--${index}`}>
|
|
114
198
|
<foreignObject
|
|
199
|
+
onMouseOver={() => onMouseOverBar(xAxisValue, bar.key)}
|
|
200
|
+
onMouseLeave={onMouseLeaveBar}
|
|
201
|
+
style={{ overflow: 'visible', transition: 'all 0.2s linear' }}
|
|
115
202
|
id={`barGroup${barGroup.index}`}
|
|
116
203
|
key={`bar-group-bar-${barGroup.index}-${bar.index}-${bar.value}-${bar.key}`}
|
|
117
204
|
x={barWidth * bar.index + offset}
|
|
118
205
|
y={barY}
|
|
119
206
|
width={barWidth}
|
|
120
207
|
height={barHeight}
|
|
121
|
-
|
|
122
|
-
opacity={transparentBar ? 0.5 : 1}
|
|
208
|
+
opacity={transparentBar ? 0.2 : 1}
|
|
123
209
|
display={displayBar ? 'block' : 'none'}
|
|
124
210
|
data-tooltip-html={tooltip}
|
|
125
211
|
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
@@ -130,14 +216,27 @@ export const BarChartVertical = props => {
|
|
|
130
216
|
setSharedFilter(config.uid, bar)
|
|
131
217
|
}
|
|
132
218
|
}}
|
|
133
|
-
|
|
219
|
+
>
|
|
220
|
+
<div style={{ position: 'relative' }}>
|
|
221
|
+
<div style={iconStyle}>{getIcon(bar, barWidth)}</div>
|
|
222
|
+
<div style={{ ...finalStyle }}></div>
|
|
223
|
+
</div>
|
|
224
|
+
</foreignObject>
|
|
134
225
|
|
|
135
|
-
<Text
|
|
136
|
-
{
|
|
226
|
+
<Text // prettier-ignore
|
|
227
|
+
display={config.labels && displayBar ? 'block' : 'none'}
|
|
228
|
+
opacity={transparentBar ? 0.5 : 1}
|
|
229
|
+
x={barWidth * (bar.index + 0.5) + offset}
|
|
230
|
+
y={barY - 5}
|
|
231
|
+
fill={labelColor}
|
|
232
|
+
textAnchor='middle'
|
|
233
|
+
>
|
|
234
|
+
{barValueLabel}
|
|
137
235
|
</Text>
|
|
138
236
|
|
|
139
237
|
{config.isLollipopChart && config.lollipopShape === 'circle' && (
|
|
140
238
|
<circle
|
|
239
|
+
display={displaylollipopShape}
|
|
141
240
|
cx={barWidth * (barGroup.bars.length - bar.index - 1) + offset + lollipopShapeSize / 3.5}
|
|
142
241
|
cy={bar.y}
|
|
143
242
|
r={lollipopShapeSize / 2}
|
|
@@ -150,6 +249,7 @@ export const BarChartVertical = props => {
|
|
|
150
249
|
)}
|
|
151
250
|
{config.isLollipopChart && config.lollipopShape === 'square' && (
|
|
152
251
|
<rect
|
|
252
|
+
display={displaylollipopShape}
|
|
153
253
|
x={offset - lollipopBarWidth / 2}
|
|
154
254
|
y={barY}
|
|
155
255
|
width={lollipopShapeSize}
|
|
@@ -197,6 +297,50 @@ export const BarChartVertical = props => {
|
|
|
197
297
|
)
|
|
198
298
|
})
|
|
199
299
|
: ''}
|
|
300
|
+
|
|
301
|
+
{config.regions && config.visualizationType !== 'Combo'
|
|
302
|
+
? config.regions.map(region => {
|
|
303
|
+
if (!Object.keys(region).includes('from') || !Object.keys(region).includes('to')) return null
|
|
304
|
+
|
|
305
|
+
let from
|
|
306
|
+
let to
|
|
307
|
+
let width
|
|
308
|
+
|
|
309
|
+
if (config.xAxis.type === 'date') {
|
|
310
|
+
from = xScale(parseDate(region.from).getTime()) - (barWidth * totalBarsInGroup) / 2
|
|
311
|
+
to = xScale(parseDate(region.to).getTime()) + (barWidth * totalBarsInGroup) / 2
|
|
312
|
+
|
|
313
|
+
width = to - from
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (config.xAxis.type === 'categorical') {
|
|
317
|
+
from = xScale(region.from)
|
|
318
|
+
to = xScale(region.to)
|
|
319
|
+
width = to - from
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (!from) return null
|
|
323
|
+
if (!to) return null
|
|
324
|
+
|
|
325
|
+
return (
|
|
326
|
+
<Group className='regions' left={0} key={region.label}>
|
|
327
|
+
<path
|
|
328
|
+
stroke='#333'
|
|
329
|
+
d={`M${from} -5
|
|
330
|
+
L${from} 5
|
|
331
|
+
M${from} 0
|
|
332
|
+
L${to} 0
|
|
333
|
+
M${to} -5
|
|
334
|
+
L${to} 5`}
|
|
335
|
+
/>
|
|
336
|
+
<rect x={from} y={0} width={width} height={yMax} fill={region.background} opacity={0.3} />
|
|
337
|
+
<Text x={from + width / 2} y={5} fill={region.color} verticalAnchor='start' textAnchor='middle'>
|
|
338
|
+
{region.label}
|
|
339
|
+
</Text>
|
|
340
|
+
</Group>
|
|
341
|
+
)
|
|
342
|
+
})
|
|
343
|
+
: ''}
|
|
200
344
|
</Group>
|
|
201
345
|
)
|
|
202
346
|
)
|
|
@@ -21,7 +21,7 @@ const BarChart = ({ xScale, yScale, seriesScale, xMax, yMax, handleTooltipMouseO
|
|
|
21
21
|
<BarChartType.Horizontal xScale={xScale} yScale={yScale} xMax={xMax} yMax={yMax} seriesScale={seriesScale} />
|
|
22
22
|
|
|
23
23
|
{/* tooltips */}
|
|
24
|
-
<Bar key={'bars'} width={Number(xMax)} height={Number(yMax)} fill={
|
|
24
|
+
<Bar key={'bars'} display={config.tooltips.singleSeries ? 'none' : 'block'} width={Number(xMax)} height={Number(yMax)} fill={'transparent'} fillOpacity={0.05} onMouseMove={e => handleTooltipMouseOver(e, data)} onMouseOut={handleTooltipMouseOff} onClick={e => handleTooltipClick(e, data)} />
|
|
25
25
|
</Group>
|
|
26
26
|
</ErrorBoundary>
|
|
27
27
|
)
|
|
@@ -125,7 +125,7 @@ export default function DeviationBar({ height, xScale }) {
|
|
|
125
125
|
})
|
|
126
126
|
}, [config.animate, config, animatedChart])
|
|
127
127
|
|
|
128
|
-
if (!config || config?.series?.length !== 1) return <></>
|
|
128
|
+
// if (!config || config?.series?.length !== 1) return <></>
|
|
129
129
|
|
|
130
130
|
return (
|
|
131
131
|
<ErrorBoundary component='Deviation Bar'>
|
|
@@ -185,10 +185,11 @@ export default function DeviationBar({ height, xScale }) {
|
|
|
185
185
|
y={barY}
|
|
186
186
|
width={barWidth}
|
|
187
187
|
height={barHeight}
|
|
188
|
-
style={{ border: `${borderWidth}px solid #333`, backgroundColor: barColor[barPosition], ...borderRadius }}
|
|
189
188
|
data-tooltip-html={tooltip}
|
|
190
189
|
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
191
|
-
|
|
190
|
+
>
|
|
191
|
+
<div style={{ width: barWidth, height: barHeight, border: `${borderWidth}px solid #333`, backgroundColor: barColor[barPosition], ...borderRadius }}></div>
|
|
192
|
+
</foreignObject>
|
|
192
193
|
{config.yAxis.displayNumbersOnBar && (
|
|
193
194
|
<Text verticalAnchor='middle' x={textX} y={textY} {...textProps[barPosition]}>
|
|
194
195
|
{formatNumber(d[seriesKey], 'left')}
|