@cdc/chart 4.26.6 → 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.
Files changed (276) hide show
  1. package/CONFIG.md +504 -368
  2. package/dist/cdcchart-CYc-Kayd.es.js +22488 -0
  3. package/dist/cdcchart-DCKn8NmI.es.js +20695 -0
  4. package/dist/cdcchart-Dyui9nk_.es.js +45828 -0
  5. package/dist/cdcchart.js +4 -96498
  6. package/examples/__data__/vega-remote-data.json +6 -0
  7. package/examples/dendrogram.json +18 -0
  8. package/examples/feature/bar/bar-chart-race-annual-change.json +68 -0
  9. package/examples/feature/heatmap/average-age-categorical.json +2 -2
  10. package/examples/feature/heatmap/calendar-heatmap.json +2 -2
  11. package/examples/feature/heatmap/cell-values-bottom-axis.json +2 -2
  12. package/examples/feature/heatmap/sparse-aggregation.json +2 -2
  13. package/examples/feature/line/line-chart-race.json +50 -0
  14. package/examples/feature/sankey/sankey-example-data.json +40 -1441
  15. package/examples/feature/sankey/sankey_chart_data.csv +9 -20
  16. package/examples/network.json +31 -0
  17. package/examples/private/box-plot.json +573 -0
  18. package/examples/private/custom-color-issue.json +625 -0
  19. package/examples/private/custom-colors.json +522 -0
  20. package/examples/private/cutoff.json +10750 -0
  21. package/examples/private/flueview.json +22051 -0
  22. package/examples/private/overlay-legend.json +485 -0
  23. package/examples/private/pie-test.json +469 -0
  24. package/examples/vega-remote.json +22 -0
  25. package/package.json +11 -13
  26. package/src/CdcChart.tsx +2 -2
  27. package/src/CdcChartComponent.tsx +444 -217
  28. package/src/_stories/Chart.BarRace.stories.tsx +443 -0
  29. package/src/_stories/Chart.BoxPlotNumericSort.stories.tsx +189 -0
  30. package/src/_stories/Chart.BoxPlotStatsParity.stories.tsx +207 -0
  31. package/src/_stories/Chart.ColorDistribution.stories.tsx +299 -0
  32. package/src/_stories/Chart.DataCutoff.stories.tsx +147 -0
  33. package/src/_stories/Chart.DataTableDownloadFilename.stories.tsx +60 -0
  34. package/src/_stories/Chart.Dendrogram.stories.tsx +373 -0
  35. package/src/_stories/Chart.Forecast.CILegend.stories.tsx +236 -0
  36. package/src/_stories/Chart.HeatMap.stories.tsx +170 -4
  37. package/src/_stories/Chart.Legend.AxisAlign.stories.tsx +119 -0
  38. package/src/_stories/Chart.LineRace.stories.tsx +149 -0
  39. package/src/_stories/Chart.Network.stories.tsx +432 -0
  40. package/src/_stories/Chart.PaletteConversion.Editor.stories.tsx +208 -0
  41. package/src/_stories/Chart.Patterns.smoke.stories.tsx +31 -0
  42. package/src/_stories/Chart.PercentageValue.stories.tsx +311 -0
  43. package/src/_stories/Chart.PieLabels.stories.tsx +49 -0
  44. package/src/_stories/Chart.RankByValueMutation.stories.tsx +206 -0
  45. package/src/_stories/Chart.RequiredFields.stories.tsx +681 -0
  46. package/src/_stories/Chart.Sankey.stories.tsx +417 -0
  47. package/src/_stories/Chart.SeriesColorAssignments.stories.tsx +47 -0
  48. package/src/_stories/Chart.SmallMultiplesNumericTileOrder.stories.tsx +137 -0
  49. package/src/_stories/Chart.TooltipSeriesLabels.stories.tsx +43 -0
  50. package/src/_stories/Chart.VegaRemoteData.stories.tsx +31 -0
  51. package/src/_stories/Chart.smoke.stories.tsx +14 -1
  52. package/src/_stories/ChartAnnotation.Editor.stories.tsx +78 -0
  53. package/src/_stories/ChartAxisTitles.smoke.stories.tsx +48 -0
  54. package/src/_stories/ChartBar.Editor.stories.tsx +499 -57
  55. package/src/_stories/ChartBrush.Editor.stories.tsx +46 -67
  56. package/src/_stories/ChartBrush.Regression.stories.tsx +135 -0
  57. package/src/_stories/ChartEditor.Editor.stories.tsx +33 -3
  58. package/src/_stories/ChartLine.EffectCompatibility.stories.tsx +120 -0
  59. package/src/_stories/ChartPrefixSuffix.smoke.stories.tsx +28 -1
  60. package/src/_stories/_mock/annotation_event-line_mock.json +2 -2
  61. package/src/_stories/_mock/editor-test-configs.json +20 -10
  62. package/src/_stories/_mock/editor-test-datasets.json +38 -42
  63. package/src/_stories/_mock/heatmap-average-age-categorical.json +2 -2
  64. package/src/_stories/_mock/heatmap.json +2 -2
  65. package/src/_stories/_mock/legend-axis-align-stacked-bar.json +125 -0
  66. package/src/_stories/_mock/sankey_mock.json +23 -27
  67. package/src/components/Annotations/components/AnnotationDraggable.styles.css +52 -0
  68. package/src/components/Annotations/components/AnnotationDraggable.tsx +639 -139
  69. package/src/components/Annotations/components/AnnotationDropdown.styles.css +44 -4
  70. package/src/components/Annotations/components/AnnotationDropdown.tsx +10 -32
  71. package/src/components/Annotations/helpers/resolveAnnotationLayout.ts +212 -0
  72. package/src/components/Annotations/tests/AnnotationDraggable.test.tsx +612 -19
  73. package/src/components/Annotations/tests/AnnotationDropdown.test.tsx +50 -0
  74. package/src/components/Annotations/tests/resolveAnnotationLayout.test.ts +203 -0
  75. package/src/components/Axis/BottomAxis.tsx +1 -1
  76. package/src/components/Axis/Categorical.Axis.tsx +3 -3
  77. package/src/components/Axis/RightAxis.tsx +21 -13
  78. package/src/components/BarChart/components/BarChart.Horizontal.tsx +39 -8
  79. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +13 -4
  80. package/src/components/BarChart/components/BarChart.StackedVertical.test.ts +28 -0
  81. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +30 -26
  82. package/src/components/BarChart/components/BarChart.Vertical.tsx +38 -28
  83. package/src/components/BarChart/components/PortionPatternOverlay.tsx +61 -0
  84. package/src/components/BarChart/components/context.tsx +6 -0
  85. package/src/components/BarChart/helpers/getBarData.ts +28 -28
  86. package/src/components/BarChart/helpers/getBarHeights.ts +2 -2
  87. package/src/components/BarChart/helpers/getPatternUrl.ts +2 -5
  88. package/src/components/BarChart/helpers/index.ts +8 -0
  89. package/src/components/BarChart/helpers/portionPattern.ts +243 -0
  90. package/src/components/BarChart/helpers/tests/addMinimumBarHeights.test.ts +42 -0
  91. package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +13 -0
  92. package/src/components/BarChart/helpers/tests/portionPattern.test.ts +280 -0
  93. package/src/components/BarChart/helpers/tests/useBarChart.test.tsx +202 -0
  94. package/src/components/BarChart/helpers/useBarChart.ts +60 -60
  95. package/src/components/BarChartRace/BarChartRace.test.tsx +199 -0
  96. package/src/components/BarChartRace/BarChartRace.tsx +230 -0
  97. package/src/components/BarChartRace/BarChartRaceFallback.test.tsx +61 -0
  98. package/src/components/BarChartRace/BarChartRaceFallback.tsx +48 -0
  99. package/src/components/BarChartRace/bar-chart-race.css +160 -0
  100. package/src/components/BarChartRace/helpers.test.ts +114 -0
  101. package/src/components/BarChartRace/helpers.ts +185 -0
  102. package/src/components/BarChartRace/index.ts +3 -0
  103. package/src/components/BoxPlot/BoxPlot.Horizontal.tsx +7 -6
  104. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +9 -7
  105. package/src/components/BoxPlot/helpers/index.ts +13 -83
  106. package/src/components/Brush/BrushSelector.tsx +10 -24
  107. package/src/components/Brush/MiniChartPreview.tsx +33 -1
  108. package/src/components/Dendrogram/components/Dendrogram.tsx +374 -0
  109. package/src/components/Dendrogram/dendrogram.css +113 -0
  110. package/src/components/Dendrogram/helpers/layoutDendrogram.test.ts +95 -0
  111. package/src/components/Dendrogram/helpers/layoutDendrogram.ts +56 -0
  112. package/src/components/Dendrogram/helpers/prepareDendrogramData.test.ts +135 -0
  113. package/src/components/Dendrogram/helpers/prepareDendrogramData.ts +166 -0
  114. package/src/components/Dendrogram/helpers/resolveDendrogramLabels.test.ts +196 -0
  115. package/src/components/Dendrogram/helpers/resolveDendrogramLabels.ts +418 -0
  116. package/src/components/Dendrogram/index.tsx +1 -0
  117. package/src/components/Dendrogram/types/index.ts +66 -0
  118. package/src/components/EditorPanel/EditorPanel.tsx +1111 -805
  119. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +50 -5
  120. package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.css +10 -0
  121. package/src/components/EditorPanel/components/Panels/Panel.Dendrogram.tsx +211 -0
  122. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +19 -8
  123. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +104 -61
  124. package/src/components/EditorPanel/components/Panels/Panel.Network.css +9 -0
  125. package/src/components/EditorPanel/components/Panels/Panel.Network.tsx +202 -0
  126. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +236 -36
  127. package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +6 -1
  128. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +89 -105
  129. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +21 -6
  130. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +1 -1
  131. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +8 -66
  132. package/src/components/EditorPanel/components/Panels/RacingControls.test.tsx +131 -0
  133. package/src/components/EditorPanel/components/Panels/RacingControls.tsx +185 -0
  134. package/src/components/EditorPanel/components/Panels/SeriesColorAssignments.tsx +2 -2
  135. package/src/components/EditorPanel/components/Panels/index.tsx +4 -0
  136. package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +20 -7
  137. package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +25 -2
  138. package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +5 -4
  139. package/src/components/EditorPanel/useEditorPermissions.test.tsx +94 -0
  140. package/src/components/EditorPanel/useEditorPermissions.ts +75 -25
  141. package/src/components/Forecasting/Forecasting.tsx +16 -7
  142. package/src/components/HeatMap/components/HeatMap.tsx +511 -178
  143. package/src/components/HeatMap/heatmap.constants.ts +7 -3
  144. package/src/components/HeatMap/heatmap.css +101 -2
  145. package/src/components/HeatMap/helpers/layout.ts +80 -0
  146. package/src/components/HeatMap/tests/HeatMap.test.tsx +339 -16
  147. package/src/components/HeatMap/tests/helpers.test.ts +79 -0
  148. package/src/components/Legend/Legend.Component.tsx +163 -148
  149. package/src/components/Legend/Legend.Suppression.tsx +3 -3
  150. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +7 -0
  151. package/src/components/Legend/LegendGroup/LegendGroup.tsx +47 -35
  152. package/src/components/Legend/helpers/createFormatLabels.test.ts +226 -0
  153. package/src/components/Legend/helpers/createFormatLabels.tsx +45 -51
  154. package/src/components/LineChart/components/LineChart.Circle.tsx +3 -3
  155. package/src/components/LineChart/helpers.test.ts +126 -38
  156. package/src/components/LineChart/helpers.ts +9 -6
  157. package/src/components/LineChart/index.tsx +71 -27
  158. package/src/components/LineChart/tests/LineChart.test.tsx +630 -0
  159. package/src/components/LineChartRace/LineChartRace.test.tsx +275 -0
  160. package/src/components/LineChartRace/LineChartRace.tsx +134 -0
  161. package/src/components/LineChartRace/LineChartRaceFallback.tsx +28 -0
  162. package/src/components/LineChartRace/helpers.test.ts +88 -0
  163. package/src/components/LineChartRace/helpers.ts +157 -0
  164. package/src/components/LineChartRace/index.ts +3 -0
  165. package/src/components/LineChartRace/line-chart-race.css +16 -0
  166. package/src/components/LinearChart/ValueAxisAnchors.tsx +58 -0
  167. package/src/components/LinearChart/VisualizationRenderer.tsx +18 -23
  168. package/src/components/LinearChart/tests/LinearChart.test.tsx +412 -13
  169. package/src/components/LinearChart/tests/VisualizationRenderer.test.tsx +141 -0
  170. package/src/components/LinearChart/tests/mockConfigContext.ts +2 -1
  171. package/src/components/LinearChart.tsx +85 -54
  172. package/src/components/Network/components/Network.tsx +372 -0
  173. package/src/components/Network/helpers/layoutNetwork.test.ts +68 -0
  174. package/src/components/Network/helpers/layoutNetwork.ts +87 -0
  175. package/src/components/Network/helpers/prepareNetworkData.test.ts +116 -0
  176. package/src/components/Network/helpers/prepareNetworkData.ts +101 -0
  177. package/src/components/Network/helpers/resolveNetworkLabels.test.ts +112 -0
  178. package/src/components/Network/helpers/resolveNetworkLabels.ts +206 -0
  179. package/src/components/Network/index.tsx +3 -0
  180. package/src/components/Network/network.css +107 -0
  181. package/src/components/Network/types/index.ts +56 -0
  182. package/src/components/PairedBarChart.jsx +5 -10
  183. package/src/components/PairedBarChart.test.tsx +71 -0
  184. package/src/components/PieChart/PieChart.tsx +121 -13
  185. package/src/components/PieChart/helpers/labelPlacement.test.ts +88 -0
  186. package/src/components/PieChart/helpers/labelPlacement.ts +95 -0
  187. package/src/components/RacingChartRenderer.tsx +44 -0
  188. package/src/components/Regions/components/Regions.test.tsx +179 -0
  189. package/src/components/Regions/components/Regions.tsx +104 -69
  190. package/src/components/Regions/index.tsx +2 -3
  191. package/src/components/Sankey/components/Sankey.tsx +264 -437
  192. package/src/components/Sankey/helpers/getSankeyTooltip.ts +12 -0
  193. package/src/components/Sankey/helpers/prepareSankeyData.test.ts +71 -0
  194. package/src/components/Sankey/helpers/prepareSankeyData.ts +90 -0
  195. package/src/components/Sankey/sankey.scss +57 -116
  196. package/src/components/Sankey/types/index.ts +41 -4
  197. package/src/components/ScatterPlot/ScatterPlot.jsx +28 -12
  198. package/src/components/ScatterPlot/ScatterPlot.test.tsx +60 -0
  199. package/src/components/SmallMultiples/SmallMultiples.tsx +12 -12
  200. package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +7 -5
  201. package/src/components/raceTiming.ts +18 -0
  202. package/src/data/initial-state.js +79 -31
  203. package/src/helpers/applyChartTypeContract.ts +71 -0
  204. package/src/helpers/axisLabelFontSize.ts +2 -2
  205. package/src/helpers/boxPlotStats.ts +60 -0
  206. package/src/helpers/bumpChartTooltip.ts +2 -1
  207. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.test.ts +37 -0
  208. package/src/helpers/calculateHorizontalBarCategoryLabelWidth.ts +3 -2
  209. package/src/helpers/calculateRightYAxisWidth.ts +60 -0
  210. package/src/helpers/categoryOrder.ts +60 -0
  211. package/src/helpers/colorAssignmentHelpers.ts +2 -2
  212. package/src/helpers/createNewChartConfig.ts +56 -0
  213. package/src/helpers/dataDrivenYAxisCategories.ts +18 -0
  214. package/src/helpers/forecastLegend.ts +88 -0
  215. package/src/helpers/getBoxPlotConfig.ts +26 -38
  216. package/src/helpers/getChartTypeDefaultPalette.ts +29 -0
  217. package/src/helpers/getColorCodeCategoryColorMap.ts +26 -0
  218. package/src/helpers/getColorScale.ts +31 -22
  219. package/src/helpers/getComboChartConfig.ts +0 -1
  220. package/src/helpers/getDynamicYAxisCategories.ts +69 -0
  221. package/src/helpers/getExcludedData.ts +0 -1
  222. package/src/helpers/getHasBoundarySuppression.ts +4 -3
  223. package/src/helpers/getMinMax.ts +11 -8
  224. package/src/helpers/getNewRuntime.ts +4 -3
  225. package/src/helpers/getPiePercent.ts +3 -3
  226. package/src/helpers/getStackedSeriesMax.ts +51 -0
  227. package/src/helpers/getV21ChartDistributionColors.ts +57 -0
  228. package/src/helpers/handleRankByValue.ts +15 -15
  229. package/src/helpers/isConvertLineToBarGraph.ts +2 -2
  230. package/src/helpers/seriesColumnSettings.ts +31 -3
  231. package/src/helpers/sizeHelpers.ts +4 -5
  232. package/src/helpers/smallMultiplesHelpers.ts +10 -13
  233. package/src/helpers/tests/applyChartTypeContract.test.ts +37 -0
  234. package/src/helpers/tests/boxPlotStats.test.ts +31 -0
  235. package/src/helpers/tests/bumpChartTooltip.test.ts +29 -0
  236. package/src/helpers/tests/calculateRightYAxisWidth.test.ts +105 -0
  237. package/src/helpers/tests/categoryOrder.test.ts +57 -0
  238. package/src/helpers/tests/countNumOfTicks.test.ts +11 -0
  239. package/src/helpers/tests/createNewChartConfig.test.ts +182 -0
  240. package/src/helpers/tests/getBoxPlotConfig.test.ts +70 -0
  241. package/src/helpers/tests/getColorCodeCategoryColorMap.test.ts +113 -0
  242. package/src/helpers/tests/getColorScale.test.ts +226 -1
  243. package/src/helpers/tests/getDynamicYAxisCategories.test.ts +61 -0
  244. package/src/helpers/tests/getMinMax.test.ts +41 -0
  245. package/src/helpers/tests/getStackedSeriesMax.test.ts +26 -0
  246. package/src/helpers/tests/handleRankByValue.test.ts +55 -37
  247. package/src/helpers/tests/seriesColumnSettings.test.ts +83 -0
  248. package/src/helpers/tests/smallMultiplesHelpers.test.ts +37 -1
  249. package/src/helpers/tests/tooltipHelpers.test.ts +80 -0
  250. package/src/helpers/tooltipHelpers.ts +16 -0
  251. package/src/hooks/tests/useRightAxis.test.tsx +143 -2
  252. package/src/hooks/tests/useScales.test.tsx +3 -6
  253. package/src/hooks/tests/useTooltip.test.tsx +484 -0
  254. package/src/hooks/usePrefersReducedMotion.ts +22 -0
  255. package/src/hooks/useReduceData.ts +4 -36
  256. package/src/hooks/useRightAxis.ts +19 -26
  257. package/src/hooks/useScales.ts +15 -0
  258. package/src/hooks/useTooltip.tsx +106 -71
  259. package/src/scss/main.scss +74 -2
  260. package/src/store/chart.reducer.ts +4 -4
  261. package/src/test/CdcChart.dataTable.test.tsx +582 -14
  262. package/src/test/CdcChart.dendrogram.test.tsx +277 -0
  263. package/src/test/CdcChart.finalization.test.tsx +143 -0
  264. package/src/test/CdcChart.network.test.tsx +271 -0
  265. package/src/types/ChartConfig.ts +91 -54
  266. package/src/types/ChartContext.ts +5 -0
  267. package/src/types/Horizon.ts +1 -1
  268. package/LICENSE +0 -201
  269. package/dist/cdcchart-BWVIUcAF.es.js +0 -4802
  270. package/src/_stories/Chart.Sankey.smoke.stories.tsx +0 -62
  271. package/src/components/Sankey/components/ColumnList.tsx +0 -19
  272. package/src/components/Sankey/helpers/getSankeyTooltip.tsx +0 -34
  273. package/src/components/Sankey/useSankeyAlert.tsx +0 -60
  274. package/src/data/legacy-defaults.ts +0 -18
  275. package/src/helpers/ensureSpecialChartAxisTypes.ts +0 -11
  276. package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +0 -30
@@ -0,0 +1,16 @@
1
+ .line-chart-race {
2
+ width: 100%;
3
+ }
4
+
5
+ .line-chart-race__header {
6
+ align-items: center;
7
+ display: flex;
8
+ gap: 0.75rem;
9
+ justify-content: flex-start;
10
+ margin-bottom: 1rem;
11
+ }
12
+
13
+ .line-chart-race__frame {
14
+ font-family: var(--fonts-nunito, var(--app-font-secondary));
15
+ font-size: 1.5rem;
16
+ }
@@ -0,0 +1,58 @@
1
+ import React from 'react'
2
+ import { Line } from '@visx/shape'
3
+ import { type Anchor } from '@cdc/core/types/Axis'
4
+
5
+ const DEFAULT_ANCHOR_STROKE_WIDTH = 1
6
+
7
+ export const alignStrokeToPixel = (position: number, strokeWidth = DEFAULT_ANCHOR_STROKE_WIDTH) =>
8
+ strokeWidth % 2 === 1 ? Math.round(position - 0.5) + 0.5 : Math.round(position)
9
+
10
+ const hasAnchorValue = (value: Anchor['value']) => value !== undefined && value !== null && value !== ''
11
+
12
+ type ValueAxisAnchorsProps = {
13
+ anchors?: Anchor[]
14
+ className: string
15
+ getOffset?: () => number
16
+ handleLineType: (lineStyle: string) => string
17
+ keyPrefix: string
18
+ xEnd: number
19
+ xStart: number
20
+ yScale: (value: string) => number
21
+ }
22
+
23
+ const ValueAxisAnchors: React.FC<ValueAxisAnchorsProps> = ({
24
+ anchors,
25
+ className,
26
+ getOffset = () => 0,
27
+ handleLineType,
28
+ keyPrefix,
29
+ xEnd,
30
+ xStart,
31
+ yScale
32
+ }) => (
33
+ <>
34
+ {anchors?.map((anchor, index) => {
35
+ if (!hasAnchorValue(anchor.value)) return null
36
+
37
+ const position = yScale(anchor.value)
38
+ if (position === undefined || position === null || Number.isNaN(Number(position))) return null
39
+
40
+ const anchorYPosition = alignStrokeToPixel(position - getOffset())
41
+
42
+ return (
43
+ // prettier-ignore
44
+ <Line
45
+ key={`${keyPrefix}-${anchor.value}--${index}`}
46
+ strokeDasharray={handleLineType(anchor.lineStyle)}
47
+ stroke={anchor.color ? anchor.color : 'rgba(0,0,0,1)'}
48
+ fill={anchor.color ? anchor.color : 'rgba(0,0,0,1)'}
49
+ className={className}
50
+ from={{ x: xStart, y: anchorYPosition }}
51
+ to={{ x: xEnd, y: anchorYPosition }}
52
+ />
53
+ )
54
+ })}
55
+ </>
56
+ )
57
+
58
+ export default ValueAxisAnchors
@@ -67,6 +67,19 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
67
67
  }) => {
68
68
  const { config, convertLineToBarGraph } = useContext(ConfigContext)
69
69
  const { visualizationType, visualizationSubType } = config
70
+ const isCombo = visualizationType === VISUALIZATION_TYPES.COMBO
71
+ const comboHasAreaSeries = isCombo && Boolean(config.runtime?.areaSeriesKeys?.length)
72
+ const comboHasBarSeries = isCombo && Boolean(config.runtime?.barSeriesKeys?.length)
73
+ const comboHasLineSeries = isCombo && Boolean(config.runtime?.lineSeriesKeys?.length)
74
+ const comboHasForecastingSeries = isCombo && Boolean(config.runtime?.forecastingSeriesKeys?.length)
75
+ const shouldRenderAreaChart =
76
+ (visualizationType === VISUALIZATION_TYPES.AREA_CHART && visualizationSubType === 'stacked') || comboHasAreaSeries
77
+ const shouldRenderBarChart =
78
+ visualizationType === VISUALIZATION_TYPES.BAR || comboHasBarSeries || convertLineToBarGraph
79
+ const shouldRenderLineChart =
80
+ comboHasLineSeries ||
81
+ (!isCombo && !LINE_CHART_EXCLUDED_TYPES.includes(visualizationType as any) && !convertLineToBarGraph)
82
+ const shouldRenderForecasting = visualizationType === VISUALIZATION_TYPES.FORECASTING || comboHasForecastingSeries
70
83
 
71
84
  return (
72
85
  <>
@@ -155,8 +168,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
155
168
  )}
156
169
 
157
170
  {/* Area Chart (Stacked) - also used by Combo */}
158
- {((visualizationType === 'Area Chart' && visualizationSubType === 'stacked') ||
159
- visualizationType === 'Combo') && (
171
+ {shouldRenderAreaChart && (
160
172
  <AreaChartStacked
161
173
  xScale={xScale}
162
174
  yScale={yScale}
@@ -174,7 +186,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
174
186
  )}
175
187
 
176
188
  {/* Bar Chart - also used by Combo and when line is converted to bar */}
177
- {(visualizationType === 'Bar' || visualizationType === 'Combo' || convertLineToBarGraph) && (
189
+ {shouldRenderBarChart && (
178
190
  <BarChart
179
191
  xScale={xScale}
180
192
  yScale={yScale}
@@ -195,8 +207,8 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
195
207
  />
196
208
  )}
197
209
 
198
- {/* Line Chart for Combo and Bump Chart */}
199
- {(visualizationType === 'Combo' || visualizationType === 'Bump Chart') && (
210
+ {/* Line Chart */}
211
+ {shouldRenderLineChart && (
200
212
  <LineChart
201
213
  xScale={xScale}
202
214
  yScale={yScale}
@@ -214,25 +226,8 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
214
226
  />
215
227
  )}
216
228
 
217
- {/* Line Chart for other visualization types */}
218
- {!LINE_CHART_EXCLUDED_TYPES.includes(visualizationType as any) && !convertLineToBarGraph && (
219
- <LineChart
220
- xScale={xScale}
221
- yScale={yScale}
222
- yAxisWidth={yAxisWidth}
223
- getXAxisData={getXAxisData}
224
- getYAxisData={getYAxisData}
225
- xMax={xMax}
226
- yMax={yMax}
227
- seriesStyle={config.runtime.series}
228
- tooltipData={tooltipData}
229
- handleTooltipMouseOver={handleTooltipMouseOver}
230
- handleTooltipMouseOff={handleTooltipMouseOff}
231
- />
232
- )}
233
-
234
229
  {/* Forecasting - also used by Combo */}
235
- {(visualizationType === 'Forecasting' || visualizationType === 'Combo') && (
230
+ {shouldRenderForecasting && (
236
231
  <Forecasting
237
232
  showTooltip={showTooltip}
238
233
  tooltipData={tooltipData}
@@ -1,30 +1,54 @@
1
1
  import React from 'react'
2
2
  import { render, screen } from '@testing-library/react'
3
- import { describe, expect, it, vi, beforeAll } from 'vitest'
3
+ import { describe, expect, it, vi, beforeAll, beforeEach } from 'vitest'
4
4
  import LinearChart from '../../LinearChart'
5
+ import RightAxis from '../../Axis/RightAxis'
5
6
  import ConfigContext from '../../../ConfigContext'
6
7
  import { createMockChartContext } from './mockConfigContext'
7
8
  import forestPlotConfig from '../../../../examples/feature/forest-plot/forest-plot.json'
8
9
  import * as suppressionHelpers from '../../../helpers/getHasBoundarySuppression'
10
+ import { scaleLinear } from '@visx/scale'
11
+
12
+ const visualizationRendererMockState = vi.hoisted(() => ({
13
+ renderActual: false
14
+ }))
15
+
16
+ vi.mock('../../LinearChart/VisualizationRenderer', async importOriginal => {
17
+ const React = await import('react')
18
+ const actual = await importOriginal<typeof import('../../LinearChart/VisualizationRenderer')>()
19
+
20
+ const MockVisualizationRenderer = props => {
21
+ if (visualizationRendererMockState.renderActual) return React.createElement(actual.default, props)
22
+ return React.createElement('g', { 'data-testid': 'mock-visualization-renderer' })
23
+ }
24
+
25
+ return {
26
+ default: MockVisualizationRenderer
27
+ }
28
+ })
9
29
 
10
30
  // Mock ResizeObserver
11
31
  vi.stubGlobal(
12
32
  'ResizeObserver',
13
- vi.fn(() => ({
14
- observe: vi.fn(),
15
- unobserve: vi.fn(),
16
- disconnect: vi.fn()
17
- }))
33
+ vi.fn(function ResizeObserver() {
34
+ return {
35
+ observe: vi.fn(),
36
+ unobserve: vi.fn(),
37
+ disconnect: vi.fn()
38
+ }
39
+ })
18
40
  )
19
41
 
20
42
  // Mock IntersectionObserver
21
43
  vi.stubGlobal(
22
44
  'IntersectionObserver',
23
- vi.fn(() => ({
24
- observe: vi.fn(),
25
- unobserve: vi.fn(),
26
- disconnect: vi.fn()
27
- }))
45
+ vi.fn(function IntersectionObserver() {
46
+ return {
47
+ observe: vi.fn(),
48
+ unobserve: vi.fn(),
49
+ disconnect: vi.fn()
50
+ }
51
+ })
28
52
  )
29
53
 
30
54
  // Mock canvas for text measurement
@@ -53,6 +77,10 @@ beforeAll(() => {
53
77
  }))
54
78
  })
55
79
 
80
+ beforeEach(() => {
81
+ visualizationRendererMockState.renderActual = false
82
+ })
83
+
56
84
  // Helper to render LinearChart with context
57
85
  const renderLinearChart = (
58
86
  configOverrides = {},
@@ -73,6 +101,40 @@ const getLeftAxisLabelTransforms = container =>
73
101
  .map(label => label.getAttribute('transform'))
74
102
  .filter(Boolean)
75
103
 
104
+ const renderRightAxis = (yAxisOverrides, runtimeYAxisOverrides = {}, rightAxisWidth = 70) => {
105
+ const context = createMockChartContext({
106
+ yAxis: {
107
+ ...createMockChartContext().config.yAxis,
108
+ rightLabel: 'Right Axis',
109
+ ...yAxisOverrides
110
+ },
111
+ runtime: {
112
+ ...createMockChartContext().config.runtime,
113
+ yAxis: {
114
+ ...createMockChartContext().config.runtime.yAxis,
115
+ rightNumTicks: 4,
116
+ ...runtimeYAxisOverrides
117
+ }
118
+ }
119
+ })
120
+
121
+ return render(
122
+ <ConfigContext.Provider value={context}>
123
+ <svg>
124
+ <RightAxis
125
+ yScaleRight={scaleLinear({ domain: [0, 100], range: [300, 0] })}
126
+ yMax={300}
127
+ xMax={400}
128
+ yAxisWidth={50}
129
+ rightAxisWidth={rightAxisWidth}
130
+ tickLabelFontSize={12}
131
+ axisLabelFontSize={14}
132
+ />
133
+ </svg>
134
+ </ConfigContext.Provider>
135
+ )
136
+ }
137
+
76
138
  const sidePlacementYAxis = {
77
139
  hideAxis: false,
78
140
  hideLabel: false,
@@ -85,7 +147,8 @@ const sidePlacementYAxis = {
85
147
  anchors: [],
86
148
  axisPadding: 0,
87
149
  labelPlacement: 'On Date/Category Axis',
88
- rightAxisSize: 0
150
+ rightAxisSize: 0,
151
+ rightTitlePlacement: 'side'
89
152
  }
90
153
 
91
154
  describe('LinearChart', () => {
@@ -147,6 +210,112 @@ describe('LinearChart', () => {
147
210
  const svg = container.querySelector('svg')
148
211
  expect(svg?.classList.contains('animated')).toBe(false)
149
212
  })
213
+
214
+ it('renders region fills above gridlines, below visualization marks, and keeps region labels above marks', () => {
215
+ const rows = [
216
+ { Date: '2024-01-01', Value: 10 },
217
+ { Date: '2024-01-08', Value: 20 }
218
+ ]
219
+ const { container } = renderLinearChart(
220
+ {
221
+ regions: [
222
+ {
223
+ from: '2024-01-01',
224
+ to: '2024-01-08',
225
+ label: 'Reporting period',
226
+ background: '#005ea8',
227
+ color: '#1b1b1b'
228
+ }
229
+ ],
230
+ series: [{ dataKey: 'Value', type: 'Line', axis: 'Left' }],
231
+ runtime: {
232
+ ...createMockChartContext().config.runtime,
233
+ seriesKeys: ['Value'],
234
+ seriesLabels: { Value: 'Value' }
235
+ }
236
+ },
237
+ { transformedData: rows, tableData: rows }
238
+ )
239
+
240
+ const fill = container.querySelector('.region-fill')
241
+ const gridlines = container.querySelector('.left-axis')
242
+ const visualization = container.querySelector('[data-testid="mock-visualization-renderer"]')
243
+ const label = container.querySelector('.region-label')
244
+
245
+ expect(fill).toBeTruthy()
246
+ expect(label).toBeTruthy()
247
+ expect(container.querySelectorAll('.region-fill')).toHaveLength(1)
248
+ expect(gridlines!.compareDocumentPosition(fill!) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
249
+ expect(fill!.compareDocumentPosition(visualization!) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
250
+ expect(visualization!.compareDocumentPosition(label!) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy()
251
+ })
252
+
253
+ it('uses band boundaries for converted lines and point boundaries for barless Combo charts', () => {
254
+ const rows = [
255
+ { Date: '2024-01-01', Value: 10 },
256
+ { Date: '2024-01-08', Value: 20 },
257
+ { Date: '2024-01-15', Value: 30 }
258
+ ]
259
+ const baseConfig = {
260
+ regions: [
261
+ {
262
+ from: '2024-01-01',
263
+ to: '2024-01-08',
264
+ label: 'Reporting period',
265
+ background: '#005ea8',
266
+ color: '#1b1b1b'
267
+ }
268
+ ],
269
+ series: [{ dataKey: 'Value', type: 'Line', axis: 'Left' }],
270
+ runtime: {
271
+ ...createMockChartContext().config.runtime,
272
+ seriesKeys: ['Value'],
273
+ seriesLabels: { Value: 'Value' }
274
+ }
275
+ }
276
+
277
+ const converted = renderLinearChart(baseConfig, {
278
+ transformedData: rows,
279
+ tableData: rows,
280
+ convertLineToBarGraph: true
281
+ })
282
+ const convertedWidth = Number(converted.container.querySelector('.region-fill')?.getAttribute('width'))
283
+ converted.unmount()
284
+
285
+ const barlessCombo = renderLinearChart(
286
+ {
287
+ ...baseConfig,
288
+ visualizationType: 'Combo',
289
+ runtime: {
290
+ ...baseConfig.runtime,
291
+ barSeriesKeys: [],
292
+ lineSeriesKeys: ['Value']
293
+ }
294
+ },
295
+ { transformedData: rows, tableData: rows }
296
+ )
297
+ const barlessComboWidth = Number(barlessCombo.container.querySelector('.region-fill')?.getAttribute('width'))
298
+
299
+ expect(convertedWidth).toBeGreaterThan(barlessComboWidth)
300
+ })
301
+
302
+ it('does not render regions for visualization types outside the explicit region whitelist', () => {
303
+ const { container } = renderLinearChart({
304
+ visualizationType: 'Scatter Plot',
305
+ regions: [
306
+ {
307
+ from: 'A',
308
+ to: 'B',
309
+ label: 'Reporting period',
310
+ background: '#005ea8',
311
+ color: '#1b1b1b'
312
+ }
313
+ ]
314
+ })
315
+
316
+ expect(container.querySelector('.region-fill')).toBeNull()
317
+ expect(container.querySelector('.region-label')).toBeNull()
318
+ })
150
319
  })
151
320
 
152
321
  describe('empty data handling', () => {
@@ -200,6 +369,8 @@ describe('LinearChart', () => {
200
369
  })
201
370
 
202
371
  it('keeps forest plot lines inside the computed plot bounds at narrow and wide widths', () => {
372
+ visualizationRendererMockState.renderActual = true
373
+
203
374
  const forestContextOverrides = {
204
375
  transformedData: forestPlotConfig.data,
205
376
  rawData: forestPlotConfig.data
@@ -242,6 +413,8 @@ describe('LinearChart', () => {
242
413
  })
243
414
 
244
415
  it('avoids rendering a duplicate manual bottom border when the forest plot x-axis is visible', () => {
416
+ visualizationRendererMockState.renderActual = true
417
+
245
418
  const { container } = renderLinearChart(
246
419
  forestPlotConfig as any,
247
420
  {
@@ -258,6 +431,8 @@ describe('LinearChart', () => {
258
431
  })
259
432
 
260
433
  it('renders forest plot rows from transformedData instead of rawData', () => {
434
+ visualizationRendererMockState.renderActual = true
435
+
261
436
  const filteredData = forestPlotConfig.data.slice(0, 2)
262
437
  const { container } = renderLinearChart(
263
438
  forestPlotConfig as any,
@@ -277,6 +452,206 @@ describe('LinearChart', () => {
277
452
  })
278
453
 
279
454
  describe('axis rendering', () => {
455
+ it('renders left y-axis and x-axis anchors independently', () => {
456
+ const data = [
457
+ { Category: 'A', Value: 5 },
458
+ { Category: 'B', Value: 10 }
459
+ ]
460
+
461
+ const { container } = renderLinearChart(
462
+ {
463
+ visualizationType: 'Bar',
464
+ debugSvg: true,
465
+ data,
466
+ series: [{ dataKey: 'Value', axis: 'Left', type: 'Bar' }],
467
+ xAxis: {
468
+ ...createMockChartContext().config.xAxis,
469
+ type: 'categorical',
470
+ dataKey: 'Category',
471
+ anchors: [{ value: 'A', color: '#135', lineStyle: 'dashed' }]
472
+ },
473
+ yAxis: {
474
+ ...createMockChartContext().config.yAxis,
475
+ anchors: [{ value: '5', color: '#531', lineStyle: 'solid' }]
476
+ },
477
+ runtime: {
478
+ ...createMockChartContext().config.runtime,
479
+ xAxis: {
480
+ ...createMockChartContext().config.runtime.xAxis,
481
+ type: 'categorical',
482
+ dataKey: 'Category'
483
+ },
484
+ originalXAxis: {
485
+ dataKey: 'Category'
486
+ },
487
+ series: [{ dataKey: 'Value', axis: 'Left', type: 'Bar' }],
488
+ seriesKeys: ['Value']
489
+ }
490
+ },
491
+ {
492
+ transformedData: data,
493
+ tableData: data
494
+ }
495
+ )
496
+
497
+ expect(container.querySelectorAll('.anchor-y')).toHaveLength(1)
498
+ expect(container.querySelectorAll('.anchor-x')).toHaveLength(1)
499
+ expect(container.querySelector('.anchor-y-right')).toBeFalsy()
500
+ })
501
+
502
+ it('renders right y-axis anchors only when a vertical Combo chart has right-axis series', () => {
503
+ const data = [{ Date: '2024-01-01', LeftValue: 25, RightValue: 50 }]
504
+ const comboConfig = {
505
+ data,
506
+ visualizationType: 'Combo',
507
+ visualizationSubType: 'regular',
508
+ debugSvg: true,
509
+ orientation: 'vertical',
510
+ preliminaryData: [],
511
+ series: [
512
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
513
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
514
+ ],
515
+ yAxis: {
516
+ ...createMockChartContext().config.yAxis,
517
+ rightAnchors: [{ value: '50', color: '#246', lineStyle: 'dashed' }],
518
+ rightAxisSize: 60
519
+ },
520
+ runtime: {
521
+ ...createMockChartContext().config.runtime,
522
+ series: [
523
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
524
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
525
+ ],
526
+ seriesKeys: ['LeftValue', 'RightValue'],
527
+ areaSeriesKeys: [],
528
+ forecastingSeriesKeys: []
529
+ }
530
+ }
531
+
532
+ const combo = renderLinearChart(comboConfig, {
533
+ transformedData: data,
534
+ tableData: data
535
+ })
536
+ const line = renderLinearChart(
537
+ {
538
+ ...comboConfig,
539
+ visualizationType: 'Line'
540
+ },
541
+ {
542
+ transformedData: data,
543
+ tableData: data
544
+ }
545
+ )
546
+
547
+ expect(combo.container.querySelectorAll('.anchor-y-right')).toHaveLength(1)
548
+ expect(line.container.querySelector('.anchor-y-right')).toBeFalsy()
549
+ })
550
+
551
+ it('uses the right y-scale for right-axis anchors', () => {
552
+ const data = [{ Date: '2024-01-01', LeftValue: 50, RightValue: 80 }]
553
+
554
+ const { container } = renderLinearChart(
555
+ {
556
+ data,
557
+ visualizationType: 'Combo',
558
+ visualizationSubType: 'regular',
559
+ debugSvg: true,
560
+ orientation: 'vertical',
561
+ preliminaryData: [],
562
+ series: [
563
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
564
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
565
+ ],
566
+ yAxis: {
567
+ ...createMockChartContext().config.yAxis,
568
+ anchors: [{ value: '50', color: '#531', lineStyle: 'solid' }],
569
+ rightAnchors: [{ value: '50', color: '#246', lineStyle: 'dashed' }],
570
+ rightAxisSize: 60,
571
+ rightMin: '0',
572
+ rightMax: '100'
573
+ },
574
+ runtime: {
575
+ ...createMockChartContext().config.runtime,
576
+ series: [
577
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
578
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
579
+ ],
580
+ seriesKeys: ['LeftValue', 'RightValue'],
581
+ areaSeriesKeys: [],
582
+ forecastingSeriesKeys: []
583
+ }
584
+ },
585
+ {
586
+ transformedData: data,
587
+ tableData: data
588
+ }
589
+ )
590
+
591
+ const leftAnchorY = Number(container.querySelector('.anchor-y')?.getAttribute('y1'))
592
+ const rightAnchorY = Number(container.querySelector('.anchor-y-right')?.getAttribute('y1'))
593
+
594
+ expect(Number.isFinite(leftAnchorY)).toBe(true)
595
+ expect(Number.isFinite(rightAnchorY)).toBe(true)
596
+ expect(rightAnchorY).toBeGreaterThan(leftAnchorY)
597
+ })
598
+
599
+ it('renders numeric zero value-axis anchors', () => {
600
+ const data = [{ Date: '2024-01-01', LeftValue: 50, RightValue: 80 }]
601
+
602
+ const { container } = renderLinearChart(
603
+ {
604
+ data,
605
+ visualizationType: 'Combo',
606
+ visualizationSubType: 'regular',
607
+ debugSvg: true,
608
+ orientation: 'vertical',
609
+ preliminaryData: [],
610
+ series: [
611
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
612
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
613
+ ],
614
+ yAxis: {
615
+ ...createMockChartContext().config.yAxis,
616
+ anchors: [{ value: 0, color: '#531', lineStyle: 'solid' }],
617
+ rightAnchors: [{ value: 0, color: '#246', lineStyle: 'dashed' }],
618
+ rightAxisSize: 60,
619
+ rightMin: '0',
620
+ rightMax: '100'
621
+ },
622
+ runtime: {
623
+ ...createMockChartContext().config.runtime,
624
+ series: [
625
+ { dataKey: 'LeftValue', axis: 'Left', type: 'Bar' },
626
+ { dataKey: 'RightValue', axis: 'Right', type: 'Line' }
627
+ ],
628
+ seriesKeys: ['LeftValue', 'RightValue'],
629
+ areaSeriesKeys: [],
630
+ forecastingSeriesKeys: []
631
+ }
632
+ } as any,
633
+ {
634
+ transformedData: data,
635
+ tableData: data
636
+ }
637
+ )
638
+
639
+ expect(container.querySelectorAll('.anchor-y')).toHaveLength(1)
640
+ expect(container.querySelectorAll('.anchor-y-right')).toHaveLength(1)
641
+ })
642
+
643
+ it('does not error when configs omit rightAnchors', () => {
644
+ const { container } = renderLinearChart({
645
+ yAxis: {
646
+ ...createMockChartContext().config.yAxis,
647
+ rightAnchors: undefined
648
+ }
649
+ })
650
+
651
+ expect(container.querySelector('svg')).toBeTruthy()
652
+ expect(container.querySelector('.anchor-y-right')).toBeFalsy()
653
+ })
654
+
280
655
  it('renders left axis group', () => {
281
656
  const { container } = renderLinearChart()
282
657
  const leftAxis = container.querySelector('.left-axis')
@@ -304,6 +679,31 @@ describe('LinearChart', () => {
304
679
  expect(container.querySelector('.left-axis text.y-label')).toBeTruthy()
305
680
  })
306
681
 
682
+ it('renders the right axis side title when rightTitlePlacement is omitted', () => {
683
+ const { container } = renderRightAxis({ rightTitlePlacement: undefined })
684
+
685
+ expect(container.querySelector('.right-axis text.y-label')?.textContent).toBe('Right Axis')
686
+ })
687
+
688
+ it('renders the right axis side title from the processed runtime label when available', () => {
689
+ const { container } = renderRightAxis({ rightTitlePlacement: 'side' }, { rightLabel: 'Processed Right Axis' })
690
+
691
+ expect(container.querySelector('.right-axis text.y-label')?.textContent).toBe('Processed Right Axis')
692
+ })
693
+
694
+ it('places right tick labels after the tick margin and keeps the side title inside the measured gutter', () => {
695
+ const { container } = renderRightAxis({ rightTitlePlacement: 'side' }, {}, 73)
696
+
697
+ expect(container.querySelector('.right-axis .vx-axis-tick text')?.getAttribute('x')).toBe('12.5')
698
+ expect(container.querySelector('.right-axis text.y-label')?.getAttribute('transform')).toContain('translate(59,')
699
+ })
700
+
701
+ it('suppresses the right axis side title when rightTitlePlacement is top', () => {
702
+ const { container } = renderRightAxis({ rightTitlePlacement: 'top' })
703
+
704
+ expect(container.querySelector('.right-axis text.y-label')).toBeFalsy()
705
+ })
706
+
307
707
  it('renders bottom axis group', () => {
308
708
  const { container } = renderLinearChart()
309
709
  const bottomAxis = container.querySelector('.bottom-axis')
@@ -515,7 +915,6 @@ describe('LinearChart', () => {
515
915
  it('sets correct width based on parentWidth prop', () => {
516
916
  const { container } = renderLinearChart({}, {}, { parentWidth: 600, parentHeight: 400 })
517
917
  const svg = container.querySelector('svg')
518
- // Width should include rightAxisSize (default 0)
519
918
  expect(svg?.getAttribute('width')).toBe('600')
520
919
  })
521
920