@cdc/chart 4.23.5 → 4.23.6

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.
@@ -27,7 +27,7 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
27
27
  const tooltip_id = `cdc-open-viz-tooltip-${config.runtime.uniqueId}`
28
28
 
29
29
  // import tooltip helpers
30
- const { tooltipData, showTooltip } = useTooltip()
30
+ const { tooltipData, showTooltip, hideTooltip } = useTooltip()
31
31
 
32
32
  // here we're inside of the svg,
33
33
  // it appears we need to use TooltipInPortal.
@@ -41,8 +41,6 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
41
41
  // Turn DEBUG on for additional context.
42
42
  if (!data) return
43
43
  let barThickness = xMax / data.length
44
- let barThicknessAdjusted = barThickness * (config.barThickness || 0.8)
45
- let offset = (barThickness * (1 - (config.barThickness || 0.8))) / 2
46
44
 
47
45
  // Tooltip helper for getting data to the closest date/category hovered.
48
46
  const getXValueFromCoordinate = x => {
@@ -87,6 +85,9 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
87
85
  if (!yScaleValues[0]) return
88
86
  for (const item of Object.entries(yScaleValues[0])) {
89
87
  if (item[0] === seriesKey) {
88
+ // let userUpdatedSeriesName = config.series.filter(series => series.dataKey === item[0])?.[0]?.name
89
+ // if (userUpdatedSeriesName) item[0] = userUpdatedSeriesName
90
+
90
91
  seriesToInclude.push(item)
91
92
  }
92
93
  }
@@ -95,6 +96,7 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
95
96
  // filter out the series that aren't added to the map.
96
97
  seriesToInclude.map(series => yScaleMaxValues.push(Number(yScaleValues[0][series])))
97
98
  if (!seriesToInclude) return
99
+
98
100
  let tooltipDataFromSeries = Object.fromEntries(seriesToInclude) ? Object.fromEntries(seriesToInclude) : {}
99
101
 
100
102
  let tooltipData = {}
@@ -143,8 +145,9 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
143
145
 
144
146
  if (config.xAxis.type === 'date') {
145
147
  data.map(d => xScale(parseDate(d[config.xAxis.dataKey])))
148
+ } else {
149
+ data.map(d => xScale(d[config.xAxis.dataKey]))
146
150
  }
147
-
148
151
  return (
149
152
  <React.Fragment key={index}>
150
153
  {/* prettier-ignore */}
@@ -182,6 +185,7 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
182
185
  fillOpacity={0.05}
183
186
  style={DEBUG ? { stroke: 'black', strokeWidth: 2 } : {}}
184
187
  onMouseMove={e => handleMouseOver(e, data)}
188
+ onMouseOut={hideTooltip}
185
189
  />
186
190
 
187
191
  {/* circles that appear on hover */}
@@ -197,25 +201,6 @@ const CoveAreaChart = ({ xScale, yScale, yMax, xMax, chartRef }) => {
197
201
  />
198
202
  )}
199
203
 
200
- {/* another tool for showing bars during debug mode. */}
201
- {DEBUG &&
202
- data.map((item, index) => {
203
- return (
204
- <Bar
205
- className='bar-here'
206
- x={Number(barThickness * index)}
207
- y={d => Number(yScale(d[config.series[index].dataKey]))}
208
- yScale={yScale}
209
- width={Number(barThickness)}
210
- height={yMax}
211
- fill={DEBUG ? 'red' : 'transparent'}
212
- fillOpacity={1}
213
- style={{ stroke: 'black', strokeWidth: 2 }}
214
- onMouseMove={e => handleMouseOver(e, data)}
215
- />
216
- )
217
- })}
218
-
219
204
  {tooltipData && Object.entries(tooltipData.data).length > 0 && (
220
205
  <TooltipInPortal key={Math.random()} top={tooltipData.dataYPosition + chartPosition?.top} left={tooltipData.dataXPosition + chartPosition?.left} style={defaultStyles}>
221
206
  <ul style={{ listStyle: 'none', paddingLeft: 'unset', fontFamily: 'sans-serif', margin: 'auto', lineHeight: '1rem' }} data-tooltip-id={tooltip_id}>
@@ -7,9 +7,10 @@ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
7
7
  import ConfigContext from '../ConfigContext'
8
8
  import { BarStackHorizontal } from '@visx/shape'
9
9
  import { useHighlightedBars } from '../hooks/useHighlightedBars'
10
+ import { act } from 'react-dom/test-utils'
10
11
 
11
12
  export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getXAxisData, getYAxisData, animatedChart, visible }) {
12
- const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, updateConfig, colorPalettes, tableData, formatDate, isNumber, getTextWidth, parseDate } = useContext(ConfigContext)
13
+ const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, updateConfig, colorPalettes, tableData, formatDate, isNumber, getTextWidth, parseDate, setSharedFilter, setSharedFilterValue, dashboardConfig } = useContext(ConfigContext)
13
14
  const { HighLightedBarUtils } = useHighlightedBars(config)
14
15
  const { orientation, visualizationSubType } = config
15
16
  const isHorizontal = orientation === 'horizontal'
@@ -202,6 +203,13 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
202
203
  display={displayBar ? 'block' : 'none'}
203
204
  data-tooltip-html={tooltip}
204
205
  data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
206
+ onClick={e => {
207
+ e.preventDefault()
208
+ if (setSharedFilter) {
209
+ bar[config.xAxis.dataKey] = xAxisValue
210
+ setSharedFilter(config.uid, bar)
211
+ }
212
+ }}
205
213
  ></foreignObject>
206
214
  </Group>
207
215
  </Group>
@@ -266,6 +274,13 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
266
274
  display={displayBar ? 'block' : 'none'}
267
275
  data-tooltip-html={tooltip}
268
276
  data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
277
+ onClick={e => {
278
+ e.preventDefault()
279
+ if (setSharedFilter) {
280
+ bar[config.xAxis.dataKey] = xAxisValue
281
+ setSharedFilter(config.uid, bar)
282
+ }
283
+ }}
269
284
  ></foreignObject>
270
285
 
271
286
  {orientation === 'horizontal' && visualizationSubType === 'stacked' && isLabelBelowBar && barStack.index === 0 && !config.yAxis.hideLabel && (
@@ -447,14 +462,54 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
447
462
  const highlightedBarColor = config.orientation === 'vertical' ? getHighlightedBarColorByValue(xAxisValue) : getHighlightedBarColorByValue(yAxisValue)
448
463
  const highlightedBar = config.orientation === 'vertical' ? getHighlightedBarByValue(xAxisValue) : getHighlightedBarByValue(yAxisValue)
449
464
 
450
- const background = isRegularLollipopColor ? barColor : isTwoToneLollipopColor ? chroma(barColor).brighten(1) : isHighlightedBar ? 'transparent' : barColor
465
+ const background = () => {
466
+ if (isRegularLollipopColor) return barColor
467
+ if (isTwoToneLollipopColor) return chroma(barColor).brighten(1)
468
+ if (isHighlightedBar) return 'transparent'
469
+ // loop through shared filters and get active values
470
+ if (dashboardConfig && dashboardConfig?.dashboard.sharedFilters?.length > 0) {
471
+ let activeFilters = []
472
+ let backgroundColor = barColor
473
+
474
+ const checkForResetValue = () => {
475
+ return dashboardConfig.dashboard.sharedFilters?.map((filter, index) => {
476
+ if (filter.resetLabel === filter.active) {
477
+ backgroundColor = barColor
478
+ } else {
479
+ return backgroundColor
480
+ }
481
+ })
482
+ }
483
+
484
+ dashboardConfig.dashboard.sharedFilters?.forEach((filter, index) => {
485
+ activeFilters.push(filter.active)
486
+ })
487
+
488
+ // if reset value is found use that.
489
+
490
+ if (config.orientation === 'horizontal') {
491
+ if (!activeFilters.includes(yAxisValue)) {
492
+ backgroundColor = '#ccc'
493
+ }
494
+ }
495
+
496
+ if (config.orientation !== 'horizontal') {
497
+ if (!activeFilters.includes(xAxisValue)) {
498
+ backgroundColor = '#ccc'
499
+ }
500
+ }
501
+ checkForResetValue()
502
+ return backgroundColor
503
+ }
504
+ return barColor
505
+ }
451
506
 
452
507
  const borderColor = isHighlightedBar ? highlightedBarColor : config.barHasBorder === 'true' ? '#000' : 'transparent'
453
508
 
454
509
  const borderWidth = isHighlightedBar ? highlightedBar.borderWidth : config.isLollipopChart ? 0 : config.barHasBorder === 'true' ? barBorderWidth : 0
455
510
 
456
511
  const finalStyle = {
457
- background,
512
+ background: background(),
458
513
  borderColor,
459
514
  borderStyle: 'solid',
460
515
  borderWidth,
@@ -485,6 +540,13 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
485
540
  display={displayBar ? 'block' : 'none'}
486
541
  data-tooltip-html={tooltip}
487
542
  data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
543
+ onClick={e => {
544
+ e.preventDefault()
545
+ if (setSharedFilter) {
546
+ bar[config.xAxis.dataKey] = config.orientation === 'horizontal' ? yAxisValue : xAxisValue
547
+ setSharedFilter(config.uid, bar)
548
+ }
549
+ }}
488
550
  ></foreignObject>
489
551
  {orientation === 'horizontal' && !config.isLollipopChart && displayNumbersOnBar && (
490
552
  <Text // prettier-ignore
@@ -2,6 +2,7 @@ import React, { useContext, useEffect, useState, useMemo } from 'react'
2
2
  import { useTable, useSortBy, useResizeColumns, useBlockLayout } from 'react-table'
3
3
  import Papa from 'papaparse'
4
4
  import { Base64 } from 'js-base64'
5
+ import { colorPalettesChart } from '@cdc/core/data/colorPalettes'
5
6
 
6
7
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
7
8
  import LegendCircle from '@cdc/core/components/LegendCircle'
@@ -9,7 +10,7 @@ import Icon from '@cdc/core/components/ui/Icon'
9
10
 
10
11
  import ConfigContext from '../ConfigContext'
11
12
 
12
- import CoveMediaControls from '@cdc/core/components/CoveMediaControls'
13
+ import MediaControls from '@cdc/core/components/MediaControls'
13
14
 
14
15
  export default function DataTable() {
15
16
  const { rawData, tableData: data, config, colorScale, parseDate, formatDate, formatNumber: numberFormatter, colorPalettes } = useContext(ConfigContext)
@@ -93,24 +94,29 @@ export default function DataTable() {
93
94
  {
94
95
  Header: '',
95
96
  Cell: ({ row }) => {
96
- const seriesLabel = config.runtime.seriesLabels ? config.runtime.seriesLabels[row.original] : row.original
97
+ const getSeriesLabel = () => {
98
+ let userUpdatedSeriesName = config.series.filter(series => series.dataKey === row.original)?.[0]?.name
99
+
100
+ if (userUpdatedSeriesName) return userUpdatedSeriesName
101
+ if (config.runtimeSeriesLabels) return config.runtime.seriesLabels[row.original]
102
+ return row.original
103
+ }
97
104
  return (
98
105
  <>
99
106
  {config.visualizationType !== 'Pie' && (
100
107
  <LegendCircle
101
108
  fill={
102
- // non-dynamic leged
103
- !config.legend.dynamicLegend
104
- ? colorScale(seriesLabel)
105
- : // dynamic legend
106
- config.legend.dynamicLegend
109
+ // non-dynamic legend
110
+ !config.legend.dynamicLegend && config.visualizationType !== 'Forecasting'
111
+ ? colorScale(getSeriesLabel())
112
+ : config.legend.dynamicLegend
107
113
  ? colorPalettes[config.palette][row.index]
108
114
  : // fallback
109
115
  '#000'
110
116
  }
111
117
  />
112
118
  )}
113
- <span>{seriesLabel}</span>
119
+ <span>{getSeriesLabel()}</span>
114
120
  </>
115
121
  )
116
122
  },
@@ -127,7 +133,19 @@ export default function DataTable() {
127
133
  const newCol = {
128
134
  Header: resolveTableHeader(),
129
135
  Cell: ({ row }) => {
130
- return <>{numberFormatter(d[row.original], 'left')}</>
136
+ let leftAxisItems = config.series.filter(item => item?.axis === 'Left')
137
+ let rightAxisItems = config.series.filter(item => item?.axis === 'Right')
138
+ let resolvedAxis = ''
139
+
140
+ leftAxisItems.map(leftSeriesItem => {
141
+ if (leftSeriesItem.dataKey === row.original) resolvedAxis = 'left'
142
+ })
143
+
144
+ rightAxisItems.map(rightSeriesItem => {
145
+ if (rightSeriesItem.dataKey === row.original) resolvedAxis = 'right'
146
+ })
147
+
148
+ return <>{numberFormatter(d[row.original], resolvedAxis)}</>
131
149
  },
132
150
  id: `${d[config.runtime.originalXAxis.dataKey]}--${index}`,
133
151
  canSort: true
@@ -210,10 +228,10 @@ export default function DataTable() {
210
228
 
211
229
  return (
212
230
  <ErrorBoundary component='DataTable'>
213
- <CoveMediaControls.Section classes={['download-links']}>
214
- <CoveMediaControls.Link config={config} />
231
+ <MediaControls.Section classes={['download-links']}>
232
+ <MediaControls.Link config={config} />
215
233
  {config.table.download && <DownloadButton data={rawData} type='link' />}
216
- </CoveMediaControls.Section>
234
+ </MediaControls.Section>
217
235
 
218
236
  <section id={config?.title ? `dataTableSection__${config?.title.replace(/\s/g, '')}` : `dataTableSection`} className={`data-table-container`} aria-label={accessibilityLabel}>
219
237
  <div