@cdc/chart 4.23.10 → 4.24.1

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 (125) hide show
  1. package/dist/cdcchart.js +34606 -32218
  2. package/examples/feature/bar/additional-column-tooltip.json +446 -0
  3. package/examples/feature/bar/example-bar-chart.json +1 -46
  4. package/examples/feature/bar/lollipop.json +156 -0
  5. package/examples/feature/bar/tall-data.json +98 -0
  6. package/examples/feature/combo/planet-combo-example-config.json +99 -9
  7. package/examples/feature/dev-4261.json +399 -0
  8. package/examples/feature/forest-plot/forest-plot.json +63 -19
  9. package/examples/feature/forest-plot/{broken.json → linear.json} +77 -23
  10. package/examples/feature/forest-plot/log.json +26 -0
  11. package/examples/feature/forest-plot/logarithmic.json +271 -0
  12. package/examples/feature/line/line-chart-preliminary.json +346 -0
  13. package/examples/feature/line/line-points.json +340 -0
  14. package/examples/feature/regions/index.json +462 -0
  15. package/examples/feature/scatterplot/scatterplot.json +272 -33
  16. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +181 -48
  17. package/examples/private/chart-t.json +3740 -0
  18. package/examples/private/combo.json +369 -0
  19. package/examples/private/epi-data.csv +13 -0
  20. package/examples/private/epi-data.json +62 -0
  21. package/examples/private/epi.json +403 -0
  22. package/examples/private/occupancy.json +109283 -0
  23. package/examples/private/prod-line-config.json +401 -0
  24. package/examples/private/region-data.json +822 -0
  25. package/examples/private/region-testing.json +312 -0
  26. package/examples/private/scaling.json +45325 -0
  27. package/examples/private/testing-data.json +1739 -0
  28. package/examples/private/testing.json +816 -0
  29. package/examples/sparkline-multilple.json +846 -0
  30. package/index.html +12 -8
  31. package/package.json +3 -3
  32. package/src/CdcChart.tsx +42 -211
  33. package/src/ConfigContext.tsx +6 -0
  34. package/src/_stories/Chart.stories.tsx +188 -0
  35. package/src/_stories/Chart.tooltip.stories.tsx +305 -0
  36. package/src/_stories/ChartBrush.stories.tsx +19 -0
  37. package/src/_stories/ChartEditor.stories.tsx +22 -0
  38. package/src/_stories/ChartLine.preliminary.tsx +19 -0
  39. package/src/_stories/ChartSuppress.stories.tsx +19 -0
  40. package/src/_stories/_mock/brush_mock.json +393 -0
  41. package/src/_stories/_mock/pie_config.json +191 -0
  42. package/src/_stories/_mock/pie_data.json +218 -0
  43. package/src/_stories/_mock/preliminary_mock.json +346 -0
  44. package/src/_stories/_mock/suppress_mock.json +911 -0
  45. package/src/components/{AreaChart.Stacked.jsx → AreaChart/components/AreaChart.Stacked.jsx} +6 -7
  46. package/src/components/{AreaChart.jsx → AreaChart/components/AreaChart.jsx} +7 -36
  47. package/src/components/AreaChart/index.tsx +4 -0
  48. package/src/components/{BarChart.Horizontal.jsx → BarChart/components/BarChart.Horizontal.tsx} +111 -34
  49. package/src/components/{BarChart.StackedHorizontal.jsx → BarChart/components/BarChart.StackedHorizontal.tsx} +55 -20
  50. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +106 -0
  51. package/src/components/{BarChart.Vertical.jsx → BarChart/components/BarChart.Vertical.tsx} +162 -34
  52. package/src/components/BarChart/components/BarChart.jsx +39 -0
  53. package/src/components/{BarChartType.jsx → BarChart/components/BarChartType.jsx} +0 -2
  54. package/src/components/BarChart/components/context.tsx +13 -0
  55. package/src/components/BarChart/index.tsx +3 -0
  56. package/src/components/{BoxPlot.jsx → BoxPlot/BoxPlot.jsx} +1 -1
  57. package/src/components/BoxPlot/index.tsx +3 -0
  58. package/src/components/DeviationBar.jsx +4 -3
  59. package/src/components/{EditorPanel.jsx → EditorPanel/EditorPanel.tsx} +807 -865
  60. package/src/components/EditorPanel/components/Panel.DateHighlighting.tsx +109 -0
  61. package/src/components/{ForestPlotSettings.jsx → EditorPanel/components/Panel.ForestPlotSettings.tsx} +190 -220
  62. package/src/components/EditorPanel/components/Panel.Regions.tsx +168 -0
  63. package/src/components/{Series.jsx → EditorPanel/components/Panel.Series.tsx} +23 -4
  64. package/src/components/EditorPanel/components/PanelProps.ts +3 -0
  65. package/src/components/EditorPanel/components/Panels.tsx +13 -0
  66. package/src/components/EditorPanel/components/panels.scss +72 -0
  67. package/src/components/EditorPanel/editor-panel.scss +751 -0
  68. package/src/components/EditorPanel/index.tsx +3 -0
  69. package/src/{hooks → components/EditorPanel}/useEditorPermissions.js +50 -5
  70. package/src/components/{Forecasting.jsx → Forecasting/Forecasting.jsx} +1 -1
  71. package/src/components/Forecasting/index.tsx +3 -0
  72. package/src/components/ForestPlot/ForestPlot.tsx +254 -0
  73. package/src/components/ForestPlot/ForestPlotProps.ts +18 -0
  74. package/src/components/ForestPlot/index.scss +1 -0
  75. package/src/components/ForestPlot/index.tsx +3 -0
  76. package/src/components/Legend/Legend.tsx +347 -0
  77. package/src/components/Legend/index.tsx +3 -0
  78. package/src/components/LineChart/LineChartProps.ts +46 -0
  79. package/src/components/{LineChart.Circle.tsx → LineChart/components/LineChart.Circle.tsx} +36 -30
  80. package/src/components/LineChart/helpers.ts +45 -0
  81. package/src/components/LineChart/index.scss +1 -0
  82. package/src/components/{LineChart.tsx → LineChart/index.tsx} +83 -42
  83. package/src/components/LinearChart.jsx +125 -82
  84. package/src/components/PairedBarChart.jsx +2 -2
  85. package/src/components/{PieChart.jsx → PieChart/PieChart.tsx} +16 -7
  86. package/src/components/PieChart/index.tsx +3 -0
  87. package/src/components/Regions/components/Regions.tsx +135 -0
  88. package/src/components/Regions/index.tsx +3 -0
  89. package/src/components/{ScatterPlot.jsx → ScatterPlot/ScatterPlot.jsx} +3 -3
  90. package/src/components/ScatterPlot/index.tsx +3 -0
  91. package/src/components/{SparkLine.jsx → Sparkline/SparkLine.jsx} +2 -2
  92. package/src/components/Sparkline/index.tsx +3 -0
  93. package/src/components/ZoomBrush.tsx +168 -0
  94. package/src/data/initial-state.js +30 -16
  95. package/src/helpers/abbreviateNumber.ts +17 -0
  96. package/src/helpers/computeMarginBottom.ts +55 -0
  97. package/src/helpers/filterData.ts +18 -0
  98. package/src/helpers/generateColorsArray.ts +8 -0
  99. package/src/helpers/getQuartiles.ts +30 -0
  100. package/src/helpers/handleChartAriaLabels.ts +19 -0
  101. package/src/helpers/handleLineType.ts +18 -0
  102. package/src/helpers/lineOptions.ts +18 -0
  103. package/src/helpers/sort.ts +7 -0
  104. package/src/helpers/tests/computeMarginBottom.test.ts +20 -0
  105. package/src/hooks/useBarChart.js +72 -7
  106. package/src/hooks/useColorScale.ts +50 -0
  107. package/src/hooks/{useMinMax.js → useMinMax.ts} +75 -23
  108. package/src/hooks/{useRightAxis.js → useRightAxis.ts} +10 -2
  109. package/src/hooks/{useScales.js → useScales.ts} +64 -17
  110. package/src/hooks/{useTooltip.jsx → useTooltip.tsx} +84 -55
  111. package/src/scss/main.scss +70 -38
  112. package/src/types/ChartConfig.ts +178 -0
  113. package/src/types/ChartContext.ts +54 -0
  114. package/src/types/ForestPlot.ts +53 -0
  115. package/examples/feature/scatterplot/scatterplot-continuous.csv +0 -17
  116. package/src/ConfigContext.jsx +0 -5
  117. package/src/components/BarChart.StackedVertical.jsx +0 -95
  118. package/src/components/BarChart.jsx +0 -30
  119. package/src/components/ForestPlot.jsx +0 -191
  120. package/src/components/Legend.jsx +0 -277
  121. package/src/scss/LinearChart.scss +0 -0
  122. package/src/scss/editor-panel.scss +0 -745
  123. package/src/scss/legend.scss +0 -206
  124. package/src/scss/mixins.scss +0 -0
  125. package/src/scss/variables.scss +0 -1
package/index.html CHANGED
@@ -34,19 +34,20 @@
34
34
  -->
35
35
 
36
36
  <!-- GENERIC CHART TYPES -->
37
- <!-- <div class="react-container" data-config="/examples/private/line-breaks.json"></div> -->
38
- <!-- <div class="react-container" data-config="/examples/private/combo.json"></div> -->
39
- <!-- <div class="react-container" data-config="/examples/feature/legend-highlights/highlights.json"></div> -->
40
- <!-- <div class="react-container" data-config="/examples/private/tooltip-issue.json"></div> -->
37
+ <!-- <div class="react-container" data-config="/examples/private/prod-line-config.json"></div> -->
38
+ <!-- <div class="react-container" data-config="/examples/private/chart-t.json"></div> -->
39
+ <!-- <div class="react-container" data-config="/examples/feature/bar/additional-column-tooltip.json"></div> -->
41
40
  <!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
42
41
  <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-city-temperature.json"></div> -->
43
42
  <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-apple.json"></div> -->
44
- <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-stacked.json"></div> -->
43
+ <!-- <div class="react-container" data-config="/examples/feature/forest-plot/linear.json"></div> -->
44
+ <!-- <div class="react-container" data-config="/examples/feature/forest-plot/logarithmic.json"></div> -->
45
45
  <!-- <div class="react-container" data-config="/examples/feature/forest-plot/forest-plot.json"></div> -->
46
46
  <!-- <div class="react-container" data-config="/examples/feature/pie/planet-pie-example-config.json"></div> -->
47
47
  <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Viz.json></div> -->
48
+ <!-- <div class="react-container" data-config=/examples/feature/regions/index.json></div> -->
49
+ <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
48
50
  <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
49
- <!-- <div class="react-container" data-config="/examples/feature/line/line-chart.json"></div> -->
50
51
  <!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
51
52
  <!-- <div class="react-container" data-config="/examples/feature/forecasting/combo-forecasting.json"></div> -->
52
53
  <!-- <div class="react-container" data-config="/examples/feature/forecasting/effective_reproduction.json"></div> -->
@@ -69,7 +70,7 @@
69
70
  <!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
70
71
 
71
72
  <!-- SPARKLINE -->
72
- <!-- <div class="react-container" data-config="/examples/feature/sparkline/example-sparkline.json"></div> -->
73
+ <!-- <div class="react-container" data-config="/examples/feature/dev-4261.json"></div> -->
73
74
 
74
75
  <!-- TESTS DATA TABLE SORTING -->
75
76
  <!-- Bar Chart with Confidence Intervals (bottom of page) -->
@@ -103,6 +104,7 @@
103
104
  <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-combo-bar-nonnumeric.json"></div> -->
104
105
  <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-bar-chart-nonnumeric.json"></div> -->
105
106
  <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/sparkline-chart-nonnumeric.json"></div> -->
107
+ <!-- <div class="react-container" data-config="/examples/feature/bar/lollipop.json"></div> -->
106
108
  <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json"></div> -->
107
109
 
108
110
  <!-- TESTS CUTOFF -->
@@ -121,6 +123,8 @@
121
123
 
122
124
  <!-- GENERIC CHART TYPES -->
123
125
  <!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
126
+ <div class="react-container" data-config="/examples/feature/line/line-chart-preliminary.json"></div>
127
+
124
128
 
125
129
  <!-- HORIZONTAL BAR CHARTS -->
126
130
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
@@ -133,7 +137,7 @@
133
137
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
134
138
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json"></div> -->
135
139
  <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
136
- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div>
140
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div> -->
137
141
 
138
142
  <noscript>You need to enable JavaScript to run this app.</noscript>
139
143
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/chart",
3
- "version": "4.23.10",
3
+ "version": "4.24.1",
4
4
  "description": "React component for visualizing tabular data in various types of charts",
5
5
  "moduleName": "CdcChart",
6
6
  "main": "dist/cdcchart",
@@ -48,7 +48,7 @@
48
48
  "js-base64": "^2.5.2",
49
49
  "papaparse": "^5.3.0",
50
50
  "react-accessible-accordion": "^3.3.4",
51
- "react-icons": "^4.10.1",
51
+ "react-icons": "^4.11.0",
52
52
  "react-spring": "^8.0.27",
53
53
  "react-table": "^7.5.0",
54
54
  "react-tooltip": "5.8.2-beta.3",
@@ -59,7 +59,7 @@
59
59
  "react": "^18.2.0",
60
60
  "react-dom": "^18.2.0"
61
61
  },
62
- "gitHead": "ff5b1ca0c84bb0629bc69e5a26a4a81254dbf69f",
62
+ "gitHead": "a352a3f74f4b681191e3244061dbb3621f36eec3",
63
63
  "devDependencies": {
64
64
  "resize-observer-polyfill": "^1.5.1"
65
65
  }
package/src/CdcChart.tsx CHANGED
@@ -12,19 +12,27 @@ import { timeParse, timeFormat } from 'd3-time-format'
12
12
  import Papa from 'papaparse'
13
13
  import parse from 'html-react-parser'
14
14
  import 'react-tooltip/dist/react-tooltip.css'
15
- import chroma from 'chroma-js'
16
15
 
17
16
  // Primary Components
18
17
  import ConfigContext from './ConfigContext'
19
- import PieChart from './components/PieChart'
18
+ import PieChart from './components/PieChart/PieChart'
20
19
  import LinearChart from './components/LinearChart'
21
20
 
22
21
  import { colorPalettesChart as colorPalettes, twoColorPalette } from '@cdc/core/data/colorPalettes'
23
22
 
24
- import SparkLine from './components/SparkLine'
23
+ import SparkLine from './components/Sparkline'
25
24
  import Legend from './components/Legend'
26
25
  import defaults from './data/initial-state'
27
26
  import EditorPanel from './components/EditorPanel'
27
+ import { abbreviateNumber } from './helpers/abbreviateNumber'
28
+ import { getQuartiles } from './helpers/getQuartiles'
29
+ import { sortAsc, sortDesc } from './helpers/sort'
30
+ import { filterData } from './helpers/filterData'
31
+ import { handleChartAriaLabels } from './helpers/handleChartAriaLabels'
32
+ import { lineOptions } from './helpers/lineOptions'
33
+ import { handleLineType } from './helpers/handleLineType'
34
+ import { generateColorsArray } from './helpers/generateColorsArray'
35
+ import { computeMarginBottom } from './helpers/computeMarginBottom'
28
36
  import Loading from '@cdc/core/components/Loading'
29
37
  import Filters from '@cdc/core/components/Filters'
30
38
  import MediaControls from '@cdc/core/components/MediaControls'
@@ -43,36 +51,7 @@ import './scss/main.scss'
43
51
  // load both then config below determines which to use
44
52
  import DataTable from '@cdc/core/components/DataTable'
45
53
  import { getFileExtension } from '@cdc/core/helpers/getFileExtension'
46
-
47
- const generateColorsArray = (color = '#000000', special = false) => {
48
- let colorObj = chroma(color)
49
- let hoverColor = special ? colorObj.brighten(0.5).hex() : colorObj.saturate(1.3).hex()
50
-
51
- return [color, hoverColor, colorObj.darken(0.3).hex()]
52
- }
53
- const hashObj = row => {
54
- try {
55
- if (!row) throw new Error('No row supplied to hashObj')
56
-
57
- let str = JSON.stringify(row)
58
- let hash = 0
59
-
60
- if (str.length === 0) return hash
61
-
62
- for (let i = 0; i < str.length; i++) {
63
- let char = str.charCodeAt(i)
64
- hash = (hash << 5) - hash + char
65
- hash = hash & hash
66
- }
67
-
68
- return hash
69
- } catch (e) {
70
- console.error('COVE: ', e) // eslint-disable-line
71
- }
72
- }
73
-
74
- // * FILE REVIEW
75
- // TODO: @tturnerswdev33 - remove/fix mentions of runtimeLegend that were added
54
+ import Title from '@cdc/core/components/ui/Title'
76
55
 
77
56
  export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
78
57
  const transform = new DataTransform()
@@ -90,7 +69,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
90
69
  const [coveLoadedEventRan, setCoveLoadedEventRan] = useState(false)
91
70
  const [dynamicLegendItems, setDynamicLegendItems] = useState<any[]>([])
92
71
  const [imageId] = useState(`cove-${Math.random().toString(16).slice(-4)}`)
93
-
72
+ type Config = typeof config
94
73
  let legendMemo = useRef(new Map()) // map collection
95
74
  let innerContainerRef = useRef()
96
75
 
@@ -110,37 +89,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
110
89
 
111
90
  const handleChartTabbing = config.showSidebar ? `#legend` : config?.title ? `#dataTableSection__${config.title.replace(/\s/g, '')}` : `#dataTableSection`
112
91
 
113
- const sortAsc = (a, b) => {
114
- return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
115
- }
116
-
117
- const sortDesc = (a, b) => {
118
- return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
119
- }
120
-
121
- const handleChartAriaLabels = (state, testing = false) => {
122
- if (testing) console.log(`handleChartAriaLabels Testing On:`, state) // eslint-disable-line
123
- try {
124
- if (!state.visualizationType) throw Error('handleChartAriaLabels: no visualization type found in state')
125
- let ariaLabel = ''
126
-
127
- if (state.visualizationType) {
128
- ariaLabel += `${state.visualizationType} chart`
129
- }
130
-
131
- if (state.title && state.visualizationType) {
132
- ariaLabel += ` with the title: ${state.title}`
133
- }
134
-
135
- return ariaLabel
136
- } catch (e) {
137
- console.error('COVE: ', e.message) // eslint-disable-line
138
- }
139
- }
140
-
141
92
  const reloadURLData = async () => {
142
93
  if (config.dataUrl) {
143
- const dataUrl = new URL(config.runtimeDataUrl || config.dataUrl)
94
+ const dataUrl = new URL(config.runtimeDataUrl || config.dataUrl, window.location.origin)
144
95
  let qsParams = Object.fromEntries(new URLSearchParams(dataUrl.search))
145
96
 
146
97
  let isUpdateNeeded = false
@@ -165,7 +116,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
165
116
  let data: any[] = []
166
117
 
167
118
  try {
168
- const ext = getFileExtension(dataUrl.pathname)
119
+ const ext = getFileExtension(dataUrl.href)
169
120
  if ('csv' === ext) {
170
121
  data = await fetch(dataUrlFinal)
171
122
  .then(response => response.text())
@@ -204,44 +155,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
204
155
  }
205
156
  }
206
157
 
207
- const handleLineType = lineType => {
208
- switch (lineType) {
209
- case 'dashed-sm':
210
- return '5 5'
211
- case 'Dashed Small':
212
- return '5 5'
213
- case 'dashed-md':
214
- return '10 5'
215
- case 'Dashed Medium':
216
- return '10 5'
217
- case 'dashed-lg':
218
- return '15 5'
219
- case 'Dashed Large':
220
- return '15 5'
221
- default:
222
- return 0
223
- }
224
- }
225
-
226
- const lineOptions = [
227
- {
228
- value: 'Dashed Small',
229
- key: 'dashed-sm'
230
- },
231
- {
232
- value: 'Dashed Medium',
233
- key: 'dashed-md'
234
- },
235
- {
236
- value: 'Dashed Large',
237
- key: 'dashed-lg'
238
- },
239
- {
240
- value: 'Solid Line',
241
- key: 'solid-line'
242
- }
243
- ]
244
-
245
158
  const loadConfig = async () => {
246
159
  let response = configObj || (await (await fetch(configUrl)).json())
247
160
 
@@ -310,8 +223,13 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
310
223
 
311
224
  newConfig.series.map(series => {
312
225
  if (!series.tooltip) series.tooltip = true
226
+ if (!series.axis) series.axis = 'Left'
313
227
  })
314
228
 
229
+ if (!newConfig.data && data) {
230
+ newConfig.data = data
231
+ }
232
+
315
233
  const processedConfig = { ...(await coveUpdateWorker(newConfig)) }
316
234
 
317
235
  updateConfig(processedConfig, data)
@@ -409,37 +327,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
409
327
  let tableData: any[] = []
410
328
  const plots: any[] = []
411
329
 
412
- /**
413
- * Calculates the first quartile (q1) and third quartile (q3) from an array of integers or decimals.
414
- *
415
- * @param {Array} arr - The array of integers or decimals.
416
- * @returns {Object} An object containing the q1 and q3 values.
417
- */
418
- const getQuartiles = arr => {
419
- arr.sort((a, b) => a - b)
420
-
421
- // Calculate the index of the median value of the array
422
- const medianIndex = Math.floor(arr.length / 2)
423
-
424
- // Check if the length of the array is even or odd
425
- const isEvenLength = arr.length % 2 === 0
426
-
427
- // Split the array into two subarrays based on the median index
428
- const q1Array = isEvenLength ? arr.slice(0, medianIndex) : arr.slice(0, medianIndex + 1)
429
- const q3Array = isEvenLength ? arr.slice(medianIndex) : arr.slice(medianIndex + 1)
430
-
431
- // Calculate the median of the first subarray to get the q1 value
432
- const q1Index = Math.floor(q1Array.length / 2)
433
- const q1 = isEvenLength ? (q1Array[q1Index - 1] + q1Array[q1Index]) / 2 : q1Array[q1Index]
434
-
435
- // Calculate the median of the second subarray to get the q3 value
436
- const q3Index = Math.floor(q3Array.length / 2)
437
- const q3 = isEvenLength ? (q3Array[q3Index - 1] + q3Array[q3Index]) / 2 : q3Array[q3Index]
438
-
439
- // Return an object containing the q1 and q3 values
440
- return { q1, q3 }
441
- }
442
-
443
330
  // group specific statistics
444
331
  // prevent re-renders
445
332
  if (!groups) return
@@ -563,7 +450,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
563
450
  if ((newConfig.visualizationType === 'Bar' && newConfig.orientation === 'horizontal') || ['Deviation Bar', 'Paired Bar', 'Forest Plot'].includes(newConfig.visualizationType)) {
564
451
  newConfig.runtime.xAxis = newConfig.yAxis
565
452
  newConfig.runtime.yAxis = newConfig.xAxis
566
- newConfig.runtime.horizontal = true
453
+
454
+ newConfig.runtime.horizontal = false
567
455
  newConfig.orientation = 'horizontal'
568
456
  } else if (['Box Plot', 'Scatter Plot', 'Area Chart', 'Line', 'Forecasting'].includes(newConfig.visualizationType)) {
569
457
  newConfig.runtime.xAxis = newConfig.xAxis
@@ -581,25 +469,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
581
469
  setConfig(newConfig)
582
470
  }
583
471
 
584
- const filterData = (filters, data) => {
585
- let filteredData: any[] = []
586
-
587
- data.forEach(row => {
588
- let add = true
589
- filters
590
- .filter(filter => filter.type !== 'url')
591
- .forEach(filter => {
592
- if (row[filter.columnName] != filter.active) {
593
- add = false
594
- }
595
- })
596
-
597
- if (add) filteredData.push(row)
598
- })
599
-
600
- return filteredData
601
- }
602
-
603
472
  // Gets filter values from dataset
604
473
  const generateValuesForFilter = (columnName, data = this.state.data) => {
605
474
  const values: any[] = []
@@ -739,7 +608,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
739
608
  // Generates color palette to pass to child chart component
740
609
  useEffect(() => {
741
610
  if (stateData && config.xAxis && config.runtime.seriesKeys) {
742
- const configPalette = config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar' ? config.twoColor.palette : config.palette
611
+ const configPalette = config.customColors ? config.customColors : config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar' ? config.twoColor.palette : config.palette
743
612
  const allPalettes = { ...colorPalettes, ...twoColorPalette }
744
613
  let palette = config.customColors || allPalettes[configPalette]
745
614
  let numberOfKeys = config.runtime.seriesKeys.length
@@ -754,7 +623,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
754
623
  newColorScale = () =>
755
624
  scaleOrdinal({
756
625
  domain: config.runtime.seriesLabelsAll,
757
- range: palette
626
+ range: palette,
627
+ unknown: null
758
628
  })
759
629
 
760
630
  setColorScale(newColorScale)
@@ -856,24 +726,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
856
726
  return Math.ceil(context.measureText(text).width)
857
727
  }
858
728
 
859
- const abbreviateNumber = num => {
860
- let unit = ''
861
- let absNum = Math.abs(num)
862
-
863
- if (absNum >= 1e9) {
864
- unit = 'B'
865
- num = num / 1e9
866
- } else if (absNum >= 1e6) {
867
- unit = 'M'
868
- num = num / 1e6
869
- } else if (absNum >= 1e3) {
870
- unit = 'K'
871
- num = num / 1e3
872
- }
873
-
874
- return num + unit
875
- }
876
-
877
729
  // Format numeric data based on settings in config OR from passed in settings for Additional Columns
878
730
  // - use only for old horizontal data - newer formatNumber is in helper/formatNumber
879
731
  // TODO: we should combine various formatNumber functions across this project.
@@ -925,11 +777,17 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
925
777
  }
926
778
  }
927
779
 
780
+ const resolveBottomTickRounding = () => {
781
+ if (config.forestPlot.type === 'Logarithmic' && !bottomRoundTo) return 2
782
+ if (Number(bottomRoundTo)) return Number(bottomRoundTo)
783
+ return 0
784
+ }
785
+
928
786
  if (axis === 'bottom') {
929
787
  stringFormattingOptions = {
930
788
  useGrouping: config.dataFormat.bottomCommas ? true : false,
931
- minimumFractionDigits: bottomRoundTo ? Number(bottomRoundTo) : 0,
932
- maximumFractionDigits: bottomRoundTo ? Number(bottomRoundTo) : 0
789
+ minimumFractionDigits: resolveBottomTickRounding(),
790
+ maximumFractionDigits: resolveBottomTickRounding()
933
791
  }
934
792
  }
935
793
 
@@ -1127,18 +985,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1127
985
  return generateColorsArray(mapColorPalette[3])
1128
986
  }
1129
987
 
1130
- let hash = hashObj(rowObj)
1131
-
1132
- if (legendMemo.current.has(hash)) {
1133
- let idx = legendMemo.current.get(hash)
1134
- if (runtimeLegend[idx]?.disabled) return false
1135
-
1136
- // DEV-784 changed to use bin prop to get color instead of idx
1137
- // bc we re-order legend when showSpecialClassesLast is checked
1138
- let legendBinColor = runtimeLegend.find(o => o.bin === idx)?.color
1139
- return generateColorsArray(legendBinColor, runtimeLegend[idx]?.special)
1140
- }
1141
-
1142
988
  // Fail state
1143
989
  return generateColorsArray()
1144
990
  } catch (e) {
@@ -1173,13 +1019,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1173
1019
  {isEditor && <EditorPanel />}
1174
1020
  {!missingRequiredSections() && !config.newViz && (
1175
1021
  <div className='cdc-chart-inner-container'>
1176
- {/* Title */}
1177
- {title && config.showTitle && (
1178
- <div role='heading' className={`chart-title ${config.theme} cove-component__header`} aria-level={2}>
1179
- {config && <sup className='superTitle'>{parse(config.superTitle || '')}</sup>}
1180
- <div>{parse(title)}</div>
1181
- </div>
1182
- )}
1022
+ <Title showTitle={config.showTitle} isDashboard={isDashboard} title={title} superTitle={config.superTitle} classes={['chart-title', `${config.theme}`, 'cove-component__header']} style={undefined} />
1023
+
1183
1024
  <a id='skip-chart-container' className='cdcdataviz-sr-only-focusable' href={handleChartTabbing}>
1184
1025
  Skip Over Chart Container
1185
1026
  </a>
@@ -1188,8 +1029,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1188
1029
  {/* Visualization */}
1189
1030
  {config?.introText && config.visualizationType !== 'Spark Line' && <section className='introText'>{parse(config.introText)}</section>}
1190
1031
  <div
1191
- style={{ marginBottom: config.legend.position !== 'bottom' && config.orientation === 'horizontal' ? `${config.runtime.xAxis.size}px` : '0px' }}
1192
- className={`chart-container p-relative ${config.legend.position === 'bottom' ? 'bottom' : ''}${config.legend.hide ? ' legend-hidden' : ''}${lineDatapointClass}${barBorderClass} ${contentClasses.join(' ')}`}
1032
+ style={{ marginBottom: computeMarginBottom(config, legend, currentViewport) }}
1033
+ className={`chart-container p-relative ${config.legend.position === 'bottom' ? 'bottom' : ''}${config.legend.hide ? ' legend-hidden' : ''}${lineDatapointClass}${barBorderClass} ${contentClasses.join(' ')} ${isDebug ? 'debug' : ''}`}
1193
1034
  >
1194
1035
  {/* All charts except sparkline */}
1195
1036
  {config.visualizationType !== 'Spark Line' && chartComponents[config.visualizationType]}
@@ -1212,7 +1053,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1212
1053
  )}
1213
1054
  </>
1214
1055
  )}
1215
- {!config.legend.hide && config.visualizationType !== 'Spark Line' && <Legend />}
1056
+ {!config.legend.hide && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Forest Plot' && <Legend />}
1216
1057
  </div>
1217
1058
  {/* Link */}
1218
1059
  {isDashboard && config.table && config.table.show && config.table.showDataTableLink ? tableLink : link && link}
@@ -1231,11 +1072,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1231
1072
  <DataTable
1232
1073
  config={config}
1233
1074
  rawData={config.data}
1234
- runtimeData={filteredData || excludedData}
1075
+ runtimeData={transform.applySuppression(filteredData || excludedData, config.suppressedData)}
1235
1076
  expandDataTable={config.table.expanded}
1236
1077
  columns={config.columns}
1237
- showDownloadButton={config.general.showDownloadButton}
1238
- runtimeLegend={dynamicLegendItems}
1239
1078
  displayDataAsText={displayDataAsText}
1240
1079
  displayGeoName={displayGeoName}
1241
1080
  applyLegendToRow={applyLegendToRow}
@@ -1243,18 +1082,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1243
1082
  indexTitle={config.table.indexLabel}
1244
1083
  vizTitle={title}
1245
1084
  viewport={currentViewport}
1246
- parseDate={parseDate}
1247
- formatDate={formatDate}
1248
- formatNumber={formatNumber}
1249
1085
  tabbingId={handleChartTabbing}
1250
- showDownloadImgButton={config.showDownloadImgButton}
1251
- showDownloadPdfButton={config.showDownloadPdfButton}
1252
- innerContainerRef={innerContainerRef}
1253
- outerContainerRef={outerContainerRef}
1254
- imageRef={imageId}
1255
1086
  colorScale={colorScale}
1256
- isDebug={isDebug}
1257
- isEditor={isEditor}
1258
1087
  />
1259
1088
  )}
1260
1089
  {config?.footnotes && <section className='footnotes'>{parse(config.footnotes)}</section>}
@@ -1274,6 +1103,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1274
1103
 
1275
1104
  const contextValues = {
1276
1105
  capitalize,
1106
+ computeMarginBottom,
1277
1107
  getXAxisData,
1278
1108
  getYAxisData,
1279
1109
  config,
@@ -1316,7 +1146,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1316
1146
  isDebug,
1317
1147
  setSharedFilter,
1318
1148
  setSharedFilterValue,
1319
- dashboardConfig
1149
+ dashboardConfig,
1150
+ debugSvg: isDebug
1320
1151
  }
1321
1152
 
1322
1153
  const classes = ['cdc-open-viz-module', 'type-chart', `${currentViewport}`, `font-${config.fontSize}`, `${config.theme}`]
@@ -0,0 +1,6 @@
1
+ import { createContext } from 'react'
2
+ import { ChartContext } from './types/ChartContext'
3
+
4
+ const ConfigContext = createContext({} as ChartContext)
5
+
6
+ export default ConfigContext