@cdc/chart 4.24.1 → 4.24.2

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 (58) hide show
  1. package/dist/cdcchart.js +30014 -29757
  2. package/examples/feature/line/line-chart-preliminary.json +84 -37
  3. package/examples/feature/regions/index.json +9 -5
  4. package/index.html +4 -2
  5. package/package.json +2 -2
  6. package/src/CdcChart.tsx +41 -24
  7. package/src/_stories/ChartEditor.stories.tsx +1 -1
  8. package/src/_stories/_mock/pie_config.json +4 -3
  9. package/src/components/AreaChart/components/AreaChart.jsx +1 -25
  10. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +7 -5
  11. package/src/components/BarChart/components/BarChart.Vertical.tsx +12 -13
  12. package/src/components/BoxPlot/BoxPlot.jsx +9 -8
  13. package/src/components/EditorPanel/EditorPanel.tsx +1563 -1959
  14. package/src/components/EditorPanel/EditorPanelContext.ts +40 -0
  15. package/src/components/EditorPanel/components/Panels/Panel.BoxPlot.tsx +148 -0
  16. package/src/components/EditorPanel/components/{Panel.ForestPlotSettings.tsx → Panels/Panel.ForestPlotSettings.tsx} +16 -7
  17. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +160 -0
  18. package/src/components/EditorPanel/components/{Panel.Regions.tsx → Panels/Panel.Regions.tsx} +5 -5
  19. package/src/components/EditorPanel/components/{Panel.Series.tsx → Panels/Panel.Series.tsx} +4 -4
  20. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +297 -0
  21. package/src/components/EditorPanel/components/Panels/index.tsx +17 -0
  22. package/src/components/EditorPanel/editor-panel.scss +1 -13
  23. package/src/components/EditorPanel/useEditorPermissions.js +5 -0
  24. package/src/components/Legend/Legend.Component.tsx +199 -0
  25. package/src/components/Legend/Legend.tsx +5 -324
  26. package/src/components/Legend/helpers/createFormatLabels.tsx +140 -0
  27. package/src/components/LineChart/LineChartProps.ts +1 -1
  28. package/src/components/LineChart/components/LineChart.Circle.tsx +85 -52
  29. package/src/components/LineChart/helpers.ts +2 -2
  30. package/src/components/LineChart/index.tsx +97 -21
  31. package/src/components/LinearChart.jsx +3 -3
  32. package/src/components/PairedBarChart.jsx +4 -2
  33. package/src/components/PieChart/PieChart.tsx +78 -25
  34. package/src/components/Regions/components/Regions.tsx +14 -5
  35. package/src/data/initial-state.js +5 -2
  36. package/src/helpers/computeMarginBottom.ts +2 -2
  37. package/src/hooks/useHighlightedBars.js +1 -1
  38. package/src/hooks/useMinMax.ts +3 -3
  39. package/src/hooks/useScales.ts +18 -5
  40. package/src/hooks/useTooltip.tsx +11 -7
  41. package/src/scss/main.scss +0 -67
  42. package/src/types/ChartConfig.ts +17 -8
  43. package/src/types/ChartContext.ts +10 -4
  44. package/src/types/Label.ts +7 -0
  45. package/examples/private/chart-t.json +0 -3740
  46. package/examples/private/combo.json +0 -369
  47. package/examples/private/epi-data.csv +0 -13
  48. package/examples/private/epi-data.json +0 -62
  49. package/examples/private/epi.json +0 -403
  50. package/examples/private/occupancy.json +0 -109283
  51. package/examples/private/prod-line-config.json +0 -401
  52. package/examples/private/region-data.json +0 -822
  53. package/examples/private/region-testing.json +0 -312
  54. package/examples/private/scaling.json +0 -45325
  55. package/examples/private/testing-data.json +0 -1739
  56. package/examples/private/testing.json +0 -816
  57. package/src/components/EditorPanel/components/Panel.DateHighlighting.tsx +0 -109
  58. package/src/components/EditorPanel/components/Panels.tsx +0 -13
@@ -10,7 +10,7 @@
10
10
  "theme": "theme-orange",
11
11
  "animate": false,
12
12
  "fontSize": "medium",
13
- "lineDatapointStyle": "hover",
13
+ "lineDatapointStyle": "always show",
14
14
  "lineDatapointColor": "Same as Line",
15
15
  "barHasBorder": "false",
16
16
  "isLollipopChart": false,
@@ -32,26 +32,10 @@
32
32
  "preliminaryData": [
33
33
  {
34
34
  "type": "effect",
35
- "label": "Cricle 1",
35
+ "label": "dashed",
36
36
  "column": "Data 2",
37
- "value": "20",
38
- "style": "Open Circles",
39
- "seriesKey": "Data 1"
40
- },
41
- {
42
- "type": "",
43
- "label": "Cricle 2",
44
- "column": "Data 3",
45
- "value": "20",
46
- "style": "Open Circles",
47
- "seriesKey": "Data 1"
48
- },
49
- {
50
- "type": "effect",
51
- "label": "circle 3",
52
- "column": "Data 2",
53
- "value": "30",
54
- "style": "Open Circles",
37
+ "value": "38",
38
+ "style": "Dashed Medium",
55
39
  "seriesKey": "Data 1"
56
40
  }
57
41
  ],
@@ -77,6 +61,7 @@
77
61
  "rightAxisTickColor": "#333",
78
62
  "numTicks": "",
79
63
  "axisPadding": 0,
64
+ "scalePadding": 10,
80
65
  "tickRotation": 0,
81
66
  "anchors": [],
82
67
  "label": "Y-Axis Label Example"
@@ -158,6 +143,7 @@
158
143
  "indexLabel": "",
159
144
  "download": true,
160
145
  "showVertical": false,
146
+ "dateDisplayFormat": "",
161
147
  "show": true
162
148
  },
163
149
  "orientation": "vertical",
@@ -186,25 +172,55 @@
186
172
  "data": [
187
173
  {
188
174
  "Year": "2015",
189
- "Data 1": "25",
175
+ "Data 1": "44",
190
176
  "Data 2": "20",
191
177
  "Data 3": "55"
192
178
  },
193
179
  {
194
180
  "Year": "2016",
195
- "Data 1": "35",
181
+ "Data 1": "",
196
182
  "Data 2": "30",
197
183
  "Data 3": "35"
198
184
  },
199
185
  {
200
186
  "Year": "2017",
201
- "Data 1": "22",
187
+ "Data 1": "133",
202
188
  "Data 2": "38",
203
- "Data 3": "40"
189
+ "Data 3": ""
204
190
  },
205
191
  {
206
192
  "Year": "2018",
207
- "Data 1": "40",
193
+ "Data 1": "122",
194
+ "Data 2": "40",
195
+ "Data 3": "20"
196
+ },
197
+ {
198
+ "Year": "2019",
199
+ "Data 1": "12",
200
+ "Data 2": "40",
201
+ "Data 3": ""
202
+ },
203
+ {
204
+ "Year": "2020",
205
+ "Data 1": "55",
206
+ "Data 2": "40",
207
+ "Data 3": "20"
208
+ },
209
+ {
210
+ "Year": "2021",
211
+ "Data 1": "34",
212
+ "Data 2": "40",
213
+ "Data 3": "20"
214
+ },
215
+ {
216
+ "Year": "2022",
217
+ "Data 1": "",
218
+ "Data 2": "40",
219
+ "Data 3": "20"
220
+ },
221
+ {
222
+ "Year": "2023",
223
+ "Data 1": "65",
208
224
  "Data 2": "40",
209
225
  "Data 3": "20"
210
226
  }
@@ -251,20 +267,21 @@
251
267
  },
252
268
  {
253
269
  "dataKey": "Data 2",
254
- "type": "Bar",
255
- "tooltip": true,
256
- "axis": "Left"
270
+ "type": "Line",
271
+ "axis": "Left",
272
+ "tooltip": true
257
273
  },
258
274
  {
259
275
  "dataKey": "Data 3",
260
- "type": "Bar",
261
- "tooltip": true,
262
- "axis": "Left"
276
+ "type": "Line",
277
+ "axis": "Left",
278
+ "tooltip": true
263
279
  }
264
280
  ],
265
281
  "tooltips": {
266
282
  "opacity": 90,
267
- "singleSeries": false
283
+ "singleSeries": false,
284
+ "dateDisplayFormat": ""
268
285
  },
269
286
  "forestPlot": {
270
287
  "startAt": 0,
@@ -317,25 +334,55 @@
317
334
  "data": [
318
335
  {
319
336
  "Year": "2015",
320
- "Data 1": "25",
337
+ "Data 1": "44",
321
338
  "Data 2": "20",
322
339
  "Data 3": "55"
323
340
  },
324
341
  {
325
342
  "Year": "2016",
326
- "Data 1": "35",
343
+ "Data 1": "",
327
344
  "Data 2": "30",
328
345
  "Data 3": "35"
329
346
  },
330
347
  {
331
348
  "Year": "2017",
332
- "Data 1": "22",
349
+ "Data 1": "133",
333
350
  "Data 2": "38",
334
- "Data 3": "40"
351
+ "Data 3": ""
335
352
  },
336
353
  {
337
354
  "Year": "2018",
338
- "Data 1": "40",
355
+ "Data 1": "122",
356
+ "Data 2": "40",
357
+ "Data 3": "20"
358
+ },
359
+ {
360
+ "Year": "2019",
361
+ "Data 1": "12",
362
+ "Data 2": "40",
363
+ "Data 3": ""
364
+ },
365
+ {
366
+ "Year": "2020",
367
+ "Data 1": "55",
368
+ "Data 2": "40",
369
+ "Data 3": "20"
370
+ },
371
+ {
372
+ "Year": "2021",
373
+ "Data 1": "34",
374
+ "Data 2": "40",
375
+ "Data 3": "20"
376
+ },
377
+ {
378
+ "Year": "2022",
379
+ "Data 1": "",
380
+ "Data 2": "40",
381
+ "Data 3": "20"
382
+ },
383
+ {
384
+ "Year": "2023",
385
+ "Data 1": "65",
339
386
  "Data 2": "40",
340
387
  "Data 3": "20"
341
388
  }
@@ -29,6 +29,7 @@
29
29
  "right": 5
30
30
  },
31
31
  "suppressedData": [],
32
+ "preliminaryData": [],
32
33
  "yAxis": {
33
34
  "hideAxis": false,
34
35
  "displayNumbersOnBar": false,
@@ -97,7 +98,7 @@
97
98
  "horizontal": 750
98
99
  },
99
100
  "xAxis": {
100
- "sortDates": false,
101
+ "sortDates": true,
101
102
  "anchors": [],
102
103
  "type": "date",
103
104
  "showTargetLabel": true,
@@ -153,6 +154,7 @@
153
154
  "dynamicLegendChartMessage": "Select Options from the Legend",
154
155
  "lineMode": false,
155
156
  "verticalSorted": false,
157
+ "highlightOnHover": false,
156
158
  "position": "right",
157
159
  "label": "Type of Data"
158
160
  },
@@ -276,7 +278,8 @@
276
278
  }
277
279
  ],
278
280
  "tooltips": {
279
- "opacity": 90
281
+ "opacity": 90,
282
+ "singleSeries": false
280
283
  },
281
284
  "forestPlot": {
282
285
  "startAt": 0,
@@ -319,9 +322,9 @@
319
322
  "leftWidthOffset": 0,
320
323
  "rightWidthOffset": 0,
321
324
  "showZeroLine": false,
322
- "hideDateCategoryCol": false,
323
325
  "leftLabel": "",
324
326
  "rightLabel": "",
327
+ "hideDateCategoryCol": false,
325
328
  "width": "auto",
326
329
  "lowerCiField": "",
327
330
  "upperCiField": ""
@@ -387,14 +390,15 @@
387
390
  "Data 6": "300"
388
391
  }
389
392
  ],
390
- "visualizationType": "Bar",
393
+ "visualizationType": "Line",
391
394
  "regions": [
392
395
  {
393
396
  "from": "03/15/2016",
394
397
  "to": "05/15/2016",
395
398
  "label": "Region Applied to Timeline",
396
399
  "color": "Black",
397
- "background": "Grey"
400
+ "background": "Grey",
401
+ "fromType": "Previous Days"
398
402
  }
399
403
  ],
400
404
  "validated": 4.23,
package/index.html CHANGED
@@ -17,6 +17,8 @@
17
17
  margin-top: 3rem;
18
18
  }
19
19
  </style>
20
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/contrib/libs/bootstrap/latest/css/bootstrap.min.css?_=39423">
21
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/4.0/assets/css/app.min.css?_=39423">
20
22
  </head>
21
23
 
22
24
  <body>
@@ -34,7 +36,7 @@
34
36
  -->
35
37
 
36
38
  <!-- GENERIC CHART TYPES -->
37
- <!-- <div class="react-container" data-config="/examples/private/prod-line-config.json"></div> -->
39
+ <div class="react-container" data-config="/examples/private/rvr.json"></div>
38
40
  <!-- <div class="react-container" data-config="/examples/private/chart-t.json"></div> -->
39
41
  <!-- <div class="react-container" data-config="/examples/feature/bar/additional-column-tooltip.json"></div> -->
40
42
  <!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
@@ -45,7 +47,7 @@
45
47
  <!-- <div class="react-container" data-config="/examples/feature/forest-plot/forest-plot.json"></div> -->
46
48
  <!-- <div class="react-container" data-config="/examples/feature/pie/planet-pie-example-config.json"></div> -->
47
49
  <!-- <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> -->
50
+ <div class="react-container" data-config=/examples/feature/regions/index.json></div>
49
51
  <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
50
52
  <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
51
53
  <!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/chart",
3
- "version": "4.24.1",
3
+ "version": "4.24.2",
4
4
  "description": "React component for visualizing tabular data in various types of charts",
5
5
  "moduleName": "CdcChart",
6
6
  "main": "dist/cdcchart",
@@ -59,7 +59,7 @@
59
59
  "react": "^18.2.0",
60
60
  "react-dom": "^18.2.0"
61
61
  },
62
- "gitHead": "a352a3f74f4b681191e3244061dbb3621f36eec3",
62
+ "gitHead": "edde49c96dee146de5e3a4537880b1bcf4dbee08",
63
63
  "devDependencies": {
64
64
  "resize-observer-polyfill": "^1.5.1"
65
65
  }
package/src/CdcChart.tsx CHANGED
@@ -52,16 +52,19 @@ import './scss/main.scss'
52
52
  import DataTable from '@cdc/core/components/DataTable'
53
53
  import { getFileExtension } from '@cdc/core/helpers/getFileExtension'
54
54
  import Title from '@cdc/core/components/ui/Title'
55
+ import { ChartConfig } from './types/ChartConfig'
56
+ import { Label } from './types/Label'
57
+ import { isSolrCsv, isSolrJson } from '@cdc/core/helpers/isSolr'
55
58
 
56
59
  export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
57
60
  const transform = new DataTransform()
58
61
  const [loading, setLoading] = useState(true)
59
62
  const [colorScale, setColorScale] = useState(null)
60
- const [config, setConfig] = useState<any>({})
63
+ const [config, setConfig] = useState<ChartConfig>({} as ChartConfig)
61
64
  const [stateData, setStateData] = useState(config.data || [])
62
65
  const [excludedData, setExcludedData] = useState<Record<string, number>[] | undefined>(undefined)
63
66
  const [filteredData, setFilteredData] = useState<Record<string, any>[] | undefined>(undefined)
64
- const [seriesHighlight, setSeriesHighlight] = useState<any[]>([])
67
+ const [seriesHighlight, setSeriesHighlight] = useState<string[]>([])
65
68
  const [currentViewport, setCurrentViewport] = useState('lg')
66
69
  const [dimensions, setDimensions] = useState<[number?, number?]>([])
67
70
  const [externalFilters, setExternalFilters] = useState<any[]>()
@@ -95,7 +98,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
95
98
  let qsParams = Object.fromEntries(new URLSearchParams(dataUrl.search))
96
99
 
97
100
  let isUpdateNeeded = false
98
- config.filters.forEach(filter => {
101
+ config.filters?.forEach(filter => {
99
102
  if (filter.type === 'url' && qsParams[filter.queryParameter] !== decodeURIComponent(filter.active)) {
100
103
  qsParams[filter.queryParameter] = filter.active
101
104
  isUpdateNeeded = true
@@ -117,7 +120,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
117
120
 
118
121
  try {
119
122
  const ext = getFileExtension(dataUrl.href)
120
- if ('csv' === ext) {
123
+ if ('csv' === ext || isSolrCsv(dataUrlFinal)) {
121
124
  data = await fetch(dataUrlFinal)
122
125
  .then(response => response.text())
123
126
  .then(responseText => {
@@ -128,7 +131,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
128
131
  })
129
132
  return parsedCsv.data
130
133
  })
131
- } else if ('json' === ext) {
134
+ } else if ('json' === ext || isSolrJson(dataUrlFinal)) {
132
135
  data = await fetch(dataUrlFinal).then(response => response.json())
133
136
  } else {
134
137
  data = []
@@ -166,7 +169,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
166
169
  if (response.dataUrl && !urlFilters) {
167
170
  try {
168
171
  const ext = getFileExtension(response.dataUrl)
169
- if ('csv' === ext) {
172
+ if ('csv' === ext || isSolrCsv(response.dataUrl)) {
170
173
  data = await fetch(response.dataUrl + `?v=${cacheBustingString()}`)
171
174
  .then(response => response.text())
172
175
  .then(responseText => {
@@ -189,7 +192,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
189
192
  })
190
193
  }
191
194
 
192
- if ('json' === ext) {
195
+ if ('json' === ext || isSolrJson(response.dataUrl)) {
193
196
  data = await fetch(response.dataUrl + `?v=${cacheBustingString()}`).then(response => response.json())
194
197
  }
195
198
  } catch {
@@ -294,6 +297,16 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
294
297
  setFilteredData(currentData)
295
298
  }
296
299
 
300
+ if (!['Area Chart', 'Bar', 'Line', 'Combo'].includes(newConfig.visualizationType) || newConfig.orientation === 'horizontal') {
301
+ newConfig.xAxis.sortDates = false
302
+ }
303
+
304
+ if (newConfig.xAxis.sortDates && newConfig.barThickness > 0.1) {
305
+ newConfig.barThickness = 0.035
306
+ } else if (!newConfig.xAxis.sortDates && newConfig.barThickness < 0.1) {
307
+ newConfig.barThickness = 0.35
308
+ }
309
+
297
310
  //Enforce default values that need to be calculated at runtime
298
311
  newConfig.runtime = {}
299
312
  newConfig.runtime.seriesLabels = {}
@@ -426,6 +439,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
426
439
  if (series.type === 'Line' || series.type === 'dashed-sm' || series.type === 'dashed-md' || series.type === 'dashed-lg') {
427
440
  newConfig.runtime.lineSeriesKeys.push(series.dataKey)
428
441
  }
442
+ if (series.type === 'Combo') {
443
+ series.type = 'Bar'
444
+ }
429
445
  })
430
446
  }
431
447
 
@@ -448,8 +464,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
448
464
  }
449
465
 
450
466
  if ((newConfig.visualizationType === 'Bar' && newConfig.orientation === 'horizontal') || ['Deviation Bar', 'Paired Bar', 'Forest Plot'].includes(newConfig.visualizationType)) {
451
- newConfig.runtime.xAxis = newConfig.yAxis
452
- newConfig.runtime.yAxis = newConfig.xAxis
467
+ newConfig.runtime.xAxis = newConfig.yAxis['yAxis'] ? newConfig.yAxis['yAxis'] : newConfig.yAxis
468
+ newConfig.runtime.yAxis = newConfig.xAxis['xAxis'] ? newConfig.xAxis['xAxis'] : newConfig.xAxis
453
469
 
454
470
  newConfig.runtime.horizontal = false
455
471
  newConfig.orientation = 'horizontal'
@@ -463,6 +479,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
463
479
  newConfig.runtime.yAxis = newConfig.yAxis
464
480
  newConfig.runtime.horizontal = false
465
481
  }
482
+
466
483
  newConfig.runtime.uniqueId = Date.now()
467
484
  newConfig.runtime.editorErrorMessage = newConfig.visualizationType === 'Pie' && !newConfig.yAxis.dataKey ? 'Data Key property in Y Axis section must be set for pie charts.' : ''
468
485
 
@@ -607,9 +624,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
607
624
 
608
625
  // Generates color palette to pass to child chart component
609
626
  useEffect(() => {
610
- if (stateData && config.xAxis && config.runtime.seriesKeys) {
611
- const configPalette = config.customColors ? config.customColors : config.visualizationType === 'Paired Bar' || config.visualizationType === 'Deviation Bar' ? config.twoColor.palette : config.palette
612
- const allPalettes = { ...colorPalettes, ...twoColorPalette }
627
+ if (stateData && config.xAxis && config.runtime?.seriesKeys) {
628
+ const configPalette = ['Paired Bar', 'Deviation Bar'].includes(config.visualizationType) ? config.twoColor.palette : config.palette
629
+ const allPalettes: Record<string, string[]> = { ...colorPalettes, ...twoColorPalette }
613
630
  let palette = config.customColors || allPalettes[configPalette]
614
631
  let numberOfKeys = config.runtime.seriesKeys.length
615
632
  let newColorScale
@@ -637,27 +654,22 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
637
654
  }, [config, stateData]) // eslint-disable-line
638
655
 
639
656
  // Called on legend click, highlights/unhighlights the data series with the given label
640
- const highlight = label => {
641
- const newSeriesHighlight: any[] = []
642
-
657
+ const highlight = (label: Label) => {
643
658
  // If we're highlighting all the series, reset them
644
659
  if (seriesHighlight.length + 1 === config.runtime.seriesKeys.length && config.visualizationType !== 'Forecasting') {
645
660
  highlightReset()
646
661
  return
647
662
  }
648
663
 
649
- seriesHighlight.forEach(value => {
650
- newSeriesHighlight.push(value)
651
- })
664
+ const newSeriesHighlight = [...seriesHighlight]
652
665
 
653
666
  let newHighlight = label.datum
654
667
  if (config.runtime.seriesLabels) {
655
- for (let i = 0; i < config.runtime.seriesKeys.length; i++) {
656
- if (config.runtime.seriesLabels[config.runtime.seriesKeys[i]] === label.datum) {
657
- newHighlight = config.runtime.seriesKeys[i]
658
- break
668
+ config.runtime.seriesKeys.forEach(key => {
669
+ if (config.runtime.seriesLabels[key] === label.datum) {
670
+ newHighlight = key
659
671
  }
660
- }
672
+ })
661
673
  }
662
674
 
663
675
  if (newSeriesHighlight.indexOf(newHighlight) !== -1) {
@@ -713,6 +725,10 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
713
725
  return timeFormat(config.runtime[section].dateDisplayFormat)(date)
714
726
  }
715
727
 
728
+ const formatTooltipsDate = date => {
729
+ return timeFormat(config.tooltips.dateDisplayFormat)(date)
730
+ }
731
+
716
732
  // function calculates the width of given text and its font-size
717
733
  function getTextWidth(text, font) {
718
734
  const canvas = document.createElement('canvas')
@@ -1071,7 +1087,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1071
1087
  {config.xAxis.dataKey && config.table.show && config.visualizationType !== 'Spark Line' && (
1072
1088
  <DataTable
1073
1089
  config={config}
1074
- rawData={config.data}
1090
+ rawData={config.table.customTableConfig ? filterData(config.filters, config.data) : config.data}
1075
1091
  runtimeData={transform.applySuppression(filteredData || excludedData, config.suppressedData)}
1076
1092
  expandDataTable={config.table.expanded}
1077
1093
  columns={config.columns}
@@ -1119,6 +1135,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1119
1135
  currentViewport,
1120
1136
  parseDate,
1121
1137
  formatDate,
1138
+ formatTooltipsDate,
1122
1139
  formatNumber,
1123
1140
  loading,
1124
1141
  updateConfig,
@@ -14,7 +14,7 @@ type Story = StoryObj<typeof Chart>
14
14
 
15
15
  export const Primary: Story = {
16
16
  args: {
17
- config: { ...pieChartExample, data: pieData },
17
+ config: { ...pieChartExample, data: pieData, columns: { someCol: { name: 'females', showInViz: true } } },
18
18
  isEditor: true
19
19
  }
20
20
  }
@@ -97,11 +97,12 @@
97
97
  "caption": "",
98
98
  "showDownloadUrl": false,
99
99
  "showDataTableLink": true,
100
- "indexLabel": "",
100
+ "indexLabel": "Cause Type",
101
101
  "download": false,
102
102
  "showVertical": true,
103
103
  "show": true,
104
- "customTableConfig": true
104
+ "customTableConfig": true,
105
+ "excludeColumns": ["location", "age", "use", "data_group", "data_sub_group", "cause_category"]
105
106
  },
106
107
  "orientation": "vertical",
107
108
  "color": "pinkpurple",
@@ -182,7 +183,7 @@
182
183
  "filters": [
183
184
  {
184
185
  "values": ["age", "sex"],
185
- "active": "age",
186
+ "active": "sex",
186
187
  "filterStyle": "dropdown",
187
188
  "order": "asc",
188
189
  "columnName": "data_group"
@@ -18,26 +18,8 @@ const AreaChart = props => {
18
18
 
19
19
  if (!data) return
20
20
 
21
- // Tooltip helper for getting data to the closest date/category hovered.
22
- const getXValueFromCoordinate = x => {
23
- if (config.xAxis.type === 'categorical' || config.visualizationType === 'Combo') {
24
- let eachBand = xScale.step()
25
- let numerator = x
26
- const index = Math.floor(Number(numerator) / eachBand)
27
- return xScale.domain()[index - 1] // fixes off by 1 error
28
- }
29
-
30
- if (config.xAxis.type === 'date' && config.visualizationType !== 'Combo') {
31
- const bisectDate = bisector(d => parseDate(d[config.xAxis.dataKey])).left
32
- const x0 = xScale.invert(x)
33
- const index = bisectDate(config.data, x0, 1)
34
- const val = parseDate(config.data[index - 1][config.xAxis.dataKey])
35
- return val
36
- }
37
- }
38
-
39
21
  const handleX = d => {
40
- return config.xAxis.type === 'date' ? xScale(parseDate(d[config.xAxis.dataKey], false)) : xScale(d[config.xAxis.dataKey])
22
+ return (config.xAxis.type === 'date' ? xScale(parseDate(d[config.xAxis.dataKey], false)) : xScale(d[config.xAxis.dataKey])) + (xScale.bandwidth ? xScale.bandwidth() / 2 : 0)
41
23
  }
42
24
 
43
25
  const handleY = (d, index, s = undefined) => {
@@ -61,12 +43,6 @@ const AreaChart = props => {
61
43
  let transparentArea = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(s.dataKey) === -1
62
44
  let displayArea = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(s.dataKey) !== -1
63
45
 
64
- if (config.xAxis.type === 'date') {
65
- data.map(d => xScale(parseDate(d[config.xAxis.dataKey])))
66
- } else {
67
- data.map(d => xScale(d[config.xAxis.dataKey]))
68
- }
69
-
70
46
  return (
71
47
  <React.Fragment key={index}>
72
48
  {/* prettier-ignore */}
@@ -25,13 +25,15 @@ const BarChartStackedVertical = () => {
25
25
  barStack.bars.map(bar => {
26
26
  let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
27
27
  let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
28
- let barThickness = xMax / barStack.bars.length
29
- let barThicknessAdjusted = barThickness * (config.barThickness || 0.8)
28
+ let barThickness = config.xAxis.type === 'date' && config.xAxis.sortDates ? (config.barThickness * (xScale.range()[1] - xScale.range()[0])) : xMax / barStack.bars.length
29
+ let barThicknessAdjusted = barThickness * (config.xAxis.type === 'date' && config.xAxis.sortDates ? 1 : (config.barThickness || 0.8))
30
30
  let offset = (barThickness * (1 - (config.barThickness || 0.8))) / 2
31
31
  // tooltips
32
- const xAxisValue = config.runtime.xAxis.type === 'date' ? formatDate(parseDate(data[bar.index][config.runtime.xAxis.dataKey])) : data[bar.index][config.runtime.xAxis.dataKey]
32
+ const rawXValue = bar.bar.data[config.runtime.xAxis.dataKey]
33
+ const xAxisValue = config.runtime.xAxis.type === 'date' ? formatDate(parseDate(rawXValue)) : rawXValue
33
34
  const yAxisValue = formatNumber(bar.bar ? bar.bar.data[bar.key] : 0, 'left')
34
35
  if (!yAxisValue) return
36
+ const barX = xScale(config.runtime.xAxis.type === 'date' ? parseDate(rawXValue) : rawXValue) - (config.xAxis.type === 'date' && config.xAxis.sortDates ? barThicknessAdjusted / 2 : 0)
35
37
  const style = applyRadius(barStack.index)
36
38
  const xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${xAxisValue}` : xAxisValue
37
39
  const additionalColTooltip = getAdditionalColumn(hoveredBar)
@@ -56,14 +58,14 @@ const BarChartStackedVertical = () => {
56
58
  `}
57
59
  </style>
58
60
  <Group key={`bar-stack-${barStack.index}-${bar.index}`} id={`barStack${barStack.index}-${bar.index}`} className='stack vertical'>
59
- <Text display={config.labels && displayBar ? 'block' : 'none'} opacity={transparentBar ? 0.5 : 1} x={barThickness * bar.index + offset} y={bar.y - 5} fill={'#000'} textAnchor='middle'>
61
+ <Text display={config.labels && displayBar ? 'block' : 'none'} opacity={transparentBar ? 0.5 : 1} x={barX + barWidth / 2} y={bar.y - 5} fill={'#000'} textAnchor='middle'>
60
62
  {yAxisValue}
61
63
  </Text>
62
64
  <foreignObject
63
65
  onMouseOver={() => onMouseOverBar(xAxisValue, bar.key)}
64
66
  onMouseLeave={onMouseLeaveBar}
65
67
  key={`bar-stack-${barStack.index}-${bar.index}`}
66
- x={barThickness * bar.index + offset}
68
+ x={barX}
67
69
  y={bar.y}
68
70
  width={barThicknessAdjusted}
69
71
  height={bar.height}