@cdc/chart 4.24.2 → 4.24.3

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 (57) hide show
  1. package/dist/cdcchart.js +47386 -36618
  2. package/examples/chart-regression-1.json +378 -0
  3. package/examples/chart-regression-2.json +2360 -0
  4. package/examples/feature/filters/url-filter.json +1076 -0
  5. package/examples/feature/line/line-chart.json +2 -1
  6. package/examples/feature/regions/index.json +50 -4
  7. package/examples/feature/sankey/sankey-example-data.json +1364 -0
  8. package/examples/feature/sankey/sankey_chart_data.csv +20 -0
  9. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +306 -19
  10. package/examples/sparkline.json +868 -0
  11. package/index.html +128 -123
  12. package/package.json +4 -2
  13. package/src/CdcChart.tsx +40 -22
  14. package/src/_stories/ChartEditor.stories.tsx +14 -3
  15. package/src/_stories/_mock/url_filter.json +1076 -0
  16. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +2 -1
  17. package/src/components/AreaChart/components/AreaChart.jsx +2 -1
  18. package/src/components/BarChart/components/BarChart.Horizontal.tsx +39 -49
  19. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +36 -56
  20. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +32 -39
  21. package/src/components/BarChart/components/BarChart.Vertical.tsx +40 -55
  22. package/src/components/BoxPlot/BoxPlot.jsx +2 -1
  23. package/src/components/DeviationBar.jsx +3 -3
  24. package/src/components/EditorPanel/EditorPanel.tsx +167 -15
  25. package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +1 -1
  26. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +108 -0
  27. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +48 -4
  28. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +41 -0
  29. package/src/components/EditorPanel/components/Panels/index.tsx +9 -7
  30. package/src/components/EditorPanel/components/panels.scss +11 -0
  31. package/src/components/EditorPanel/useEditorPermissions.js +40 -14
  32. package/src/components/Legend/Legend.Component.tsx +23 -15
  33. package/src/components/Legend/Legend.tsx +4 -4
  34. package/src/components/LineChart/LineChartProps.ts +1 -0
  35. package/src/components/LineChart/helpers.ts +2 -2
  36. package/src/components/LineChart/index.tsx +7 -7
  37. package/src/components/LinearChart.jsx +9 -30
  38. package/src/components/PairedBarChart.jsx +6 -10
  39. package/src/components/PieChart/PieChart.tsx +3 -3
  40. package/src/components/Regions/components/Regions.tsx +120 -78
  41. package/src/components/Sankey/index.tsx +434 -0
  42. package/src/components/Sankey/sankey.scss +153 -0
  43. package/src/components/Sankey/types/index.ts +16 -0
  44. package/src/components/ScatterPlot/ScatterPlot.jsx +1 -0
  45. package/src/components/Sparkline/{SparkLine.jsx → components/SparkLine.tsx} +14 -30
  46. package/src/components/Sparkline/index.scss +3 -0
  47. package/src/components/Sparkline/index.tsx +1 -1
  48. package/src/components/ZoomBrush.tsx +2 -1
  49. package/src/data/initial-state.js +46 -2
  50. package/src/helpers/computeMarginBottom.ts +2 -1
  51. package/src/helpers/tests/computeMarginBottom.test.ts +2 -1
  52. package/src/hooks/useBarChart.js +5 -2
  53. package/src/hooks/useScales.ts +15 -18
  54. package/src/hooks/useTooltip.tsx +9 -8
  55. package/src/scss/main.scss +8 -29
  56. package/src/types/ChartConfig.ts +32 -14
  57. package/src/types/ChartContext.ts +7 -0
package/index.html CHANGED
@@ -1,27 +1,36 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
-
4
- <head>
5
- <meta charset="utf-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
7
- <style>
8
- body {
9
- /* max-width: 1000px; */
10
- margin: 0 auto !important;
11
- display: flex;
12
- flex-direction: column;
13
- justify-content: center;
14
- }
15
-
16
- .react-container+.react-container {
17
- margin-top: 3rem;
18
- }
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">
22
- </head>
23
-
24
- <body>
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
6
+ <style>
7
+ body {
8
+ /* max-width: 1000px; */
9
+ margin: 0 auto !important;
10
+ display: flex;
11
+ flex-direction: column;
12
+ justify-content: center;
13
+ }
14
+
15
+ .react-container + .react-container {
16
+ margin-top: 3rem;
17
+ }
18
+ </style>
19
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/contrib/libs/bootstrap/latest/css/bootstrap.min.css?_=39423" />
20
+ <link rel="stylesheet prefetch" href="https://www.cdc.gov/TemplatePackage/4.0/assets/css/app.min.css?_=39423" />
21
+ </head>
22
+
23
+ <body>
24
+ <!-- SANKEY EXAMPLE -->
25
+ <!-- <div class="container d-flex flex-wrap body-wrapper bg-white">
26
+ <main class="col-lg-9 order-lg-2" role="main" aria-label="Main Content Area">
27
+ <div class="row">
28
+ <div class="col-md-12"> -->
29
+ <!-- <div class="react-container" data-config="/examples/feature/sankey/sankey-example-data.json"></div> -->
30
+ <!-- </div>
31
+ </div>
32
+ </main>
33
+ </div> -->
25
34
 
26
35
  <!--
27
36
  EXAMPLES:
@@ -35,87 +44,86 @@
35
44
 
36
45
  -->
37
46
 
38
- <!-- GENERIC CHART TYPES -->
39
- <div class="react-container" data-config="/examples/private/rvr.json"></div>
40
- <!-- <div class="react-container" data-config="/examples/private/chart-t.json"></div> -->
41
- <!-- <div class="react-container" data-config="/examples/feature/bar/additional-column-tooltip.json"></div> -->
42
- <!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
43
- <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-city-temperature.json"></div> -->
44
- <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-apple.json"></div> -->
45
- <!-- <div class="react-container" data-config="/examples/feature/forest-plot/linear.json"></div> -->
46
- <!-- <div class="react-container" data-config="/examples/feature/forest-plot/logarithmic.json"></div> -->
47
- <!-- <div class="react-container" data-config="/examples/feature/forest-plot/forest-plot.json"></div> -->
48
- <!-- <div class="react-container" data-config="/examples/feature/pie/planet-pie-example-config.json"></div> -->
49
- <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Viz.json></div> -->
50
- <div class="react-container" data-config=/examples/feature/regions/index.json></div>
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> -->
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> -->
53
- <!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
54
- <!-- <div class="react-container" data-config="/examples/feature/forecasting/combo-forecasting.json"></div> -->
55
- <!-- <div class="react-container" data-config="/examples/feature/forecasting/effective_reproduction.json"></div> -->
56
- <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date.json"></div> -->
57
- <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-category.json"></div> -->
58
- <!-- <div class="react-container" data-config="/examples/feature/scatterplot/scatterplot.json"></div> -->
59
- <!-- <div class="react-container" data-config="/examples/feature/deviation/planet-deviation-config.json"></div> -->
60
- <!-- <div class="react-container" data-config="/examples/feature/boxplot/boxplot.json"></div> -->
61
- <!-- <div class="react-container" data-config="/examples/feature/combo/planet-combo-example-config.json"></div> -->
62
- <!-- <div class="react-container" data-config="/examples/feature/combo/right-issues.json"></div> -->
63
- <!-- <div class="react-container" data-config="/examples/feature/paired-bar/paired-bar-example.json"></div> -->
64
-
65
- <!-- BAR -->
66
- <!-- <div class="react-container" data-config="/examples/feature/bar/planet-example-config.json"></div> -->
67
- <!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
68
- <!-- <div class="react-container" data-config="/examples/feature/bar/example-bar-chart.json"></div> -->
69
- <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-chart-max-increase.json"></div> -->
70
- <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-chart.json"></div> -->
71
- <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-stacked-bar-chart.json"></div> -->
72
- <!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
73
-
74
- <!-- SPARKLINE -->
75
- <!-- <div class="react-container" data-config="/examples/feature/dev-4261.json"></div> -->
76
-
77
- <!-- TESTS DATA TABLE SORTING -->
78
- <!-- Bar Chart with Confidence Intervals (bottom of page) -->
79
- <!-- <div class="react-container" data-config="https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Example_Bar_CI.json"></div> -->
80
- <!-- TPOXX Patient Data -->
81
- <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/tpoxx_weekly_race_eth.json"></div> -->
82
- <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpx-tpoxx-age-gender.json"></div> -->
83
- <!-- Non-Variola Orthopoxvirus (NVO) Laboratory Testing by Demographics -->
84
- <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/poxvirus/mpox/modules/data-viz/lab-data.json"></div> -->
85
- <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/poxvirus/mpox/modules/data-viz/lab-data-age.json"></div> -->
86
- <!-- PROBLEM WITH THEIR PAGE CONFIG or CONFLICT with -->
87
- <!-- CORS ERROR pulling data on Covid Flu RSV page at https://wwwdev-cdc.msappproxy.net/respiratory-viruses/index.html-->
88
- <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/respiratory-viruses/modules/emergency-dept-visits_live.json"></div> -->
89
- <!-- MPOX -->
90
- <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpox-demographics-monthly.json"></div> -->
91
- <!-- <div class="react-container" data-config="/https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpx-age-sex1.json"></div> -->
92
-
93
-
94
- <!-- TESTS DATE EXCLUSIONS -->
95
- <!-- <div class="react-container" data-config="/examples/feature/tests-date-exclusions/date-exclusions-config.json"></div> -->
96
- <!-- <div class="react-container" data-config="/examples/feature/tests-case-rate/case-rate-example-config.json"></div> -->
97
-
98
- <!-- TESTS BIG SMALL-->
99
- <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-line.json"></div> -->
100
- <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-bar.json"></div> -->
101
- <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-negative.json"></div> -->
102
- <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/line-chart-max-increase.json"></div> -->
103
-
104
- <!-- TESTS NONNUMERICS -->
105
- <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json"></div> -->
106
- <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-combo-bar-nonnumeric.json"></div> -->
107
- <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-bar-chart-nonnumeric.json"></div> -->
108
- <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/sparkline-chart-nonnumeric.json"></div> -->
109
- <!-- <div class="react-container" data-config="/examples/feature/bar/lollipop.json"></div> -->
110
- <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json"></div> -->
111
-
112
- <!-- TESTS CUTOFF -->
113
- <!-- <div class="react-container" data-config="/examples/feature/tests-cutoff/cutoff-example-config.json"></div> -->
114
-
115
- <!-- TESTS COVID -->
116
- <!-- <div class="react-container" data-config="/examples/feature/tests-covid/covid-confidence-example-config.json"></div> -->
117
- <!-- <div class="react-container" data-config="/examples/feature/tests-covid/covid-example-config.json"></div> -->
118
-
47
+ <!-- GENERIC CHART TYPES -->
48
+ <!-- <div class="react-container" data-config="/examples/private/rvr.json"></div> -->
49
+ <!-- <div class="react-container" data-config="/examples/feature/filters/url-filter.json"></div> -->
50
+ <!-- <div class="react-container" data-config="/examples/feature/bar/additional-column-tooltip.json"></div> -->
51
+ <!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
52
+ <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-city-temperature.json"></div> -->
53
+ <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-apple.json"></div> -->
54
+ <!-- <div class="react-container" data-config="/examples/feature/forest-plot/linear.json"></div> -->
55
+ <!-- <div class="react-container" data-config="/examples/feature/forest-plot/logarithmic.json"></div> -->
56
+ <!-- <div class="react-container" data-config="/examples/feature/forest-plot/forest-plot.json"></div> -->
57
+ <!-- <div class="react-container" data-config="/examples/feature/pie/planet-pie-example-config.json"></div> -->
58
+ <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Viz.json></div> -->
59
+ <!-- <div class="react-container" data-config=/examples/feature/regions/index.json></div> -->
60
+ <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
61
+ <!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
62
+ <!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
63
+ <!-- <div class="react-container" data-config="/examples/feature/forecasting/combo-forecasting.json"></div> -->
64
+ <!-- <div class="react-container" data-config="/examples/feature/forecasting/effective_reproduction.json"></div> -->
65
+ <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date.json"></div> -->
66
+ <!-- <div class="react-container" data-config="/examples/feature/area/area-chart-category.json"></div> -->
67
+ <!-- <div class="react-container" data-config="/examples/feature/scatterplot/scatterplot.json"></div> -->
68
+ <!-- <div class="react-container" data-config="/examples/feature/deviation/planet-deviation-config.json"></div> -->
69
+ <!-- <div class="react-container" data-config="/examples/feature/boxplot/boxplot.json"></div> -->
70
+ <!-- <div class="react-container" data-config="/examples/feature/combo/planet-combo-example-config.json"></div> -->
71
+ <!-- <div class="react-container" data-config="/examples/feature/combo/right-issues.json"></div> -->
72
+ <div class="react-container" data-config="/examples/region-issue.json"></div>
73
+
74
+ <!-- BAR -->
75
+ <!-- <div class="react-container" data-config="/examples/feature/bar/planet-example-config.json"></div> -->
76
+ <!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
77
+ <!-- <div class="react-container" data-config="/examples/feature/bar/example-bar-chart.json"></div> -->
78
+ <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-chart-max-increase.json"></div> -->
79
+ <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-chart.json"></div> -->
80
+ <!-- <div class="react-container" data-config="/examples/feature/bar/horizontal-stacked-bar-chart.json"></div> -->
81
+ <!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
82
+
83
+ <!-- SPARKLINE -->
84
+ <!-- <div class="react-container" data-config="/examples/feature/dev-4261.json"></div> -->
85
+
86
+ <!-- TESTS DATA TABLE SORTING -->
87
+ <!-- Bar Chart with Confidence Intervals (bottom of page) -->
88
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Example_Bar_CI.json"></div> -->
89
+ <!-- TPOXX Patient Data -->
90
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/tpoxx_weekly_race_eth.json"></div> -->
91
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpx-tpoxx-age-gender.json"></div> -->
92
+ <!-- Non-Variola Orthopoxvirus (NVO) Laboratory Testing by Demographics -->
93
+ <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/poxvirus/mpox/modules/data-viz/lab-data.json"></div> -->
94
+ <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/poxvirus/mpox/modules/data-viz/lab-data-age.json"></div> -->
95
+ <!-- PROBLEM WITH THEIR PAGE CONFIG or CONFLICT with -->
96
+ <!-- CORS ERROR pulling data on Covid Flu RSV page at https://wwwdev-cdc.msappproxy.net/respiratory-viruses/index.html-->
97
+ <!-- <div class="react-container" data-config="https://wwwdev-cdc.msappproxy.net/respiratory-viruses/modules/emergency-dept-visits_live.json"></div> -->
98
+ <!-- MPOX -->
99
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpox-demographics-monthly.json"></div> -->
100
+ <!-- <div class="react-container" data-config="/https://www.cdc.gov/poxvirus/mpox/modules/data-viz/mpx-age-sex1.json"></div> -->
101
+
102
+ <!-- TESTS DATE EXCLUSIONS -->
103
+ <!-- <div class="react-container" data-config="/examples/feature/tests-date-exclusions/date-exclusions-config.json"></div> -->
104
+ <!-- <div class="react-container" data-config="/examples/feature/tests-case-rate/case-rate-example-config.json"></div> -->
105
+
106
+ <!-- TESTS BIG SMALL-->
107
+ <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-line.json"></div> -->
108
+ <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-bar.json"></div> -->
109
+ <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/big-small-test-negative.json"></div> -->
110
+ <!-- <div class="react-container" data-config="/examples/feature/tests-big-small/line-chart-max-increase.json"></div> -->
111
+
112
+ <!-- TESTS NONNUMERICS -->
113
+ <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json"></div> -->
114
+ <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-combo-bar-nonnumeric.json"></div> -->
115
+ <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-bar-chart-nonnumeric.json"></div> -->
116
+ <!-- <div class="react-container" data-config="/examples/sparkline.json"></div> -->
117
+ <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/sparkline-chart-nonnumeric.json"></div> -->
118
+ <!-- <div class="react-container" data-config="/examples/feature/bar/lollipop.json"></div> -->
119
+ <!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json"></div> -->
120
+
121
+ <!-- TESTS CUTOFF -->
122
+ <!-- <div class="react-container" data-config="/examples/feature/tests-cutoff/cutoff-example-config.json"></div> -->
123
+
124
+ <!-- TESTS COVID -->
125
+ <!-- <div class="react-container" data-config="/examples/feature/tests-covid/covid-confidence-example-config.json"></div> -->
126
+ <!-- <div class="react-container" data-config="/examples/feature/tests-covid/covid-example-config.json"></div> -->
119
127
 
120
128
  <!--
121
129
  GALLERY EXAMPLES BELOW THIS LINE...
@@ -123,28 +131,25 @@
123
131
 
124
132
  -->
125
133
 
126
- <!-- GENERIC CHART TYPES -->
127
- <!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
128
- <div class="react-container" data-config="/examples/feature/line/line-chart-preliminary.json"></div>
129
-
130
-
131
- <!-- HORIZONTAL BAR CHARTS -->
132
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
133
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
134
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-stacked.json"></div> -->
134
+ <!-- GENERIC CHART TYPES -->
135
+ <!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
136
+ <!-- <div class="react-container" data-config="/examples/feature/line/line-chart.json"></div> -->
135
137
 
136
- <!-- VERTICAL BAR CHARTS -->
137
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
138
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
139
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
140
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json"></div> -->
141
- <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
142
- <!-- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div> -->
138
+ <!-- HORIZONTAL BAR CHARTS -->
139
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
140
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
141
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-stacked.json"></div> -->
143
142
 
144
- <noscript>You need to enable JavaScript to run this app.</noscript>
145
- </body>
143
+ <!-- VERTICAL BAR CHARTS -->
144
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
145
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
146
+ <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div>
147
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json"></div> -->
148
+ <!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
149
+ <!-- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div> -->
146
150
 
147
- <script type="module" src="./src/index.jsx"></script>
148
- </body>
151
+ <noscript>You need to enable JavaScript to run this app.</noscript>
149
152
 
153
+ <script type="module" src="./src/index.jsx"></script>
154
+ </body>
150
155
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cdc/chart",
3
- "version": "4.24.2",
3
+ "version": "4.24.3",
4
4
  "description": "React component for visualizing tabular data in various types of charts",
5
5
  "moduleName": "CdcChart",
6
6
  "main": "dist/cdcchart",
@@ -43,6 +43,7 @@
43
43
  "chroma-js": "^2.1.2",
44
44
  "d3-array": "^2.8.0",
45
45
  "d3-format": "^3.1.0",
46
+ "d3-sankey": "^0.12.3",
46
47
  "d3-time-format": "^3.0.0",
47
48
  "html-react-parser": "^3.0.8",
48
49
  "js-base64": "^2.5.2",
@@ -59,8 +60,9 @@
59
60
  "react": "^18.2.0",
60
61
  "react-dom": "^18.2.0"
61
62
  },
62
- "gitHead": "edde49c96dee146de5e3a4537880b1bcf4dbee08",
63
+ "gitHead": "9c7ef7ca74f2d2a1e04d923b133fe0fc557a62bf",
63
64
  "devDependencies": {
65
+ "@types/d3-sankey": "^0.12.4",
64
66
  "resize-observer-polyfill": "^1.5.1"
65
67
  }
66
68
  }
package/src/CdcChart.tsx CHANGED
@@ -15,8 +15,10 @@ import 'react-tooltip/dist/react-tooltip.css'
15
15
 
16
16
  // Primary Components
17
17
  import ConfigContext from './ConfigContext'
18
- import PieChart from './components/PieChart/PieChart'
18
+ import PieChart from './components/PieChart'
19
+ import SankeyChart from './components/Sankey'
19
20
  import LinearChart from './components/LinearChart'
21
+ import { isDateScale } from '@cdc/core/helpers/cove/date'
20
22
 
21
23
  import { colorPalettesChart as colorPalettes, twoColorPalette } from '@cdc/core/data/colorPalettes'
22
24
 
@@ -46,6 +48,7 @@ import { DataTransform } from '@cdc/core/helpers/DataTransform'
46
48
  import cacheBustingString from '@cdc/core/helpers/cacheBustingString'
47
49
  import isNumber from '@cdc/core/helpers/isNumber'
48
50
  import coveUpdateWorker from '@cdc/core/helpers/coveUpdateWorker'
51
+ import { getQueryStringFilterValue } from '@cdc/core/helpers/queryStringUtils'
49
52
 
50
53
  import './scss/main.scss'
51
54
  // load both then config below determines which to use
@@ -55,6 +58,7 @@ import Title from '@cdc/core/components/ui/Title'
55
58
  import { ChartConfig } from './types/ChartConfig'
56
59
  import { Label } from './types/Label'
57
60
  import { isSolrCsv, isSolrJson } from '@cdc/core/helpers/isSolr'
61
+ import SkipTo from '@cdc/core/components/elements/SkipTo'
58
62
 
59
63
  export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
60
64
  const transform = new DataTransform()
@@ -64,7 +68,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
64
68
  const [stateData, setStateData] = useState(config.data || [])
65
69
  const [excludedData, setExcludedData] = useState<Record<string, number>[] | undefined>(undefined)
66
70
  const [filteredData, setFilteredData] = useState<Record<string, any>[] | undefined>(undefined)
67
- const [seriesHighlight, setSeriesHighlight] = useState<string[]>([])
71
+ const [seriesHighlight, setSeriesHighlight] = useState<string[]>(configObj && configObj?.legend?.seriesHighlight?.length ? [...configObj?.legend?.seriesHighlight] : [])
68
72
  const [currentViewport, setCurrentViewport] = useState('lg')
69
73
  const [dimensions, setDimensions] = useState<[number?, number?]>([])
70
74
  const [externalFilters, setExternalFilters] = useState<any[]>()
@@ -75,6 +79,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
75
79
  type Config = typeof config
76
80
  let legendMemo = useRef(new Map()) // map collection
77
81
  let innerContainerRef = useRef()
82
+ const legendRef = useRef(null)
78
83
 
79
84
  if (isDebug) console.log('Chart config, isEditor', config, isEditor)
80
85
 
@@ -90,7 +95,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
90
95
 
91
96
  const { barBorderClass, lineDatapointClass, contentClasses, sparkLineStyles } = useDataVizClasses(config)
92
97
 
93
- const handleChartTabbing = config.showSidebar ? `#legend` : config?.title ? `#dataTableSection__${config.title.replace(/\s/g, '')}` : `#dataTableSection`
98
+ const handleChartTabbing = !config.legend?.hide ? `legend` : config?.title ? `dataTableSection__${config.title.replace(/\s/g, '')}` : `dataTableSection`
94
99
 
95
100
  const reloadURLData = async () => {
96
101
  if (config.dataUrl) {
@@ -219,6 +224,15 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
219
224
  }
220
225
  }
221
226
  let newConfig = { ...defaults, ...response }
227
+ if (newConfig.filters) {
228
+ newConfig.filters.forEach((filter, index) => {
229
+ const queryStringFilterValue = getQueryStringFilterValue(filter)
230
+ if (queryStringFilterValue) {
231
+ newConfig.filters[index].active = queryStringFilterValue
232
+ }
233
+ })
234
+ }
235
+
222
236
  if (newConfig.visualizationType === 'Box Plot') {
223
237
  newConfig.legend.hide = true
224
238
  }
@@ -253,7 +267,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
253
267
  if (newConfig.exclusions && newConfig.exclusions.active) {
254
268
  if (newConfig.xAxis.type === 'categorical' && newConfig.exclusions.keys?.length > 0) {
255
269
  newExcludedData = data.filter(e => !newConfig.exclusions.keys.includes(e[newConfig.xAxis.dataKey]))
256
- } else if (newConfig.xAxis.type === 'date' && (newConfig.exclusions.dateStart || newConfig.exclusions.dateEnd) && newConfig.xAxis.dateParseFormat) {
270
+ } else if (isDateScale(newConfig.xAxis) && (newConfig.exclusions.dateStart || newConfig.exclusions.dateEnd) && newConfig.xAxis.dateParseFormat) {
257
271
  // Filter dates
258
272
  const timestamp = e => new Date(e).getTime()
259
273
 
@@ -297,13 +311,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
297
311
  setFilteredData(currentData)
298
312
  }
299
313
 
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) {
314
+ if (newConfig.xAxis.type === 'date-time' && newConfig.barThickness > 0.1) {
305
315
  newConfig.barThickness = 0.035
306
- } else if (!newConfig.xAxis.sortDates && newConfig.barThickness < 0.1) {
316
+ } else if (newConfig.xAxis.type !== 'date-time' && newConfig.barThickness < 0.1) {
307
317
  newConfig.barThickness = 0.35
308
318
  }
309
319
 
@@ -483,6 +493,13 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
483
493
  newConfig.runtime.uniqueId = Date.now()
484
494
  newConfig.runtime.editorErrorMessage = newConfig.visualizationType === 'Pie' && !newConfig.yAxis.dataKey ? 'Data Key property in Y Axis section must be set for pie charts.' : ''
485
495
 
496
+ // Sankey Description box error message
497
+ newConfig.runtime.editorErrorMessage = newConfig.visualizationType === 'Sankey' && !newConfig.description ? 'SUBTEXT/CITATION field is empty: A description of the Sankey Diagram data must be inputted.' : ''
498
+
499
+ if (newConfig.legend.seriesHighlight?.length) {
500
+ setSeriesHighlight(newConfig.legend?.seriesHighlight)
501
+ }
502
+
486
503
  setConfig(newConfig)
487
504
  }
488
505
 
@@ -698,7 +715,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
698
715
  // Called on reset button click, unhighlights all data series
699
716
  const highlightReset = () => {
700
717
  try {
701
- const legend = document.getElementById('legend')
718
+ const legend = legendRef.current
702
719
  if (!legend) throw new Error('No legend available to set previous focus on.')
703
720
  legend.focus()
704
721
  } catch (e) {
@@ -903,6 +920,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
903
920
  }
904
921
 
905
922
  const missingRequiredSections = () => {
923
+ if (config.visualizationType === 'Sankey') return false // skip checks for now
906
924
  if (config.visualizationType === 'Forecasting') return false // skip required checks for now.
907
925
  if (config.visualizationType === 'Forest Plot') return false // skip required checks for now.
908
926
  if (config.visualizationType === 'Pie') {
@@ -1034,14 +1052,12 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1034
1052
  <>
1035
1053
  {isEditor && <EditorPanel />}
1036
1054
  {!missingRequiredSections() && !config.newViz && (
1037
- <div className='cdc-chart-inner-container'>
1055
+ <div className='cdc-chart-inner-container' aria-label={handleChartAriaLabels(config)} tabIndex={0}>
1038
1056
  <Title showTitle={config.showTitle} isDashboard={isDashboard} title={title} superTitle={config.superTitle} classes={['chart-title', `${config.theme}`, 'cove-component__header']} style={undefined} />
1057
+ <SkipTo skipId={handleChartTabbing} skipMessage='Skip Over Chart Container' />
1039
1058
 
1040
- <a id='skip-chart-container' className='cdcdataviz-sr-only-focusable' href={handleChartTabbing}>
1041
- Skip Over Chart Container
1042
- </a>
1043
1059
  {/* Filters */}
1044
- {config.filters && !externalFilters && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
1060
+ {config.filters && !externalFilters && config.visualizationType !== 'Spark Line' && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
1045
1061
  {/* Visualization */}
1046
1062
  {config?.introText && config.visualizationType !== 'Spark Line' && <section className='introText'>{parse(config.introText)}</section>}
1047
1063
  <div
@@ -1054,6 +1070,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1054
1070
  {/* Sparkline */}
1055
1071
  {config.visualizationType === 'Spark Line' && (
1056
1072
  <>
1073
+ <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />
1057
1074
  {config?.introText && (
1058
1075
  <section className='introText' style={{ padding: '0px 0 35px' }}>
1059
1076
  {parse(config.introText)}
@@ -1069,7 +1086,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1069
1086
  )}
1070
1087
  </>
1071
1088
  )}
1072
- {!config.legend.hide && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Forest Plot' && <Legend />}
1089
+ {/* Sankey */}
1090
+ {config.visualizationType === 'Sankey' && <ParentSize aria-hidden='true'>{parent => <SankeyChart runtime={config.runtime} width={parent.width} height={parent.height} />}</ParentSize>}
1091
+ {!config.legend.hide && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Sankey' && <Legend ref={legendRef} />}
1073
1092
  </div>
1074
1093
  {/* Link */}
1075
1094
  {isDashboard && config.table && config.table.show && config.table.showDataTableLink ? tableLink : link && link}
@@ -1084,11 +1103,11 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1084
1103
  </MediaControls.Section>
1085
1104
 
1086
1105
  {/* Data Table */}
1087
- {config.xAxis.dataKey && config.table.show && config.visualizationType !== 'Spark Line' && (
1106
+ {((config.xAxis.dataKey && config.table.show && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Sankey') || (config.visualizationType === 'Sankey' && config.table.show)) && (
1088
1107
  <DataTable
1089
1108
  config={config}
1090
- rawData={config.table.customTableConfig ? filterData(config.filters, config.data) : config.data}
1091
- runtimeData={transform.applySuppression(filteredData || excludedData, config.suppressedData)}
1109
+ rawData={config.visualizationType === 'Sankey' ? config?.data?.[0]?.tableData : config.table.customTableConfig ? filterData(config.filters, config.data) : config.data}
1110
+ runtimeData={config.visualizationType === 'Sankey' ? config?.data?.[0]?.tableData : transform.applySuppression(filteredData || excludedData, config.suppressedData)}
1092
1111
  expandDataTable={config.table.expanded}
1093
1112
  columns={config.columns}
1094
1113
  displayDataAsText={displayDataAsText}
@@ -1110,13 +1129,12 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
1110
1129
  )
1111
1130
  }
1112
1131
 
1113
- const getXAxisData = d => (config.runtime.xAxis.type === 'date' ? parseDate(d[config.runtime.originalXAxis.dataKey]).getTime() : d[config.runtime.originalXAxis.dataKey])
1132
+ const getXAxisData = d => (isDateScale(config.runtime.xAxis) ? parseDate(d[config.runtime.originalXAxis.dataKey]).getTime() : d[config.runtime.originalXAxis.dataKey])
1114
1133
  const getYAxisData = (d, seriesKey) => d[seriesKey]
1115
1134
 
1116
1135
  const capitalize = str => {
1117
1136
  return str.charAt(0).toUpperCase() + str.slice(1)
1118
1137
  }
1119
-
1120
1138
  const contextValues = {
1121
1139
  capitalize,
1122
1140
  computeMarginBottom,
@@ -1,12 +1,12 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react'
2
-
2
+ import { userEvent, within } from '@storybook/testing-library'
3
3
  import Chart from '../CdcChart'
4
-
5
4
  import pieChartExample from './_mock/pie_config.json'
6
5
  import pieData from './_mock/pie_data.json'
6
+ import urlFilterExample from './_mock/url_filter.json'
7
7
 
8
8
  const meta: Meta<typeof Chart> = {
9
- title: 'Components/Templates/Editor/Chart',
9
+ title: 'Components/Templates/Chart/Editor',
10
10
  component: Chart
11
11
  }
12
12
 
@@ -19,4 +19,15 @@ export const Primary: Story = {
19
19
  }
20
20
  }
21
21
 
22
+ const sleep = ms => {
23
+ return new Promise(r => setTimeout(r, ms))
24
+ }
25
+
26
+ export const Url_Filter: Story = {
27
+ args: {
28
+ config: urlFilterExample,
29
+ isEditor: true
30
+ }
31
+ }
32
+
22
33
  export default meta