@cdc/chart 4.26.2 → 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 (165) hide show
  1. package/CONFIG.md +169 -0
  2. package/README.md +42 -17
  3. package/dist/cdcchart.js +39419 -35180
  4. package/examples/__data__/data-with-metadata.json +10 -0
  5. package/examples/feature/bar/additional-column-tooltip.json +3 -3
  6. package/examples/feature/deviation/planet-deviation-config.json +2 -2
  7. package/examples/feature/paired-bar/paired-bar-example.json +2 -2
  8. package/examples/feature/pie/planet-pie-example-config.json +2 -1
  9. package/examples/feature/tests-case-rate/case-rate-example-config.json +2 -2
  10. package/examples/feature/tests-covid/covid-confidence-example-config.json +2 -2
  11. package/examples/feature/tests-covid/covid-example-config.json +2 -2
  12. package/examples/feature/tests-cutoff/cutoff-example-config.json +2 -2
  13. package/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json +2 -2
  14. package/examples/metadata-variables.json +58 -0
  15. package/examples/minimal-example.json +24 -0
  16. package/examples/private/test2.json +35012 -0
  17. package/package.json +4 -4
  18. package/src/CdcChart.tsx +8 -4
  19. package/src/CdcChartComponent.tsx +326 -290
  20. package/src/_stories/Chart.CustomColors.smoke.stories.tsx +97 -0
  21. package/src/_stories/Chart.Defaults.smoke.stories.tsx +95 -0
  22. package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
  23. package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
  24. package/src/_stories/{Chart.SmallMultiples.stories.tsx → Chart.SmallMultiples.smoke.stories.tsx} +17 -1
  25. package/src/_stories/Chart.SmallestLeftAxisMax.smoke.stories.tsx +64 -0
  26. package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +48 -2
  27. package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
  28. package/src/_stories/ChartBar.Editor.stories.tsx +177 -115
  29. package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
  30. package/src/_stories/ChartEditor.Editor.stories.tsx +24 -1
  31. package/src/_stories/{Chart.CustomColors.stories.tsx → ChartLine.DashedDates.smoke.stories.tsx} +4 -4
  32. package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
  33. package/src/_stories/_mock/paired-bar-abbr.json +421 -0
  34. package/src/_stories/_mock/paired-bar.json +1 -1
  35. package/src/_stories/_mock/pie_custom_colors.json +268 -0
  36. package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
  37. package/src/components/Annotations/components/AnnotationDraggable.styles.css +10 -10
  38. package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -1
  39. package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -1
  40. package/src/components/Annotations/components/AnnotationList.styles.css +11 -11
  41. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
  42. package/src/components/Axis/BottomAxis.tsx +10 -3
  43. package/src/components/Axis/LeftAxis.tsx +2 -4
  44. package/src/components/Axis/LeftAxisGridlines.tsx +1 -3
  45. package/src/components/Axis/PairedBarAxis.tsx +10 -4
  46. package/src/components/BarChart/components/BarChart.Horizontal.tsx +21 -33
  47. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +21 -35
  48. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +21 -36
  49. package/src/components/BarChart/components/BarChart.Vertical.tsx +21 -34
  50. package/src/components/BarChart/components/BarChart.tsx +2 -6
  51. package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
  52. package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
  53. package/src/components/BarChart/helpers/useBarChart.ts +4 -1
  54. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
  55. package/src/components/Brush/BrushSelector.tsx +2 -1
  56. package/src/components/Brush/MiniChartPreview.tsx +21 -26
  57. package/src/components/EditorPanel/EditorPanel.tsx +692 -954
  58. package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
  59. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +218 -167
  60. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
  61. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +39 -1
  62. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +169 -135
  63. package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +154 -109
  64. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
  65. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +95 -28
  66. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +45 -42
  67. package/src/components/EditorPanel/editor-panel.scss +1 -1
  68. package/src/components/EditorPanel/useEditorPermissions.ts +1 -10
  69. package/src/components/Forecasting/Forecasting.tsx +2 -2
  70. package/src/components/ForestPlot/ForestPlot.tsx +26 -22
  71. package/src/components/HorizonChart/HorizonChart.tsx +10 -2
  72. package/src/components/HoverLine/HoverLine.tsx +6 -8
  73. package/src/components/Legend/Legend.Component.tsx +4 -4
  74. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +9 -4
  75. package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
  76. package/src/components/Legend/helpers/createFormatLabels.tsx +3 -2
  77. package/src/components/Legend/helpers/index.ts +0 -2
  78. package/src/components/LineChart/LineChartProps.ts +1 -0
  79. package/src/components/LineChart/components/LineChart.BumpCircle.tsx +3 -2
  80. package/src/components/LineChart/index.tsx +11 -4
  81. package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
  82. package/src/components/LinearChart/tests/LinearChart.test.tsx +224 -0
  83. package/src/components/LinearChart/tests/mockConfigContext.ts +2 -0
  84. package/src/components/LinearChart.tsx +124 -47
  85. package/src/components/PairedBarChart.jsx +2 -2
  86. package/src/components/PieChart/PieChart.tsx +30 -13
  87. package/src/components/RadarChart/RadarChart.tsx +1 -1
  88. package/src/components/Regions/components/Regions.tsx +36 -26
  89. package/src/components/Sankey/components/Sankey.tsx +3 -3
  90. package/src/components/Sankey/sankey.scss +1 -1
  91. package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
  92. package/src/components/SmallMultiples/SmallMultipleTile.tsx +1 -0
  93. package/src/components/SmallMultiples/SmallMultiples.css +5 -5
  94. package/src/components/Sparkline/components/SparkLine.tsx +1 -1
  95. package/src/components/Sparkline/index.scss +4 -2
  96. package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
  97. package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
  98. package/src/data/initial-state.js +24 -14
  99. package/src/data/legacy-defaults.ts +18 -0
  100. package/src/helpers/abbreviateNumber.ts +24 -17
  101. package/src/helpers/calculateLeftYAxisWidth.ts +193 -0
  102. package/src/helpers/getChartPatternId.ts +17 -0
  103. package/src/helpers/getMinMax.ts +16 -2
  104. package/src/helpers/seriesColumnSettings.ts +114 -0
  105. package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
  106. package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
  107. package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
  108. package/src/helpers/tooltipHelpers.ts +176 -0
  109. package/src/hooks/useHighlightedBars.ts +9 -16
  110. package/src/hooks/useProgrammaticTooltip.ts +16 -2
  111. package/src/hooks/useRightAxis.ts +14 -0
  112. package/src/hooks/useScales.ts +92 -56
  113. package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
  114. package/src/hooks/useTooltip.tsx +186 -40
  115. package/src/scss/main.scss +152 -79
  116. package/src/test/CdcChart.test.jsx +26 -2
  117. package/src/types/ChartConfig.ts +5 -0
  118. package/tests/fixtures/chart-config-with-metadata.json +29 -0
  119. package/tests/fixtures/data-with-metadata.json +10 -0
  120. package/examples/chart-regression-2.json +0 -2360
  121. package/examples/feature/__data__/age-adjusted-rates.json +0 -1486
  122. package/examples/feature/__data__/city-temperature.json +0 -2198
  123. package/examples/feature/bar/Barchart_with_negative.json +0 -34
  124. package/examples/feature/boxplot/box-plot-data.json +0 -71
  125. package/examples/feature/boxplot/boxplot-data.json +0 -156
  126. package/examples/feature/combo/combochart-categories_are_numbers .json +0 -18
  127. package/examples/feature/forest-plot/log.json +0 -26
  128. package/examples/feature/tests-date-exclusions/date-exclusions-data.json +0 -162
  129. package/examples/region-issue.json +0 -2065
  130. package/examples/xaxis.json +0 -493
  131. /package/examples/feature/bar/{tall-data.json → __data__/tall-data.json} +0 -0
  132. /package/examples/feature/deviation/{planet-deviation-data.json → __data__/planet-deviation-data.json} +0 -0
  133. /package/examples/feature/paired-bar/{paired-bar-data.json → __data__/paired-bar-data.json} +0 -0
  134. /package/examples/feature/paired-bar/{paired-bar-formatted.json → __data__/paired-bar-formatted.json} +0 -0
  135. /package/examples/feature/tests-case-rate/{case-rate-example-data.json → __data__/case-rate-example-data.json} +0 -0
  136. /package/examples/feature/tests-covid/{covid-example-data-confidence.json → __data__/covid-example-data-confidence.json} +0 -0
  137. /package/examples/feature/tests-covid/{covid-example-data.json → __data__/covid-example-data.json} +0 -0
  138. /package/examples/feature/tests-cutoff/{cutoff-example-data.json → __data__/cutoff-example-data.json} +0 -0
  139. /package/examples/feature/tests-non-numerics/{planet-example-data-nonnumeric.json → __data__/planet-example-data-nonnumeric.json} +0 -0
  140. /package/src/_stories/{Chart.Anchors.stories.tsx → Chart.Anchors.smoke.stories.tsx} +0 -0
  141. /package/src/_stories/{Chart.BoxPlot.stories.tsx → Chart.BoxPlot.smoke.stories.tsx} +0 -0
  142. /package/src/_stories/{Chart.CI.stories.tsx → Chart.CI.smoke.stories.tsx} +0 -0
  143. /package/src/_stories/{Chart.Combo.stories.tsx → Chart.Combo.smoke.stories.tsx} +0 -0
  144. /package/src/_stories/{Chart.DynamicSeries.stories.tsx → Chart.DynamicSeries.smoke.stories.tsx} +0 -0
  145. /package/src/_stories/{Chart.Filters.stories.tsx → Chart.Filters.smoke.stories.tsx} +0 -0
  146. /package/src/_stories/{Chart.Forecast.stories.tsx → Chart.Forecast.smoke.stories.tsx} +0 -0
  147. /package/src/_stories/{Chart.Legend.Gradient.stories.tsx → Chart.Legend.Gradient.smoke.stories.tsx} +0 -0
  148. /package/src/_stories/{Chart.Patterns.stories.tsx → Chart.Patterns.smoke.stories.tsx} +0 -0
  149. /package/src/_stories/{Chart.PreserveDecimals.stories.tsx → Chart.PreserveDecimals.smoke.stories.tsx} +0 -0
  150. /package/src/_stories/{Chart.Regions.Categorical.stories.tsx → Chart.Regions.Categorical.smoke.stories.tsx} +0 -0
  151. /package/src/_stories/{Chart.Regions.DateScale.stories.tsx → Chart.Regions.DateScale.smoke.stories.tsx} +0 -0
  152. /package/src/_stories/{Chart.Regions.DateTimeScale.stories.tsx → Chart.Regions.DateTimeScale.smoke.stories.tsx} +0 -0
  153. /package/src/_stories/{Chart.ScatterPlot.stories.tsx → Chart.ScatterPlot.smoke.stories.tsx} +0 -0
  154. /package/src/_stories/{ChartAnnotation.stories.tsx → ChartAnnotation.smoke.stories.tsx} +0 -0
  155. /package/src/_stories/{ChartAxisLabels.stories.tsx → ChartAxisLabels.smoke.stories.tsx} +0 -0
  156. /package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +0 -0
  157. /package/src/_stories/{ChartBrush.Matrix.Continuous.stories.tsx → ChartBrush.Matrix.Continuous.smoke.stories.tsx} +0 -0
  158. /package/src/_stories/{ChartBrush.Matrix.Date.stories.tsx → ChartBrush.Matrix.Date.smoke.stories.tsx} +0 -0
  159. /package/src/_stories/{ChartBrush.Matrix.DateTime.stories.tsx → ChartBrush.Matrix.DateTime.smoke.stories.tsx} +0 -0
  160. /package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +0 -0
  161. /package/src/_stories/{ChartLine.QuadrantAngles.stories.tsx → ChartLine.QuadrantAngles.smoke.stories.tsx} +0 -0
  162. /package/src/_stories/{ChartLine.Suppression.stories.tsx → ChartLine.Suppression.smoke.stories.tsx} +0 -0
  163. /package/src/_stories/{ChartLine.Symbols.stories.tsx → ChartLine.Symbols.smoke.stories.tsx} +0 -0
  164. /package/src/_stories/{ChartPrefixSuffix.stories.tsx → ChartPrefixSuffix.smoke.stories.tsx} +0 -0
  165. /package/src/_stories/{TechAdoptionWithLinks.stories.tsx → TechAdoptionWithLinks.smoke.stories.tsx} +0 -0
@@ -274,16 +274,7 @@ export const useEditorPermissions = () => {
274
274
  }
275
275
 
276
276
  const visSupportsRegions = () => {
277
- const disabledCharts = [
278
- 'Forest Plot',
279
- 'Horizon Chart',
280
- 'Pie',
281
- 'Paired Bar',
282
- 'Radar',
283
- 'Spark Line',
284
- 'Sankey',
285
- 'Warming Stripes'
286
- ]
277
+ const disabledCharts = ['Forest Plot', 'Pie', 'Paired Bar', 'Radar', 'Spark Line', 'Sankey', 'Warming Stripes']
287
278
  if (disabledCharts.includes(visualizationType)) return false
288
279
  return true
289
280
  }
@@ -110,7 +110,7 @@ const prepareForecastData = (
110
110
  return segments.length > 0 ? segments : [sortedData]
111
111
  }
112
112
 
113
- const Forecasting = ({ xScale, yScale, height, width, handleTooltipMouseOver, handleTooltipMouseOff }) => {
113
+ const Forecasting = ({ xScale, yScale, height, width, yAxisWidth, handleTooltipMouseOver, handleTooltipMouseOff }) => {
114
114
  const { transformedData: data, rawData, config, seriesHighlight, parseDate } = useContext(ConfigContext)
115
115
  const { xAxis, yAxis, legend, runtime } = config
116
116
  const DEBUG = false
@@ -143,7 +143,7 @@ const Forecasting = ({ xScale, yScale, height, width, handleTooltipMouseOver, ha
143
143
  return (
144
144
  data && (
145
145
  <ErrorBoundary component='ForecastingChart'>
146
- <Group className='forecasting-items' key='forecasting-items-wrapper' left={Number(yAxis.size)}>
146
+ <Group className='forecasting-items' key='forecasting-items-wrapper' left={yAxisWidth}>
147
147
  {runtime.forecastingSeriesKeys?.map((group, index) => {
148
148
  if (!group || !group.stages) return false
149
149
  return group.stages.map((stage, stageIndex) => {
@@ -26,7 +26,7 @@ const ForestPlot = ({
26
26
  handleTooltipMouseOver,
27
27
  forestPlotRightLabelRef
28
28
  }: ForestPlotProps) => {
29
- const { rawData: data, updateConfig } = useContext<ChartContext>(ConfigContext)
29
+ const { transformedData: data, updateConfig } = useContext<ChartContext>(ConfigContext)
30
30
  const { forestPlot } = config as ChartConfig
31
31
  const labelPosition = config.xAxis.tickWidthMax + 10
32
32
  const [initialLogTicksSet, setInitialLogTicks] = useState(false)
@@ -90,7 +90,9 @@ const ForestPlot = ({
90
90
  }
91
91
  }, [config.forestPlot.type])
92
92
 
93
- const pooledData = config.data.find(d => d[config.xAxis.dataKey] === config.forestPlot.pooledResult.column)
93
+ const pooledData = data.find(d => d[config.xAxis.dataKey] === config.forestPlot.pooledResult.column)
94
+ const [plotStart, plotEnd] = [...xScale.range()].sort((a, b) => a - b)
95
+ const plotWidth = plotEnd - plotStart
94
96
 
95
97
  const regressionPoints = pooledData
96
98
  ? [
@@ -112,12 +114,12 @@ const ForestPlot = ({
112
114
 
113
115
  const topLine = [
114
116
  { x: 0, y: topMarginOffset },
115
- { x: width, y: topMarginOffset }
117
+ { x: plotEnd, y: topMarginOffset }
116
118
  ]
117
119
 
118
120
  const bottomLine = [
119
121
  { x: 0, y: height },
120
- { x: width, y: height }
122
+ { x: plotEnd, y: height }
121
123
  ]
122
124
 
123
125
  type Columns = {
@@ -289,30 +291,21 @@ const ForestPlot = ({
289
291
  {forestPlot.regression.description}
290
292
  </Text>
291
293
  )}
292
-
293
- <Bar
294
- key='forest-plot-tooltip-area'
295
- className='forest-plot-tooltip-area'
296
- width={width}
297
- height={height}
298
- fill={false ? 'red' : 'transparent'}
299
- fillOpacity={0.5}
300
- onMouseMove={e => handleTooltipMouseOver(e, data)}
301
- onMouseOut={handleTooltipMouseOff}
302
- />
303
294
  </Group>
304
295
  <Line
305
296
  from={topLine[0]}
306
297
  to={topLine[1]}
307
- style={{ stroke: 'black', strokeWidth: 2 }}
298
+ style={{ stroke: '#333', strokeWidth: 1 }}
308
299
  className='forestplot__top-line'
309
300
  />
310
- <Line
311
- from={bottomLine[0]}
312
- to={bottomLine[1]}
313
- style={{ stroke: 'black', strokeWidth: 2 }}
314
- className='forestplot__bottom-line'
315
- />
301
+ {config.xAxis.hideAxis && (
302
+ <Line
303
+ from={bottomLine[0]}
304
+ to={bottomLine[1]}
305
+ style={{ stroke: '#333', strokeWidth: 1 }}
306
+ className='forestplot__bottom-line'
307
+ />
308
+ )}
316
309
 
317
310
  {/* column data */}
318
311
  {columnsOnChart.map((column, colIndex) => {
@@ -400,6 +393,17 @@ const ForestPlot = ({
400
393
  {forestPlot.rightLabel}
401
394
  </Text>
402
395
  )}
396
+ <Bar
397
+ key='forest-plot-tooltip-area'
398
+ className='forest-plot-tooltip-area'
399
+ x={0}
400
+ width={width}
401
+ height={height}
402
+ fill={false ? 'red' : 'transparent'}
403
+ fillOpacity={0.5}
404
+ onMouseMove={e => handleTooltipMouseOver(e, data)}
405
+ onMouseOut={handleTooltipMouseOff}
406
+ />
403
407
  </>
404
408
  )
405
409
  }
@@ -23,13 +23,21 @@ type HorizonChartProps = {
23
23
  yScale: any
24
24
  xMax: number
25
25
  yMax: number
26
+ yAxisWidth: number
26
27
  handleTooltipMouseOver: (e: any, additionalData?: any) => void
27
28
  handleTooltipMouseOff: () => void
28
29
  tooltipData?: any
29
30
  showTooltip?: boolean
30
31
  }
31
32
 
32
- const HorizonChart = ({ xScale, xMax, yMax, handleTooltipMouseOver, handleTooltipMouseOff }: HorizonChartProps) => {
33
+ const HorizonChart = ({
34
+ xScale,
35
+ xMax,
36
+ yMax,
37
+ yAxisWidth,
38
+ handleTooltipMouseOver,
39
+ handleTooltipMouseOff
40
+ }: HorizonChartProps) => {
33
41
  // Get data and config from context
34
42
  const { transformedData: data, config, colorScale, rawData, parseDate } = useContext(ConfigContext)
35
43
 
@@ -94,7 +102,7 @@ const HorizonChart = ({ xScale, xMax, yMax, handleTooltipMouseOver, handleToolti
94
102
 
95
103
  return (
96
104
  <ErrorBoundary component='HorizonChart'>
97
- <Group className='horizon-chart' key='horizon-wrapper' left={Number(config.yAxis.size)} height={Number(yMax)}>
105
+ <Group className='horizon-chart' key='horizon-wrapper' left={yAxisWidth} height={Number(yMax)}>
98
106
  {seriesKeys.map((seriesKey, index) => {
99
107
  const rowY = getRowY(index)
100
108
  return (
@@ -9,9 +9,10 @@ type HoverLineProps = {
9
9
  yMax?: number
10
10
  point: { x: number; y: number }
11
11
  orientation: 'horizontal' | 'vertical'
12
+ yAxisWidth: number
12
13
  }
13
14
 
14
- const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, orientation }) => {
15
+ const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, orientation, yAxisWidth }) => {
15
16
  const { config } = useContext(ConfigContext)
16
17
  const { verticalHoverLine, horizontalHoverLine } = config.visual
17
18
  const { visualizationType } = config
@@ -23,8 +24,9 @@ const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, o
23
24
  const showHorizontalHoverLine = horizontalHoverLine || (horizontalHoverLine && isScatterPlot)
24
25
 
25
26
  const getX = () => {
26
- if (point.x > xMax + Number(config.yAxis.size)) return xMax
27
- if (point.x < config.yAxis.size) return config.yAxis.size
27
+ if (point.x < yAxisWidth) return yAxisWidth
28
+ if (xMax === undefined) return point.x
29
+ if (point.x > xMax + yAxisWidth) return xMax + yAxisWidth
28
30
  return point.x
29
31
  }
30
32
 
@@ -52,11 +54,7 @@ const HoverLine: React.FC<HoverLineProps> = ({ tooltipData, xMax, yMax, point, o
52
54
  if (isHorizontal) {
53
55
  return (
54
56
  showHorizontalHoverLine && (
55
- <Group
56
- key={`tooltipLine-horizontal${point.y}${point.x}`}
57
- className='horizontal-tooltip-line'
58
- left={config.yAxis.size ? config.yAxis.size : 0}
59
- >
57
+ <Group key={`tooltipLine-horizontal${point.y}${point.x}`} className='horizontal-tooltip-line' left={yAxisWidth}>
60
58
  <Line
61
59
  from={{ x: 0, y: getY() }}
62
60
  to={{ x: xMax, y: getY() }}
@@ -117,8 +117,8 @@ const Legend: React.FC<LegendProps> = forwardRef(
117
117
  >
118
118
  {(legend.label || legend.description) && (
119
119
  <div className={legend.description ? 'mb-3' : 'mb-2'}>
120
- {legend.label && <h3 className='fw-bold'>{parse(legend.label)}</h3>}
121
- {legend.description && <p className='mt-2'>{parse(legend.description)}</p>}
120
+ {legend.label && <h3 className='fw-bold cove-prose'>{parse(legend.label)}</h3>}
121
+ {legend.description && <p className='mt-2 cove-prose'>{parse(legend.description)}</p>}
122
122
  </div>
123
123
  )}
124
124
  <LegendGradient
@@ -242,7 +242,7 @@ const Legend: React.FC<LegendProps> = forwardRef(
242
242
  </>
243
243
  )}
244
244
  </>
245
- <LegendLabel align='left' className='m-0'>
245
+ <LegendLabel align='left' className='m-0 cove-prose'>
246
246
  {parse(label.text)}
247
247
  </LegendLabel>
248
248
  </LegendItem>
@@ -361,7 +361,7 @@ const Legend: React.FC<LegendProps> = forwardRef(
361
361
  />
362
362
  </svg>
363
363
  </span>
364
- <LegendLabel align='left' className='m-0'>
364
+ <LegendLabel align='left' className='m-0 cove-prose'>
365
365
  {parse(String((pattern as any)?.label || key))}
366
366
  </LegendLabel>
367
367
  </LegendItem>
@@ -6,25 +6,30 @@
6
6
  margin-bottom: 0.5rem;
7
7
 
8
8
  .group-item .visx-legend-label {
9
- font-weight: 400;
10
9
  font-size: 0.889rem;
10
+ font-weight: 400;
11
11
  margin-bottom: 0.5rem;
12
12
  }
13
13
  .group-label {
14
- font-weight: 500;
15
14
  font-family: Nunito, sans-serif;
16
15
  font-size: 1rem;
16
+ font-weight: 500;
17
17
  }
18
18
  }
19
19
 
20
+ .legend-group-grid {
21
+ display: flex;
22
+ flex-wrap: wrap;
23
+ }
24
+
20
25
  .legend-group.top,
21
26
  .legend-group.bottom {
22
27
  grid-gap: 10px;
23
28
 
24
29
  &.group-item {
30
+ align-items: flex-start;
25
31
  display: flex;
26
32
  flex-direction: column;
27
- align-items: flex-start;
28
33
  }
29
34
 
30
35
  & .inactive {
@@ -32,9 +37,9 @@
32
37
  transition: 0.2s all;
33
38
  }
34
39
  & .highlighted {
40
+ border-radius: 1px;
35
41
  outline: 1px solid #005ea2;
36
42
  outline-offset: 5px;
37
- border-radius: 1px;
38
43
  }
39
44
  }
40
45
  }
@@ -32,7 +32,7 @@ const LegendGroup = ({ formatLabels }) => {
32
32
 
33
33
  const groups: string[] = getSubGroups(data, config.legend.groupBy)
34
34
 
35
- const classNames = ['legend-group', 'container', config.legend.position, currentViewport, 'row']
35
+ const classNames = ['legend-group', 'legend-group-grid', 'container', config.legend.position, currentViewport]
36
36
 
37
37
  const gridCol =
38
38
  currentViewport === 'xs'
@@ -47,6 +47,8 @@ const LegendGroup = ({ formatLabels }) => {
47
47
 
48
48
  let classNameItem = ['legend-group group-item', isSigleCol]
49
49
 
50
+ if (groups.length === 0) return null
51
+
50
52
  return (
51
53
  <div className={classNames.join(' ')}>
52
54
  {groups.map(group => {
@@ -17,7 +17,8 @@ import { FaStar } from 'react-icons/fa'
17
17
  import { Label } from '../../../types/Label'
18
18
  import { ColorScale, TransformedData } from '../../../types/ChartContext'
19
19
  import { ChartConfig } from '../../../types/ChartConfig'
20
- import _ from 'lodash'
20
+ import cloneDeep from 'lodash/cloneDeep'
21
+ import sortBy from 'lodash/sortBy'
21
22
  import { scaleSequential } from 'd3-scale'
22
23
  import { interpolateRgbBasis } from 'd3-interpolate'
23
24
  import { filterChartColorPalettes } from '@cdc/core/helpers/filterColorPalettes'
@@ -173,7 +174,7 @@ export const createFormatLabels =
173
174
 
174
175
  const sortVertical = labels =>
175
176
  legend.verticalSorted
176
- ? _.sortBy(_.cloneDeep(labels), label => {
177
+ ? sortBy(cloneDeep(labels), label => {
177
178
  const match = label.datum?.match(/-?\d+(\.\d+)?/)
178
179
  return match ? parseFloat(match[0]) : Number.MAX_SAFE_INTEGER
179
180
  })
@@ -40,8 +40,6 @@ export const getMarginBottom = (isLegendBottom, config) => {
40
40
 
41
41
  if (isLegendTop) marginBottom = 27
42
42
 
43
- if (isLegendTop && config.yAxis?.inlineLabel) marginBottom += 9
44
-
45
43
  if (isLegendBottom) marginBottom += 9
46
44
 
47
45
  if (hasSuppression) marginBottom += 40
@@ -8,6 +8,7 @@ export type LineChartProps = {
8
8
  getYAxisData: Function
9
9
  xMax: number
10
10
  yMax: number
11
+ yAxisWidth: number
11
12
  handleTooltipMouseOver: Function
12
13
  handleTooltipMouseOff: Function
13
14
  showTooltip: boolean
@@ -10,10 +10,11 @@ type LineChartBumpCircleProp = {
10
10
  xScale: any
11
11
  yScale: any
12
12
  parseDate: any
13
+ yAxisWidth: number
13
14
  }
14
15
 
15
16
  const LineChartBumpCircle = (props: LineChartBumpCircleProp) => {
16
- const { config, xScale, yScale, parseDate } = props
17
+ const { config, xScale, yScale, parseDate, yAxisWidth } = props
17
18
 
18
19
  // get xScale and yScale...
19
20
  if (!config?.runtime?.series) return
@@ -55,7 +56,7 @@ const LineChartBumpCircle = (props: LineChartBumpCircleProp) => {
55
56
  let axis_dataKey = d[config.xAxis.dataKey]
56
57
  return (
57
58
  <React.Fragment key={`bump-circle-${series_dataKey}-${dataIndex}`}>
58
- <Group left={Number(config.runtime.yAxis.size)}>
59
+ <Group left={yAxisWidth}>
59
60
  {series_dataKey && (
60
61
  <>
61
62
  <circle
@@ -36,6 +36,7 @@ const LineChart = (props: LineChartProps) => {
36
36
  xScale,
37
37
  yMax,
38
38
  yScale,
39
+ yAxisWidth,
39
40
  } = props
40
41
 
41
42
  // prettier-ignore
@@ -55,7 +56,7 @@ const LineChart = (props: LineChartProps) => {
55
56
 
56
57
  return (
57
58
  <ErrorBoundary component='LineChart'>
58
- <Group left={Number(config.runtime.yAxis.size)} className='line-chart-group'>
59
+ <Group left={yAxisWidth} className='line-chart-group'>
59
60
  {/* left - expects a number not a string */}
60
61
  {(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => {
61
62
  const seriesData = config.runtime.series.find(item => item.dataKey === seriesKey)
@@ -264,7 +265,7 @@ const LineChart = (props: LineChartProps) => {
264
265
  }
265
266
  styles={createStyles({
266
267
  preliminaryData: config.preliminaryData,
267
- data: tableData,
268
+ data: _data,
268
269
  stroke: colorScale(config.runtime.seriesLabels[seriesKey]),
269
270
  strokeWidth: seriesData.weight || 2,
270
271
  handleLineType,
@@ -496,7 +497,7 @@ const LineChart = (props: LineChartProps) => {
496
497
  </Text>
497
498
  )}
498
499
  </Group>
499
- <Group left={Number(config.runtime.yAxis.size)} className='glyph-tooltip-group'>
500
+ <Group left={yAxisWidth} className='glyph-tooltip-group'>
500
501
  <Group key={`tooltip-group`} display={'block'}>
501
502
  {/* tooltips */}
502
503
  <Bar
@@ -543,7 +544,13 @@ const LineChart = (props: LineChartProps) => {
543
544
  </Group>
544
545
  </Group>
545
546
  {config.visualizationType === 'Bump Chart' && (
546
- <LineChartBumpCircle config={config} xScale={xScale} yScale={yScale} />
547
+ <LineChartBumpCircle
548
+ config={config}
549
+ xScale={xScale}
550
+ yScale={yScale}
551
+ parseDate={parseDate}
552
+ yAxisWidth={yAxisWidth}
553
+ />
547
554
  )}
548
555
  </ErrorBoundary>
549
556
  )
@@ -76,13 +76,16 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
76
76
  )}
77
77
 
78
78
  {/* Paired Bar Chart */}
79
- {visualizationType === 'Paired Bar' && <PairedBarChart originalWidth={parentWidth} width={xMax} height={yMax} />}
79
+ {visualizationType === 'Paired Bar' && (
80
+ <PairedBarChart originalWidth={parentWidth} width={xMax} height={yMax} yAxisWidth={yAxisWidth} />
81
+ )}
80
82
 
81
83
  {/* Scatter Plot */}
82
84
  {visualizationType === 'Scatter Plot' && (
83
85
  <ScatterPlot
84
86
  xScale={xScale}
85
87
  yScale={yScale}
88
+ yAxisWidth={yAxisWidth}
86
89
  getXAxisData={getXAxisData}
87
90
  getYAxisData={getYAxisData}
88
91
  xMax={xMax}
@@ -102,6 +105,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
102
105
  yScale={yScale}
103
106
  xMax={xMax}
104
107
  yMax={yMax}
108
+ yAxisWidth={yAxisWidth}
105
109
  synchronizedXValue={synchronizedXValue}
106
110
  showTooltip={showTooltip}
107
111
  handleTooltipMouseOff={handleTooltipMouseOff}
@@ -115,6 +119,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
115
119
  yScale={yScale}
116
120
  xMax={xMax}
117
121
  yMax={yMax}
122
+ yAxisWidth={yAxisWidth}
118
123
  handleTooltipMouseOver={handleTooltipMouseOver}
119
124
  handleTooltipMouseOff={handleTooltipMouseOff}
120
125
  tooltipData={tooltipData}
@@ -132,6 +137,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
132
137
  max={max}
133
138
  xScale={xScale}
134
139
  yScale={yScale}
140
+ yAxisWidth={yAxisWidth}
135
141
  />
136
142
  )}
137
143
 
@@ -156,6 +162,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
156
162
  yScale={yScale}
157
163
  yMax={yMax}
158
164
  xMax={xMax}
165
+ yAxisWidth={yAxisWidth}
159
166
  chartRef={svgRef}
160
167
  width={xMax}
161
168
  height={yMax}
@@ -193,6 +200,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
193
200
  <LineChart
194
201
  xScale={xScale}
195
202
  yScale={yScale}
203
+ yAxisWidth={yAxisWidth}
196
204
  getXAxisData={getXAxisData}
197
205
  getYAxisData={getYAxisData}
198
206
  xMax={xMax}
@@ -211,6 +219,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
211
219
  <LineChart
212
220
  xScale={xScale}
213
221
  yScale={yScale}
222
+ yAxisWidth={yAxisWidth}
214
223
  getXAxisData={getXAxisData}
215
224
  getYAxisData={getYAxisData}
216
225
  xMax={xMax}
@@ -229,6 +238,7 @@ const VisualizationRenderer: React.FC<VisualizationRendererProps> = ({
229
238
  tooltipData={tooltipData}
230
239
  xScale={xScale}
231
240
  yScale={yScale}
241
+ yAxisWidth={yAxisWidth}
232
242
  width={xMax}
233
243
  height={yMax}
234
244
  xScaleNoPadding={xScaleNoPadding}