@cdc/chart 4.23.11 → 4.24.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/dist/cdcchart.js +35740 -35027
  2. package/examples/feature/bar/additional-column-tooltip.json +446 -0
  3. package/examples/feature/bar/tall-data.json +98 -0
  4. package/examples/feature/forest-plot/forest-plot.json +63 -19
  5. package/examples/feature/forest-plot/linear.json +52 -3
  6. package/examples/feature/forest-plot/log.json +26 -0
  7. package/examples/feature/forest-plot/logarithmic.json +0 -35
  8. package/examples/feature/line/line-chart-preliminary.json +393 -0
  9. package/examples/feature/regions/index.json +9 -5
  10. package/examples/feature/scatterplot/scatterplot.json +272 -33
  11. package/index.html +10 -8
  12. package/package.json +2 -2
  13. package/src/CdcChart.tsx +70 -234
  14. package/src/ConfigContext.tsx +6 -0
  15. package/src/_stories/ChartEditor.stories.tsx +22 -0
  16. package/src/_stories/ChartLine.preliminary.tsx +19 -0
  17. package/src/_stories/_mock/pie_config.json +192 -0
  18. package/src/_stories/_mock/pie_data.json +218 -0
  19. package/src/_stories/_mock/preliminary_mock.json +346 -0
  20. package/src/components/{AreaChart.Stacked.jsx → AreaChart/components/AreaChart.Stacked.jsx} +2 -2
  21. package/src/components/{AreaChart.jsx → AreaChart/components/AreaChart.jsx} +2 -26
  22. package/src/components/AreaChart/index.tsx +4 -0
  23. package/src/components/{BarChart.Horizontal.tsx → BarChart/components/BarChart.Horizontal.tsx} +8 -8
  24. package/src/components/{BarChart.StackedHorizontal.tsx → BarChart/components/BarChart.StackedHorizontal.tsx} +37 -7
  25. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +108 -0
  26. package/src/components/{BarChart.Vertical.tsx → BarChart/components/BarChart.Vertical.tsx} +53 -70
  27. package/src/components/BarChart/components/BarChart.jsx +39 -0
  28. package/src/components/{BarChartType.jsx → BarChart/components/BarChartType.jsx} +0 -2
  29. package/src/components/BarChart/components/context.tsx +13 -0
  30. package/src/components/BarChart/index.tsx +3 -0
  31. package/src/components/{BoxPlot.jsx → BoxPlot/BoxPlot.jsx} +10 -9
  32. package/src/components/BoxPlot/index.tsx +3 -0
  33. package/src/components/EditorPanel/EditorPanel.tsx +2776 -0
  34. package/src/components/EditorPanel/EditorPanelContext.ts +40 -0
  35. package/src/components/EditorPanel/components/PanelProps.ts +3 -0
  36. package/src/components/EditorPanel/components/Panels/Panel.BoxPlot.tsx +148 -0
  37. package/src/components/{ForestPlotSettings.jsx → EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx} +97 -167
  38. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +160 -0
  39. package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +168 -0
  40. package/src/components/{Series.jsx → EditorPanel/components/Panels/Panel.Series.tsx} +4 -4
  41. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +297 -0
  42. package/src/components/EditorPanel/components/Panels/index.tsx +17 -0
  43. package/src/components/EditorPanel/components/panels.scss +72 -0
  44. package/src/components/EditorPanel/editor-panel.scss +739 -0
  45. package/src/components/EditorPanel/index.tsx +3 -0
  46. package/src/{hooks → components/EditorPanel}/useEditorPermissions.js +34 -2
  47. package/src/components/{Forecasting.jsx → Forecasting/Forecasting.jsx} +1 -1
  48. package/src/components/Forecasting/index.tsx +3 -0
  49. package/src/components/ForestPlot/ForestPlot.tsx +254 -0
  50. package/src/components/ForestPlot/ForestPlotProps.ts +7 -0
  51. package/src/components/ForestPlot/index.tsx +1 -209
  52. package/src/components/Legend/Legend.Component.tsx +199 -0
  53. package/src/components/Legend/Legend.tsx +28 -0
  54. package/src/components/Legend/helpers/createFormatLabels.tsx +140 -0
  55. package/src/components/Legend/index.tsx +3 -0
  56. package/src/components/LineChart/LineChartProps.ts +29 -0
  57. package/src/components/LineChart/components/LineChart.Circle.tsx +147 -0
  58. package/src/components/LineChart/helpers.ts +45 -0
  59. package/src/components/LineChart/index.tsx +111 -23
  60. package/src/components/LinearChart.jsx +55 -72
  61. package/src/components/PairedBarChart.jsx +4 -2
  62. package/src/components/{PieChart.jsx → PieChart/PieChart.tsx} +93 -31
  63. package/src/components/PieChart/index.tsx +3 -0
  64. package/src/components/Regions/components/Regions.tsx +144 -0
  65. package/src/components/Regions/index.tsx +3 -0
  66. package/src/components/{ScatterPlot.jsx → ScatterPlot/ScatterPlot.jsx} +3 -3
  67. package/src/components/ScatterPlot/index.tsx +3 -0
  68. package/src/components/{SparkLine.jsx → Sparkline/SparkLine.jsx} +2 -2
  69. package/src/components/Sparkline/index.tsx +3 -0
  70. package/src/data/initial-state.js +10 -8
  71. package/src/helpers/abbreviateNumber.ts +17 -0
  72. package/src/helpers/computeMarginBottom.ts +55 -0
  73. package/src/helpers/filterData.ts +18 -0
  74. package/src/helpers/generateColorsArray.ts +8 -0
  75. package/src/helpers/getQuartiles.ts +30 -0
  76. package/src/helpers/handleChartAriaLabels.ts +19 -0
  77. package/src/helpers/handleLineType.ts +18 -0
  78. package/src/helpers/lineOptions.ts +18 -0
  79. package/src/helpers/sort.ts +7 -0
  80. package/src/helpers/tests/computeMarginBottom.test.ts +20 -0
  81. package/src/hooks/useBarChart.js +7 -6
  82. package/src/hooks/useHighlightedBars.js +1 -1
  83. package/src/hooks/useMinMax.ts +3 -3
  84. package/src/hooks/useScales.ts +19 -6
  85. package/src/hooks/{useTooltip.jsx → useTooltip.tsx} +31 -25
  86. package/src/scss/main.scss +0 -3
  87. package/src/types/ChartConfig.ts +167 -23
  88. package/src/types/ChartContext.ts +34 -12
  89. package/src/types/ForestPlot.ts +7 -14
  90. package/src/types/Label.ts +7 -0
  91. package/examples/feature/scatterplot/scatterplot-continuous.csv +0 -17
  92. package/src/ConfigContext.jsx +0 -5
  93. package/src/components/BarChart.StackedVertical.tsx +0 -91
  94. package/src/components/BarChart.jsx +0 -30
  95. package/src/components/EditorPanel.jsx +0 -3356
  96. package/src/components/ForestPlot/Readme.md +0 -0
  97. package/src/components/Legend.jsx +0 -310
  98. package/src/components/LineChart/LineChart.Circle.tsx +0 -105
  99. package/src/scss/LinearChart.scss +0 -0
  100. package/src/scss/editor-panel.scss +0 -745
  101. package/src/scss/legend.scss +0 -206
  102. package/src/scss/mixins.scss +0 -0
  103. package/src/scss/variables.scss +0 -1
  104. package/src/types/ChartProps.ts +0 -7
@@ -0,0 +1,346 @@
1
+ {
2
+ "type": "chart",
3
+ "debugSvg": false,
4
+ "chartMessage": {
5
+ "noData": "No Data Available"
6
+ },
7
+ "title": "Example Stacked Bar Chart",
8
+ "showTitle": true,
9
+ "showDownloadMediaButton": false,
10
+ "theme": "theme-orange",
11
+ "animate": false,
12
+ "fontSize": "medium",
13
+ "lineDatapointStyle": "hover",
14
+ "lineDatapointColor": "Same as Line",
15
+ "barHasBorder": "false",
16
+ "isLollipopChart": false,
17
+ "lollipopShape": "circle",
18
+ "lollipopColorStyle": "two-tone",
19
+ "visualizationSubType": "stacked",
20
+ "barStyle": "",
21
+ "roundingStyle": "standard",
22
+ "tipRounding": "top",
23
+ "isResponsiveTicks": false,
24
+ "general": {
25
+ "showDownloadButton": false
26
+ },
27
+ "padding": {
28
+ "left": 5,
29
+ "right": 5
30
+ },
31
+ "suppressedData": [],
32
+ "preliminaryData": [
33
+ {
34
+ "type": "effect",
35
+ "label": "Dashed Large",
36
+ "column": "Data 2",
37
+ "value": "20",
38
+ "style": "Dashed Large",
39
+ "seriesKey": "Data 1"
40
+ },
41
+ {
42
+ "type": "effect",
43
+ "label": "Circle",
44
+ "column": "Data 1",
45
+ "value": "35",
46
+ "style": "Open Circles",
47
+ "seriesKey": "Data 2"
48
+ },
49
+ {
50
+ "type": "effect",
51
+ "label": "Dashed Medium",
52
+ "column": "Data 2",
53
+ "value": "20",
54
+ "style": "Dashed Medium",
55
+ "seriesKey": "Data 3"
56
+ }
57
+ ],
58
+ "yAxis": {
59
+ "hideAxis": false,
60
+ "displayNumbersOnBar": false,
61
+ "hideLabel": false,
62
+ "hideTicks": false,
63
+ "size": "64",
64
+ "gridLines": false,
65
+ "enablePadding": false,
66
+ "min": "",
67
+ "max": "",
68
+ "labelColor": "#333",
69
+ "tickLabelColor": "#333",
70
+ "tickColor": "#333",
71
+ "rightHideAxis": true,
72
+ "rightAxisSize": 0,
73
+ "rightLabel": "",
74
+ "rightLabelOffsetSize": 0,
75
+ "rightAxisLabelColor": "#333",
76
+ "rightAxisTickLabelColor": "#333",
77
+ "rightAxisTickColor": "#333",
78
+ "numTicks": "",
79
+ "axisPadding": 0,
80
+ "tickRotation": 0,
81
+ "anchors": [],
82
+ "label": "Y-Axis Label Example"
83
+ },
84
+ "boxplot": {
85
+ "plots": [],
86
+ "borders": "true",
87
+ "firstQuartilePercentage": 25,
88
+ "thirdQuartilePercentage": 75,
89
+ "boxWidthPercentage": 40,
90
+ "plotOutlierValues": false,
91
+ "plotNonOutlierValues": true,
92
+ "legend": {
93
+ "showHowToReadText": false,
94
+ "howToReadText": ""
95
+ },
96
+ "labels": {
97
+ "q1": "Lower Quartile",
98
+ "q2": "q2",
99
+ "q3": "Upper Quartile",
100
+ "q4": "q4",
101
+ "minimum": "Minimum",
102
+ "maximum": "Maximum",
103
+ "mean": "Mean",
104
+ "median": "Median",
105
+ "sd": "Standard Deviation",
106
+ "iqr": "Interquartile Range",
107
+ "total": "Total",
108
+ "outliers": "Outliers",
109
+ "values": "Values",
110
+ "lowerBounds": "Lower Bounds",
111
+ "upperBounds": "Upper Bounds"
112
+ }
113
+ },
114
+ "topAxis": {
115
+ "hasLine": false
116
+ },
117
+ "isLegendValue": false,
118
+ "barThickness": 0.35,
119
+ "barHeight": 25,
120
+ "barSpace": 15,
121
+ "heights": {
122
+ "vertical": 300,
123
+ "horizontal": 750
124
+ },
125
+ "xAxis": {
126
+ "sortDates": false,
127
+ "anchors": [],
128
+ "type": "categorical",
129
+ "showTargetLabel": true,
130
+ "targetLabel": "Target",
131
+ "hideAxis": false,
132
+ "hideLabel": false,
133
+ "hideTicks": false,
134
+ "size": "67",
135
+ "tickRotation": "25",
136
+ "min": "",
137
+ "max": "",
138
+ "labelColor": "#333",
139
+ "tickLabelColor": "#333",
140
+ "tickColor": "#333",
141
+ "numTicks": "",
142
+ "labelOffset": 65,
143
+ "axisPadding": 0,
144
+ "target": 0,
145
+ "maxTickRotation": 0,
146
+ "dataKey": "Year",
147
+ "label": "X-Axis Label Example",
148
+ "tickWidthMax": 41
149
+ },
150
+ "table": {
151
+ "label": "Data Table",
152
+ "expanded": true,
153
+ "limitHeight": false,
154
+ "height": "",
155
+ "caption": "",
156
+ "showDownloadUrl": false,
157
+ "showDataTableLink": true,
158
+ "indexLabel": "",
159
+ "download": true,
160
+ "showVertical": false,
161
+ "show": true
162
+ },
163
+ "orientation": "vertical",
164
+ "color": "pinkpurple",
165
+ "columns": {},
166
+ "legend": {
167
+ "hide": false,
168
+ "behavior": "isolate",
169
+ "singleRow": false,
170
+ "colorCode": "",
171
+ "reverseLabelOrder": false,
172
+ "description": "",
173
+ "dynamicLegend": false,
174
+ "dynamicLegendDefaultText": "Show All",
175
+ "dynamicLegendItemLimit": 5,
176
+ "dynamicLegendItemLimitMessage": "Dynamic Legend Item Limit Hit.",
177
+ "dynamicLegendChartMessage": "Select Options from the Legend",
178
+ "lineMode": false,
179
+ "verticalSorted": false,
180
+ "highlightOnHover": false,
181
+ "position": "right",
182
+ "label": "Data Type"
183
+ },
184
+ "brush": {
185
+ "height": 25,
186
+ "data": [
187
+ {
188
+ "Year": "2015",
189
+ "Data 1": "25",
190
+ "Data 2": "20",
191
+ "Data 3": "55"
192
+ },
193
+ {
194
+ "Year": "2016",
195
+ "Data 1": "35",
196
+ "Data 2": "30",
197
+ "Data 3": "35"
198
+ },
199
+ {
200
+ "Year": "2017",
201
+ "Data 1": "22",
202
+ "Data 2": "38",
203
+ "Data 3": "40"
204
+ },
205
+ {
206
+ "Year": "2018",
207
+ "Data 1": "40",
208
+ "Data 2": "40",
209
+ "Data 3": "20"
210
+ }
211
+ ],
212
+ "active": false
213
+ },
214
+ "exclusions": {
215
+ "active": false,
216
+ "keys": []
217
+ },
218
+ "palette": "qualitative-bold",
219
+ "isPaletteReversed": false,
220
+ "twoColor": {
221
+ "palette": "monochrome-1",
222
+ "isPaletteReversed": false
223
+ },
224
+ "labels": false,
225
+ "dataFormat": {
226
+ "commas": false,
227
+ "prefix": "",
228
+ "suffix": "%",
229
+ "abbreviated": false,
230
+ "bottomSuffix": "",
231
+ "bottomPrefix": "",
232
+ "bottomAbbreviated": false
233
+ },
234
+ "confidenceKeys": {},
235
+ "visual": {
236
+ "border": true,
237
+ "accent": true,
238
+ "background": true,
239
+ "verticalHoverLine": false,
240
+ "horizontalHoverLine": false
241
+ },
242
+ "useLogScale": false,
243
+ "filterBehavior": "Filter Change",
244
+ "highlightedBarValues": [],
245
+ "series": [
246
+ {
247
+ "dataKey": "Data 1",
248
+ "type": "Bar",
249
+ "tooltip": true,
250
+ "axis": "Left"
251
+ },
252
+ {
253
+ "dataKey": "Data 2",
254
+ "type": "Bar",
255
+ "tooltip": true,
256
+ "axis": "Left"
257
+ },
258
+ {
259
+ "dataKey": "Data 3",
260
+ "type": "Bar",
261
+ "tooltip": true,
262
+ "axis": "Left"
263
+ }
264
+ ],
265
+ "tooltips": {
266
+ "opacity": 90,
267
+ "singleSeries": false
268
+ },
269
+ "forestPlot": {
270
+ "startAt": 0,
271
+ "colors": {
272
+ "line": "",
273
+ "shape": ""
274
+ },
275
+ "lineOfNoEffect": {
276
+ "show": true
277
+ },
278
+ "type": "",
279
+ "pooledResult": {
280
+ "diamondHeight": 5,
281
+ "column": ""
282
+ },
283
+ "estimateField": "",
284
+ "estimateRadius": "",
285
+ "shape": "square",
286
+ "rowHeight": 20,
287
+ "description": {
288
+ "show": true,
289
+ "text": "description",
290
+ "location": 0
291
+ },
292
+ "result": {
293
+ "show": true,
294
+ "text": "result",
295
+ "location": 100
296
+ },
297
+ "radius": {
298
+ "min": 2,
299
+ "max": 10,
300
+ "scalingColumn": ""
301
+ },
302
+ "regression": {
303
+ "lower": 0,
304
+ "upper": 0,
305
+ "estimateField": 0
306
+ },
307
+ "leftWidthOffset": 0,
308
+ "rightWidthOffset": 0,
309
+ "showZeroLine": false,
310
+ "leftLabel": "",
311
+ "rightLabel": ""
312
+ },
313
+ "area": {
314
+ "isStacked": false
315
+ },
316
+ "height": "375",
317
+ "data": [
318
+ {
319
+ "Year": "2015",
320
+ "Data 1": "25",
321
+ "Data 2": "20",
322
+ "Data 3": "55"
323
+ },
324
+ {
325
+ "Year": "2016",
326
+ "Data 1": "35",
327
+ "Data 2": "30",
328
+ "Data 3": "35"
329
+ },
330
+ {
331
+ "Year": "2017",
332
+ "Data 1": "22",
333
+ "Data 2": "38",
334
+ "Data 3": "40"
335
+ },
336
+ {
337
+ "Year": "2018",
338
+ "Data 1": "40",
339
+ "Data 2": "40",
340
+ "Data 3": "20"
341
+ }
342
+ ],
343
+ "visualizationType": "Line",
344
+ "validated": 4.23,
345
+ "dynamicMarginTop": 0
346
+ }
@@ -1,7 +1,7 @@
1
1
  import React, { useContext, memo } from 'react'
2
2
 
3
3
  // cdc
4
- import ConfigContext from '../ConfigContext'
4
+ import ConfigContext from '../../../ConfigContext'
5
5
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
6
6
 
7
7
  // visx & d3
@@ -53,7 +53,7 @@ const AreaChartStacked = ({ xScale, yScale, yMax, xMax, handleTooltipMouseOver,
53
53
  d={path(stack) || ''}
54
54
  strokeWidth={2}
55
55
  stroke={displayArea ? colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[stack.key] : stack.key) : '#000' : 'transparent'}
56
- fillOpacity={transparentArea ? 0.25 : 0.5}
56
+ fillOpacity={transparentArea ? 0.2 : 1}
57
57
  fill={displayArea ? colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[stack.key] : stack.key) : '#000' : 'transparent'}
58
58
  />
59
59
  )
@@ -1,7 +1,7 @@
1
1
  import React, { useContext, memo } from 'react'
2
2
 
3
3
  // cdc
4
- import ConfigContext from '../ConfigContext'
4
+ import ConfigContext from '../../../ConfigContext'
5
5
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
6
6
 
7
7
  // visx & d3
@@ -18,26 +18,8 @@ const AreaChart = props => {
18
18
 
19
19
  if (!data) return
20
20
 
21
- // Tooltip helper for getting data to the closest date/category hovered.
22
- const getXValueFromCoordinate = x => {
23
- if (config.xAxis.type === 'categorical' || config.visualizationType === 'Combo') {
24
- let eachBand = xScale.step()
25
- let numerator = x
26
- const index = Math.floor(Number(numerator) / eachBand)
27
- return xScale.domain()[index - 1] // fixes off by 1 error
28
- }
29
-
30
- if (config.xAxis.type === 'date' && config.visualizationType !== 'Combo') {
31
- const bisectDate = bisector(d => parseDate(d[config.xAxis.dataKey])).left
32
- const x0 = xScale.invert(x)
33
- const index = bisectDate(config.data, x0, 1)
34
- const val = parseDate(config.data[index - 1][config.xAxis.dataKey])
35
- return val
36
- }
37
- }
38
-
39
21
  const handleX = d => {
40
- return config.xAxis.type === 'date' ? xScale(parseDate(d[config.xAxis.dataKey], false)) : xScale(d[config.xAxis.dataKey])
22
+ return (config.xAxis.type === 'date' ? xScale(parseDate(d[config.xAxis.dataKey], false)) : xScale(d[config.xAxis.dataKey])) + (xScale.bandwidth ? xScale.bandwidth() / 2 : 0)
41
23
  }
42
24
 
43
25
  const handleY = (d, index, s = undefined) => {
@@ -61,12 +43,6 @@ const AreaChart = props => {
61
43
  let transparentArea = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(s.dataKey) === -1
62
44
  let displayArea = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(s.dataKey) !== -1
63
45
 
64
- if (config.xAxis.type === 'date') {
65
- data.map(d => xScale(parseDate(d[config.xAxis.dataKey])))
66
- } else {
67
- data.map(d => xScale(d[config.xAxis.dataKey]))
68
- }
69
-
70
46
  return (
71
47
  <React.Fragment key={index}>
72
48
  {/* prettier-ignore */}
@@ -0,0 +1,4 @@
1
+ import AreaChart from './components/AreaChart'
2
+ import AreaChartStacked from './components/AreaChart.Stacked'
3
+
4
+ export { AreaChart, AreaChartStacked }
@@ -1,20 +1,20 @@
1
1
  import React, { useContext } from 'react'
2
- import ConfigContext from '../ConfigContext'
3
- import { useBarChart } from '../hooks/useBarChart'
2
+ import ConfigContext from '../../../ConfigContext'
3
+ import { useBarChart } from '../../../hooks/useBarChart'
4
4
  import { Group } from '@visx/group'
5
5
  import { Text } from '@visx/text'
6
6
  import { BarGroup } from '@visx/shape'
7
- import { useHighlightedBars } from '../hooks/useHighlightedBars'
7
+ import { useHighlightedBars } from '../../../hooks/useHighlightedBars'
8
8
  import { FaStar } from 'react-icons/fa'
9
9
 
10
10
  // third party
11
11
  import chroma from 'chroma-js'
12
+ import BarChartContext, { BarChartContextValues } from './context'
13
+ import { ChartContext } from '../../../types/ChartContext'
12
14
 
13
- import { type BarChartProps } from '../types/ChartProps'
14
-
15
- export const BarChartHorizontal = (props: BarChartProps) => {
16
- const { xScale, yScale, yMax, seriesScale } = props
17
- const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter, isNumber, getTextWidth, getYAxisData, getXAxisData } = useContext(ConfigContext)
15
+ export const BarChartHorizontal = () => {
16
+ const { xScale, yScale, yMax, seriesScale } = useContext<BarChartContextValues>(BarChartContext)
17
+ const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter, isNumber, getTextWidth, getYAxisData, getXAxisData } = useContext<ChartContext>(ConfigContext)
18
18
  const {
19
19
  isHorizontal,
20
20
  barBorderWidth,
@@ -1,6 +1,6 @@
1
1
  import React, { useContext } from 'react'
2
- import ConfigContext from '../ConfigContext'
3
- import { useBarChart } from '../hooks/useBarChart'
2
+ import ConfigContext from '../../../ConfigContext'
3
+ import { useBarChart } from '../../../hooks/useBarChart'
4
4
  import { BarStackHorizontal } from '@visx/shape'
5
5
  import { Group } from '@visx/group'
6
6
  import { Text } from '@visx/text'
@@ -8,12 +8,42 @@ import { Text } from '@visx/text'
8
8
  // third party
9
9
  import chroma from 'chroma-js'
10
10
 
11
- import { type BarChartProps } from '../types/ChartProps'
11
+ // types
12
+ import BarChartContext, { type BarChartContextValues } from './context'
13
+ import { type ChartContext } from '../../../types/ChartContext'
14
+
15
+ const BarChartStackedHorizontal = () => {
16
+ const { yMax, yScale, xScale } = useContext<BarChartContextValues>(BarChartContext)
17
+
18
+ // prettier-ignore
19
+ const {
20
+ animatedChart,
21
+ colorScale,
22
+ config,
23
+ formatDate,
24
+ formatNumber,
25
+ getTextWidth,
26
+ parseDate,
27
+ seriesHighlight,
28
+ setSharedFilter,
29
+ transformedData: data
30
+ } = useContext<ChartContext>(ConfigContext)
31
+
32
+ // prettier-ignore
33
+ const {
34
+ applyRadius,
35
+ barBorderWidth,
36
+ displayNumbersOnBar,
37
+ fontSize,
38
+ getAdditionalColumn,
39
+ hoveredBar,
40
+ isHorizontal,
41
+ isLabelBelowBar,
42
+ onMouseLeaveBar,
43
+ onMouseOverBar,
44
+ updateBars
45
+ } = useBarChart()
12
46
 
13
- const BarChartStackedHorizontal = (props: BarChartProps) => {
14
- const { xScale, yScale, xMax, yMax } = props
15
- const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter, animatedChart, getTextWidth, setSeriesHighlight } = useContext(ConfigContext)
16
- const { isHorizontal, barBorderWidth, hasMultipleSeries, applyRadius, updateBars, isLabelBelowBar, displayNumbersOnBar, fontSize, getAdditionalColumn, hoveredBar, onMouseLeaveBar, onMouseOverBar } = useBarChart()
17
47
  const { orientation, visualizationSubType } = config
18
48
 
19
49
  return (
@@ -0,0 +1,108 @@
1
+ import React, { useContext, useState } from 'react'
2
+ import ConfigContext from '../../../ConfigContext'
3
+ import { useBarChart } from '../../../hooks/useBarChart'
4
+ import { BarStack } from '@visx/shape'
5
+ import { Group } from '@visx/group'
6
+ import { Text } from '@visx/text'
7
+ import BarChartContext from './context'
8
+ import Regions from '../../Regions'
9
+
10
+ const BarChartStackedVertical = () => {
11
+ const [barWidth, setBarWidth] = useState(0)
12
+ const { xScale, yScale, xMax, yMax } = useContext(BarChartContext)
13
+ const { transformedData, colorScale, seriesHighlight, config, formatNumber, formatDate, parseDate, setSharedFilter } = useContext(ConfigContext)
14
+ const { isHorizontal, barBorderWidth, applyRadius, hoveredBar, getAdditionalColumn, onMouseLeaveBar, onMouseOverBar } = useBarChart()
15
+ const { orientation } = config
16
+ const data = config.brush.active && config.brush.data?.length ? config.brush.data : transformedData
17
+
18
+ return (
19
+ config.visualizationSubType === 'stacked' &&
20
+ !isHorizontal && (
21
+ <>
22
+ <BarStack data={data} keys={config.runtime.barSeriesKeys || config.runtime.seriesKeys} x={d => d[config.runtime.xAxis.dataKey]} xScale={xScale} yScale={yScale} color={colorScale}>
23
+ {barStacks =>
24
+ barStacks.reverse().map(barStack =>
25
+ barStack.bars.map(bar => {
26
+ let transparentBar = config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(bar.key) === -1
27
+ let displayBar = config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(bar.key) !== -1
28
+ let barThickness = config.xAxis.type === 'date' && config.xAxis.sortDates ? (config.barThickness * (xScale.range()[1] - xScale.range()[0])) : xMax / barStack.bars.length
29
+ let barThicknessAdjusted = barThickness * (config.xAxis.type === 'date' && config.xAxis.sortDates ? 1 : (config.barThickness || 0.8))
30
+ let offset = (barThickness * (1 - (config.barThickness || 0.8))) / 2
31
+ // tooltips
32
+ const rawXValue = bar.bar.data[config.runtime.xAxis.dataKey]
33
+ const xAxisValue = config.runtime.xAxis.type === 'date' ? formatDate(parseDate(rawXValue)) : rawXValue
34
+ const yAxisValue = formatNumber(bar.bar ? bar.bar.data[bar.key] : 0, 'left')
35
+ if (!yAxisValue) return
36
+ const barX = xScale(config.runtime.xAxis.type === 'date' ? parseDate(rawXValue) : rawXValue) - (config.xAxis.type === 'date' && config.xAxis.sortDates ? barThicknessAdjusted / 2 : 0)
37
+ const style = applyRadius(barStack.index)
38
+ const xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${xAxisValue}` : xAxisValue
39
+ const additionalColTooltip = getAdditionalColumn(hoveredBar)
40
+ const tooltipBody = `${config.runtime.seriesLabels[bar.key]}: ${yAxisValue}`
41
+ const tooltip = `<ul>
42
+ <li class="tooltip-heading"">${xAxisTooltip}</li>
43
+ <li class="tooltip-body ">${tooltipBody}</li>
44
+ <li class="tooltip-body ">${additionalColTooltip}</li>
45
+ </li></ul>`
46
+
47
+ setBarWidth(barThicknessAdjusted)
48
+
49
+ return (
50
+ <Group key={`${barStack.index}--${bar.index}--${orientation}`}>
51
+ <style>
52
+ {`
53
+ #barStack${barStack.index}-${bar.index} rect,
54
+ #barStack${barStack.index}-${bar.index} foreignObject div{
55
+ animation-delay: ${barStack.index * 0.5}s;
56
+ transform-origin: ${barThicknessAdjusted / 2}px ${bar.y + bar.height}px
57
+ }
58
+ `}
59
+ </style>
60
+ <Group key={`bar-stack-${barStack.index}-${bar.index}`} id={`barStack${barStack.index}-${bar.index}`} className='stack vertical'>
61
+ <Text display={config.labels && displayBar ? 'block' : 'none'} opacity={transparentBar ? 0.5 : 1} x={barX + barWidth / 2} y={bar.y - 5} fill={'#000'} textAnchor='middle'>
62
+ {yAxisValue}
63
+ </Text>
64
+ <foreignObject
65
+ onMouseOver={() => onMouseOverBar(xAxisValue, bar.key)}
66
+ onMouseLeave={onMouseLeaveBar}
67
+ key={`bar-stack-${barStack.index}-${bar.index}`}
68
+ x={barX}
69
+ y={bar.y}
70
+ width={barThicknessAdjusted}
71
+ height={bar.height}
72
+ display={displayBar ? 'block' : 'none'}
73
+ data-tooltip-html={tooltip}
74
+ data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
75
+ onClick={e => {
76
+ e.preventDefault()
77
+ if (setSharedFilter) {
78
+ bar[config.xAxis.dataKey] = xAxisValue
79
+ setSharedFilter(config.uid, bar)
80
+ }
81
+ }}
82
+ >
83
+ <div
84
+ style={{
85
+ transition: 'all 0.2s linear',
86
+ opacity: transparentBar ? 0.2 : 1,
87
+ width: barThicknessAdjusted,
88
+ height: bar.height,
89
+ background: colorScale(config.runtime.seriesLabels[bar.key]),
90
+ border: `${config.barHasBorder === 'true' ? barBorderWidth : 0}px solid #333`,
91
+ ...style
92
+ }}
93
+ ></div>
94
+ </foreignObject>
95
+ </Group>
96
+ </Group>
97
+ )
98
+ })
99
+ )
100
+ }
101
+ </BarStack>
102
+ <Regions xScale={xScale} yMax={yMax} barWidth={barWidth} totalBarsInGroup={1} />
103
+ </>
104
+ )
105
+ )
106
+ }
107
+
108
+ export default BarChartStackedVertical