@cdc/chart 4.24.9 → 4.24.11

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 (95) hide show
  1. package/LICENSE +201 -0
  2. package/dist/cdcchart.js +45911 -41739
  3. package/examples/feature/boxplot/boxplot-data.json +88 -22
  4. package/examples/feature/boxplot/boxplot.json +540 -16
  5. package/examples/feature/boxplot/testing.csv +7 -7
  6. package/examples/feature/sankey/sankey-example-data.json +0 -1
  7. package/examples/private/test.json +20092 -0
  8. package/index.html +4 -4
  9. package/package.json +2 -2
  10. package/src/CdcChart.tsx +209 -188
  11. package/src/_stories/Chart.CustomColors.stories.tsx +19 -0
  12. package/src/_stories/Chart.DynamicSeries.stories.tsx +27 -0
  13. package/src/_stories/Chart.Legend.Gradient.stories.tsx +74 -0
  14. package/src/_stories/Chart.stories.tsx +30 -3
  15. package/src/_stories/ChartAxisLabels.stories.tsx +20 -0
  16. package/src/_stories/ChartAxisTitles.stories.tsx +53 -0
  17. package/src/_stories/ChartEditor.stories.tsx +27 -0
  18. package/src/_stories/ChartLine.Suppression.stories.tsx +25 -0
  19. package/src/_stories/ChartPrefixSuffix.stories.tsx +159 -0
  20. package/src/_stories/_mock/boxplot_multiseries.json +647 -0
  21. package/src/_stories/_mock/dynamic_series_bar_config.json +723 -0
  22. package/src/_stories/_mock/dynamic_series_config.json +979 -0
  23. package/src/_stories/_mock/horizontal_bar.json +257 -0
  24. package/src/_stories/_mock/large_x_axis_labels.json +261 -0
  25. package/src/_stories/_mock/paired-bar.json +262 -0
  26. package/src/_stories/_mock/pie_with_data.json +255 -0
  27. package/{examples/feature/scatterplot/scatterplot.json → src/_stories/_mock/scatterplot_mock.json} +62 -92
  28. package/src/_stories/_mock/simplified_line.json +1510 -0
  29. package/src/_stories/_mock/suppression_mock.json +1549 -0
  30. package/src/components/Annotations/components/AnnotationDraggable.tsx +0 -3
  31. package/src/components/Annotations/components/AnnotationDropdown.tsx +1 -1
  32. package/src/components/Axis/Categorical.Axis.tsx +22 -4
  33. package/src/components/BarChart/components/BarChart.Horizontal.tsx +95 -16
  34. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +41 -17
  35. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +43 -9
  36. package/src/components/BarChart/components/BarChart.Vertical.tsx +123 -47
  37. package/src/components/BarChart/helpers/index.ts +23 -5
  38. package/src/components/BoxPlot/BoxPlot.tsx +189 -0
  39. package/src/components/BrushChart.tsx +3 -2
  40. package/src/components/DeviationBar.jsx +58 -8
  41. package/src/components/EditorPanel/EditorPanel.tsx +127 -102
  42. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +11 -28
  43. package/src/components/EditorPanel/components/Panels/Panel.BoxPlot.tsx +51 -6
  44. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +21 -4
  45. package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +40 -9
  46. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
  47. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +121 -56
  48. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +296 -35
  49. package/src/components/EditorPanel/components/panels.scss +4 -6
  50. package/src/components/EditorPanel/editor-panel.scss +0 -8
  51. package/src/components/EditorPanel/helpers/tests/updateFieldRankByValue.test.ts +38 -0
  52. package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +42 -0
  53. package/src/components/EditorPanel/useEditorPermissions.ts +16 -1
  54. package/src/components/ForestPlot/ForestPlot.tsx +2 -3
  55. package/src/components/ForestPlot/ForestPlotProps.ts +2 -0
  56. package/src/components/Legend/Legend.Component.tsx +23 -24
  57. package/src/components/Legend/Legend.Suppression.tsx +25 -20
  58. package/src/components/Legend/Legend.tsx +16 -18
  59. package/src/components/Legend/helpers/index.ts +16 -19
  60. package/src/components/LegendWrapper.tsx +3 -1
  61. package/src/components/LineChart/components/LineChart.Circle.tsx +10 -0
  62. package/src/components/LineChart/helpers.ts +48 -43
  63. package/src/components/LineChart/index.tsx +88 -82
  64. package/src/components/LinearChart.tsx +747 -562
  65. package/src/components/PairedBarChart.jsx +50 -10
  66. package/src/components/PieChart/PieChart.tsx +1 -6
  67. package/src/components/Regions/components/Regions.tsx +33 -19
  68. package/src/components/Sankey/index.tsx +50 -32
  69. package/src/components/Sankey/sankey.scss +6 -5
  70. package/src/components/Sankey/useSankeyAlert.tsx +60 -0
  71. package/src/components/ScatterPlot/ScatterPlot.jsx +20 -4
  72. package/src/components/ZoomBrush.tsx +25 -6
  73. package/src/coreStyles_chart.scss +3 -0
  74. package/src/data/initial-state.js +8 -10
  75. package/src/helpers/configHelpers.ts +28 -0
  76. package/src/helpers/handleRankByValue.ts +15 -0
  77. package/src/helpers/sizeHelpers.ts +25 -0
  78. package/src/helpers/tests/handleRankByValue.test.ts +37 -0
  79. package/src/helpers/tests/sizeHelpers.test.ts +80 -0
  80. package/src/hooks/useColorPalette.js +10 -2
  81. package/src/hooks/useLegendClasses.ts +13 -22
  82. package/src/hooks/useMinMax.ts +27 -13
  83. package/src/hooks/useReduceData.ts +43 -10
  84. package/src/hooks/useScales.ts +87 -38
  85. package/src/hooks/useTooltip.tsx +62 -53
  86. package/src/index.jsx +1 -0
  87. package/src/scss/DataTable.scss +5 -4
  88. package/src/scss/main.scss +57 -70
  89. package/src/types/ChartConfig.ts +43 -34
  90. package/src/types/ChartContext.ts +22 -15
  91. package/src/types/ForestPlot.ts +8 -0
  92. package/src/_stories/Chart.Legend.Gradient.tsx +0 -19
  93. package/src/_stories/ChartBrush.stories.tsx +0 -19
  94. package/src/components/BoxPlot/BoxPlot.jsx +0 -111
  95. package/src/components/LinearChart.jsx +0 -817
@@ -8,15 +8,31 @@ import { Table } from '@cdc/core/types/Table'
8
8
  import { BoxPlot } from '@cdc/core/types/BoxPlot'
9
9
  import { General } from '@cdc/core/types/General'
10
10
  import { type Link } from './../components/Sankey/types'
11
+ import { type DataDescription } from '@cdc/core/types/DataDescription'
12
+ import { type Legend as CoreLegend } from '@cdc/core/types/Legend'
11
13
  import { ConfidenceInterval } from '@cdc/core/types/ConfidenceInterval'
12
14
  import { Region } from '@cdc/core/types/Region'
13
-
14
15
  import { VizFilter } from '@cdc/core/types/VizFilter'
15
16
  import { type Annotation } from '@cdc/core/types/Annotation'
16
17
 
17
18
  export type ViewportSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg'
18
19
  export type ChartColumns = Record<string, Column>
19
-
20
+ export type ChartOrientation = 'vertical' | 'horizontal'
21
+ export type VisualizationType =
22
+ | 'Area Chart'
23
+ | 'Bar'
24
+ | 'Box Plot'
25
+ | 'Deviation Bar'
26
+ | 'Forest Plot'
27
+ | 'Line'
28
+ | 'Paired Bar'
29
+ | 'Pie'
30
+ | 'Scatter Plot'
31
+ | 'Spark Line'
32
+ | 'Combo'
33
+ | 'Forecasting'
34
+ | 'Sankey'
35
+ | 'Bump Chart'
20
36
  export interface PreliminaryDataItem {
21
37
  column: string
22
38
  displayLegend: boolean
@@ -51,6 +67,7 @@ type DataFormat = {
51
67
  rightSuffix: string
52
68
  roundTo: number
53
69
  suffix: string
70
+ onlyShowTopPrefixSuffix?: boolean
54
71
  }
55
72
 
56
73
  type Exclusions = {
@@ -60,31 +77,16 @@ type Exclusions = {
60
77
  dateEnd: string
61
78
  }
62
79
 
63
- export type Legend = {
80
+ export type Legend = CoreLegend & {
64
81
  seriesHighlight: string[]
65
- additionalCategories: string[]
66
- // general legend onClick behavior
67
- behavior: 'highlight' | 'isolate' | string
68
- axisAlign: boolean
69
- colorCode: string
70
- description: string
71
- // show or hide the legend
72
- hide: boolean
73
- highlightOnHover: boolean
74
- label: string
75
- position: 'left' | 'bottom' | 'top' | 'right'
76
- reverseLabelOrder: boolean
77
- singleRow: boolean
78
- type: string
79
- verticalSorted: boolean
80
- hideSuppressionLink:boolean
81
- style:'circles'|'boxes'|'gradient'|'lines'
82
- subStyle:'linear blocks'|'smooth'
83
- hideSuppressedLabels:boolean
84
- tickRotation:string
85
- hideBorder:{
86
- side:boolean
87
- topBottom:boolean
82
+ hideSuppressionLink: boolean
83
+ style: 'circles' | 'boxes' | 'gradient' | 'lines'
84
+ subStyle: 'linear blocks' | 'smooth'
85
+
86
+ tickRotation: string
87
+ hideBorder: {
88
+ side: boolean
89
+ topBottom: boolean
88
90
  }
89
91
  }
90
92
 
@@ -105,7 +107,7 @@ export type AllChartsConfig = {
105
107
  barHasBorder: 'true' | 'false'
106
108
  barHeight: number
107
109
  barSpace: number
108
- barStyle: 'lollipop'|'rounded'|'flat'
110
+ barStyle: 'lollipop' | 'rounded' | 'flat'
109
111
  barThickness: number
110
112
  boxplot: BoxPlot
111
113
  brush: {
@@ -121,7 +123,7 @@ export type AllChartsConfig = {
121
123
  data: Object[]
122
124
  dataUrl: string
123
125
  dataCutoff: number
124
- dataDescription: string
126
+ dataDescription: Partial<DataDescription>
125
127
  dataFormat: DataFormat
126
128
  dataKey: string
127
129
  description: string
@@ -135,6 +137,7 @@ export type AllChartsConfig = {
135
137
  formattedData: Object[] & { urlFiltered: boolean }
136
138
  heights: {
137
139
  vertical: number
140
+ horizontal: number
138
141
  mobileVertical: number
139
142
  }
140
143
  highlightedBarValues: { value: any; color: string; borderWidth: number; legendLabel: string }[]
@@ -150,12 +153,13 @@ export type AllChartsConfig = {
150
153
  lollipopColorStyle: 'regular' | 'two-tone'
151
154
  lollipopShape: string
152
155
  lollipopSize: 'small' | 'medium' | 'large'
153
- newViz: Object
154
- orientation: 'vertical' | 'horizontal'
156
+ newViz: boolean
157
+ orientation: ChartOrientation
155
158
  palette: string
156
159
  pieType?: string
157
160
  preliminaryData: PreliminaryDataItem[]
158
161
  primary?: DataFormat
162
+ rankByValue: 'asc' | 'desc'
159
163
  roundingStyle: string
160
164
  runtime: Runtime
161
165
  runtimeDataUrl: string
@@ -180,8 +184,9 @@ export type AllChartsConfig = {
180
184
  twoColor: { palette: string }
181
185
  type: 'chart' | 'dashboard'
182
186
  uid: string | number
187
+ version: string
183
188
  visual: Visual
184
- visualizationType: 'Area Chart' | 'Bar' | 'Box Plot' | 'Deviation Bar' | 'Forest Plot' | 'Line' | 'Paired Bar' | 'Pie' | 'Scatter Plot' | 'Spark Line' | 'Combo' | 'Forecasting' | 'Sankey' | 'Bump Chart'
189
+ visualizationType: VisualizationType
185
190
  visualizationSubType: string
186
191
  xAxis: Axis
187
192
  yAxis: Axis
@@ -197,7 +202,12 @@ export type AllChartsConfig = {
197
202
  }
198
203
  margin: { margin_x: number; margin_y: number }
199
204
  nodeColor: { default: boolean; inactive: boolean }
200
- opacity: { LinkOpacityInactive: string; LinkOpacityDefault: string; nodeOpacityInactive: boolean; nodeOpacityDefault: boolean }
205
+ opacity: {
206
+ LinkOpacityInactive: string
207
+ LinkOpacityDefault: string
208
+ nodeOpacityInactive: boolean
209
+ nodeOpacityDefault: boolean
210
+ }
201
211
  rxValue: number
202
212
  nodeFontColor: string
203
213
  nodeValueStyle: {
@@ -257,9 +267,8 @@ export type SankeyChartConfig = {
257
267
  source: SankeyLink
258
268
  target: SankeyLink
259
269
  value: number
260
- }[],
270
+ }[]
261
271
  storyNodeText: StoryNode[]
262
- :
263
272
  }
264
273
  ]
265
274
  visualizationType: 'Sankey'
@@ -1,9 +1,8 @@
1
1
  import { type ChartConfig } from './ChartConfig'
2
2
  import { PickD3Scale } from '@visx/scale'
3
- import { type SharedFilter } from '@cdc/dashboard/src/types/SharedFilter'
4
3
  import { type Annotation } from '@cdc/core/types/Annotation'
5
4
  import { DimensionsType } from '@cdc/core/types/Dimensions'
6
-
5
+ import { type DashboardConfig } from '@cdc/dashboard/src/types/DashboardConfig'
7
6
  export type ColorScale = PickD3Scale<'ordinal', any, any>
8
7
 
9
8
  export type TransformedData = {
@@ -13,26 +12,30 @@ export type TransformedData = {
13
12
 
14
13
  type SharedChartContext = {
15
14
  animatedChart?: boolean
16
- // process top level chart aria label for each chart type
17
- handleChartAriaLabels: (config: any) => string
15
+ brushConfig: { data: []; isBrushing: boolean; isActive: boolean }
16
+ capitalize: (value: string) => string
17
+ clean: Function
18
18
  colorScale?: ColorScale
19
19
  config: ChartConfig
20
20
  currentViewport?: 'lg' | 'md' | 'sm' | 'xs' | 'xxs'
21
+ dashboardConfig?: DashboardConfig
22
+ // process top level chart aria label for each chart type
23
+ handleChartAriaLabels: (config: any) => string
24
+ handleDragStateChange: (isDragging: any) => void
21
25
  highlight?: Function
22
26
  highlightReset?: Function
23
- legendIsolateValues?: string[]
24
- setLegendIsolateValues?: Function
25
- getTextWidth?: (a: string, b: string) => string
26
- brushConfig: { data: []; isBrushing: boolean; isActive: boolean }
27
- setBrushConfig: Function
28
- clean: Function
29
- capitalize: (value: string) => string
30
27
  // whether or not the legend is appearing below the chart
31
28
  isLegendBottom?: boolean
32
29
  // whether or not the chart is viewed within the editor screen
33
30
  isEditor?: boolean
34
31
  // whether or not the user is dragging an annotation
35
32
  isDraggingAnnotation?: boolean
33
+ legendIsolateValues?: string[]
34
+ legendRef?: React.RefObject<HTMLDivElement>
35
+ parentRef?: React.RefObject<HTMLDivElement>
36
+ setBrushConfig: Function
37
+ setLegendIsolateValues?: Function
38
+ svgRef?: React.RefObject<SVGSVGElement>
36
39
  }
37
40
 
38
41
  // Line Chart Specific Context
@@ -60,22 +63,26 @@ export type ChartContext =
60
63
  | LineChartContext
61
64
  | (SharedChartContext & {
62
65
  annotations: Annotation[]
66
+ colorPalettes: any
63
67
  dimensions: DimensionsType
64
68
  formatDate?: Function
65
69
  formatTooltipsDate: Function
66
70
  formatNumber?: Function
67
71
  handleLineType?: Function
72
+ // 508 compliance: tabbing handler for charts
73
+ handleChartTabbing?: (chartConfig: ChartConfig, legendId: string) => string
68
74
  isNumber?: boolean
75
+ // 508 compliance: tabbing id for legends
76
+ legendId: string
69
77
  // url param added to allow various console logs and chart helpers
70
78
  isDebug?: boolean
71
79
  parseDate?: Function
72
80
  rawData?: Object[]
73
81
  seriesHighlight?: string[]
74
- tableData?: Object[]
75
- transformedData?: TransformedData[]
76
82
  setSharedFilter?: Function
77
83
  sharedFilterValue?: string
78
- updateConfig?: Function
79
- colorPalettes: any
84
+ tableData?: Object[]
85
+ transformedData?: TransformedData[]
80
86
  twoColorPalette: any
87
+ updateConfig?: Function
81
88
  })
@@ -50,4 +50,12 @@ export type ForestPlotConfigSettings = {
50
50
  // labels under chart
51
51
  leftLabel: string
52
52
  rightLabel: string
53
+ /** rightWidthOffsetMobile */
54
+ rightWidthOffsetMobile: number
55
+ /** leftWidthOffsetMobile */
56
+ leftWidthOffsetMobile: number
57
+ regression: {
58
+ showDiamond: boolean
59
+ description: boolean
60
+ }
53
61
  }
@@ -1,19 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react'
2
- import chartGradientConfig from './_mock/legend.gradient_mock.json'
3
-
4
- import Chart from '../CdcChart'
5
-
6
- const meta: Meta<typeof Chart> = {
7
- title: 'Components/Templates/Chart/Legend',
8
- component: Chart
9
- }
10
-
11
- type Story = StoryObj<typeof Chart>
12
-
13
- export const Legend_gradient: Story = {
14
- args: {
15
- config: chartGradientConfig
16
- }
17
- }
18
-
19
- export default meta
@@ -1,19 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react'
2
- import chartBrushConfig from './_mock/brush_mock.json'
3
-
4
- import Chart from '../CdcChart'
5
-
6
- const meta: Meta<typeof Chart> = {
7
- title: 'Components/Templates/Chart/Brush',
8
- component: Chart
9
- }
10
-
11
- type Story = StoryObj<typeof Chart>
12
-
13
- export const Area_Brush: Story = {
14
- args: {
15
- config: chartBrushConfig
16
- }
17
- }
18
-
19
- export default meta
@@ -1,111 +0,0 @@
1
- import React, { useContext, useEffect } from 'react'
2
- import { BoxPlot } from '@visx/stats'
3
- import { Group } from '@visx/group'
4
- import ConfigContext from '../../ConfigContext'
5
- import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
6
- import { colorPalettesChart } from '@cdc/core/data/colorPalettes'
7
-
8
- const CoveBoxPlot = ({ xScale, yScale }) => {
9
- const { config, setConfig } = useContext(ConfigContext)
10
- const { boxplot } = config
11
-
12
- useEffect(() => {
13
- if (config.legend.hide === false) {
14
- setConfig({
15
- ...config,
16
- legend: {
17
- ...config.legend,
18
- hide: true
19
- }
20
- })
21
- }
22
- }, []) // eslint-disable-line
23
-
24
- // tooltips
25
- const tooltip_id = `cdc-open-viz-tooltip-${config.runtime.uniqueId}`
26
- const handleTooltip = d => {
27
- return `
28
- <strong>${d.columnCategory}</strong></br>
29
- ${boxplot.labels.q1}: ${d.columnFirstQuartile}<br/>
30
- ${boxplot.labels.q3}: ${d.columnThirdQuartile}<br/>
31
- ${boxplot.labels.iqr}: ${d.columnIqr}<br/>
32
- ${boxplot.labels.median}: ${d.columnMedian}
33
- `
34
- }
35
-
36
- // accessors & constants
37
- const max = d => Number(d.columnMax)
38
- const min = d => Number(d.columnMin)
39
- const median = d => Number(d.columnMedian)
40
- const thirdQuartile = d => Number(d.columnThirdQuartile)
41
- const firstQuartile = d => Number(d.columnFirstQuartile)
42
- const fillOpacity = 0.5
43
- const boxWidth = xScale.bandwidth()
44
- const constrainedWidth = Math.min(40, boxWidth)
45
- const color_0 = colorPalettesChart[config?.palette][0] ? colorPalettesChart[config?.palette][0] : '#000'
46
-
47
- return (
48
- <ErrorBoundary component='BoxPlot'>
49
- <Group className='boxplot' key={`boxplot-group`}>
50
- {boxplot.plots.map((d, i) => {
51
- const offset = boxWidth - constrainedWidth
52
- const radius = 4
53
- return (
54
- <Group key={`boxplotplot-${i}`}>
55
- {boxplot.plotNonOutlierValues &&
56
- d.nonOutlierValues.map((value, index) => {
57
- return <circle cx={xScale(d.columnCategory) + Number(config.yAxis.size) + boxWidth / 2} cy={yScale(value)} r={radius} fill={'#ccc'} style={{ opacity: 1, fillOpacity: 1, stroke: 'black' }} key={`boxplot-${i}--circle-${index}`} />
58
- })}
59
- <BoxPlot
60
- data-left={xScale(d.columnCategory) + config.yAxis.size + offset / 2 + 0.5}
61
- key={`box-plot-${i}`}
62
- min={min(d)}
63
- max={max(d)}
64
- left={Number(xScale(d.columnCategory)) + Number(config.yAxis.size) + offset / 2 + 0.5}
65
- firstQuartile={firstQuartile(d)}
66
- thirdQuartile={thirdQuartile(d)}
67
- median={median(d)}
68
- boxWidth={constrainedWidth}
69
- fill={color_0}
70
- fillOpacity={fillOpacity}
71
- stroke='black'
72
- valueScale={yScale}
73
- outliers={boxplot.plotOutlierValues ? d.columnOutliers : []}
74
- outlierProps={{
75
- style: {
76
- fill: `${color_0}`,
77
- opacity: 1
78
- }
79
- }}
80
- medianProps={{
81
- style: {
82
- stroke: 'black'
83
- }
84
- }}
85
- boxProps={{
86
- style: {
87
- stroke: 'black',
88
- strokeWidth: boxplot.borders === 'true' ? 1 : 0
89
- }
90
- }}
91
- maxProps={{
92
- style: {
93
- stroke: 'black'
94
- }
95
- }}
96
- container
97
- containerProps={{
98
- 'data-tooltip-html': handleTooltip(d),
99
- 'data-tooltip-id': tooltip_id,
100
- tabIndex: -1
101
- }}
102
- />
103
- </Group>
104
- )
105
- })}
106
- </Group>
107
- </ErrorBoundary>
108
- )
109
- }
110
-
111
- export default CoveBoxPlot