@cdc/chart 4.26.7 → 4.26.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONFIG.md +502 -368
- package/dist/cdcchart-CYc-Kayd.es.js +22488 -0
- package/dist/cdcchart-DCKn8NmI.es.js +20695 -0
- package/dist/cdcchart-Dyui9nk_.es.js +45828 -0
- package/dist/cdcchart.js +4 -97406
- package/examples/__data__/vega-remote-data.json +6 -0
- package/examples/dendrogram.json +18 -0
- package/examples/feature/bar/bar-chart-race-annual-change.json +68 -0
- package/examples/feature/heatmap/average-age-categorical.json +2 -2
- package/examples/feature/heatmap/calendar-heatmap.json +2 -2
- package/examples/feature/heatmap/cell-values-bottom-axis.json +2 -2
- package/examples/feature/heatmap/sparse-aggregation.json +2 -2
- package/examples/feature/line/line-chart-race.json +50 -0
- package/examples/feature/sankey/sankey-example-data.json +40 -1441
- package/examples/feature/sankey/sankey_chart_data.csv +9 -20
- package/examples/network.json +31 -0
- package/examples/private/box-plot.json +573 -0
- package/examples/private/custom-color-issue.json +625 -0
- package/examples/private/custom-colors.json +522 -0
- package/examples/private/cutoff.json +10750 -0
- package/examples/private/overlay-legend.json +485 -0
- package/examples/private/pie-test.json +469 -0
- package/examples/vega-remote.json +22 -0
- package/package.json +11 -5
- package/src/CdcChartComponent.tsx +405 -208
- package/src/_stories/Chart.BarRace.stories.tsx +443 -0
- package/src/_stories/Chart.BoxPlotNumericSort.stories.tsx +189 -0
- package/src/_stories/Chart.BoxPlotStatsParity.stories.tsx +207 -0
- package/src/_stories/Chart.ColorDistribution.stories.tsx +299 -0
- package/src/_stories/Chart.DataCutoff.stories.tsx +147 -0
- package/src/_stories/Chart.DataTableDownloadFilename.stories.tsx +60 -0
- package/src/_stories/Chart.Dendrogram.stories.tsx +373 -0
- package/src/_stories/Chart.Forecast.CILegend.stories.tsx +236 -0
- package/src/_stories/Chart.HeatMap.stories.tsx +170 -4
- package/src/_stories/Chart.Legend.AxisAlign.stories.tsx +119 -0
- package/src/_stories/Chart.LineRace.stories.tsx +149 -0
- package/src/_stories/Chart.Network.stories.tsx +432 -0
- package/src/_stories/Chart.PaletteConversion.Editor.stories.tsx +208 -0
- package/src/_stories/Chart.Patterns.smoke.stories.tsx +31 -0
- package/src/_stories/Chart.PercentageValue.stories.tsx +311 -0
- package/src/_stories/Chart.PieLabels.stories.tsx +4 -2
- package/src/_stories/Chart.RankByValueMutation.stories.tsx +206 -0
- package/src/_stories/Chart.RequiredFields.stories.tsx +681 -0
- package/src/_stories/Chart.Sankey.stories.tsx +417 -0
- package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +47 -0
- package/src/_stories/Chart.SmallMultiplesNumericTileOrder.stories.tsx +137 -0
- package/src/_stories/Chart.TooltipSeriesLabels.stories.tsx +43 -0
- package/src/_stories/Chart.VegaRemoteData.stories.tsx +31 -0
- package/src/_stories/ChartAnnotation.Editor.stories.tsx +78 -0
- package/src/_stories/ChartAxisTitles.smoke.stories.tsx +48 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +499 -57
- package/src/_stories/ChartBrush.Editor.stories.tsx +46 -67
- package/src/_stories/ChartBrush.Regression.stories.tsx +135 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +33 -3
- package/src/_stories/ChartLine.EffectCompatibility.stories.tsx +120 -0
- package/src/_stories/_mock/annotation_event-line_mock.json +2 -2
- package/src/_stories/_mock/editor-test-configs.json +20 -10
- package/src/_stories/_mock/editor-test-datasets.json +38 -42
- package/src/_stories/_mock/heatmap-average-age-categorical.json +2 -2
- package/src/_stories/_mock/heatmap.json +2 -2
- package/src/_stories/_mock/legend-axis-align-stacked-bar.json +125 -0
- package/src/_stories/_mock/sankey_mock.json +23 -27
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +52 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +639 -139
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +44 -4
- package/src/components/Annotations/components/AnnotationDropdown.tsx +10 -32
- package/src/components/Annotations/helpers/resolveAnnotationLayout.ts +212 -0
- package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +612 -19
- package/src/components/Annotations/tests/AnnotationDropdown.test.tsx +50 -0
- package/src/components/Annotations/tests/resolveAnnotationLayout.test.ts +203 -0
- package/src/components/Axis/BottomAxis.tsx +1 -1
- package/src/components/Axis/Categorical.Axis.tsx +3 -3
- package/src/components/Axis/RightAxis.tsx +21 -13
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +38 -6
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +12 -3
- package/src/components/BarChart/components/BarChart.StackedVertical.test.ts +28 -0
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +29 -25
- package/src/components/BarChart/components/BarChart.Vertical.tsx +37 -26
- package/src/components/BarChart/components/PortionPatternOverlay.tsx +61 -0
- package/src/components/BarChart/components/context.tsx +6 -0
- package/src/components/BarChart/helpers/getPatternUrl.ts +2 -5
- package/src/components/BarChart/helpers/index.ts +8 -0
- package/src/components/BarChart/helpers/portionPattern.ts +243 -0
- package/src/components/BarChart/helpers/tests/addMinimumBarHeights.test.ts +42 -0
- package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +13 -0
- package/src/components/BarChart/helpers/tests/portionPattern.test.ts +280 -0
- package/src/components/BarChart/helpers/tests/useBarChart.test.tsx +104 -0
- package/src/components/BarChart/helpers/useBarChart.ts +60 -59
- package/src/components/BarChartRace/BarChartRace.test.tsx +199 -0
- package/src/components/BarChartRace/BarChartRace.tsx +230 -0
- package/src/components/BarChartRace/BarChartRaceFallback.test.tsx +61 -0
- package/src/components/BarChartRace/BarChartRaceFallback.tsx +48 -0
- package/src/components/BarChartRace/bar-chart-race.css +160 -0
- package/src/components/BarChartRace/helpers.test.ts +114 -0
- package/src/components/BarChartRace/helpers.ts +185 -0
- package/src/components/BarChartRace/index.ts +3 -0
- package/src/components/BoxPlot/helpers/index.ts +11 -82
- package/src/components/Brush/BrushSelector.tsx +9 -23
- package/src/components/Brush/MiniChartPreview.tsx +33 -1
- package/src/components/Dendrogram/components/Dendrogram.tsx +374 -0
- package/src/components/Dendrogram/dendrogram.css +113 -0
- package/src/components/Dendrogram/helpers/layoutDendrogram.test.ts +95 -0
- package/src/components/Dendrogram/helpers/layoutDendrogram.ts +56 -0
- package/src/components/Dendrogram/helpers/prepareDendrogramData.test.ts +135 -0
- package/src/components/Dendrogram/helpers/prepareDendrogramData.ts +166 -0
- package/src/components/Dendrogram/helpers/resolveDendrogramLabels.test.ts +196 -0
- package/src/components/Dendrogram/helpers/resolveDendrogramLabels.ts +418 -0
- package/src/components/Dendrogram/index.tsx +1 -0
- package/src/components/Dendrogram/types/index.ts +66 -0
- package/src/components/EditorPanel/EditorPanel.tsx +1005 -760
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +50 -5
- package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.css +10 -0
- package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.tsx +211 -0
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +19 -8
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +88 -54
- package/src/components/EditorPanel/components/Panels/Panel.Network.css +9 -0
- package/src/components/EditorPanel/components/Panels/Panel.Network.tsx +202 -0
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +233 -33
- package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +6 -1
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +89 -105
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +2 -2
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +8 -66
- package/src/components/EditorPanel/components/Panels/RacingControls.test.tsx +131 -0
- package/src/components/EditorPanel/components/Panels/RacingControls.tsx +185 -0
- package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +2 -2
- package/src/components/EditorPanel/components/Panels/index.tsx +4 -0
- package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +20 -7
- package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +25 -2
- package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +2 -1
- package/src/components/EditorPanel/useEditorPermissions.test.tsx +62 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +70 -24
- package/src/components/Forecasting/Forecasting.tsx +15 -6
- package/src/components/HeatMap/components/HeatMap.tsx +511 -178
- package/src/components/HeatMap/heatmap.constants.ts +7 -3
- package/src/components/HeatMap/heatmap.css +101 -2
- package/src/components/HeatMap/helpers/layout.ts +80 -0
- package/src/components/HeatMap/tests/HeatMap.test.tsx +339 -16
- package/src/components/HeatMap/tests/helpers.test.ts +79 -0
- package/src/components/Legend/Legend.Component.tsx +110 -90
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +7 -0
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +47 -34
- package/src/components/Legend/helpers/createFormatLabels.test.ts +226 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +45 -51
- package/src/components/LineChart/components/LineChart.Circle.tsx +3 -3
- package/src/components/LineChart/helpers.test.ts +126 -38
- package/src/components/LineChart/helpers.ts +9 -4
- package/src/components/LineChart/index.tsx +69 -24
- package/src/components/LineChart/tests/LineChart.test.tsx +630 -0
- package/src/components/LineChartRace/LineChartRace.test.tsx +275 -0
- package/src/components/LineChartRace/LineChartRace.tsx +134 -0
- package/src/components/LineChartRace/LineChartRaceFallback.tsx +28 -0
- package/src/components/LineChartRace/helpers.test.ts +88 -0
- package/src/components/LineChartRace/helpers.ts +157 -0
- package/src/components/LineChartRace/index.ts +3 -0
- package/src/components/LineChartRace/line-chart-race.css +16 -0
- package/src/components/LinearChart/ValueAxisAnchors.tsx +58 -0
- package/src/components/LinearChart/VisualizationRenderer.tsx +18 -23
- package/src/components/LinearChart/tests/LinearChart.test.tsx +412 -13
- package/src/components/LinearChart/tests/VisualizationRenderer.test.tsx +141 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +2 -1
- package/src/components/LinearChart.tsx +81 -51
- package/src/components/Network/components/Network.tsx +372 -0
- package/src/components/Network/helpers/layoutNetwork.test.ts +68 -0
- package/src/components/Network/helpers/layoutNetwork.ts +87 -0
- package/src/components/Network/helpers/prepareNetworkData.test.ts +116 -0
- package/src/components/Network/helpers/prepareNetworkData.ts +101 -0
- package/src/components/Network/helpers/resolveNetworkLabels.test.ts +112 -0
- package/src/components/Network/helpers/resolveNetworkLabels.ts +206 -0
- package/src/components/Network/index.tsx +3 -0
- package/src/components/Network/network.css +107 -0
- package/src/components/Network/types/index.ts +56 -0
- package/src/components/PairedBarChart.jsx +5 -10
- package/src/components/PairedBarChart.test.tsx +71 -0
- package/src/components/PieChart/PieChart.tsx +9 -8
- package/src/components/RacingChartRenderer.tsx +44 -0
- package/src/components/Regions/components/Regions.test.tsx +179 -0
- package/src/components/Regions/components/Regions.tsx +104 -69
- package/src/components/Regions/index.tsx +2 -3
- package/src/components/Sankey/components/Sankey.tsx +264 -437
- package/src/components/Sankey/helpers/getSankeyTooltip.ts +12 -0
- package/src/components/Sankey/helpers/prepareSankeyData.test.ts +71 -0
- package/src/components/Sankey/helpers/prepareSankeyData.ts +90 -0
- package/src/components/Sankey/sankey.scss +57 -116
- package/src/components/Sankey/types/index.ts +41 -4
- package/src/components/ScatterPlot/ScatterPlot.jsx +28 -4
- package/src/components/ScatterPlot/ScatterPlot.test.tsx +60 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +12 -12
- package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +7 -5
- package/src/components/raceTiming.ts +18 -0
- package/src/data/initial-state.js +77 -31
- package/src/helpers/applyChartTypeContract.ts +71 -0
- package/src/helpers/axisLabelFontSize.ts +2 -2
- package/src/helpers/boxPlotStats.ts +60 -0
- package/src/helpers/bumpChartTooltip.ts +2 -1
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.test.ts +37 -0
- package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +3 -2
- package/src/helpers/calculateRightYAxisWidth.ts +60 -0
- package/src/helpers/colorAssignmentHelpers.ts +2 -2
- package/src/helpers/createNewChartConfig.ts +56 -0
- package/src/helpers/dataDrivenYAxisCategories.ts +18 -0
- package/src/helpers/forecastLegend.ts +88 -0
- package/src/helpers/getBoxPlotConfig.ts +18 -37
- package/src/helpers/getChartTypeDefaultPalette.ts +29 -0
- package/src/helpers/getColorCodeCategoryColorMap.ts +26 -0
- package/src/helpers/getColorScale.ts +31 -22
- package/src/helpers/getDynamicYAxisCategories.ts +69 -0
- package/src/helpers/getMinMax.ts +9 -7
- package/src/helpers/getNewRuntime.ts +5 -2
- package/src/helpers/getStackedSeriesMax.ts +51 -0
- package/src/helpers/getV21ChartDistributionColors.ts +57 -0
- package/src/helpers/handleRankByValue.ts +15 -15
- package/src/helpers/seriesColumnSettings.ts +10 -0
- package/src/helpers/sizeHelpers.ts +4 -3
- package/src/helpers/smallMultiplesHelpers.ts +10 -13
- package/src/helpers/tests/applyChartTypeContract.test.ts +37 -0
- package/src/helpers/tests/boxPlotStats.test.ts +31 -0
- package/src/helpers/tests/bumpChartTooltip.test.ts +29 -0
- package/src/helpers/tests/calculateRightYAxisWidth.test.ts +105 -0
- package/src/helpers/tests/countNumOfTicks.test.ts +11 -0
- package/src/helpers/tests/createNewChartConfig.test.ts +182 -0
- package/src/helpers/tests/getBoxPlotConfig.test.ts +70 -0
- package/src/helpers/tests/getColorCodeCategoryColorMap.test.ts +113 -0
- package/src/helpers/tests/getColorScale.test.ts +226 -1
- package/src/helpers/tests/getDynamicYAxisCategories.test.ts +61 -0
- package/src/helpers/tests/getMinMax.test.ts +41 -0
- package/src/helpers/tests/getStackedSeriesMax.test.ts +26 -0
- package/src/helpers/tests/handleRankByValue.test.ts +55 -37
- package/src/helpers/tests/seriesColumnSettings.test.ts +23 -0
- package/src/helpers/tests/smallMultiplesHelpers.test.ts +37 -1
- package/src/helpers/tests/tooltipHelpers.test.ts +80 -0
- package/src/helpers/tooltipHelpers.ts +16 -0
- package/src/hooks/tests/useTooltip.test.tsx +353 -1
- package/src/hooks/usePrefersReducedMotion.ts +22 -0
- package/src/hooks/useReduceData.ts +4 -36
- package/src/hooks/useScales.ts +15 -0
- package/src/hooks/useTooltip.tsx +95 -64
- package/src/scss/main.scss +74 -2
- package/src/store/chart.reducer.ts +4 -3
- package/src/test/CdcChart.dataTable.test.tsx +490 -16
- package/src/test/CdcChart.dendrogram.test.tsx +277 -0
- package/src/test/CdcChart.finalization.test.tsx +143 -0
- package/src/test/CdcChart.network.test.tsx +271 -0
- package/src/types/ChartConfig.ts +91 -54
- package/src/types/ChartContext.ts +5 -0
- package/src/types/Horizon.ts +1 -1
- package/LICENSE +0 -201
- package/dist/cdcchart-BWVIUcAF.es.js +0 -4802
- package/src/_stories/Chart.Sankey.smoke.stories.tsx +0 -62
- package/src/components/Sankey/components/ColumnList.tsx +0 -19
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +0 -34
- package/src/components/Sankey/useSankeyAlert.tsx +0 -60
- package/src/data/legacy-defaults.ts +0 -18
- package/src/helpers/ensureSpecialChartAxisTypes.ts +0 -11
- package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +0 -30
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useContext
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
2
|
// Local contexts
|
|
3
3
|
import ConfigContext from '../../../ConfigContext'
|
|
4
4
|
import BarChartContext, { type BarChartContextValues } from './context'
|
|
@@ -10,27 +10,29 @@ import { Group } from '@visx/group'
|
|
|
10
10
|
import { Text } from '@visx/text'
|
|
11
11
|
import { BarGroup } from '@visx/shape'
|
|
12
12
|
import { PatternLines, PatternCircles, PatternWaves } from '@visx/pattern'
|
|
13
|
-
// Local components
|
|
14
|
-
import Regions from '../../Regions'
|
|
15
13
|
// CDC core components and helpers
|
|
16
14
|
import { isDateScale } from '@cdc/core/helpers/cove/date'
|
|
17
15
|
import isNumber from '@cdc/core/helpers/isNumber'
|
|
18
16
|
import createBarElement from '@cdc/core/components/createBarElement'
|
|
19
17
|
import { APP_FONT_COLOR } from '@cdc/core/helpers/constants'
|
|
18
|
+
import { getSeriesValueLabel } from '@cdc/core/helpers/getSeriesName'
|
|
20
19
|
// Types
|
|
21
20
|
import { type ChartContext } from '../../../types/ChartContext'
|
|
22
21
|
import { getBarData } from '../helpers/getBarData'
|
|
23
22
|
import { getPatternUrl as getPatternUrlForBar } from '../helpers/getPatternUrl'
|
|
23
|
+
import { getPortionPatternRenderData } from '../helpers/portionPattern'
|
|
24
24
|
import { getChartPatternId } from '../../../helpers/getChartPatternId'
|
|
25
25
|
import { buildSeriesTooltipListHtml } from '../../../helpers/tooltipHelpers'
|
|
26
|
+
import { BarPortionPatternOverlay } from './PortionPatternOverlay'
|
|
26
27
|
|
|
27
28
|
const BarChartVertical = () => {
|
|
28
|
-
const { xScale, yScale,
|
|
29
|
+
const { xScale, yScale, yMax, seriesScale, convertLineToBarGraph, barChart } =
|
|
29
30
|
useContext<BarChartContextValues>(BarChartContext)
|
|
30
31
|
const {
|
|
31
32
|
assignColorsToValues,
|
|
32
33
|
barBorderWidth,
|
|
33
34
|
getAdditionalColumn,
|
|
35
|
+
formatTooltipValue,
|
|
34
36
|
getHighlightedBarByValue,
|
|
35
37
|
getHighlightedBarColorByValue,
|
|
36
38
|
labelFontSize,
|
|
@@ -41,16 +43,12 @@ const BarChartVertical = () => {
|
|
|
41
43
|
section
|
|
42
44
|
} = barChart
|
|
43
45
|
|
|
44
|
-
const [barWidth, setBarWidth] = useState(0)
|
|
45
|
-
const [totalBarsInGroup, setTotalBarsInGroup] = useState(0)
|
|
46
|
-
|
|
47
46
|
const {
|
|
48
47
|
colorScale,
|
|
49
48
|
config,
|
|
50
49
|
currentViewport,
|
|
51
50
|
vizViewport,
|
|
52
51
|
dashboardConfig,
|
|
53
|
-
tableData,
|
|
54
52
|
formatDate,
|
|
55
53
|
formatNumber,
|
|
56
54
|
parseDate,
|
|
@@ -63,13 +61,7 @@ const BarChartVertical = () => {
|
|
|
63
61
|
|
|
64
62
|
const root = document.documentElement
|
|
65
63
|
|
|
66
|
-
|
|
67
|
-
// check if user add suppression
|
|
68
|
-
const isSuppressionActive = config.preliminaryData.some(pd => pd.value && pd.type === 'suppression')
|
|
69
|
-
// if suppression active use table data (filtere | excluded) but non cleaned
|
|
70
|
-
if (isSuppressionActive) {
|
|
71
|
-
data = tableData
|
|
72
|
-
}
|
|
64
|
+
const data = transformedData
|
|
73
65
|
|
|
74
66
|
const hasConfidenceInterval =
|
|
75
67
|
config.confidenceKeys.upper &&
|
|
@@ -134,8 +126,9 @@ const BarChartVertical = () => {
|
|
|
134
126
|
id={patternId}
|
|
135
127
|
height={size}
|
|
136
128
|
width={size}
|
|
137
|
-
fill=
|
|
138
|
-
|
|
129
|
+
fill='transparent'
|
|
130
|
+
stroke={pattern.color}
|
|
131
|
+
strokeWidth={0.75}
|
|
139
132
|
/>
|
|
140
133
|
)
|
|
141
134
|
default:
|
|
@@ -215,12 +208,12 @@ const BarChartVertical = () => {
|
|
|
215
208
|
bar.x +
|
|
216
209
|
(config.isLollipopChart ? (barGroupWidth / barGroup.bars.length - lollipopBarWidth) / 2 : 0) -
|
|
217
210
|
(config.xAxis.type === 'date-time' ? barGroupWidth / 2 : 0)
|
|
218
|
-
setBarWidth(barWidth)
|
|
219
|
-
setTotalBarsInGroup(barGroup.bars.length)
|
|
220
211
|
const yAxisValue = formatNumber(/[a-zA-Z]/.test(String(bar.value)) ? '' : bar.value, 'left')
|
|
221
212
|
const xAxisValue =
|
|
222
213
|
config.runtime[section].type === 'date' ? formatDate(parseDate(dataValue)) : dataValue
|
|
223
214
|
|
|
215
|
+
const tooltipValue = formatTooltipValue(bar.key, dataValue, yAxisValue, barGroup.index)
|
|
216
|
+
|
|
224
217
|
// create new Index for bars with negative values
|
|
225
218
|
const newIndex = bar.value < 0 ? -1 : index
|
|
226
219
|
// tooltips
|
|
@@ -228,7 +221,7 @@ const BarChartVertical = () => {
|
|
|
228
221
|
let xAxisTooltip = config.runtime.xAxis.label
|
|
229
222
|
? `${config.runtime.xAxis.label}: ${xAxisValue}`
|
|
230
223
|
: xAxisValue
|
|
231
|
-
const tooltipBody = `${
|
|
224
|
+
const tooltipBody = `${getSeriesValueLabel(bar.key, config)}: ${tooltipValue}`
|
|
232
225
|
const tooltip = buildSeriesTooltipListHtml({
|
|
233
226
|
config,
|
|
234
227
|
colorScale,
|
|
@@ -308,8 +301,7 @@ const BarChartVertical = () => {
|
|
|
308
301
|
if (isRegularLollipopColor) _barColor = barColor
|
|
309
302
|
|
|
310
303
|
if (isHighlightedBar) _barColor = 'transparent'
|
|
311
|
-
if (config.legend.colorCode)
|
|
312
|
-
_barColor = assignColorsToValues(barGroups.length, barGroup.index, barColor)
|
|
304
|
+
if (config.legend.colorCode) _barColor = assignColorsToValues(barGroup.index, barColor)
|
|
313
305
|
if (isTwoToneLollipopColor) {
|
|
314
306
|
_barColor = getLollipopStemColor(barColor)
|
|
315
307
|
}
|
|
@@ -320,8 +312,7 @@ const BarChartVertical = () => {
|
|
|
320
312
|
if (isTwoToneLollipopColor) {
|
|
321
313
|
_barColor = getLollipopStemColor(barColor)
|
|
322
314
|
}
|
|
323
|
-
if (config.legend.colorCode)
|
|
324
|
-
_barColor = assignColorsToValues(barGroups.length, barGroup.index, barColor)
|
|
315
|
+
if (config.legend.colorCode) _barColor = assignColorsToValues(barGroup.index, barColor)
|
|
325
316
|
|
|
326
317
|
// if we're highlighting a bar make it invisible since it gets a border
|
|
327
318
|
if (isHighlightedBar) _barColor = 'transparent'
|
|
@@ -339,6 +330,15 @@ const BarChartVertical = () => {
|
|
|
339
330
|
allowNonSeriesFieldMatch: !config.series || config.series.length <= 1
|
|
340
331
|
})
|
|
341
332
|
const baseBackground = getBarBackgroundColor(colorScale(config.runtime.seriesLabels[bar.key]))
|
|
333
|
+
const portionPatternRenderData = getPortionPatternRenderData({
|
|
334
|
+
config,
|
|
335
|
+
orientation: 'vertical',
|
|
336
|
+
bounds: { x: barX, y: barY, width: barWidth, height: barHeight },
|
|
337
|
+
patterns: config.legend?.patterns,
|
|
338
|
+
datum,
|
|
339
|
+
seriesKey: bar.key,
|
|
340
|
+
totalValue: bar.value
|
|
341
|
+
})
|
|
342
342
|
|
|
343
343
|
// Confidence Interval Variables
|
|
344
344
|
const tickWidth = 5
|
|
@@ -419,6 +419,19 @@ const BarChartVertical = () => {
|
|
|
419
419
|
}
|
|
420
420
|
})}
|
|
421
421
|
|
|
422
|
+
{portionPatternRenderData && (
|
|
423
|
+
<BarPortionPatternOverlay
|
|
424
|
+
config={config}
|
|
425
|
+
index={newIndex}
|
|
426
|
+
renderData={portionPatternRenderData}
|
|
427
|
+
transformOrigin={`0 ${barY + barHeight}px`}
|
|
428
|
+
style={{
|
|
429
|
+
opacity: transparentBar ? 0.2 : 1,
|
|
430
|
+
display: displayBar ? 'block' : 'none'
|
|
431
|
+
}}
|
|
432
|
+
/>
|
|
433
|
+
)}
|
|
434
|
+
|
|
422
435
|
{(absentDataLabel || isSuppressed) && (
|
|
423
436
|
<rect
|
|
424
437
|
x={barX}
|
|
@@ -551,8 +564,6 @@ const BarChartVertical = () => {
|
|
|
551
564
|
))
|
|
552
565
|
}}
|
|
553
566
|
</BarGroup>
|
|
554
|
-
|
|
555
|
-
<Regions xScale={xScale} yMax={yMax} barWidth={barWidth} totalBarsInGroup={totalBarsInGroup} xMax={xMax} />
|
|
556
567
|
</Group>
|
|
557
568
|
)
|
|
558
569
|
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import createBarElement from '@cdc/core/components/createBarElement'
|
|
4
|
+
|
|
5
|
+
import { type ChartConfig } from '../../../types/ChartConfig'
|
|
6
|
+
import { type PortionPatternRenderData } from '../helpers/portionPattern'
|
|
7
|
+
|
|
8
|
+
type PortionPatternBoundaryProps = {
|
|
9
|
+
renderData: PortionPatternRenderData
|
|
10
|
+
brush?: boolean
|
|
11
|
+
style?: React.CSSProperties
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
type BarPortionPatternOverlayProps = PortionPatternBoundaryProps & {
|
|
15
|
+
config: ChartConfig
|
|
16
|
+
index: number
|
|
17
|
+
transformOrigin: string
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const PortionPatternBoundary = ({ renderData, brush = false, style }: PortionPatternBoundaryProps) => {
|
|
21
|
+
if (!renderData.patternColor || !renderData.boundaryGeometry) return null
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<line
|
|
25
|
+
className={`pattern-overlay__boundary${brush ? ' pattern-overlay__boundary--brush' : ''}`}
|
|
26
|
+
{...renderData.boundaryGeometry}
|
|
27
|
+
stroke={renderData.patternColor}
|
|
28
|
+
strokeWidth={0.75}
|
|
29
|
+
vectorEffect='non-scaling-stroke'
|
|
30
|
+
pointerEvents='none'
|
|
31
|
+
aria-hidden='true'
|
|
32
|
+
style={style}
|
|
33
|
+
/>
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const BarPortionPatternOverlay = ({
|
|
38
|
+
config,
|
|
39
|
+
index,
|
|
40
|
+
renderData,
|
|
41
|
+
transformOrigin,
|
|
42
|
+
style
|
|
43
|
+
}: BarPortionPatternOverlayProps) => (
|
|
44
|
+
<>
|
|
45
|
+
{createBarElement({
|
|
46
|
+
config,
|
|
47
|
+
index: renderData.placement === 'end' ? index : undefined,
|
|
48
|
+
className: 'pattern-overlay pattern-overlay--portion',
|
|
49
|
+
background: renderData.patternUrl,
|
|
50
|
+
borderColor: 'transparent',
|
|
51
|
+
borderWidth: '0px',
|
|
52
|
+
...renderData.geometry,
|
|
53
|
+
styleOverrides: {
|
|
54
|
+
transformOrigin,
|
|
55
|
+
...style,
|
|
56
|
+
pointerEvents: 'none'
|
|
57
|
+
}
|
|
58
|
+
})}
|
|
59
|
+
<PortionPatternBoundary renderData={renderData} style={style} />
|
|
60
|
+
</>
|
|
61
|
+
)
|
|
@@ -14,6 +14,12 @@ export type BarChartContextValues = {
|
|
|
14
14
|
assignColorsToValues: Function
|
|
15
15
|
barBorderWidth: number
|
|
16
16
|
getAdditionalColumn: Function
|
|
17
|
+
formatTooltipValue: (
|
|
18
|
+
seriesKey: string,
|
|
19
|
+
xAxisValue: unknown,
|
|
20
|
+
displayValue: string | number,
|
|
21
|
+
rowIndex?: number
|
|
22
|
+
) => string | number
|
|
17
23
|
getHighlightedBarByValue: Function
|
|
18
24
|
getHighlightedBarColorByValue: Function
|
|
19
25
|
lollipopBarWidth: number
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { getChartPatternId } from '../../../helpers/getChartPatternId'
|
|
2
|
-
|
|
3
|
-
type LegendPattern = {
|
|
4
|
-
dataKey?: string
|
|
5
|
-
dataValue?: string | number
|
|
6
|
-
}
|
|
2
|
+
import { type LegendPattern } from '../../../types/ChartConfig'
|
|
7
3
|
|
|
8
4
|
type SeriesLabels = Record<string, string> | undefined
|
|
9
5
|
|
|
@@ -64,6 +60,7 @@ export const getPatternUrl = ({
|
|
|
64
60
|
for (const patternKey in patterns) {
|
|
65
61
|
if (!Object.prototype.hasOwnProperty.call(patterns, patternKey)) continue
|
|
66
62
|
const pattern = patterns[patternKey]
|
|
63
|
+
if (pattern.application === 'portion') continue
|
|
67
64
|
const dataKey = normalizeString(pattern.dataKey)
|
|
68
65
|
|
|
69
66
|
if (!hasPatternValue(pattern.dataValue)) {
|
|
@@ -125,6 +125,14 @@ export const addMinimumBarHeights = barStacks => {
|
|
|
125
125
|
const segmentsNeedingAdjustment = segments.filter(segment => segment.height > 0 && segment.height < MIN_BAR_HEIGHT)
|
|
126
126
|
const segmentsToShrink = segments.filter(segment => segment.height > MIN_BAR_HEIGHT)
|
|
127
127
|
|
|
128
|
+
if (segments.length === 1 && segmentsNeedingAdjustment.length === 1) {
|
|
129
|
+
const segment = segmentsNeedingAdjustment[0]
|
|
130
|
+
const bottom = segment.y + segment.height
|
|
131
|
+
segment.height = MIN_BAR_HEIGHT
|
|
132
|
+
segment.y = bottom - MIN_BAR_HEIGHT
|
|
133
|
+
return
|
|
134
|
+
}
|
|
135
|
+
|
|
128
136
|
if (segmentsNeedingAdjustment.length > 0 && segmentsToShrink.length > 0) {
|
|
129
137
|
segmentsNeedingAdjustment.forEach(smallSegment => {
|
|
130
138
|
const heightToAdd = MIN_BAR_HEIGHT - smallSegment.height
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import { type Column } from '@cdc/core/types/Column'
|
|
2
|
+
|
|
3
|
+
import { getChartPatternId } from '../../../helpers/getChartPatternId'
|
|
4
|
+
import { type ChartConfig, type LegendPattern } from '../../../types/ChartConfig'
|
|
5
|
+
|
|
6
|
+
type PortionPatternSupportConfig = Pick<
|
|
7
|
+
ChartConfig,
|
|
8
|
+
'visualizationType' | 'visualizationSubType' | 'isLollipopChart' | 'yAxis'
|
|
9
|
+
>
|
|
10
|
+
|
|
11
|
+
export type PortionPatternOverlay = {
|
|
12
|
+
patternUrl: string
|
|
13
|
+
ratio: number
|
|
14
|
+
placement: 'start' | 'end'
|
|
15
|
+
patternColor?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type PortionPatternGeometry = {
|
|
19
|
+
x: number
|
|
20
|
+
y: number
|
|
21
|
+
width: number
|
|
22
|
+
height: number
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type PortionPatternBoundaryGeometry = {
|
|
26
|
+
x1: number
|
|
27
|
+
y1: number
|
|
28
|
+
x2: number
|
|
29
|
+
y2: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type PortionPatternRenderData = PortionPatternOverlay & {
|
|
33
|
+
geometry: PortionPatternGeometry
|
|
34
|
+
boundaryGeometry: PortionPatternBoundaryGeometry | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type GetPortionPatternOverlayArgs = {
|
|
38
|
+
patterns?: Record<string, LegendPattern>
|
|
39
|
+
datum: Record<string, any>
|
|
40
|
+
seriesKey: string
|
|
41
|
+
totalValue: unknown
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
type GetPortionPatternGeometryArgs = {
|
|
45
|
+
orientation: 'vertical' | 'horizontal'
|
|
46
|
+
bounds: PortionPatternGeometry
|
|
47
|
+
overlay: Pick<PortionPatternOverlay, 'ratio' | 'placement'>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
type GetPortionPatternBoundaryGeometryArgs = {
|
|
51
|
+
orientation: 'vertical' | 'horizontal'
|
|
52
|
+
geometry: PortionPatternGeometry
|
|
53
|
+
overlay: Pick<PortionPatternOverlay, 'ratio' | 'placement'>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type GetPortionPatternRenderDataArgs = GetPortionPatternOverlayArgs & {
|
|
57
|
+
config: PortionPatternSupportConfig
|
|
58
|
+
orientation: 'vertical' | 'horizontal'
|
|
59
|
+
bounds: PortionPatternGeometry
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type ChartColumns = Record<string, Column>
|
|
63
|
+
|
|
64
|
+
export const findColumnConfigKey = (columns: ChartColumns, columnName: string): string | undefined =>
|
|
65
|
+
Object.entries(columns).find(
|
|
66
|
+
([columnKey, column]) => column?.name === columnName || (!column?.name && columnKey === columnName)
|
|
67
|
+
)?.[0]
|
|
68
|
+
|
|
69
|
+
export const createPatternColumnConfig = (columnName: string): Column =>
|
|
70
|
+
({
|
|
71
|
+
name: columnName,
|
|
72
|
+
label: columnName,
|
|
73
|
+
prefix: '',
|
|
74
|
+
suffix: '',
|
|
75
|
+
roundToPlace: 0,
|
|
76
|
+
commas: true,
|
|
77
|
+
dataTable: true,
|
|
78
|
+
tooltips: true
|
|
79
|
+
} as Column)
|
|
80
|
+
|
|
81
|
+
export const ensurePatternColumnConfig = (columns: ChartColumns, columnName?: string): ChartColumns => {
|
|
82
|
+
if (!columnName || findColumnConfigKey(columns, columnName)) return columns
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
...columns,
|
|
86
|
+
[columnName]: createPatternColumnConfig(columnName)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export const removeUnusedPatternColumnConfig = ({
|
|
91
|
+
columns,
|
|
92
|
+
columnName,
|
|
93
|
+
patterns,
|
|
94
|
+
protectedColumnNames = []
|
|
95
|
+
}: {
|
|
96
|
+
columns: ChartColumns
|
|
97
|
+
columnName?: string
|
|
98
|
+
patterns: Record<string, LegendPattern>
|
|
99
|
+
protectedColumnNames?: Array<string | undefined>
|
|
100
|
+
}): ChartColumns => {
|
|
101
|
+
if (!columnName) return columns
|
|
102
|
+
|
|
103
|
+
const isStillUsedByPattern = Object.values(patterns).some(
|
|
104
|
+
pattern => pattern.application === 'portion' && pattern.patternValueKey === columnName
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
if (isStillUsedByPattern || protectedColumnNames.includes(columnName)) return columns
|
|
108
|
+
|
|
109
|
+
const columnConfigKey = findColumnConfigKey(columns, columnName)
|
|
110
|
+
if (!columnConfigKey) return columns
|
|
111
|
+
|
|
112
|
+
const nextColumns = { ...columns }
|
|
113
|
+
delete nextColumns[columnConfigKey]
|
|
114
|
+
return nextColumns
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const normalizeString = (value: unknown): string => String(value ?? '').trim()
|
|
118
|
+
|
|
119
|
+
const toPositiveFiniteNumber = (value: unknown): number | null => {
|
|
120
|
+
if (typeof value !== 'number' && typeof value !== 'string') return null
|
|
121
|
+
if (typeof value === 'string' && value.trim() === '') return null
|
|
122
|
+
|
|
123
|
+
const numericValue = Number(value)
|
|
124
|
+
return Number.isFinite(numericValue) && numericValue > 0 ? numericValue : null
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const isPortionPatternSupported = (config: PortionPatternSupportConfig): boolean =>
|
|
128
|
+
['Bar', 'Combo'].includes(config.visualizationType) &&
|
|
129
|
+
config.visualizationSubType !== 'stacked' &&
|
|
130
|
+
!config.isLollipopChart &&
|
|
131
|
+
config.yAxis?.type !== 'logarithmic'
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Resolves the first configured portion pattern for a bar series. The first
|
|
135
|
+
* matching entry wins even when its row values are invalid, so manually
|
|
136
|
+
* authored duplicate targets remain deterministic.
|
|
137
|
+
*/
|
|
138
|
+
export const getPortionPatternOverlay = ({
|
|
139
|
+
patterns,
|
|
140
|
+
datum,
|
|
141
|
+
seriesKey,
|
|
142
|
+
totalValue
|
|
143
|
+
}: GetPortionPatternOverlayArgs): PortionPatternOverlay | null => {
|
|
144
|
+
if (!patterns) return null
|
|
145
|
+
|
|
146
|
+
for (const patternKey in patterns) {
|
|
147
|
+
if (!Object.prototype.hasOwnProperty.call(patterns, patternKey)) continue
|
|
148
|
+
|
|
149
|
+
const pattern = patterns[patternKey]
|
|
150
|
+
if (pattern.application !== 'portion' || normalizeString(pattern.dataKey) !== seriesKey) continue
|
|
151
|
+
|
|
152
|
+
const total = toPositiveFiniteNumber(totalValue)
|
|
153
|
+
const portion = toPositiveFiniteNumber(datum?.[normalizeString(pattern.patternValueKey)])
|
|
154
|
+
|
|
155
|
+
if (total === null || portion === null || portion > total) return null
|
|
156
|
+
|
|
157
|
+
const patternColor = normalizeString(pattern.color)
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
patternUrl: `url(#${getChartPatternId(patternKey)})`,
|
|
161
|
+
ratio: portion / total,
|
|
162
|
+
placement: pattern.placement === 'start' ? 'start' : 'end',
|
|
163
|
+
...(patternColor ? { patternColor } : {})
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return null
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export const getPortionPatternGeometry = ({
|
|
171
|
+
orientation,
|
|
172
|
+
bounds,
|
|
173
|
+
overlay
|
|
174
|
+
}: GetPortionPatternGeometryArgs): PortionPatternGeometry => {
|
|
175
|
+
const { x, y, width, height } = bounds
|
|
176
|
+
|
|
177
|
+
if (orientation === 'horizontal') {
|
|
178
|
+
const overlayWidth = width * overlay.ratio
|
|
179
|
+
return {
|
|
180
|
+
x: overlay.placement === 'end' ? x + width - overlayWidth : x,
|
|
181
|
+
y,
|
|
182
|
+
width: overlayWidth,
|
|
183
|
+
height
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const overlayHeight = height * overlay.ratio
|
|
188
|
+
return {
|
|
189
|
+
x,
|
|
190
|
+
y: overlay.placement === 'start' ? y + height - overlayHeight : y,
|
|
191
|
+
width,
|
|
192
|
+
height: overlayHeight
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export const getPortionPatternBoundaryGeometry = ({
|
|
197
|
+
orientation,
|
|
198
|
+
geometry,
|
|
199
|
+
overlay
|
|
200
|
+
}: GetPortionPatternBoundaryGeometryArgs): PortionPatternBoundaryGeometry | null => {
|
|
201
|
+
if (overlay.ratio >= 1) return null
|
|
202
|
+
|
|
203
|
+
if (orientation === 'horizontal') {
|
|
204
|
+
const boundaryX = overlay.placement === 'end' ? geometry.x : geometry.x + geometry.width
|
|
205
|
+
return {
|
|
206
|
+
x1: boundaryX,
|
|
207
|
+
y1: geometry.y,
|
|
208
|
+
x2: boundaryX,
|
|
209
|
+
y2: geometry.y + geometry.height
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const boundaryY = overlay.placement === 'end' ? geometry.y + geometry.height : geometry.y
|
|
214
|
+
return {
|
|
215
|
+
x1: geometry.x,
|
|
216
|
+
y1: boundaryY,
|
|
217
|
+
x2: geometry.x + geometry.width,
|
|
218
|
+
y2: boundaryY
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export const getPortionPatternRenderData = ({
|
|
223
|
+
config,
|
|
224
|
+
orientation,
|
|
225
|
+
bounds,
|
|
226
|
+
patterns,
|
|
227
|
+
datum,
|
|
228
|
+
seriesKey,
|
|
229
|
+
totalValue
|
|
230
|
+
}: GetPortionPatternRenderDataArgs): PortionPatternRenderData | null => {
|
|
231
|
+
if (!isPortionPatternSupported(config)) return null
|
|
232
|
+
|
|
233
|
+
const overlay = getPortionPatternOverlay({ patterns, datum, seriesKey, totalValue })
|
|
234
|
+
if (!overlay) return null
|
|
235
|
+
|
|
236
|
+
const geometry = getPortionPatternGeometry({ orientation, bounds, overlay })
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
...overlay,
|
|
240
|
+
geometry,
|
|
241
|
+
boundaryGeometry: getPortionPatternBoundaryGeometry({ orientation, geometry, overlay })
|
|
242
|
+
}
|
|
243
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { addMinimumBarHeights } from '..'
|
|
3
|
+
|
|
4
|
+
const createSegment = ({ key, height, y, value }: { key: string; height: number; y: number; value: unknown }) => ({
|
|
5
|
+
key,
|
|
6
|
+
height,
|
|
7
|
+
y,
|
|
8
|
+
bar: {
|
|
9
|
+
data: {
|
|
10
|
+
[key]: value
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
describe('addMinimumBarHeights', () => {
|
|
16
|
+
it('gives an isolated tiny positive segment a minimum visible height while preserving its baseline', () => {
|
|
17
|
+
const barStacks = [
|
|
18
|
+
{
|
|
19
|
+
bars: [createSegment({ key: 'Tiny', height: 0.02, y: 99.98, value: 0.005 })]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
addMinimumBarHeights(barStacks)
|
|
24
|
+
|
|
25
|
+
expect(barStacks[0].bars[0].height).toBe(3)
|
|
26
|
+
expect(barStacks[0].bars[0].y).toBeCloseTo(97)
|
|
27
|
+
expect(barStacks[0].bars[0].y + barStacks[0].bars[0].height).toBeCloseTo(100)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('leaves exact zero segments at zero height', () => {
|
|
31
|
+
const barStacks = [
|
|
32
|
+
{
|
|
33
|
+
bars: [createSegment({ key: 'Zero', height: 0, y: 100, value: 0 })]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
addMinimumBarHeights(barStacks)
|
|
38
|
+
|
|
39
|
+
expect(barStacks[0].bars[0].height).toBe(0)
|
|
40
|
+
expect(barStacks[0].bars[0].y).toBe(100)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -131,4 +131,17 @@ describe('getPatternUrl', () => {
|
|
|
131
131
|
expect(idA.startsWith('chart-pattern-A-B-')).toBe(true)
|
|
132
132
|
expect(idB.startsWith('chart-pattern-A-B-')).toBe(true)
|
|
133
133
|
})
|
|
134
|
+
|
|
135
|
+
it('does not treat portion patterns as exact-value patterns', () => {
|
|
136
|
+
expect(
|
|
137
|
+
getPatternUrl({
|
|
138
|
+
patterns: {
|
|
139
|
+
Pattern1: { application: 'portion', dataKey: 'y1', dataValue: 100, patternValueKey: 'portion' }
|
|
140
|
+
},
|
|
141
|
+
datum: { y1: 100, portion: 25 },
|
|
142
|
+
seriesKey: 'y1',
|
|
143
|
+
seriesValue: 100
|
|
144
|
+
})
|
|
145
|
+
).toBeNull()
|
|
146
|
+
})
|
|
134
147
|
})
|