@cdc/chart 4.26.3 → 4.26.4

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 (128) hide show
  1. package/CONFIG.md +169 -0
  2. package/README.md +42 -17
  3. package/dist/cdcchart.js +34725 -33730
  4. package/examples/feature/bar/additional-column-tooltip.json +3 -3
  5. package/examples/feature/deviation/planet-deviation-config.json +2 -2
  6. package/examples/feature/paired-bar/paired-bar-example.json +2 -2
  7. package/examples/feature/tests-case-rate/case-rate-example-config.json +2 -2
  8. package/examples/feature/tests-covid/covid-confidence-example-config.json +2 -2
  9. package/examples/feature/tests-covid/covid-example-config.json +2 -2
  10. package/examples/feature/tests-cutoff/cutoff-example-config.json +2 -2
  11. package/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json +2 -2
  12. package/examples/metadata-variables.json +1 -1
  13. package/examples/minimal-example.json +24 -0
  14. package/examples/private/test2.json +35012 -0
  15. package/package.json +4 -4
  16. package/src/CdcChartComponent.tsx +9 -6
  17. package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
  18. package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
  19. package/src/_stories/{Chart.SmallMultiples.stories.tsx → Chart.SmallMultiples.smoke.stories.tsx} +17 -1
  20. package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +12 -0
  21. package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
  22. package/src/_stories/ChartBar.Editor.stories.tsx +88 -85
  23. package/src/_stories/ChartEditor.Editor.stories.tsx +23 -0
  24. package/src/_stories/ChartLine.DashedDates.smoke.stories.tsx +23 -0
  25. package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
  26. package/src/_stories/_mock/paired-bar-abbr.json +1 -1
  27. package/src/_stories/_mock/paired-bar.json +1 -1
  28. package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -1
  29. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
  30. package/src/components/Axis/BottomAxis.tsx +1 -1
  31. package/src/components/Axis/LeftAxis.tsx +2 -4
  32. package/src/components/Axis/LeftAxisGridlines.tsx +1 -3
  33. package/src/components/BarChart/components/BarChart.Horizontal.tsx +9 -5
  34. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +9 -5
  35. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +9 -5
  36. package/src/components/BarChart/components/BarChart.Vertical.tsx +9 -6
  37. package/src/components/BarChart/components/BarChart.tsx +2 -6
  38. package/src/components/BarChart/helpers/useBarChart.ts +1 -1
  39. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
  40. package/src/components/EditorPanel/EditorPanel.tsx +633 -908
  41. package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
  42. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +216 -165
  43. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +168 -116
  44. package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +154 -109
  45. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
  46. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +12 -26
  47. package/src/components/EditorPanel/useEditorPermissions.ts +1 -10
  48. package/src/components/Forecasting/Forecasting.tsx +2 -2
  49. package/src/components/HorizonChart/HorizonChart.tsx +10 -2
  50. package/src/components/HoverLine/HoverLine.tsx +6 -8
  51. package/src/components/Legend/Legend.Component.tsx +4 -4
  52. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +5 -0
  53. package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
  54. package/src/components/Legend/helpers/index.ts +0 -2
  55. package/src/components/LineChart/LineChartProps.ts +1 -0
  56. package/src/components/LineChart/components/LineChart.BumpCircle.tsx +3 -2
  57. package/src/components/LineChart/index.tsx +11 -4
  58. package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
  59. package/src/components/LinearChart/tests/LinearChart.test.tsx +147 -0
  60. package/src/components/LinearChart.tsx +98 -41
  61. package/src/components/PairedBarChart.jsx +2 -2
  62. package/src/components/PieChart/PieChart.tsx +11 -9
  63. package/src/components/Regions/components/Regions.tsx +30 -20
  64. package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
  65. package/src/components/SmallMultiples/SmallMultipleTile.tsx +1 -0
  66. package/src/components/Sparkline/components/SparkLine.tsx +1 -1
  67. package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
  68. package/src/data/initial-state.js +1 -0
  69. package/src/helpers/calculateLeftYAxisWidth.ts +193 -0
  70. package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
  71. package/src/helpers/tooltipHelpers.ts +176 -0
  72. package/src/hooks/useHighlightedBars.ts +9 -16
  73. package/src/hooks/useProgrammaticTooltip.ts +16 -2
  74. package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
  75. package/src/hooks/useTooltip.tsx +167 -38
  76. package/src/test/CdcChart.test.jsx +24 -0
  77. package/src/types/ChartConfig.ts +1 -0
  78. package/LICENSE +0 -201
  79. package/examples/chart-regression-2.json +0 -2360
  80. package/examples/feature/__data__/age-adjusted-rates.json +0 -1486
  81. package/examples/feature/__data__/city-temperature.json +0 -2198
  82. package/examples/feature/bar/Barchart_with_negative.json +0 -34
  83. package/examples/feature/boxplot/box-plot-data.json +0 -71
  84. package/examples/feature/boxplot/boxplot-data.json +0 -156
  85. package/examples/feature/combo/combochart-categories_are_numbers .json +0 -18
  86. package/examples/feature/forest-plot/log.json +0 -26
  87. package/examples/feature/tests-date-exclusions/date-exclusions-data.json +0 -162
  88. package/examples/region-issue.json +0 -2065
  89. package/examples/xaxis.json +0 -493
  90. /package/examples/{data → __data__}/data-with-metadata.json +0 -0
  91. /package/examples/feature/bar/{tall-data.json → __data__/tall-data.json} +0 -0
  92. /package/examples/feature/deviation/{planet-deviation-data.json → __data__/planet-deviation-data.json} +0 -0
  93. /package/examples/feature/paired-bar/{paired-bar-data.json → __data__/paired-bar-data.json} +0 -0
  94. /package/examples/feature/paired-bar/{paired-bar-formatted.json → __data__/paired-bar-formatted.json} +0 -0
  95. /package/examples/feature/tests-case-rate/{case-rate-example-data.json → __data__/case-rate-example-data.json} +0 -0
  96. /package/examples/feature/tests-covid/{covid-example-data-confidence.json → __data__/covid-example-data-confidence.json} +0 -0
  97. /package/examples/feature/tests-covid/{covid-example-data.json → __data__/covid-example-data.json} +0 -0
  98. /package/examples/feature/tests-cutoff/{cutoff-example-data.json → __data__/cutoff-example-data.json} +0 -0
  99. /package/examples/feature/tests-non-numerics/{planet-example-data-nonnumeric.json → __data__/planet-example-data-nonnumeric.json} +0 -0
  100. /package/src/_stories/{Chart.Anchors.stories.tsx → Chart.Anchors.smoke.stories.tsx} +0 -0
  101. /package/src/_stories/{Chart.BoxPlot.stories.tsx → Chart.BoxPlot.smoke.stories.tsx} +0 -0
  102. /package/src/_stories/{Chart.CI.stories.tsx → Chart.CI.smoke.stories.tsx} +0 -0
  103. /package/src/_stories/{Chart.Combo.stories.tsx → Chart.Combo.smoke.stories.tsx} +0 -0
  104. /package/src/_stories/{Chart.CustomColors.stories.tsx → Chart.CustomColors.smoke.stories.tsx} +0 -0
  105. /package/src/_stories/{Chart.Defaults.stories.tsx → Chart.Defaults.smoke.stories.tsx} +0 -0
  106. /package/src/_stories/{Chart.DynamicSeries.stories.tsx → Chart.DynamicSeries.smoke.stories.tsx} +0 -0
  107. /package/src/_stories/{Chart.Filters.stories.tsx → Chart.Filters.smoke.stories.tsx} +0 -0
  108. /package/src/_stories/{Chart.Forecast.stories.tsx → Chart.Forecast.smoke.stories.tsx} +0 -0
  109. /package/src/_stories/{Chart.Legend.Gradient.stories.tsx → Chart.Legend.Gradient.smoke.stories.tsx} +0 -0
  110. /package/src/_stories/{Chart.Patterns.stories.tsx → Chart.Patterns.smoke.stories.tsx} +0 -0
  111. /package/src/_stories/{Chart.PreserveDecimals.stories.tsx → Chart.PreserveDecimals.smoke.stories.tsx} +0 -0
  112. /package/src/_stories/{Chart.Regions.Categorical.stories.tsx → Chart.Regions.Categorical.smoke.stories.tsx} +0 -0
  113. /package/src/_stories/{Chart.Regions.DateScale.stories.tsx → Chart.Regions.DateScale.smoke.stories.tsx} +0 -0
  114. /package/src/_stories/{Chart.Regions.DateTimeScale.stories.tsx → Chart.Regions.DateTimeScale.smoke.stories.tsx} +0 -0
  115. /package/src/_stories/{Chart.ScatterPlot.stories.tsx → Chart.ScatterPlot.smoke.stories.tsx} +0 -0
  116. /package/src/_stories/{Chart.SmallestLeftAxisMax.stories.tsx → Chart.SmallestLeftAxisMax.smoke.stories.tsx} +0 -0
  117. /package/src/_stories/{ChartAnnotation.stories.tsx → ChartAnnotation.smoke.stories.tsx} +0 -0
  118. /package/src/_stories/{ChartAxisLabels.stories.tsx → ChartAxisLabels.smoke.stories.tsx} +0 -0
  119. /package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +0 -0
  120. /package/src/_stories/{ChartBrush.Matrix.Continuous.stories.tsx → ChartBrush.Matrix.Continuous.smoke.stories.tsx} +0 -0
  121. /package/src/_stories/{ChartBrush.Matrix.Date.stories.tsx → ChartBrush.Matrix.Date.smoke.stories.tsx} +0 -0
  122. /package/src/_stories/{ChartBrush.Matrix.DateTime.stories.tsx → ChartBrush.Matrix.DateTime.smoke.stories.tsx} +0 -0
  123. /package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +0 -0
  124. /package/src/_stories/{ChartLine.QuadrantAngles.stories.tsx → ChartLine.QuadrantAngles.smoke.stories.tsx} +0 -0
  125. /package/src/_stories/{ChartLine.Suppression.stories.tsx → ChartLine.Suppression.smoke.stories.tsx} +0 -0
  126. /package/src/_stories/{ChartLine.Symbols.stories.tsx → ChartLine.Symbols.smoke.stories.tsx} +0 -0
  127. /package/src/_stories/{ChartPrefixSuffix.stories.tsx → ChartPrefixSuffix.smoke.stories.tsx} +0 -0
  128. /package/src/_stories/{TechAdoptionWithLinks.stories.tsx → TechAdoptionWithLinks.smoke.stories.tsx} +0 -0
@@ -0,0 +1,23 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite'
2
+ import Chart from '../CdcChartComponent'
3
+ import config from './_mock/line_chart_dashed_dates.json'
4
+ import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
5
+
6
+ const meta: Meta<typeof Chart> = {
7
+ title: 'Components/Templates/Chart/Special Lines - Dashed on Date Axis',
8
+ component: Chart
9
+ }
10
+
11
+ type Story = StoryObj<typeof Chart>
12
+
13
+ export const DashedSpecialLineWithDates: Story = {
14
+ args: {
15
+ config: config,
16
+ isEditor: false
17
+ },
18
+ play: async ({ canvasElement }) => {
19
+ await assertVisualizationRendered(canvasElement)
20
+ }
21
+ }
22
+
23
+ export default meta
@@ -0,0 +1,276 @@
1
+ {
2
+ "type": "chart",
3
+ "title": "Special Lines - Dashed Effect on Date Axis",
4
+ "theme": "theme-blue",
5
+ "animate": false,
6
+ "fontSize": "medium",
7
+ "lineDatapointStyle": "hover",
8
+ "lineDatapointColor": "Same as Line",
9
+ "visualizationSubType": "regular",
10
+ "visualizationType": "Line",
11
+ "isLollipopChart": false,
12
+ "lollipopShape": "circle",
13
+ "lollipopColorStyle": "two-tone",
14
+ "barStyle": "flat",
15
+ "roundingStyle": "standard",
16
+ "tipRounding": "top",
17
+ "isResponsiveTicks": false,
18
+ "general": {
19
+ "annotationDropdownText": "Annotations",
20
+ "showDownloadButton": false,
21
+ "showMissingDataLabel": true,
22
+ "showSuppressedSymbol": true,
23
+ "showZeroValueData": true,
24
+ "hideNullValue": true
25
+ },
26
+ "padding": { "left": 5, "right": 5 },
27
+ "preliminaryData": [
28
+ {
29
+ "type": "effect",
30
+ "seriesKeys": ["Value"],
31
+ "label": "Preliminary",
32
+ "column": "Status",
33
+ "value": "preliminary",
34
+ "style": "Dashed Small",
35
+ "displayTooltip": true,
36
+ "displayLegend": true,
37
+ "displayTable": true,
38
+ "symbol": "",
39
+ "iconCode": "",
40
+ "lineCode": "- - -",
41
+ "hideBarSymbol": false,
42
+ "hideLineStyle": false,
43
+ "circleSize": 6,
44
+ "displayGray": false
45
+ }
46
+ ],
47
+ "yAxis": {
48
+ "hideAxis": false,
49
+ "displayNumbersOnBar": false,
50
+ "hideLabel": false,
51
+ "hideTicks": false,
52
+ "size": 50,
53
+ "gridLines": true,
54
+ "enablePadding": false,
55
+ "min": "",
56
+ "max": "",
57
+ "labelColor": "#333",
58
+ "tickLabelColor": "#333",
59
+ "tickColor": "#333",
60
+ "rightHideAxis": true,
61
+ "rightAxisSize": 0,
62
+ "rightLabel": "",
63
+ "rightLabelOffsetSize": 0,
64
+ "rightAxisLabelColor": "#333",
65
+ "rightAxisTickLabelColor": "#333",
66
+ "rightAxisTickColor": "#333",
67
+ "numTicks": "",
68
+ "axisPadding": 0,
69
+ "scalePadding": 10,
70
+ "tickRotation": 0,
71
+ "anchors": [],
72
+ "shoMissingDataLabel": true,
73
+ "showMissingDataLine": true,
74
+ "categories": [],
75
+ "label": "Count"
76
+ },
77
+ "boxplot": {
78
+ "plots": [],
79
+ "borders": "true",
80
+ "plotOutlierValues": false,
81
+ "plotNonOutlierValues": true,
82
+ "labels": {
83
+ "q1": "Lower Quartile",
84
+ "q2": "q2",
85
+ "q3": "Upper Quartile",
86
+ "q4": "q4",
87
+ "minimum": "Minimum",
88
+ "maximum": "Maximum",
89
+ "mean": "Mean",
90
+ "median": "Median",
91
+ "sd": "Standard Deviation",
92
+ "iqr": "Interquartile Range",
93
+ "outliers": "Outliers",
94
+ "values": "Values",
95
+ "lowerBounds": "Lower Bounds",
96
+ "upperBounds": "Upper Bounds"
97
+ }
98
+ },
99
+ "topAxis": { "hasLine": false },
100
+ "isLegendValue": false,
101
+ "barThickness": 0.35,
102
+ "barHeight": 25,
103
+ "barSpace": 15,
104
+ "heights": { "vertical": 300, "horizontal": 750 },
105
+ "xAxis": {
106
+ "sortDates": false,
107
+ "anchors": [],
108
+ "type": "date",
109
+ "showTargetLabel": false,
110
+ "targetLabel": "Target",
111
+ "hideAxis": false,
112
+ "hideLabel": false,
113
+ "hideTicks": false,
114
+ "size": 75,
115
+ "tickRotation": 0,
116
+ "min": "",
117
+ "max": "",
118
+ "labelColor": "#333",
119
+ "tickLabelColor": "#333",
120
+ "tickColor": "#333",
121
+ "numTicks": "",
122
+ "labelOffset": 0,
123
+ "axisPadding": 0,
124
+ "target": 0,
125
+ "maxTickRotation": 0,
126
+ "padding": 6,
127
+ "showYearsOnce": false,
128
+ "dataKey": "date",
129
+ "label": "",
130
+ "dateParseFormat": "%Y-%m-%d",
131
+ "dateDisplayFormat": "%b %Y"
132
+ },
133
+ "table": {
134
+ "label": "Data Table",
135
+ "expanded": false,
136
+ "limitHeight": false,
137
+ "height": "",
138
+ "caption": "",
139
+ "showDownloadUrl": false,
140
+ "showDataTableLink": true,
141
+ "showDownloadLinkBelow": true,
142
+ "indexLabel": "",
143
+ "download": false,
144
+ "showVertical": true,
145
+ "dateDisplayFormat": "",
146
+ "showMissingDataLabel": true,
147
+ "showSuppressedSymbol": true,
148
+ "show": true
149
+ },
150
+ "orientation": "vertical",
151
+ "color": "pinkpurple",
152
+ "columns": {},
153
+ "legend": {
154
+ "hide": false,
155
+ "behavior": "highlight",
156
+ "axisAlign": true,
157
+ "singleRow": true,
158
+ "colorCode": "",
159
+ "reverseLabelOrder": false,
160
+ "description": "",
161
+ "dynamicLegend": false,
162
+ "dynamicLegendDefaultText": "Show All",
163
+ "dynamicLegendItemLimit": 5,
164
+ "dynamicLegendItemLimitMessage": "Dynamic Legend Item Limit Hit.",
165
+ "dynamicLegendChartMessage": "Select Options from the Legend",
166
+ "label": "",
167
+ "lineMode": false,
168
+ "verticalSorted": false,
169
+ "highlightOnHover": false,
170
+ "hideSuppressedLabels": false,
171
+ "hideSuppressionLink": false,
172
+ "seriesHighlight": [],
173
+ "style": "lines",
174
+ "subStyle": "linear blocks",
175
+ "tickRotation": "",
176
+ "hideBorder": { "side": false, "topBottom": true }
177
+ },
178
+ "brush": { "height": 25, "active": false },
179
+ "exclusions": { "active": false, "keys": [] },
180
+ "palette": "qualitative-bold",
181
+ "isPaletteReversed": false,
182
+ "twoColor": { "palette": "monochrome-1", "isPaletteReversed": false },
183
+ "labels": false,
184
+ "dataFormat": {
185
+ "commas": false,
186
+ "prefix": "",
187
+ "suffix": "",
188
+ "abbreviated": false,
189
+ "bottomSuffix": "",
190
+ "bottomPrefix": "",
191
+ "bottomAbbreviated": false
192
+ },
193
+ "confidenceKeys": {},
194
+ "visual": {
195
+ "border": true,
196
+ "accent": true,
197
+ "background": true,
198
+ "verticalHoverLine": true,
199
+ "horizontalHoverLine": false
200
+ },
201
+ "useLogScale": false,
202
+ "filterBehavior": "Filter Change",
203
+ "highlightedBarValues": [],
204
+ "series": [
205
+ {
206
+ "dataKey": "Value",
207
+ "type": "Line",
208
+ "lineType": "curveLinear",
209
+ "axis": "Left",
210
+ "tooltip": true
211
+ }
212
+ ],
213
+ "tooltips": { "opacity": 90, "singleSeries": false, "dateDisplayFormat": "" },
214
+ "annotations": [],
215
+ "debugSvg": false,
216
+ "chartMessage": { "noData": "No Data Available" },
217
+ "showTitle": true,
218
+ "showDownloadMediaButton": false,
219
+ "isResponsiveTicks": false,
220
+ "forestPlot": {
221
+ "startAt": 0,
222
+ "colors": { "line": "", "shape": "" },
223
+ "lineOfNoEffect": { "show": true },
224
+ "type": "",
225
+ "pooledResult": { "diamondHeight": 5, "column": "" },
226
+ "estimateField": "",
227
+ "estimateRadius": "",
228
+ "shape": "square",
229
+ "rowHeight": 20,
230
+ "description": { "show": true, "text": "description", "location": 0 },
231
+ "result": { "show": true, "text": "result", "location": 100 },
232
+ "radius": { "min": 2, "max": 10, "scalingColumn": "" },
233
+ "regression": { "lower": 0, "upper": 0, "estimateField": 0 },
234
+ "leftWidthOffset": 0,
235
+ "rightWidthOffset": 0,
236
+ "showZeroLine": false,
237
+ "leftLabel": "",
238
+ "rightLabel": ""
239
+ },
240
+ "area": { "isStacked": false },
241
+ "sankey": {
242
+ "title": { "defaultColor": "black" },
243
+ "iterations": 1,
244
+ "rxValue": 0.9,
245
+ "overallSize": { "width": 900, "height": 700 },
246
+ "margin": { "margin_y": 25, "margin_x": 0 },
247
+ "nodeSize": { "nodeWidth": 26, "nodeHeight": 40 },
248
+ "nodePadding": 55,
249
+ "nodeFontColor": "black",
250
+ "nodeColor": { "default": "#ff8500", "inactive": "#808080" },
251
+ "linkColor": { "default": "#ffc900", "inactive": "#D3D3D3" },
252
+ "opacity": {
253
+ "nodeOpacityDefault": 1,
254
+ "nodeOpacityInactive": 0.1,
255
+ "LinkOpacityDefault": 1,
256
+ "LinkOpacityInactive": 0.1
257
+ },
258
+ "storyNodeFontColor": "#006778",
259
+ "storyNodeText": [],
260
+ "nodeValueStyle": { "textBefore": "(", "textAfter": ")" },
261
+ "data": []
262
+ },
263
+ "version": "4.25.1",
264
+ "dynamicMarginTop": 0,
265
+ "data": [
266
+ { "date": "2024-07-01", "Value": "42", "Status": "final" },
267
+ { "date": "2024-08-01", "Value": "55", "Status": "final" },
268
+ { "date": "2024-09-01", "Value": "61", "Status": "final" },
269
+ { "date": "2024-10-01", "Value": "48", "Status": "final" },
270
+ { "date": "2024-11-01", "Value": "53", "Status": "final" },
271
+ { "date": "2024-12-01", "Value": "67", "Status": "final" },
272
+ { "date": "2025-01-01", "Value": "72", "Status": "preliminary" },
273
+ { "date": "2025-02-01", "Value": "78", "Status": "preliminary" },
274
+ { "date": "2025-03-01", "Value": "85", "Status": "preliminary" }
275
+ ]
276
+ }
@@ -366,7 +366,7 @@
366
366
  "Female": "500"
367
367
  }
368
368
  ],
369
- "dataFileName": "paired-bar-formatted.json",
369
+ "dataFileName": "/examples/feature/paired-bar/__data__/paired-bar-formatted.json",
370
370
  "dataFileSourceType": "file",
371
371
  "formattedData": [
372
372
  {
@@ -246,7 +246,7 @@
246
246
  { "Age Group": "45-54", "Male": "8259", "Female": "5633" },
247
247
  { "Age Group": "55-64", "Male": "1235", "Female": "810" }
248
248
  ],
249
- "dataFileName": "paired-bar-formatted.json",
249
+ "dataFileName": "/examples/feature/paired-bar/__data__/paired-bar-formatted.json",
250
250
  "dataFileSourceType": "file",
251
251
  "formattedData": [
252
252
  { "Age Group": "65", "Male": "730", "Female": "402" },
@@ -218,7 +218,7 @@ const Annotations = ({
218
218
  return (
219
219
  <HtmlLabel
220
220
  className='annotation__desktop-label'
221
- containerStyle={{ width: `${labelWidth}px` }}
221
+ containerStyle={{ width: 'fit-content', maxWidth: `${labelWidth}px` }}
222
222
  horizontalAnchor={horizontalAnchor}
223
223
  verticalAnchor={verticalAnchor}
224
224
  showAnchorLine={false}
@@ -11,7 +11,15 @@ import { Bar, AreaStack } from '@visx/shape'
11
11
  import { Group } from '@visx/group'
12
12
  import { approvedCurveTypes } from '@cdc/core/helpers/lineChartHelpers'
13
13
 
14
- const AreaChartStacked = ({ xScale, yScale, yMax, xMax, handleTooltipMouseOver, handleTooltipMouseOff }) => {
14
+ const AreaChartStacked = ({
15
+ xScale,
16
+ yScale,
17
+ yMax,
18
+ xMax,
19
+ yAxisWidth,
20
+ handleTooltipMouseOver,
21
+ handleTooltipMouseOff
22
+ }) => {
15
23
  // import data from context
16
24
  let { transformedData: data, config, seriesHighlight, colorScale, rawData, parseDate } = useContext(ConfigContext)
17
25
  // Draw transparent bars over the chart to get tooltip data
@@ -39,7 +47,7 @@ const AreaChartStacked = ({ xScale, yScale, yMax, xMax, handleTooltipMouseOver,
39
47
  <Group
40
48
  className='area-chart'
41
49
  key='area-wrapper'
42
- left={Number(config.yAxis.size) + strokeWidth / 2}
50
+ left={yAxisWidth + strokeWidth / 2}
43
51
  height={Number(yMax)}
44
52
  style={{ overflow: 'hidden' }}
45
53
  >
@@ -205,7 +205,7 @@ const BottomAxis: React.FC<BottomAxisProps> = ({
205
205
  const tickLength = showTick === 'block' ? MAJOR_TICK_LENGTH : DEFAULT_TICK_LENGTH
206
206
  const to = { x: tick.to.x, y: tickLength }
207
207
  const tickSlotWidth = filteredTicks.length > 0 ? xMax / filteredTicks.length : xMax
208
- const limitedWidth = Math.max(Math.min(maxLengthOfTick, tickSlotWidth), 0)
208
+ const limitedWidth = Math.max(Math.min(maxLengthOfTick, tickSlotWidth), 1)
209
209
 
210
210
  // Configure rotation using effective values (computed above without mutations)
211
211
  const tickRotation =
@@ -36,7 +36,6 @@ interface LeftAxisProps {
36
36
  suffixWidth?: number
37
37
  horizontalYAxisLabelSpace?: number
38
38
  categoryLabelSpace?: number
39
- yLabelOffset?: number
40
39
  }
41
40
 
42
41
  const LeftAxis: React.FC<LeftAxisProps> = ({
@@ -53,8 +52,7 @@ const LeftAxis: React.FC<LeftAxisProps> = ({
53
52
  suffixRef,
54
53
  suffixWidth = 0,
55
54
  horizontalYAxisLabelSpace = 0,
56
- categoryLabelSpace = 0,
57
- yLabelOffset = 0
55
+ categoryLabelSpace = 0
58
56
  }) => {
59
57
  const { config, colorScale, seriesHighlight } = useContext(ConfigContext)
60
58
  const { runtime, orientation, visualizationType, visualizationSubType, heights } = config
@@ -387,7 +385,7 @@ const LeftAxis: React.FC<LeftAxisProps> = ({
387
385
  className='y-label'
388
386
  textAnchor='middle'
389
387
  verticalAnchor='start'
390
- transform={`translate(${-1 * yAxisWidth + yLabelOffset}, ${axisCenter}) rotate(-90)`}
388
+ transform={`translate(${-1 * yAxisWidth}, ${axisCenter}) rotate(-90)`}
391
389
  fontWeight='bold'
392
390
  fill={config.yAxis.labelColor}
393
391
  fontSize={axisLabelFontSize}
@@ -10,7 +10,6 @@ interface LeftAxisGridlinesProps {
10
10
  xMax: number
11
11
  yAxisWidth: number
12
12
  numTicks: number
13
- yLabelOffset: number
14
13
  axisLabelFontSize: number
15
14
  }
16
15
 
@@ -19,7 +18,6 @@ const LeftAxisGridlines: React.FC<LeftAxisGridlinesProps> = ({
19
18
  xMax,
20
19
  yAxisWidth,
21
20
  numTicks,
22
- yLabelOffset,
23
21
  axisLabelFontSize
24
22
  }) => {
25
23
  const { config } = useContext(ConfigContext)
@@ -60,7 +58,7 @@ const LeftAxisGridlines: React.FC<LeftAxisGridlinesProps> = ({
60
58
  className='y-label'
61
59
  textAnchor='middle'
62
60
  verticalAnchor='start'
63
- transform={`translate(${-1 * yAxisWidth + yLabelOffset}, ${axisCenter}) rotate(-90)`}
61
+ transform={`translate(${-1 * yAxisWidth}, ${axisCenter}) rotate(-90)`}
64
62
  fontWeight='bold'
65
63
  fill={config.yAxis.labelColor}
66
64
  fontSize={axisLabelFontSize}
@@ -26,6 +26,7 @@ import { getBarData } from '../helpers/getBarData'
26
26
  import { getHorizontalBarHeights } from '../helpers/getBarHeights'
27
27
  import { getPatternUrl as getPatternUrlForBar } from '../helpers/getPatternUrl'
28
28
  import { getChartPatternId } from '../../../helpers/getChartPatternId'
29
+ import { buildSeriesTooltipListHtml } from '../../../helpers/tooltipHelpers'
29
30
 
30
31
  const BarChartHorizontal = () => {
31
32
  const { xScale, yScale, yMax, seriesScale, barChart } = useContext<BarChartContextValues>(BarChartContext)
@@ -243,11 +244,14 @@ const BarChartHorizontal = () => {
243
244
  : xAxisValue
244
245
  const additionalColTooltip = getAdditionalColumn(bar.key, hoveredBar)
245
246
  const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${yAxisValue}`
246
- const tooltip = `<ul>
247
- <li class="tooltip-heading"">${yAxisTooltip}</li>
248
- <li class="tooltip-body ">${tooltipBody}</li>
249
- <li class="tooltip-body ">${additionalColTooltip}</li>
250
- </li></ul>`
247
+ const tooltip = buildSeriesTooltipListHtml({
248
+ config,
249
+ colorScale,
250
+ heading: yAxisTooltip,
251
+ seriesKey: bar.key,
252
+ seriesText: tooltipBody,
253
+ extraRows: additionalColTooltip ? [additionalColTooltip] : []
254
+ })
251
255
 
252
256
  // configure colors
253
257
  let labelColor = APP_FONT_COLOR
@@ -16,6 +16,7 @@ import createBarElement from '@cdc/core/components/createBarElement'
16
16
  import { getHorizontalBarHeights } from '../helpers/getBarHeights'
17
17
  import { getPatternUrl as getPatternUrlForBar } from '../helpers/getPatternUrl'
18
18
  import { getChartPatternId } from '../../../helpers/getChartPatternId'
19
+ import { buildSeriesTooltipListHtml } from '../../../helpers/tooltipHelpers'
19
20
 
20
21
  const BarChartStackedHorizontal = () => {
21
22
  const { yMax, yScale, xScale, barChart } = useContext<BarChartContextValues>(BarChartContext)
@@ -161,11 +162,14 @@ const BarChartStackedHorizontal = () => {
161
162
  const textWidth = getTextWidth(xAxisValue, `normal ${labelFontSize}px sans-serif`)
162
163
  const additionalColTooltip = getAdditionalColumn(bar.key, hoveredBar)
163
164
  const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${xAxisValue}`
164
- const tooltip = `<ul>
165
- <li class="tooltip-heading"">${yAxisTooltip}</li>
166
- <li class="tooltip-body ">${tooltipBody}</li>
167
- <li class="tooltip-body ">${additionalColTooltip}</li>
168
- </li></ul>`
165
+ const tooltip = buildSeriesTooltipListHtml({
166
+ config,
167
+ colorScale,
168
+ heading: yAxisTooltip,
169
+ seriesKey: bar.key,
170
+ seriesText: tooltipBody,
171
+ extraRows: additionalColTooltip ? [additionalColTooltip] : []
172
+ })
169
173
 
170
174
  // Check if this bar should use a pattern
171
175
  const patternUrl = getPatternUrlForBar({
@@ -10,6 +10,7 @@ import { addMinimumBarHeights } from '../helpers'
10
10
  import createBarElement from '@cdc/core/components/createBarElement'
11
11
  import { getPatternUrl as getPatternUrlForBar } from '../helpers/getPatternUrl'
12
12
  import { getChartPatternId } from '../../../helpers/getChartPatternId'
13
+ import { buildSeriesTooltipListHtml } from '../../../helpers/tooltipHelpers'
13
14
 
14
15
  const BarChartStackedVertical = () => {
15
16
  const [barWidth, setBarWidth] = useState(0)
@@ -143,11 +144,14 @@ const BarChartStackedVertical = () => {
143
144
  : xAxisValue
144
145
  const additionalColTooltip = getAdditionalColumn(bar.key, hoveredBar)
145
146
  const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${yAxisValue}`
146
- const tooltip = `<ul>
147
- <li class="tooltip-heading"">${xAxisTooltip}</li>
148
- <li class="tooltip-body ">${tooltipBody}</li>
149
- <li class="tooltip-body ">${additionalColTooltip}</li>
150
- </li></ul>`
147
+ const tooltip = buildSeriesTooltipListHtml({
148
+ config,
149
+ colorScale,
150
+ heading: xAxisTooltip,
151
+ seriesKey: bar.key,
152
+ seriesText: tooltipBody,
153
+ extraRows: additionalColTooltip ? [additionalColTooltip] : []
154
+ })
151
155
 
152
156
  setBarWidth(barThickness)
153
157
 
@@ -23,6 +23,7 @@ import _ from 'lodash'
23
23
  import { getBarData } from '../helpers/getBarData'
24
24
  import { getPatternUrl as getPatternUrlForBar } from '../helpers/getPatternUrl'
25
25
  import { getChartPatternId } from '../../../helpers/getChartPatternId'
26
+ import { buildSeriesTooltipListHtml } from '../../../helpers/tooltipHelpers'
26
27
 
27
28
  const BarChartVertical = () => {
28
29
  const { xScale, yScale, xMax, yMax, seriesScale, convertLineToBarGraph, barChart } =
@@ -229,12 +230,14 @@ const BarChartVertical = () => {
229
230
  ? `${config.runtime.xAxis.label}: ${xAxisValue}`
230
231
  : xAxisValue
231
232
  const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${yAxisValue}`
232
-
233
- const tooltip = `<ul>
234
- <li class="tooltip-heading">${xAxisTooltip}</li>
235
- <li class="tooltip-body ">${tooltipBody}</li>
236
- ${additionalColTooltip ? '<li class="tooltip-body ">' + additionalColTooltip + '</li>' : ''}
237
- </li></ul>`
233
+ const tooltip = buildSeriesTooltipListHtml({
234
+ config,
235
+ colorScale,
236
+ heading: xAxisTooltip,
237
+ seriesKey: bar.key,
238
+ seriesText: tooltipBody,
239
+ extraRows: additionalColTooltip ? [additionalColTooltip] : []
240
+ })
238
241
  const { barHeight, isSuppressed, getBarY, absentDataLabel } = getBarConfig({
239
242
  bar,
240
243
  defaultBarHeight,
@@ -18,7 +18,7 @@ type BarChartProps = {
18
18
  seriesScale: PositionScale
19
19
  xMax: number
20
20
  yMax: number
21
- yAxisWidth?: number
21
+ yAxisWidth: number
22
22
  handleTooltipMouseOver: MouseEventHandler<SVGRectElement>
23
23
  handleTooltipMouseOff: MouseEventHandler<SVGRectElement>
24
24
  handleTooltipClick: MouseEventHandler<SVGRectElement>
@@ -49,14 +49,10 @@ const BarChart: React.FC<BarChartProps> = ({
49
49
  barChart
50
50
  }
51
51
 
52
- // Use yAxisWidth prop if provided (for horizontal bar charts with dynamic labels)
53
- // otherwise fall back to config value
54
- const leftOffset = yAxisWidth ?? parseFloat(config.runtime.yAxis.size)
55
-
56
52
  return (
57
53
  <ErrorBoundary component='BarChart'>
58
54
  <BarChartContext.Provider value={contextValues}>
59
- <Group left={leftOffset}>
55
+ <Group left={yAxisWidth}>
60
56
  <BarChartType.StackedVertical />
61
57
  <BarChartType.StackedHorizontal />
62
58
  <BarChartType.Vertical />
@@ -193,7 +193,7 @@ export const useBarChart = (handleTooltipMouseOver, handleTooltipMouseOff, confi
193
193
  const formattedValue = formatColNumber(
194
194
  closestVal[config.columns[colKeys].name],
195
195
  'left',
196
- true,
196
+ false,
197
197
  config,
198
198
  formattingParams
199
199
  )
@@ -9,7 +9,7 @@ import { handleTooltip, createPlots } from './helpers/index'
9
9
  import { APP_FONT_COLOR } from '@cdc/core/helpers/constants'
10
10
  import _ from 'lodash'
11
11
 
12
- const BoxPlotVertical = ({ xScale, yScale, seriesScale }) => {
12
+ const BoxPlotVertical = ({ xScale, yScale, seriesScale, yAxisWidth }) => {
13
13
  const { config, colorScale, seriesHighlight, transformedData: data } = useContext(ConfigContext)
14
14
  const { boxplot } = config
15
15
 
@@ -23,7 +23,7 @@ const BoxPlotVertical = ({ xScale, yScale, seriesScale }) => {
23
23
  const plots = createPlots(data, config)
24
24
  return (
25
25
  <ErrorBoundary component='BoxPlot Vertical'>
26
- <Group left={Number(config.yAxis.size)} className='boxplot' key={`boxplot-group`}>
26
+ <Group left={yAxisWidth} className='boxplot' key={`boxplot-group`}>
27
27
  {plots.map((d, i) => {
28
28
  const offset = boxWidth - constrainedWidth
29
29
  const radius = 4
@@ -63,7 +63,7 @@ const BoxPlotVertical = ({ xScale, yScale, seriesScale }) => {
63
63
  {displayPlot && (
64
64
  <BoxPlot
65
65
  display={displayPlot ? 'block' : 'none'}
66
- data-left={xScale(d.columnCategory) + config.yAxis.size + offset / 2 + 0.5}
66
+ data-left={xScale(d.columnCategory) + yAxisWidth + offset / 2 + 0.5}
67
67
  key={`box-plot-${i}-${item}`}
68
68
  min={Number(d.min[item.dataKey])}
69
69
  max={Number(d.max[item.dataKey])}