@cdc/chart 4.24.11 → 4.24.12-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.
- package/dist/cdcchart.js +32134 -32039
- package/examples/feature/sankey/sankey-example-data.json +126 -13
- package/examples/feature/tests-date-exclusions/date-exclusions-config.json +372 -12
- package/examples/private/DEV-8850-2.json +493 -0
- package/examples/private/DEV-9822.json +574 -0
- package/examples/private/DEV-9840.json +553 -0
- package/examples/private/DEV-9850-3.json +461 -0
- package/examples/private/chart.json +1084 -0
- package/examples/private/ci_formatted.json +202 -0
- package/examples/private/ci_issue.json +3016 -0
- package/examples/private/completed.json +634 -0
- package/examples/private/dem-data-long.csv +20 -0
- package/examples/private/dem-data-long.json +36 -0
- package/examples/private/demographic_data.csv +157 -0
- package/examples/private/demographic_data.json +2654 -0
- package/examples/private/demographic_dynamic.json +443 -0
- package/examples/private/demographic_standard.json +560 -0
- package/examples/private/ehdi.json +29939 -0
- package/examples/private/test.json +448 -20047
- package/index.html +9 -6
- package/package.json +2 -2
- package/src/CdcChart.tsx +62 -82
- package/src/_stories/Chart.Anchors.stories.tsx +31 -0
- package/src/_stories/Chart.DynamicSeries.stories.tsx +8 -1
- package/src/_stories/Chart.stories.tsx +32 -0
- package/src/_stories/ChartAxisLabels.stories.tsx +4 -1
- package/{examples/feature/area/area-chart-date-city-temperature.json → src/_stories/_mock/area_chart_stacked.json} +125 -27
- package/src/_stories/_mock/line_chart_dynamic_ci.json +493 -0
- package/src/_stories/_mock/line_chart_non_dynamic_ci.json +522 -0
- package/src/_stories/_mock/short_dates.json +288 -0
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +15 -3
- package/src/components/Axis/Categorical.Axis.tsx +2 -2
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +46 -37
- package/src/components/BarChart/components/BarChart.Vertical.tsx +28 -40
- package/src/components/BarChart/helpers/getBarData.ts +28 -0
- package/src/components/BarChart/helpers/tests/getBarData.test.ts +74 -0
- package/src/components/BoxPlot/BoxPlot.tsx +12 -70
- package/src/components/BoxPlot/helpers/index.ts +54 -0
- package/src/components/BrushChart.tsx +23 -26
- package/src/components/EditorPanel/EditorPanel.tsx +55 -79
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +1 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +5 -1
- package/src/components/Legend/Legend.Component.tsx +2 -2
- package/src/{hooks/useLegendClasses.ts → components/Legend/helpers/getLegendClasses.ts} +5 -5
- package/src/components/Legend/helpers/index.ts +2 -1
- package/src/components/Legend/tests/getLegendClasses.test.ts +115 -0
- package/src/components/LineChart/components/LineChart.Circle.tsx +1 -1
- package/src/components/LineChart/helpers.ts +1 -0
- package/src/components/LineChart/index.tsx +47 -1
- package/src/components/LinearChart.tsx +180 -172
- package/src/components/PieChart/PieChart.tsx +7 -1
- package/src/components/Sankey/components/ColumnList.tsx +19 -0
- package/src/components/Sankey/components/Sankey.tsx +479 -0
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +33 -0
- package/src/components/Sankey/index.tsx +1 -510
- package/src/components/Sankey/sankey.scss +16 -16
- package/src/components/Sankey/types/index.ts +1 -1
- package/src/data/initial-state.js +4 -3
- package/src/helpers/countNumOfTicks.ts +57 -0
- package/src/helpers/getQuartiles.ts +15 -18
- package/src/hooks/useMinMax.ts +18 -4
- package/src/hooks/useScales.ts +38 -4
- package/src/hooks/useTooltip.tsx +5 -1
- package/src/scss/DataTable.scss +5 -0
- package/src/scss/main.scss +6 -2
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
{
|
|
2
|
+
"annotations": [],
|
|
3
|
+
"type": "chart",
|
|
4
|
+
"debugSvg": false,
|
|
5
|
+
"chartMessage": { "noData": "No Data Available" },
|
|
6
|
+
"title": "",
|
|
7
|
+
"showTitle": true,
|
|
8
|
+
"showDownloadMediaButton": false,
|
|
9
|
+
"theme": "theme-blue",
|
|
10
|
+
"animate": false,
|
|
11
|
+
"fontSize": "medium",
|
|
12
|
+
"lineDatapointStyle": "hover",
|
|
13
|
+
"lineDatapointColor": "Same as Line",
|
|
14
|
+
"barHasBorder": "false",
|
|
15
|
+
"isLollipopChart": false,
|
|
16
|
+
"lollipopShape": "circle",
|
|
17
|
+
"lollipopColorStyle": "two-tone",
|
|
18
|
+
"visualizationSubType": "regular",
|
|
19
|
+
"barStyle": "flat",
|
|
20
|
+
"roundingStyle": "standard",
|
|
21
|
+
"tipRounding": "top",
|
|
22
|
+
"isResponsiveTicks": false,
|
|
23
|
+
"general": {
|
|
24
|
+
"annotationDropdownText": "Annotations",
|
|
25
|
+
"showDownloadButton": false,
|
|
26
|
+
"showMissingDataLabel": true,
|
|
27
|
+
"showSuppressedSymbol": true,
|
|
28
|
+
"showZeroValueData": true,
|
|
29
|
+
"hideNullValue": true,
|
|
30
|
+
"showAnnotationDropdown": false
|
|
31
|
+
},
|
|
32
|
+
"padding": { "left": 5, "right": 5 },
|
|
33
|
+
"preliminaryData": [],
|
|
34
|
+
"yAxis": {
|
|
35
|
+
"hideAxis": true,
|
|
36
|
+
"displayNumbersOnBar": false,
|
|
37
|
+
"hideLabel": false,
|
|
38
|
+
"hideTicks": true,
|
|
39
|
+
"size": "50",
|
|
40
|
+
"gridLines": true,
|
|
41
|
+
"enablePadding": true,
|
|
42
|
+
"min": "0",
|
|
43
|
+
"max": "99",
|
|
44
|
+
"labelColor": "#333",
|
|
45
|
+
"tickLabelColor": "#333",
|
|
46
|
+
"tickColor": "#333",
|
|
47
|
+
"rightHideAxis": true,
|
|
48
|
+
"rightAxisSize": 0,
|
|
49
|
+
"rightLabel": "",
|
|
50
|
+
"rightLabelOffsetSize": 0,
|
|
51
|
+
"rightAxisLabelColor": "#333",
|
|
52
|
+
"rightAxisTickLabelColor": "#333",
|
|
53
|
+
"rightAxisTickColor": "#333",
|
|
54
|
+
"numTicks": "5",
|
|
55
|
+
"axisPadding": 0,
|
|
56
|
+
"scalePadding": 10,
|
|
57
|
+
"tickRotation": 0,
|
|
58
|
+
"anchors": [],
|
|
59
|
+
"shoMissingDataLabel": true,
|
|
60
|
+
"showMissingDataLine": true,
|
|
61
|
+
"categories": [],
|
|
62
|
+
"label": "",
|
|
63
|
+
"maxValue": 108.9
|
|
64
|
+
},
|
|
65
|
+
"boxplot": {
|
|
66
|
+
"plots": [],
|
|
67
|
+
"borders": "true",
|
|
68
|
+
"plotOutlierValues": false,
|
|
69
|
+
"plotNonOutlierValues": true,
|
|
70
|
+
"labels": {
|
|
71
|
+
"q1": "Lower Quartile",
|
|
72
|
+
"q2": "q2",
|
|
73
|
+
"q3": "Upper Quartile",
|
|
74
|
+
"q4": "q4",
|
|
75
|
+
"minimum": "Minimum",
|
|
76
|
+
"maximum": "Maximum",
|
|
77
|
+
"mean": "Mean",
|
|
78
|
+
"median": "Median",
|
|
79
|
+
"sd": "Standard Deviation",
|
|
80
|
+
"iqr": "Interquartile Range",
|
|
81
|
+
"total": "Total",
|
|
82
|
+
"outliers": "Outliers",
|
|
83
|
+
"values": "Values",
|
|
84
|
+
"lowerBounds": "Lower Bounds",
|
|
85
|
+
"upperBounds": "Upper Bounds"
|
|
86
|
+
},
|
|
87
|
+
"firstQuartilePercentage": 25,
|
|
88
|
+
"thirdQuartilePercentage": 75,
|
|
89
|
+
"boxWidthPercentage": 40,
|
|
90
|
+
"legend": { "showHowToReadText": false, "howToReadText": "" }
|
|
91
|
+
},
|
|
92
|
+
"topAxis": { "hasLine": false },
|
|
93
|
+
"isLegendValue": false,
|
|
94
|
+
"barThickness": 0.35,
|
|
95
|
+
"barHeight": 25,
|
|
96
|
+
"barSpace": 15,
|
|
97
|
+
"heights": { "vertical": "250", "horizontal": 750, "mobileVertical": "150" },
|
|
98
|
+
"xAxis": {
|
|
99
|
+
"sortDates": false,
|
|
100
|
+
"anchors": [],
|
|
101
|
+
"type": "date-time",
|
|
102
|
+
"showTargetLabel": true,
|
|
103
|
+
"targetLabel": "Target",
|
|
104
|
+
"hideAxis": false,
|
|
105
|
+
"hideLabel": false,
|
|
106
|
+
"hideTicks": false,
|
|
107
|
+
"size": "0",
|
|
108
|
+
"tickRotation": 0,
|
|
109
|
+
"min": "",
|
|
110
|
+
"max": "",
|
|
111
|
+
"labelColor": "#333",
|
|
112
|
+
"tickLabelColor": "#333",
|
|
113
|
+
"tickColor": "#333",
|
|
114
|
+
"numTicks": "6",
|
|
115
|
+
"labelOffset": 0,
|
|
116
|
+
"axisPadding": 200,
|
|
117
|
+
"target": 0,
|
|
118
|
+
"maxTickRotation": "45",
|
|
119
|
+
"padding": "0",
|
|
120
|
+
"showYearsOnce": false,
|
|
121
|
+
"sortByRecentDate": false,
|
|
122
|
+
"dataKey": "week_end",
|
|
123
|
+
"label": "",
|
|
124
|
+
"dateParseFormat": "%Y-%m-%d",
|
|
125
|
+
"dateDisplayFormat": "%b. %-d %Y",
|
|
126
|
+
"axisBBox": 24.939998626708984,
|
|
127
|
+
"tickWidthMax": 108,
|
|
128
|
+
"viewportNumTicks": { "xxs": "4" },
|
|
129
|
+
"manual": true
|
|
130
|
+
},
|
|
131
|
+
"table": {
|
|
132
|
+
"label": "Data Table",
|
|
133
|
+
"expanded": false,
|
|
134
|
+
"limitHeight": false,
|
|
135
|
+
"height": "",
|
|
136
|
+
"caption": "",
|
|
137
|
+
"showDownloadUrl": false,
|
|
138
|
+
"showDataTableLink": true,
|
|
139
|
+
"showDownloadLinkBelow": true,
|
|
140
|
+
"indexLabel": "Week Ending",
|
|
141
|
+
"download": true,
|
|
142
|
+
"showVertical": true,
|
|
143
|
+
"dateDisplayFormat": "",
|
|
144
|
+
"showMissingDataLabel": true,
|
|
145
|
+
"showSuppressedSymbol": true,
|
|
146
|
+
"show": true
|
|
147
|
+
},
|
|
148
|
+
"orientation": "vertical",
|
|
149
|
+
"color": "pinkpurple",
|
|
150
|
+
"columns": {},
|
|
151
|
+
"legend": {
|
|
152
|
+
"hide": false,
|
|
153
|
+
"behavior": "isolate",
|
|
154
|
+
"axisAlign": true,
|
|
155
|
+
"singleRow": true,
|
|
156
|
+
"colorCode": "",
|
|
157
|
+
"reverseLabelOrder": false,
|
|
158
|
+
"description": "",
|
|
159
|
+
"dynamicLegend": false,
|
|
160
|
+
"dynamicLegendDefaultText": "Show All",
|
|
161
|
+
"dynamicLegendItemLimit": 5,
|
|
162
|
+
"dynamicLegendItemLimitMessage": "Dynamic Legend Item Limit Hit.",
|
|
163
|
+
"dynamicLegendChartMessage": "Select Options from the Legend",
|
|
164
|
+
"label": "",
|
|
165
|
+
"lineMode": false,
|
|
166
|
+
"verticalSorted": false,
|
|
167
|
+
"highlightOnHover": false,
|
|
168
|
+
"hideSuppressedLabels": false,
|
|
169
|
+
"hideSuppressionLink": false,
|
|
170
|
+
"seriesHighlight": [],
|
|
171
|
+
"style": "lines",
|
|
172
|
+
"subStyle": "linear blocks",
|
|
173
|
+
"tickRotation": "",
|
|
174
|
+
"hideBorder": { "side": false, "topBottom": true },
|
|
175
|
+
"position": "bottom"
|
|
176
|
+
},
|
|
177
|
+
"brush": { "height": 25, "active": false },
|
|
178
|
+
"exclusions": { "active": false, "keys": [] },
|
|
179
|
+
"palette": "qualitative-bold",
|
|
180
|
+
"isPaletteReversed": false,
|
|
181
|
+
"twoColor": { "palette": "monochrome-1", "isPaletteReversed": false },
|
|
182
|
+
"labels": false,
|
|
183
|
+
"dataFormat": {
|
|
184
|
+
"commas": true,
|
|
185
|
+
"prefix": "",
|
|
186
|
+
"suffix": " percent vaccinated",
|
|
187
|
+
"abbreviated": true,
|
|
188
|
+
"bottomSuffix": "",
|
|
189
|
+
"bottomPrefix": "",
|
|
190
|
+
"bottomAbbreviated": false,
|
|
191
|
+
"roundTo": "1",
|
|
192
|
+
"onlyShowTopPrefixSuffix": true
|
|
193
|
+
},
|
|
194
|
+
"confidenceKeys": {},
|
|
195
|
+
"visual": {
|
|
196
|
+
"border": true,
|
|
197
|
+
"accent": true,
|
|
198
|
+
"background": true,
|
|
199
|
+
"verticalHoverLine": true,
|
|
200
|
+
"horizontalHoverLine": false
|
|
201
|
+
},
|
|
202
|
+
"useLogScale": false,
|
|
203
|
+
"filterBehavior": "Filter Change",
|
|
204
|
+
"highlightedBarValues": [],
|
|
205
|
+
"series": [
|
|
206
|
+
{ "dataKey": "Adults", "type": "Line", "axis": "Left", "tooltip": true, "name": "Adults (18+)" },
|
|
207
|
+
{ "dataKey": "Children", "type": "dashed-md", "axis": "Left", "tooltip": true, "name": "Children (under 18)" }
|
|
208
|
+
],
|
|
209
|
+
"tooltips": { "opacity": 90, "singleSeries": false, "dateDisplayFormat": "%B %-d, %Y" },
|
|
210
|
+
"forestPlot": {
|
|
211
|
+
"startAt": 0,
|
|
212
|
+
"colors": { "line": "", "shape": "" },
|
|
213
|
+
"lineOfNoEffect": { "show": true },
|
|
214
|
+
"type": "",
|
|
215
|
+
"pooledResult": { "diamondHeight": 5, "column": "" },
|
|
216
|
+
"estimateField": "",
|
|
217
|
+
"estimateRadius": "",
|
|
218
|
+
"shape": "square",
|
|
219
|
+
"rowHeight": 20,
|
|
220
|
+
"description": { "show": true, "text": "description", "location": 0 },
|
|
221
|
+
"result": { "show": true, "text": "result", "location": 100 },
|
|
222
|
+
"radius": { "min": 2, "max": 10, "scalingColumn": "" },
|
|
223
|
+
"regression": { "lower": 0, "upper": 0, "estimateField": 0 },
|
|
224
|
+
"leftWidthOffset": 0,
|
|
225
|
+
"rightWidthOffset": 0,
|
|
226
|
+
"showZeroLine": false,
|
|
227
|
+
"leftLabel": "",
|
|
228
|
+
"rightLabel": ""
|
|
229
|
+
},
|
|
230
|
+
"area": { "isStacked": false },
|
|
231
|
+
"sankey": {
|
|
232
|
+
"title": { "defaultColor": "black" },
|
|
233
|
+
"iterations": 1,
|
|
234
|
+
"rxValue": 0.9,
|
|
235
|
+
"overallSize": { "width": 900, "height": 700 },
|
|
236
|
+
"margin": { "margin_y": 25, "margin_x": 0 },
|
|
237
|
+
"nodeSize": { "nodeWidth": 26, "nodeHeight": 40 },
|
|
238
|
+
"nodePadding": 55,
|
|
239
|
+
"nodeFontColor": "black",
|
|
240
|
+
"nodeColor": { "default": "#ff8500", "inactive": "#808080" },
|
|
241
|
+
"linkColor": { "default": "#ffc900", "inactive": "#D3D3D3" },
|
|
242
|
+
"opacity": {
|
|
243
|
+
"nodeOpacityDefault": 1,
|
|
244
|
+
"nodeOpacityInactive": 0.1,
|
|
245
|
+
"LinkOpacityDefault": 1,
|
|
246
|
+
"LinkOpacityInactive": 0.1
|
|
247
|
+
},
|
|
248
|
+
"storyNodeFontColor": "#006778",
|
|
249
|
+
"storyNodeText": [],
|
|
250
|
+
"nodeValueStyle": { "textBefore": "(", "textAfter": ")" },
|
|
251
|
+
"data": []
|
|
252
|
+
},
|
|
253
|
+
"visualizationType": "Line",
|
|
254
|
+
"customColors": ["#f06f19", "#f06f19", "#f06f19", "#000000", "#0A6C75", "#C0F2FD", "#C0F2FD", "#C0F2FD", "#C0F2FD"],
|
|
255
|
+
"dataFileName": "/wcms/vizdata/Respitory_Viruses/NISVaccinationsCumulative7a.json",
|
|
256
|
+
"dataFileSourceType": "url",
|
|
257
|
+
"dataUrl": "https://www.cdc.gov/wcms/vizdata/Respitory_Viruses/NISVaccinationsCumulative7a.json",
|
|
258
|
+
"dataDescription": {
|
|
259
|
+
"horizontal": false,
|
|
260
|
+
"series": true,
|
|
261
|
+
"singleRow": false,
|
|
262
|
+
"xKey": "week_end",
|
|
263
|
+
"valueKeysTallSupport": ["value"],
|
|
264
|
+
"ignoredKeys": [
|
|
265
|
+
"suppression_flag",
|
|
266
|
+
"95_confidence_interval_lower",
|
|
267
|
+
"95_confidence_interval_upper",
|
|
268
|
+
"95_confidence_internal_range"
|
|
269
|
+
],
|
|
270
|
+
"seriesKey": "demographic_group"
|
|
271
|
+
},
|
|
272
|
+
"version": "4.24.10",
|
|
273
|
+
"description": "<div class=\"text-left\"><p class=\"fnote\">95% confidence intervals for the point estimates are presented at the data.cdc.gov link below.<br><br> Data last updated on <span data-timestamp=\"NISVaccinationsCumulative7a:Data_as_of\"></span> and presented through <span data-timestamp=\"NISVaccinationsCumulative7a:Data_Presented_Through\"></span>. <a href=\"https://data.cdc.gov/Vaccinations/Weekly-Respiratory-Virus-Vaccination-Data-Children/5c6r-xi2t\">View this dataset</a> on data.CDC.gov.</p></div>",
|
|
274
|
+
"dynamicMarginTop": 0,
|
|
275
|
+
"filters": [
|
|
276
|
+
{
|
|
277
|
+
"values": ["COVID-19", "Influenza", "RSV"],
|
|
278
|
+
"filterStyle": "dropdown",
|
|
279
|
+
"id": 1726688167656,
|
|
280
|
+
"columnName": "pathogen",
|
|
281
|
+
"showDropdown": false,
|
|
282
|
+
"active": "COVID-19"
|
|
283
|
+
}
|
|
284
|
+
],
|
|
285
|
+
"runtimeDataUrl": "https://wcms-wp.cdc.gov/wcms/vizdata/Respitory_Viruses/NISVaccinationsCumulative7a.json",
|
|
286
|
+
"showLineSeriesLabels": false,
|
|
287
|
+
"colorMatchLineSeriesLabels": false
|
|
288
|
+
}
|
|
@@ -33,7 +33,13 @@ const AreaChartStacked = ({ xScale, yScale, yMax, xMax, handleTooltipMouseOver,
|
|
|
33
33
|
data && (
|
|
34
34
|
<svg height={Number(yMax)}>
|
|
35
35
|
<ErrorBoundary component='AreaChartStacked'>
|
|
36
|
-
<Group
|
|
36
|
+
<Group
|
|
37
|
+
className='area-chart'
|
|
38
|
+
key='area-wrapper'
|
|
39
|
+
left={Number(config.yAxis.size) + strokeWidth / 2}
|
|
40
|
+
height={Number(yMax)}
|
|
41
|
+
style={{ overflow: 'hidden' }}
|
|
42
|
+
>
|
|
37
43
|
<AreaStack
|
|
38
44
|
data={data}
|
|
39
45
|
keys={config.runtime.areaSeriesKeys.map(s => s.dataKey) || config.series.map(s => s.dataKey)}
|
|
@@ -44,8 +50,14 @@ const AreaChartStacked = ({ xScale, yScale, yMax, xMax, handleTooltipMouseOver,
|
|
|
44
50
|
>
|
|
45
51
|
{({ stacks, path }) => {
|
|
46
52
|
return stacks.map((stack, stackIndex) => {
|
|
47
|
-
let transparentArea =
|
|
48
|
-
|
|
53
|
+
let transparentArea =
|
|
54
|
+
config.legend.behavior === 'highlight' &&
|
|
55
|
+
seriesHighlight.length > 0 &&
|
|
56
|
+
seriesHighlight.indexOf(stack.key) === -1
|
|
57
|
+
let displayArea =
|
|
58
|
+
config.legend.behavior === 'highlight' ||
|
|
59
|
+
seriesHighlight.length === 0 ||
|
|
60
|
+
seriesHighlight.indexOf(stack.key) !== -1
|
|
49
61
|
|
|
50
62
|
return (
|
|
51
63
|
// prettier-ignore
|
|
@@ -44,7 +44,7 @@ const CategoricalYAxis = ({ yMax, leftSize, max, xMax }) => {
|
|
|
44
44
|
if (categoryObj[lastheight] === '') {
|
|
45
45
|
// Calculate the sum of the numeric values of all other heights
|
|
46
46
|
const sumOfValues = heights.slice(0, -1).reduce((sum, label) => {
|
|
47
|
-
const value =
|
|
47
|
+
const value = Number(categoryObj[label])
|
|
48
48
|
return sum + (isNaN(value) ? 0 : value)
|
|
49
49
|
}, 0)
|
|
50
50
|
|
|
@@ -52,7 +52,7 @@ const CategoricalYAxis = ({ yMax, leftSize, max, xMax }) => {
|
|
|
52
52
|
const newValue = max - sumOfValues
|
|
53
53
|
|
|
54
54
|
// Update the last height with the new value
|
|
55
|
-
categoryObj[lastheight] = newValue
|
|
55
|
+
categoryObj[lastheight] = newValue
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
return [categoryObj]
|
|
@@ -22,6 +22,8 @@ import chroma from 'chroma-js'
|
|
|
22
22
|
// Local context and types
|
|
23
23
|
import BarChartContext, { BarChartContextValues } from './context'
|
|
24
24
|
import { ChartContext } from '../../../types/ChartContext'
|
|
25
|
+
import _ from 'lodash'
|
|
26
|
+
import { getBarData } from '../helpers/getBarData'
|
|
25
27
|
|
|
26
28
|
export const BarChartHorizontal = () => {
|
|
27
29
|
const { xScale, yScale, yMax, seriesScale } = useContext<BarChartContextValues>(BarChartContext)
|
|
@@ -35,9 +37,7 @@ export const BarChartHorizontal = () => {
|
|
|
35
37
|
formatDate,
|
|
36
38
|
parseDate,
|
|
37
39
|
setSharedFilter,
|
|
38
|
-
isNumber
|
|
39
|
-
getYAxisData,
|
|
40
|
-
getXAxisData
|
|
40
|
+
isNumber
|
|
41
41
|
} = useContext<ChartContext>(ConfigContext)
|
|
42
42
|
const {
|
|
43
43
|
isHorizontal,
|
|
@@ -60,13 +60,21 @@ export const BarChartHorizontal = () => {
|
|
|
60
60
|
|
|
61
61
|
const { HighLightedBarUtils } = useHighlightedBars(config)
|
|
62
62
|
|
|
63
|
+
const hasConfidenceInterval = Object.keys(config.confidenceKeys).length > 0
|
|
64
|
+
|
|
65
|
+
const _data = getBarData(config, data, hasConfidenceInterval)
|
|
66
|
+
|
|
67
|
+
const root = document.documentElement
|
|
68
|
+
|
|
69
|
+
const coolGray90 = getComputedStyle(root).getPropertyValue('--cool-gray-90')
|
|
70
|
+
|
|
63
71
|
return (
|
|
64
72
|
config.visualizationSubType !== 'stacked' &&
|
|
65
73
|
config.visualizationType === 'Bar' &&
|
|
66
74
|
config.orientation === 'horizontal' && (
|
|
67
75
|
<Group>
|
|
68
76
|
<BarGroup
|
|
69
|
-
data={config.preliminaryData?.some(pd => pd.value && pd.type === 'suppression') ? tableData :
|
|
77
|
+
data={config.preliminaryData?.some(pd => pd.value && pd.type === 'suppression') ? tableData : _data}
|
|
70
78
|
keys={config.runtime.barSeriesKeys || config.runtime.seriesKeys}
|
|
71
79
|
height={yMax}
|
|
72
80
|
x0={d => d[config.runtime.originalXAxis.dataKey]}
|
|
@@ -86,6 +94,8 @@ export const BarChartHorizontal = () => {
|
|
|
86
94
|
top={barGroup.y}
|
|
87
95
|
>
|
|
88
96
|
{barGroup.bars.map((bar, index) => {
|
|
97
|
+
const datum = _data[barGroup.index]
|
|
98
|
+
const dataValue = datum[config.runtime.originalXAxis.dataKey]
|
|
89
99
|
const scaleVal = config.yAxis.type === 'logarithmic' ? 0.1 : 0
|
|
90
100
|
let highlightedBarValues = config.highlightedBarValues
|
|
91
101
|
.map(item => item.value)
|
|
@@ -119,9 +129,7 @@ export const BarChartHorizontal = () => {
|
|
|
119
129
|
const barX = bar.value < 0 ? Math.abs(xScale(bar.value)) : xScale(scaleVal)
|
|
120
130
|
const yAxisValue = formatNumber(bar.value, 'left')
|
|
121
131
|
const xAxisValue =
|
|
122
|
-
config.runtime[section].type === 'date'
|
|
123
|
-
? formatDate(parseDate(data[barGroup.index][config.runtime.originalXAxis.dataKey]))
|
|
124
|
-
: data[barGroup.index][config.runtime.originalXAxis.dataKey]
|
|
132
|
+
config.runtime[section].type === 'date' ? formatDate(parseDate(dataValue)) : dataValue
|
|
125
133
|
|
|
126
134
|
const barPosition = !isPositiveBar ? 'below' : 'above'
|
|
127
135
|
const absentDataLabel = getAbsentDataLabel(yAxisValue)
|
|
@@ -167,7 +175,10 @@ export const BarChartHorizontal = () => {
|
|
|
167
175
|
config.runtime.seriesLabels && config.runtime.seriesLabels[bar.key]
|
|
168
176
|
? colorScale(config.runtime.seriesLabels[bar.key])
|
|
169
177
|
: colorScale(bar.key)
|
|
170
|
-
|
|
178
|
+
const hasDynamicCategory = config.series.find(s => s.dynamicCategory)
|
|
179
|
+
if (!hasDynamicCategory) {
|
|
180
|
+
barColor = assignColorsToValues(barGroups.length, barGroup.index, barColor) // Color code by category
|
|
181
|
+
}
|
|
171
182
|
const isRegularLollipopColor = config.isLollipopChart && config.lollipopColorStyle === 'regular'
|
|
172
183
|
const isTwoToneLollipopColor = config.isLollipopChart && config.lollipopColorStyle === 'two-tone'
|
|
173
184
|
const isHighlightedBar = highlightedBarValues?.includes(xAxisValue)
|
|
@@ -199,6 +210,16 @@ export const BarChartHorizontal = () => {
|
|
|
199
210
|
return barColor
|
|
200
211
|
}
|
|
201
212
|
|
|
213
|
+
// Confidence Interval Variables
|
|
214
|
+
const tickWidth = 5
|
|
215
|
+
const yPos = barHeight * bar.index + barHeight / 2
|
|
216
|
+
const [upperPos, lowerPos] = ['upper', 'lower'].map(position => {
|
|
217
|
+
if (!hasConfidenceInterval) return
|
|
218
|
+
const d = datum.dynamicData ? datum.CI[bar.key][position] : datum[config.confidenceKeys[position]]
|
|
219
|
+
return xScale(d)
|
|
220
|
+
})
|
|
221
|
+
// End Confidence Interval Variables
|
|
222
|
+
|
|
202
223
|
return (
|
|
203
224
|
<Group key={`${barGroup.index}--${index}`}>
|
|
204
225
|
<Group key={`bar-sub-group-${barGroup.index}-${barGroup.x0}-${barY}--${index}`}>
|
|
@@ -321,10 +342,10 @@ export const BarChartHorizontal = () => {
|
|
|
321
342
|
textAnchor={'start'}
|
|
322
343
|
>
|
|
323
344
|
{config.runtime.yAxis.type === 'date'
|
|
324
|
-
? formatDate(parseDate(
|
|
345
|
+
? formatDate(parseDate(dataValue))
|
|
325
346
|
: isHorizontal
|
|
326
|
-
?
|
|
327
|
-
: formatNumber(
|
|
347
|
+
? dataValue
|
|
348
|
+
: formatNumber(dataValue)}
|
|
328
349
|
</Text>
|
|
329
350
|
)}
|
|
330
351
|
|
|
@@ -357,6 +378,20 @@ export const BarChartHorizontal = () => {
|
|
|
357
378
|
<animate attributeName='height' values={`0, ${lollipopShapeSize}`} dur='2.5s' />
|
|
358
379
|
</rect>
|
|
359
380
|
)}
|
|
381
|
+
{hasConfidenceInterval && (
|
|
382
|
+
<path
|
|
383
|
+
key={`confidence-interval-h-${yPos}-${datum[config.runtime.originalXAxis.dataKey]}`}
|
|
384
|
+
stroke={coolGray90}
|
|
385
|
+
strokeWidth='px'
|
|
386
|
+
d={`
|
|
387
|
+
M${lowerPos} ${yPos - tickWidth}
|
|
388
|
+
L${lowerPos} ${yPos + tickWidth}
|
|
389
|
+
M${lowerPos} ${yPos}
|
|
390
|
+
L${upperPos} ${yPos}
|
|
391
|
+
M${upperPos} ${yPos - tickWidth}
|
|
392
|
+
L${upperPos} ${yPos + tickWidth} `}
|
|
393
|
+
/>
|
|
394
|
+
)}
|
|
360
395
|
</Group>
|
|
361
396
|
</Group>
|
|
362
397
|
)
|
|
@@ -365,32 +400,6 @@ export const BarChartHorizontal = () => {
|
|
|
365
400
|
))
|
|
366
401
|
}}
|
|
367
402
|
</BarGroup>
|
|
368
|
-
|
|
369
|
-
{Object.keys(config.confidenceKeys).length > 0
|
|
370
|
-
? data.map(d => {
|
|
371
|
-
let xPos, yPos
|
|
372
|
-
let upperPos
|
|
373
|
-
let lowerPos
|
|
374
|
-
let tickWidth = 5
|
|
375
|
-
yPos = yScale(getXAxisData(d)) - 0.75 * config.barHeight
|
|
376
|
-
upperPos = xScale(getYAxisData(d, config.confidenceKeys.upper))
|
|
377
|
-
lowerPos = xScale(getYAxisData(d, config.confidenceKeys.lower))
|
|
378
|
-
return (
|
|
379
|
-
<path
|
|
380
|
-
key={`confidence-interval-h-${yPos}-${d[config.runtime.originalXAxis.dataKey]}`}
|
|
381
|
-
stroke='#333'
|
|
382
|
-
strokeWidth='px'
|
|
383
|
-
d={`
|
|
384
|
-
M${lowerPos} ${yPos - tickWidth}
|
|
385
|
-
L${lowerPos} ${yPos + tickWidth}
|
|
386
|
-
M${lowerPos} ${yPos}
|
|
387
|
-
L${upperPos} ${yPos}
|
|
388
|
-
M${upperPos} ${yPos - tickWidth}
|
|
389
|
-
L${upperPos} ${yPos + tickWidth} `}
|
|
390
|
-
/>
|
|
391
|
-
)
|
|
392
|
-
})
|
|
393
|
-
: ''}
|
|
394
403
|
</Group>
|
|
395
404
|
)
|
|
396
405
|
)
|
|
@@ -21,7 +21,8 @@ import createBarElement from '@cdc/core/components/createBarElement'
|
|
|
21
21
|
import chroma from 'chroma-js'
|
|
22
22
|
// Types
|
|
23
23
|
import { type ChartContext } from '../../../types/ChartContext'
|
|
24
|
-
import _
|
|
24
|
+
import _ from 'lodash'
|
|
25
|
+
import { getBarData } from '../helpers/getBarData'
|
|
25
26
|
|
|
26
27
|
export const BarChartVertical = () => {
|
|
27
28
|
const { xScale, yScale, xMax, yMax, seriesScale } = useContext<BarChartContextValues>(BarChartContext)
|
|
@@ -44,8 +45,14 @@ export const BarChartVertical = () => {
|
|
|
44
45
|
} = useBarChart()
|
|
45
46
|
|
|
46
47
|
// prettier-ignore
|
|
47
|
-
const { colorScale, config, dashboardConfig, tableData, formatDate, formatNumber,
|
|
48
|
+
const { colorScale, config, dashboardConfig, tableData, formatDate, formatNumber, parseDate, seriesHighlight, setSharedFilter, transformedData, brushConfig } = useContext<ChartContext>(ConfigContext)
|
|
49
|
+
|
|
48
50
|
const { HighLightedBarUtils } = useHighlightedBars(config)
|
|
51
|
+
|
|
52
|
+
const root = document.documentElement
|
|
53
|
+
|
|
54
|
+
const coolGray90 = getComputedStyle(root).getPropertyValue('--cool-gray-90')
|
|
55
|
+
|
|
49
56
|
let data = transformedData
|
|
50
57
|
// check if user add suppression
|
|
51
58
|
const isSuppressionActive = config.preliminaryData.some(pd => pd.value && pd.type === 'suppression')
|
|
@@ -60,32 +67,7 @@ export const BarChartVertical = () => {
|
|
|
60
67
|
|
|
61
68
|
const hasConfidenceInterval = Object.keys(config.confidenceKeys).length > 0
|
|
62
69
|
|
|
63
|
-
const
|
|
64
|
-
const dynamicSeries = config.series.find(s => s.dynamicCategory)
|
|
65
|
-
if (!dynamicSeries) return data
|
|
66
|
-
const { dynamicCategory, dataKey } = dynamicSeries
|
|
67
|
-
const xAxisKey = config.runtime.originalXAxis.dataKey
|
|
68
|
-
const xAxisGroupDataLookup = _.groupBy(data, xAxisKey)
|
|
69
|
-
return Object.values(xAxisGroupDataLookup).map(group => {
|
|
70
|
-
return group.reduce((acc, datum) => {
|
|
71
|
-
const dataValue = datum[dataKey]
|
|
72
|
-
const dataCategory = datum[dynamicCategory]
|
|
73
|
-
if (hasConfidenceInterval) {
|
|
74
|
-
const { lower, upper } = config.confidenceKeys
|
|
75
|
-
if (!acc.CI) acc.CI = {}
|
|
76
|
-
const lowerValue = datum[lower]
|
|
77
|
-
const upperValue = datum[upper]
|
|
78
|
-
acc.CI[dataCategory] = { lower: lowerValue, upper: upperValue }
|
|
79
|
-
}
|
|
80
|
-
acc[dataCategory] = dataValue
|
|
81
|
-
acc[xAxisKey] = datum[xAxisKey]
|
|
82
|
-
acc.dynamicData = true
|
|
83
|
-
return acc
|
|
84
|
-
}, {})
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const _data = getData()
|
|
70
|
+
const _data = getBarData(config, data, hasConfidenceInterval)
|
|
89
71
|
return (
|
|
90
72
|
config.visualizationSubType !== 'stacked' &&
|
|
91
73
|
(config.visualizationType === 'Bar' ||
|
|
@@ -109,11 +91,11 @@ export const BarChartVertical = () => {
|
|
|
109
91
|
}}
|
|
110
92
|
>
|
|
111
93
|
{barGroups => {
|
|
112
|
-
return barGroups.map((barGroup,
|
|
94
|
+
return barGroups.map((barGroup, _index) => (
|
|
113
95
|
<Group
|
|
114
|
-
className={`bar-group-${barGroup.index}-${barGroup.x0}--${
|
|
115
|
-
key={`bar-group-${barGroup.index}-${barGroup.x0}--${
|
|
116
|
-
id={`bar-group-${barGroup.index}-${barGroup.x0}--${
|
|
96
|
+
className={`bar-group-${barGroup.index}-${barGroup.x0}--${_index} ${config.orientation}`}
|
|
97
|
+
key={`bar-group-${barGroup.index}-${barGroup.x0}--${_index}`}
|
|
98
|
+
id={`bar-group-${barGroup.index}-${barGroup.x0}--${_index}`}
|
|
117
99
|
left={barGroup.x0}
|
|
118
100
|
>
|
|
119
101
|
{barGroup.bars.map((bar, index) => {
|
|
@@ -249,11 +231,17 @@ export const BarChartVertical = () => {
|
|
|
249
231
|
// Confidence Interval Variables
|
|
250
232
|
const tickWidth = 5
|
|
251
233
|
const xPos = barX + (config.xAxis.type !== 'date-time' ? barWidth / 2 : 0)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
234
|
+
|
|
235
|
+
const upperPos = yScale(
|
|
236
|
+
datum.dynamicData && datum?.CI?.[bar.key]
|
|
237
|
+
? datum.CI[bar.key].upper
|
|
238
|
+
: datum[config.confidenceKeys.upper]
|
|
239
|
+
)
|
|
240
|
+
const lowerPos = yScale(
|
|
241
|
+
datum.dynamicData && datum?.CI?.[bar.key]
|
|
242
|
+
? datum.CI[bar.key].lower
|
|
243
|
+
: datum[config.confidenceKeys.lower]
|
|
244
|
+
)
|
|
257
245
|
// End Confidence Interval Variables
|
|
258
246
|
|
|
259
247
|
return (
|
|
@@ -372,7 +360,7 @@ export const BarChartVertical = () => {
|
|
|
372
360
|
<rect
|
|
373
361
|
display={displaylollipopShape}
|
|
374
362
|
x={barX - lollipopBarWidth / 2}
|
|
375
|
-
y={
|
|
363
|
+
y={bar.y}
|
|
376
364
|
width={lollipopShapeSize}
|
|
377
365
|
height={lollipopShapeSize}
|
|
378
366
|
fill={getBarBackgroundColor(colorScale(config.runtime.seriesLabels[bar.key]))}
|
|
@@ -384,10 +372,10 @@ export const BarChartVertical = () => {
|
|
|
384
372
|
<animate attributeName='height' values={`0, ${lollipopShapeSize}`} dur='2.5s' />
|
|
385
373
|
</rect>
|
|
386
374
|
)}
|
|
387
|
-
{hasConfidenceInterval && (
|
|
375
|
+
{hasConfidenceInterval && bar.value !== undefined && datum && (
|
|
388
376
|
<path
|
|
389
377
|
key={`confidence-interval-v-${datum[config.runtime.originalXAxis.dataKey]}`}
|
|
390
|
-
stroke=
|
|
378
|
+
stroke={coolGray90}
|
|
391
379
|
strokeWidth='px'
|
|
392
380
|
d={`M${xPos - tickWidth} ${upperPos}
|
|
393
381
|
L${xPos + tickWidth} ${upperPos}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import { TransformedData } from '../../../types/ChartContext'
|
|
3
|
+
import { ChartConfig } from '../../../types/ChartConfig'
|
|
4
|
+
|
|
5
|
+
export const getBarData = (config: ChartConfig, data: TransformedData[], hasConfidenceInterval: boolean) => {
|
|
6
|
+
const dynamicSeries = config.series.find(s => s.dynamicCategory)
|
|
7
|
+
if (!dynamicSeries) return data
|
|
8
|
+
const { dynamicCategory, dataKey } = dynamicSeries
|
|
9
|
+
const xAxisKey = config.runtime.originalXAxis.dataKey
|
|
10
|
+
const xAxisGroupDataLookup = _.groupBy(data, xAxisKey)
|
|
11
|
+
return Object.values(xAxisGroupDataLookup).map(group => {
|
|
12
|
+
return group.reduce((acc, datum) => {
|
|
13
|
+
const dataValue = datum[dataKey]
|
|
14
|
+
const dataCategory = datum[dynamicCategory]
|
|
15
|
+
if (hasConfidenceInterval) {
|
|
16
|
+
const { lower, upper } = config.confidenceKeys
|
|
17
|
+
if (!acc.CI) acc.CI = {}
|
|
18
|
+
const lowerValue = datum[lower]
|
|
19
|
+
const upperValue = datum[upper]
|
|
20
|
+
acc.CI[dataCategory] = { lower: lowerValue, upper: upperValue }
|
|
21
|
+
}
|
|
22
|
+
acc[dataCategory] = dataValue
|
|
23
|
+
acc[xAxisKey] = datum[xAxisKey]
|
|
24
|
+
acc.dynamicData = true
|
|
25
|
+
return acc
|
|
26
|
+
}, {})
|
|
27
|
+
})
|
|
28
|
+
}
|