@cdc/chart 4.25.8 → 4.25.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/.claude/settings.local.json +9 -0
- package/dist/{cdcchart-1a1724a1.es.js → cdcchart-dgT_1dIT.es.js} +136 -151
- package/dist/cdcchart.js +44236 -40355
- package/examples/feature/__data__/planet-example-data.json +0 -30
- package/examples/feature/boxplot/valid-boxplot.csv +38 -17
- package/examples/grouped-bar-test.json +400 -0
- package/examples/private/DEV-11825.json +573 -0
- package/examples/private/d.json +382 -0
- package/examples/private/example-2.json +49784 -0
- package/examples/private/f2.json +1 -0
- package/examples/private/f4.json +1577 -0
- package/examples/private/forecast.json +1180 -0
- package/examples/private/lollipop.json +468 -0
- package/examples/private/na.json +913 -0
- package/examples/private/new.json +48756 -0
- package/examples/private/pie-chart-legend.json +904 -0
- package/examples/private/test-data.csv +28 -0
- package/examples/suppressed_tooltip.json +480 -0
- package/index.html +2 -133
- package/package.json +25 -7
- package/src/CdcChart.tsx +9 -13
- package/src/CdcChartComponent.tsx +403 -92
- package/src/_stories/Chart.Anchors.stories.tsx +2 -2
- package/src/_stories/Chart.BoxPlot.stories.tsx +1 -1
- package/src/_stories/Chart.CI.stories.tsx +1 -1
- package/src/_stories/Chart.Combo.stories.tsx +18 -0
- package/src/_stories/Chart.CustomColors.stories.tsx +1 -1
- package/src/_stories/Chart.DynamicSeries.stories.tsx +2 -2
- package/src/_stories/Chart.Filters.stories.tsx +2 -2
- package/src/_stories/Chart.Forecast.stories.tsx +36 -0
- package/src/_stories/Chart.HTMLInDataTable.stories.tsx +520 -0
- package/src/_stories/Chart.Legend.Gradient.stories.tsx +2 -2
- package/src/_stories/Chart.Patterns.stories.tsx +20 -0
- package/src/_stories/Chart.PreserveDecimals.stories.tsx +220 -0
- package/src/_stories/Chart.ScatterPlot.stories.tsx +1 -1
- package/src/_stories/Chart.SmallMultiples.stories.tsx +47 -0
- package/src/_stories/Chart.stories.tsx +8 -5
- package/src/_stories/Chart.tooltip.stories.tsx +1 -1
- package/src/_stories/ChartAnnotation.stories.tsx +7 -4
- package/src/_stories/ChartAxisLabels.stories.tsx +2 -2
- package/src/_stories/ChartAxisTitles.stories.tsx +2 -2
- package/src/_stories/ChartBar.Editor.stories.tsx +3580 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +658 -0
- package/src/_stories/ChartEditor.stories.tsx +59 -60
- package/src/_stories/ChartLine.Suppression.stories.tsx +1 -1
- package/src/_stories/ChartLine.Symbols.stories.tsx +1 -1
- package/src/_stories/ChartPrefixSuffix.stories.tsx +2 -2
- package/src/_stories/_mock/combo.json +451 -0
- package/src/_stories/_mock/editor-test-configs.json +376 -0
- package/src/_stories/_mock/editor-test-datasets.json +477 -0
- package/src/_stories/_mock/editor-tests/bar-chart-editor-test.json +255 -0
- package/src/_stories/_mock/editor-tests/bar-chart-general-test.json +267 -0
- package/src/_stories/_mock/editor-tests/bar-chart-test.json +237 -0
- package/src/_stories/_mock/forecast_combo_with_gaps.json +913 -0
- package/src/_stories/_mock/pie_config.json +257 -62
- package/src/_stories/_mock/small_multiples/small_multiples_bars.json +1944 -0
- package/src/_stories/_mock/small_multiples/small_multiples_big_data_bars.json +1114 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +2646 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines_colors.json +1305 -0
- package/src/_stories/_mock/small_multiples/small_multiples_stacked_bars.json +1936 -0
- package/src/_stories/_mock/stacked-pattern-test.json +520 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -0
- package/src/components/Annotations/components/AnnotationDropdown.tsx +1 -1
- package/src/components/Annotations/components/findNearestDatum.ts +6 -41
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -6
- package/src/components/AreaChart/index.tsx +1 -2
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +161 -22
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +138 -5
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +215 -73
- package/src/components/BarChart/components/BarChart.Vertical.tsx +155 -22
- package/src/components/BarChart/helpers/index.ts +43 -4
- package/src/components/BarChart/helpers/lollipopColors.ts +27 -0
- package/src/components/BarChart/helpers/useBarChart.ts +25 -3
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +2 -1
- package/src/components/BoxPlot/helpers/index.ts +3 -3
- package/src/components/Brush/BrushChart.tsx +1 -1
- package/src/components/DeviationBar.jsx +9 -6
- package/src/components/EditorPanel/EditorPanel.tsx +563 -229
- package/src/components/EditorPanel/EditorPanelContext.ts +3 -0
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +96 -111
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +19 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +461 -0
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +80 -67
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +422 -0
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +188 -139
- package/src/components/EditorPanel/components/Panels/index.tsx +5 -1
- package/src/components/EditorPanel/components/Panels/panelVisual.styles.css +0 -8
- package/src/components/EditorPanel/editor-panel.scss +0 -20
- package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +49 -48
- package/src/components/EditorPanel/useEditorPermissions.ts +7 -15
- package/src/components/Forecasting/Forecasting.tsx +175 -27
- package/src/components/ForestPlot/ForestPlot.tsx +11 -7
- package/src/components/ForestPlot/ForestPlotProps.ts +1 -1
- package/src/components/Legend/Legend.Component.tsx +114 -14
- package/src/components/Legend/helpers/createFormatLabels.tsx +230 -171
- package/src/components/Legend/helpers/getLegendClasses.ts +0 -1
- package/src/components/LegendWrapper.tsx +1 -1
- package/src/components/LineChart/LineChartProps.ts +0 -3
- package/src/components/LineChart/components/LineChart.Circle.tsx +2 -2
- package/src/components/LineChart/helpers.ts +1 -1
- package/src/components/LineChart/index.tsx +38 -15
- package/src/components/LinearChart.tsx +96 -84
- package/src/components/PairedBarChart.jsx +6 -4
- package/src/components/PieChart/PieChart.tsx +170 -54
- package/src/components/Regions/components/Regions.tsx +3 -24
- package/src/components/Sankey/components/Sankey.tsx +7 -1
- package/src/components/Sankey/types/index.ts +1 -1
- package/src/components/ScatterPlot/ScatterPlot.jsx +32 -4
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +198 -0
- package/src/components/SmallMultiples/SmallMultiples.css +32 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +271 -0
- package/src/components/SmallMultiples/index.ts +2 -0
- package/src/data/initial-state.js +327 -293
- package/src/helpers/buildForecastPaletteMappings.ts +112 -0
- package/src/helpers/buildForecastPaletteOptions.ts +71 -0
- package/src/helpers/getColorScale.ts +82 -8
- package/src/{hooks/useMinMax.ts → helpers/getMinMax.ts} +14 -7
- package/src/helpers/getNewRuntime.ts +1 -1
- package/src/helpers/getTransformedData.ts +1 -1
- package/src/helpers/getYAxisAutoPadding.ts +53 -0
- package/src/helpers/smallMultiplesHelpers.ts +529 -0
- package/src/hooks/useChartHoverAnalytics.tsx +44 -0
- package/src/hooks/useProgrammaticTooltip.ts +96 -0
- package/src/hooks/useReduceData.ts +105 -70
- package/src/hooks/useScales.ts +88 -34
- package/src/hooks/useSmallMultipleSynchronization.ts +59 -0
- package/src/hooks/useTooltip.tsx +116 -29
- package/src/index.jsx +0 -2
- package/src/scss/main.scss +13 -80
- package/src/store/chart.actions.ts +2 -0
- package/src/store/chart.reducer.ts +5 -1
- package/src/test/CdcChart.test.jsx +8 -3
- package/src/types/ChartConfig.ts +53 -11
- package/src/types/ChartContext.ts +4 -0
- package/vite.config.js +1 -1
- package/vitest.config.ts +16 -0
- package/src/_stories/_mock/pie_data.json +0 -218
- package/src/components/AreaChart/components/AreaChart.jsx +0 -109
- package/src/coreStyles_chart.scss +0 -3
- package/src/helpers/configHelpers.ts +0 -28
- package/src/helpers/generateColorsArray.ts +0 -8
- package/src/helpers/sort.ts +0 -7
- package/src/hooks/useActiveElement.js +0 -19
- package/src/hooks/useChartClasses.js +0 -41
- package/src/hooks/useColorPalette.js +0 -76
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import React, { forwardRef, useContext, useEffect, useMemo, useRef, useState } from 'react'
|
|
1
|
+
import React, { forwardRef, useContext, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
// Libraries
|
|
4
4
|
import { AxisLeft, AxisBottom, AxisRight, AxisTop } from '@visx/axis'
|
|
5
5
|
import { Group } from '@visx/group'
|
|
6
6
|
import { Line, Bar } from '@visx/shape'
|
|
7
7
|
import { Tooltip as ReactTooltip } from 'react-tooltip'
|
|
8
|
+
import 'react-tooltip/dist/react-tooltip.css'
|
|
8
9
|
import { Text } from '@visx/text'
|
|
9
10
|
import { useTooltip, TooltipWithBounds } from '@visx/tooltip'
|
|
10
11
|
import _ from 'lodash'
|
|
@@ -35,18 +36,21 @@ import { calcInitialHeight, handleAutoPaddingRight } from '../helpers/sizeHelper
|
|
|
35
36
|
import { filterAndShiftLinearDateTicks } from '../helpers/filterAndShiftLinearDateTicks'
|
|
36
37
|
|
|
37
38
|
// Hooks
|
|
38
|
-
import useMinMax from '../hooks/useMinMax'
|
|
39
39
|
import useReduceData from '../hooks/useReduceData'
|
|
40
40
|
import useRightAxis from '../hooks/useRightAxis'
|
|
41
41
|
import useScales, { getTickValues } from '../hooks/useScales'
|
|
42
|
+
import { useProgrammaticTooltip } from '../hooks/useProgrammaticTooltip'
|
|
43
|
+
import { useSmallMultipleSynchronization } from '../hooks/useSmallMultipleSynchronization'
|
|
42
44
|
|
|
43
45
|
import getTopAxis from '../helpers/getTopAxis'
|
|
44
46
|
import { useTooltip as useCoveTooltip } from '../hooks/useTooltip'
|
|
47
|
+
import { useChartHoverAnalytics } from '../hooks/useChartHoverAnalytics'
|
|
45
48
|
import { useEditorPermissions } from './EditorPanel/useEditorPermissions'
|
|
46
49
|
import Annotation from './Annotations'
|
|
47
50
|
import { BlurStrokeText } from '@cdc/core/components/BlurStrokeText'
|
|
48
51
|
import { countNumOfTicks } from '../helpers/countNumOfTicks'
|
|
49
52
|
import HoverLine from './HoverLine/HoverLine'
|
|
53
|
+
import { SmallMultiples } from './SmallMultiples'
|
|
50
54
|
|
|
51
55
|
type LinearChartProps = {
|
|
52
56
|
parentWidth: number
|
|
@@ -84,20 +88,21 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
84
88
|
config,
|
|
85
89
|
convertLineToBarGraph,
|
|
86
90
|
currentViewport,
|
|
91
|
+
vizViewport,
|
|
87
92
|
dimensions,
|
|
88
93
|
formatDate,
|
|
89
94
|
formatNumber,
|
|
90
95
|
handleChartAriaLabels,
|
|
91
96
|
handleLineType,
|
|
92
97
|
handleDragStateChange,
|
|
98
|
+
interactionLabel,
|
|
93
99
|
isDraggingAnnotation,
|
|
94
100
|
legendRef,
|
|
95
101
|
parseDate,
|
|
96
102
|
parentRef,
|
|
97
103
|
tableData,
|
|
98
104
|
transformedData: data,
|
|
99
|
-
seriesHighlight
|
|
100
|
-
|
|
105
|
+
seriesHighlight
|
|
101
106
|
} = useContext(ConfigContext)
|
|
102
107
|
|
|
103
108
|
// CONFIG
|
|
@@ -116,6 +121,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
116
121
|
dataFormat,
|
|
117
122
|
debugSvg
|
|
118
123
|
} = config
|
|
124
|
+
|
|
119
125
|
const { labelsAboveGridlines, hideAxis, inlineLabel } = config.yAxis
|
|
120
126
|
|
|
121
127
|
// HOOKS % STATES
|
|
@@ -126,7 +132,6 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
126
132
|
const [showHoverLine, setShowHoverLine] = useState(false)
|
|
127
133
|
const [point, setPoint] = useState({ x: 0, y: 0 })
|
|
128
134
|
const [suffixWidth, setSuffixWidth] = useState(0)
|
|
129
|
-
const [yAxisAutoPadding, setYAxisAutoPadding] = useState(0)
|
|
130
135
|
|
|
131
136
|
// REFS
|
|
132
137
|
const axisBottomRef = useRef(null)
|
|
@@ -136,7 +141,6 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
136
141
|
const triggerRef = useRef()
|
|
137
142
|
const xAxisLabelRefs = useRef([])
|
|
138
143
|
const xAxisTitleRef = useRef(null)
|
|
139
|
-
const lastMaxValue = useRef(maxValue)
|
|
140
144
|
const gridLineRefs = useRef([])
|
|
141
145
|
const tooltipRef = useRef(null)
|
|
142
146
|
|
|
@@ -151,11 +155,11 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
151
155
|
const isForestPlot = visualizationType === 'Forest Plot'
|
|
152
156
|
const isDateTime = config.xAxis.type === 'date-time'
|
|
153
157
|
const inlineLabelHasNoSpace = !inlineLabel?.includes(' ')
|
|
154
|
-
const
|
|
158
|
+
const needsYAxisAutoPadding = inlineLabel && !inlineLabelHasNoSpace
|
|
155
159
|
const padding = orientation === 'horizontal' ? Number(config.xAxis.size) : Number(config.yAxis.size)
|
|
156
160
|
const yLabelOffset = isNaN(parseInt(`${runtime.yAxis.labelOffset}`)) ? 0 : parseInt(`${runtime.yAxis.labelOffset}`)
|
|
157
|
-
const tickLabelFontSize = isMobileFontViewport(
|
|
158
|
-
const axisLabelFontSize = isMobileFontViewport(
|
|
161
|
+
const tickLabelFontSize = isMobileFontViewport(vizViewport) ? TICK_LABEL_FONT_SIZE_SMALL : TICK_LABEL_FONT_SIZE
|
|
162
|
+
const axisLabelFontSize = isMobileFontViewport(vizViewport) ? AXIS_LABEL_FONT_SIZE_SMALL : AXIS_LABEL_FONT_SIZE
|
|
159
163
|
const GET_TEXT_WIDTH_FONT = `normal ${tickLabelFontSize}px Nunito, sans-serif`
|
|
160
164
|
|
|
161
165
|
// zero if not forest plot
|
|
@@ -204,7 +208,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
204
208
|
const xMax = width - runtime.yAxis.size - (visualizationType === 'Combo' ? config.yAxis.rightAxisSize : 0)
|
|
205
209
|
const yMax = initialHeight + forestRowsHeight
|
|
206
210
|
|
|
207
|
-
const isNoDataAvailable = config.filters
|
|
211
|
+
const isNoDataAvailable = config.filters?.length > 0 && data.length === 0
|
|
208
212
|
|
|
209
213
|
const getXAxisData = d =>
|
|
210
214
|
isDateScale(config.runtime.xAxis)
|
|
@@ -212,39 +216,37 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
212
216
|
: d[config.runtime.originalXAxis.dataKey]
|
|
213
217
|
const getYAxisData = (d, seriesKey) => d[seriesKey]
|
|
214
218
|
const xAxisDataMapped = data.map(d => getXAxisData(d))
|
|
215
|
-
const
|
|
216
|
-
|
|
219
|
+
const { yScaleRight, hasRightAxis } = useRightAxis({ config, yMax, data })
|
|
220
|
+
|
|
221
|
+
const {
|
|
222
|
+
xScale,
|
|
223
|
+
yScale,
|
|
224
|
+
seriesScale,
|
|
225
|
+
g1xScale,
|
|
226
|
+
g2xScale,
|
|
227
|
+
xScaleNoPadding,
|
|
228
|
+
xScaleAnnotation,
|
|
229
|
+
min,
|
|
230
|
+
max,
|
|
231
|
+
leftMax,
|
|
232
|
+
rightMax
|
|
233
|
+
} = useScales({
|
|
217
234
|
data,
|
|
218
235
|
tableData,
|
|
219
|
-
config
|
|
220
|
-
...config,
|
|
221
|
-
yAxis: {
|
|
222
|
-
...config.yAxis,
|
|
223
|
-
scalePadding: labelsOverflow ? yAxisAutoPadding : config.yAxis.scalePadding,
|
|
224
|
-
enablePadding: labelsOverflow || config.yAxis.enablePadding
|
|
225
|
-
}
|
|
226
|
-
},
|
|
236
|
+
config,
|
|
227
237
|
minValue,
|
|
228
238
|
maxValue,
|
|
229
239
|
isAllLine,
|
|
230
240
|
existPositiveValue,
|
|
231
241
|
xAxisDataMapped,
|
|
232
|
-
|
|
233
|
-
yMax
|
|
234
|
-
}
|
|
235
|
-
const { min, max, leftMax, rightMax } = useMinMax(properties)
|
|
236
|
-
const { yScaleRight, hasRightAxis } = useRightAxis({ config, yMax, data })
|
|
237
|
-
const { xScale, yScale, seriesScale, g1xScale, g2xScale, xScaleNoPadding, xScaleAnnotation } = useScales({
|
|
238
|
-
...properties,
|
|
239
|
-
min,
|
|
240
|
-
max,
|
|
241
|
-
leftMax,
|
|
242
|
-
rightMax,
|
|
242
|
+
yMax,
|
|
243
243
|
dimensions,
|
|
244
244
|
xMax:
|
|
245
245
|
parentWidth -
|
|
246
246
|
Number(config.orientation === 'horizontal' ? config.xAxis.size : config.yAxis.size) -
|
|
247
|
-
(hasRightAxis ? config.yAxis.rightAxisSize : 0)
|
|
247
|
+
(hasRightAxis ? config.yAxis.rightAxisSize : 0),
|
|
248
|
+
needsYAxisAutoPadding,
|
|
249
|
+
currentViewport
|
|
248
250
|
})
|
|
249
251
|
|
|
250
252
|
const [yTickCount, xTickCount] = ['yAxis', 'xAxis'].map(axis =>
|
|
@@ -263,13 +265,23 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
263
265
|
handleTooltipClick,
|
|
264
266
|
handleTooltipMouseOff,
|
|
265
267
|
TooltipListItem,
|
|
268
|
+
getXValueFromCoordinate,
|
|
269
|
+
getCoordinateFromXValue,
|
|
266
270
|
} = useCoveTooltip({
|
|
267
271
|
xScale,
|
|
268
272
|
yScale,
|
|
269
273
|
seriesScale,
|
|
270
274
|
showTooltip,
|
|
271
|
-
hideTooltip
|
|
275
|
+
hideTooltip,
|
|
276
|
+
interactionLabel
|
|
277
|
+
})
|
|
278
|
+
|
|
279
|
+
// Analytics tracking for chart hover
|
|
280
|
+
const { handleChartMouseEnter, handleChartMouseLeave } = useChartHoverAnalytics({
|
|
281
|
+
config,
|
|
282
|
+
interactionLabel
|
|
272
283
|
})
|
|
284
|
+
|
|
273
285
|
// get the number of months between the first and last date
|
|
274
286
|
const { dataKey } = runtime.xAxis
|
|
275
287
|
const dateSpanMonths =
|
|
@@ -339,6 +351,8 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
339
351
|
return manualStep
|
|
340
352
|
}
|
|
341
353
|
|
|
354
|
+
const smallMultiplesSync = useSmallMultipleSynchronization(xMax, yMax, getXValueFromCoordinate)
|
|
355
|
+
|
|
342
356
|
const onMouseMove = event => {
|
|
343
357
|
const svgRect = event.currentTarget.getBoundingClientRect()
|
|
344
358
|
const x = event.clientX - svgRect.left
|
|
@@ -348,8 +362,25 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
348
362
|
x,
|
|
349
363
|
y
|
|
350
364
|
})
|
|
365
|
+
|
|
366
|
+
smallMultiplesSync.onMouseMove?.(event)
|
|
351
367
|
}
|
|
352
368
|
|
|
369
|
+
const onMouseLeave = () => {
|
|
370
|
+
smallMultiplesSync.onMouseLeave?.()
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// Use custom hook to provide programmatic tooltip control for small multiples
|
|
374
|
+
const internalSvgRef = useProgrammaticTooltip({
|
|
375
|
+
svgRef,
|
|
376
|
+
getCoordinateFromXValue,
|
|
377
|
+
config,
|
|
378
|
+
setPoint,
|
|
379
|
+
setShowHoverLine,
|
|
380
|
+
handleTooltipMouseOver,
|
|
381
|
+
hideTooltip
|
|
382
|
+
})
|
|
383
|
+
|
|
353
384
|
// EFFECTS
|
|
354
385
|
// Adjust padding on the right side of the chart to accommodate for overflow
|
|
355
386
|
useEffect(() => {
|
|
@@ -438,7 +469,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
438
469
|
if (!topLabelOnGridlineHeight) return
|
|
439
470
|
|
|
440
471
|
// Adjust the viewBox for the svg
|
|
441
|
-
const svg =
|
|
472
|
+
const svg = internalSvgRef.current
|
|
442
473
|
if (!svg) return
|
|
443
474
|
const parentWidthFromRef = parentRef.current.getBoundingClientRect().width
|
|
444
475
|
svg.setAttribute('viewBox', `0 ${-topLabelOnGridlineHeight} ${parentWidthFromRef} ${newHeight}`)
|
|
@@ -458,45 +489,6 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
458
489
|
initialHeight
|
|
459
490
|
])
|
|
460
491
|
|
|
461
|
-
useEffect(() => {
|
|
462
|
-
if (lastMaxValue.current === maxValue) return
|
|
463
|
-
lastMaxValue.current = maxValue
|
|
464
|
-
|
|
465
|
-
if (!yAxisAutoPadding) return
|
|
466
|
-
setYAxisAutoPadding(0)
|
|
467
|
-
}, [maxValue])
|
|
468
|
-
|
|
469
|
-
useEffect(() => {
|
|
470
|
-
if (!yScale?.ticks) return
|
|
471
|
-
const ticks = yScale.ticks(handleNumTicks)
|
|
472
|
-
if (orientation === 'horizontal' || !labelsOverflow || config.yAxis?.max || ticks.length === 0) {
|
|
473
|
-
setYAxisAutoPadding(0)
|
|
474
|
-
return
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// minimum percentage of the max value that the distance should be from the top grid line
|
|
478
|
-
const MINIMUM_DISTANCE_PERCENTAGE = 0.025
|
|
479
|
-
|
|
480
|
-
const topGridLine = Math.max(...ticks)
|
|
481
|
-
const needsPaddingThreshold = topGridLine - maxValue * MINIMUM_DISTANCE_PERCENTAGE
|
|
482
|
-
const maxValueIsGreaterThanThreshold = maxValue > needsPaddingThreshold
|
|
483
|
-
|
|
484
|
-
if (!maxValueIsGreaterThanThreshold) return
|
|
485
|
-
|
|
486
|
-
const tickGap = ticks.length === 1 ? ticks[0] : ticks[1] - ticks[0]
|
|
487
|
-
const nextTick = Math.max(...yScale.ticks(handleNumTicks)) + tickGap
|
|
488
|
-
const divideBy = minValue < 0 ? maxValue / 2 : maxValue
|
|
489
|
-
const calculatedPadding = (nextTick - maxValue) / divideBy
|
|
490
|
-
|
|
491
|
-
// if auto padding is too close to next tick, add one more ticks worth of padding
|
|
492
|
-
const newPadding =
|
|
493
|
-
calculatedPadding > MINIMUM_DISTANCE_PERCENTAGE ? calculatedPadding : calculatedPadding + tickGap / divideBy
|
|
494
|
-
|
|
495
|
-
/* sometimes even though the padding is getting to the next tick exactly,
|
|
496
|
-
d3 still doesn't show the tick. we add 0.1 to ensure to tip it over the edge */
|
|
497
|
-
setYAxisAutoPadding(newPadding * 100 + 0.1)
|
|
498
|
-
}, [maxValue, labelsOverflow, yScale, handleNumTicks])
|
|
499
|
-
|
|
500
492
|
useEffect(() => {
|
|
501
493
|
if (!tooltipOpen) return
|
|
502
494
|
if (!tooltipRef.current) return
|
|
@@ -514,6 +506,19 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
514
506
|
tooltipRef.current.node.style.maxWidth = `${maxWidth}px`
|
|
515
507
|
}, [tooltipOpen, tooltipData])
|
|
516
508
|
|
|
509
|
+
// Check if small multiples are enabled - if so, render SmallMultiples instead
|
|
510
|
+
if (config.smallMultiples?.mode) {
|
|
511
|
+
return (
|
|
512
|
+
<SmallMultiples
|
|
513
|
+
config={config}
|
|
514
|
+
data={data}
|
|
515
|
+
svgRef={svgRef}
|
|
516
|
+
parentWidth={parentWidth}
|
|
517
|
+
parentHeight={parentHeight}
|
|
518
|
+
/>
|
|
519
|
+
)
|
|
520
|
+
}
|
|
521
|
+
|
|
517
522
|
// Render Functions
|
|
518
523
|
const generatePairedBarAxis = () => {
|
|
519
524
|
const axisMaxHeight = bottomLabelStart + BOTTOM_LABEL_PADDING
|
|
@@ -648,7 +653,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
648
653
|
verticalAnchor='start'
|
|
649
654
|
fontSize={axisLabelFontSize}
|
|
650
655
|
>
|
|
651
|
-
{runtime.xAxis.label}
|
|
656
|
+
{!config.hideXAxisLabel ? runtime.xAxis.label : null}
|
|
652
657
|
</Text>
|
|
653
658
|
</Group>
|
|
654
659
|
</>
|
|
@@ -668,7 +673,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
668
673
|
className='tooltip-boundary'
|
|
669
674
|
>
|
|
670
675
|
<svg
|
|
671
|
-
ref={
|
|
676
|
+
ref={internalSvgRef}
|
|
672
677
|
onMouseMove={onMouseMove}
|
|
673
678
|
width={parentWidth + config.yAxis.rightAxisSize}
|
|
674
679
|
height={isNoDataAvailable ? 1 : parentHeight}
|
|
@@ -678,8 +683,15 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
678
683
|
role='img'
|
|
679
684
|
aria-label={handleChartAriaLabels(config)}
|
|
680
685
|
style={{ overflow: 'visible' }}
|
|
681
|
-
onMouseLeave={() =>
|
|
682
|
-
|
|
686
|
+
onMouseLeave={() => {
|
|
687
|
+
setShowHoverLine(false)
|
|
688
|
+
handleChartMouseLeave()
|
|
689
|
+
onMouseLeave()
|
|
690
|
+
}}
|
|
691
|
+
onMouseEnter={() => {
|
|
692
|
+
setShowHoverLine(true)
|
|
693
|
+
handleChartMouseEnter()
|
|
694
|
+
}}
|
|
683
695
|
>
|
|
684
696
|
{!isDraggingAnnotation && <Bar width={parentWidth} height={initialHeight} fill={'transparent'}></Bar>}{' '}
|
|
685
697
|
{/* GRID LINES */}
|
|
@@ -693,7 +705,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
693
705
|
{props => {
|
|
694
706
|
const axisCenter =
|
|
695
707
|
config.orientation === 'horizontal'
|
|
696
|
-
? (props.axisToPoint.y - props.axisFromPoint.y) / 2
|
|
708
|
+
? Math.abs(props.axisToPoint.y - props.axisFromPoint.y) / 2
|
|
697
709
|
: (props.axisFromPoint.y - props.axisToPoint.y) / 2
|
|
698
710
|
return (
|
|
699
711
|
<Group className='left-axis'>
|
|
@@ -727,7 +739,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
727
739
|
fill={config.yAxis.labelColor}
|
|
728
740
|
fontSize={axisLabelFontSize}
|
|
729
741
|
>
|
|
730
|
-
{props.label}
|
|
742
|
+
{!config.hideYAxisLabel ? props.label : null}
|
|
731
743
|
</Text>
|
|
732
744
|
</Group>
|
|
733
745
|
)
|
|
@@ -1027,7 +1039,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
1027
1039
|
{props => {
|
|
1028
1040
|
const axisCenter =
|
|
1029
1041
|
config.orientation === 'horizontal'
|
|
1030
|
-
? (props.axisToPoint.y - props.axisFromPoint.y) / 2
|
|
1042
|
+
? Math.abs(props.axisToPoint.y - props.axisFromPoint.y) / 2
|
|
1031
1043
|
: (props.axisFromPoint.y - props.axisToPoint.y) / 2
|
|
1032
1044
|
const horizontalTickOffset =
|
|
1033
1045
|
yMax / props.ticks.length / 2 - (yMax / props.ticks.length) * (1 - config.barThickness) + 5
|
|
@@ -1289,7 +1301,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
1289
1301
|
fill={config.yAxis.labelColor}
|
|
1290
1302
|
fontSize={axisLabelFontSize}
|
|
1291
1303
|
>
|
|
1292
|
-
{props.label}
|
|
1304
|
+
{!config.hideYAxisLabel ? props.label : null}
|
|
1293
1305
|
</Text>
|
|
1294
1306
|
</Group>
|
|
1295
1307
|
)
|
|
@@ -1403,7 +1415,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
1403
1415
|
: yMax
|
|
1404
1416
|
}
|
|
1405
1417
|
left={config.visualizationType !== 'Forest Plot' ? Number(runtime.yAxis.size) : 0}
|
|
1406
|
-
label={
|
|
1418
|
+
label={runtime.xAxis.label}
|
|
1407
1419
|
tickFormat={handleBottomTickFormatting}
|
|
1408
1420
|
scale={xScale}
|
|
1409
1421
|
stroke='#333'
|
|
@@ -1537,7 +1549,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
1537
1549
|
verticalAnchor={tickRotation < -50 ? 'middle' : 'start'}
|
|
1538
1550
|
textAnchor={tickRotation ? 'end' : 'middle'}
|
|
1539
1551
|
width={
|
|
1540
|
-
areTicksTouching && !config.isResponsiveTicks && !Number(config
|
|
1552
|
+
areTicksTouching && !config.isResponsiveTicks && !Number(config.xAxis.tickRotation)
|
|
1541
1553
|
? limitedWidth
|
|
1542
1554
|
: undefined
|
|
1543
1555
|
}
|
|
@@ -1562,7 +1574,7 @@ const LinearChart = forwardRef<SVGAElement, LinearChartProps>(({ parentHeight, p
|
|
|
1562
1574
|
fill={config.xAxis.labelColor}
|
|
1563
1575
|
fontSize={axisLabelFontSize}
|
|
1564
1576
|
>
|
|
1565
|
-
{props.label}
|
|
1577
|
+
{!config.hideXAxisLabel ? props.label : null}
|
|
1566
1578
|
</Text>
|
|
1567
1579
|
</Group>
|
|
1568
1580
|
)
|
|
@@ -113,7 +113,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
113
113
|
const textFits = textWidth < barWidth - 5 // minus padding dx(5)
|
|
114
114
|
|
|
115
115
|
return (
|
|
116
|
-
|
|
116
|
+
<React.Fragment key={`fragment-group1-${groupOne.dataKey}-${index}`}>
|
|
117
117
|
<Group key={`group-${groupOne.dataKey}-${d[config.xAxis.dataKey]}`} className='horizontal'>
|
|
118
118
|
<Bar
|
|
119
119
|
id={`bar-${groupOne.dataKey}-${d[config.dataDescription?.xKey]}`}
|
|
@@ -124,6 +124,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
124
124
|
width={xScale(d[config.series[0].dataKey])}
|
|
125
125
|
height={barHeight}
|
|
126
126
|
fill={groupOne.color}
|
|
127
|
+
onMouseEnter={() => {}}
|
|
127
128
|
data-tooltip-html={dataTipOne(d)}
|
|
128
129
|
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
129
130
|
stroke='#333'
|
|
@@ -145,7 +146,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
145
146
|
</Text>
|
|
146
147
|
)}
|
|
147
148
|
</Group>
|
|
148
|
-
|
|
149
|
+
</React.Fragment>
|
|
149
150
|
)
|
|
150
151
|
})}
|
|
151
152
|
{data
|
|
@@ -171,7 +172,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
171
172
|
const isTextFits = textWidth < barWidth - 5 // minus padding dx(5)
|
|
172
173
|
|
|
173
174
|
return (
|
|
174
|
-
|
|
175
|
+
<React.Fragment key={`fragment-group2-${groupTwo.dataKey}-${index}`}>
|
|
175
176
|
<style>
|
|
176
177
|
{`
|
|
177
178
|
.bar-${groupTwo.dataKey}-${d[config.xAxis.dataKey]} {
|
|
@@ -189,6 +190,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
189
190
|
width={xScale(d[config.series[1].dataKey])}
|
|
190
191
|
height={barHeight}
|
|
191
192
|
fill={groupTwo.color}
|
|
193
|
+
onMouseEnter={() => {}}
|
|
192
194
|
data-tooltip-html={dataTipTwo(d)}
|
|
193
195
|
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
194
196
|
strokeWidth={borderWidth}
|
|
@@ -210,7 +212,7 @@ const PairedBarChart = ({ width, height, originalWidth }) => {
|
|
|
210
212
|
</Text>
|
|
211
213
|
)}
|
|
212
214
|
</Group>
|
|
213
|
-
|
|
215
|
+
</React.Fragment>
|
|
214
216
|
)
|
|
215
217
|
})}
|
|
216
218
|
</Group>
|