@cdc/chart 4.25.10 → 4.25.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/{cdcchart-1a1724a1.es.js → cdcchart-dgT_1dIT.es.js} +136 -151
  2. package/dist/cdcchart.js +36258 -34658
  3. package/examples/feature/__data__/planet-example-data.json +1 -1
  4. package/examples/feature/boxplot/valid-boxplot.csv +38 -17
  5. package/examples/private/DEV-11825.json +573 -0
  6. package/examples/private/na.json +913 -0
  7. package/examples/private/test-data.csv +28 -0
  8. package/index.html +2 -121
  9. package/package.json +4 -4
  10. package/src/CdcChart.tsx +8 -11
  11. package/src/CdcChartComponent.tsx +256 -87
  12. package/src/_stories/Chart.Combo.stories.tsx +18 -0
  13. package/src/_stories/Chart.Forecast.stories.tsx +36 -0
  14. package/src/_stories/Chart.HTMLInDataTable.stories.tsx +520 -0
  15. package/src/_stories/Chart.Patterns.stories.tsx +2 -1
  16. package/src/_stories/Chart.PreserveDecimals.stories.tsx +220 -0
  17. package/src/_stories/Chart.SmallMultiples.stories.tsx +47 -0
  18. package/src/_stories/ChartAnnotation.stories.tsx +6 -3
  19. package/src/_stories/ChartBar.Editor.stories.tsx +3580 -0
  20. package/src/_stories/ChartEditor.Editor.stories.tsx +658 -0
  21. package/src/_stories/ChartEditor.stories.tsx +1 -2
  22. package/src/_stories/_mock/combo.json +451 -0
  23. package/src/_stories/_mock/editor-test-configs.json +376 -0
  24. package/src/_stories/_mock/editor-test-datasets.json +477 -0
  25. package/src/_stories/_mock/editor-tests/bar-chart-editor-test.json +255 -0
  26. package/src/_stories/_mock/editor-tests/bar-chart-general-test.json +267 -0
  27. package/src/_stories/_mock/editor-tests/bar-chart-test.json +237 -0
  28. package/src/_stories/_mock/forecast_combo_with_gaps.json +913 -0
  29. package/src/_stories/_mock/pie_config.json +257 -62
  30. package/src/_stories/_mock/small_multiples/small_multiples_bars.json +1944 -0
  31. package/src/_stories/_mock/small_multiples/small_multiples_big_data_bars.json +1114 -0
  32. package/src/_stories/_mock/small_multiples/small_multiples_lines.json +2646 -0
  33. package/src/_stories/_mock/small_multiples/small_multiples_lines_colors.json +1305 -0
  34. package/src/_stories/_mock/small_multiples/small_multiples_stacked_bars.json +1936 -0
  35. package/src/components/Annotations/components/findNearestDatum.ts +6 -41
  36. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -6
  37. package/src/components/AreaChart/index.tsx +1 -2
  38. package/src/components/BarChart/components/BarChart.Horizontal.tsx +4 -4
  39. package/src/components/BarChart/components/BarChart.Vertical.tsx +3 -2
  40. package/src/components/BoxPlot/helpers/index.ts +3 -3
  41. package/src/components/Brush/BrushChart.tsx +1 -1
  42. package/src/components/EditorPanel/EditorPanel.tsx +199 -190
  43. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +96 -111
  44. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +19 -1
  45. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +102 -55
  46. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +54 -49
  47. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +422 -0
  48. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +75 -21
  49. package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
  50. package/src/components/EditorPanel/editor-panel.scss +0 -20
  51. package/src/components/EditorPanel/useEditorPermissions.ts +7 -15
  52. package/src/components/Forecasting/Forecasting.tsx +139 -21
  53. package/src/components/Legend/Legend.Component.tsx +16 -9
  54. package/src/components/Legend/helpers/createFormatLabels.tsx +181 -181
  55. package/src/components/Legend/helpers/getLegendClasses.ts +0 -1
  56. package/src/components/LineChart/LineChartProps.ts +0 -3
  57. package/src/components/LineChart/helpers.ts +1 -1
  58. package/src/components/LineChart/index.tsx +36 -13
  59. package/src/components/LinearChart.tsx +75 -80
  60. package/src/components/Regions/components/Regions.tsx +3 -24
  61. package/src/components/Sankey/types/index.ts +1 -1
  62. package/src/components/SmallMultiples/SmallMultipleTile.tsx +198 -0
  63. package/src/components/SmallMultiples/SmallMultiples.css +32 -0
  64. package/src/components/SmallMultiples/SmallMultiples.tsx +271 -0
  65. package/src/components/SmallMultiples/index.ts +2 -0
  66. package/src/data/initial-state.js +13 -1
  67. package/src/helpers/buildForecastPaletteOptions.ts +0 -38
  68. package/src/helpers/getColorScale.ts +10 -0
  69. package/src/{hooks/useMinMax.ts → helpers/getMinMax.ts} +14 -7
  70. package/src/helpers/getYAxisAutoPadding.ts +53 -0
  71. package/src/helpers/smallMultiplesHelpers.ts +529 -0
  72. package/src/hooks/useProgrammaticTooltip.ts +96 -0
  73. package/src/hooks/useScales.ts +88 -34
  74. package/src/hooks/useSmallMultipleSynchronization.ts +59 -0
  75. package/src/hooks/useTooltip.tsx +60 -15
  76. package/src/scss/main.scss +1 -80
  77. package/src/store/chart.actions.ts +2 -0
  78. package/src/store/chart.reducer.ts +4 -0
  79. package/src/types/ChartConfig.ts +24 -6
  80. package/src/types/ChartContext.ts +3 -0
  81. package/src/_stories/_mock/pie_data.json +0 -218
  82. package/src/components/AreaChart/components/AreaChart.jsx +0 -109
  83. package/src/helpers/sort.ts +0 -7
  84. package/src/hooks/useActiveElement.js +0 -19
  85. package/src/hooks/useChartClasses.js +0 -41
@@ -20,211 +20,211 @@ import _ from 'lodash'
20
20
 
21
21
  export const createFormatLabels =
22
22
  (config: ChartConfig, tableData: Object[], data: TransformedData[], colorScale: ColorScale) =>
23
- (defaultLabels: Label[]): Label[] => {
24
- const { visualizationType, visualizationSubType, series, runtime, legend } = config
25
- const sortVertical = labels =>
26
- legend.verticalSorted
27
- ? _.sortBy(_.cloneDeep(labels), label => {
23
+ (defaultLabels: Label[]): Label[] => {
24
+ const { visualizationType, visualizationSubType, series, runtime, legend } = config
25
+ const sortVertical = labels =>
26
+ legend.verticalSorted
27
+ ? _.sortBy(_.cloneDeep(labels), label => {
28
28
  const match = label.datum?.match(/-?\d+(\.\d+)?/)
29
29
  return match ? parseFloat(match[0]) : Number.MAX_SAFE_INTEGER
30
30
  })
31
- : labels
32
- const reverseLabels = labels => {
33
- if (config.series.some(series => series.dynamicCategory)) {
34
- return orderDynamicLabels(labels)
35
- }
31
+ : labels
32
+ const reverseLabels = labels => {
33
+ if (config.series.some(series => series.dynamicCategory)) {
34
+ return orderDynamicLabels(labels)
35
+ }
36
+
37
+ return config.legend.reverseLabelOrder ? sortVertical(labels).reverse() : sortVertical(labels)
38
+ }
39
+
40
+ const orderDynamicLabels = labels => {
41
+ // Handle different ordering configurations
42
+ switch (config.legend.order) {
43
+ case 'dataColumn':
44
+ return labels
45
+ case 'asc':
46
+ case 'desc':
47
+ return labels.sort((a, b) => {
48
+ const valA = a.datum || a.text
49
+ const valB = b.datum || b.text
50
+ const numA = parseFloat(valA)
51
+ const numB = parseFloat(valB)
52
+ if (!isNaN(numA) && !isNaN(numB)) {
53
+ return config.legend.order === 'asc' ? numA - numB : numB - numA
54
+ } else {
55
+ return config.legend.order === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA)
56
+ }
57
+ })
36
58
 
37
- return config.legend.reverseLabelOrder ? sortVertical(labels).reverse() : sortVertical(labels)
59
+ default:
60
+ return labels // Default case to handle any unexpected config.legend.order values
61
+ }
62
+ }
63
+ const colorCode = config.legend?.colorCode
64
+ if (visualizationType === 'Deviation Bar') {
65
+ let versionName = isV1Palette(config) ? 'v1' : 'v2'
66
+ const [belowColor, aboveColor] = twoColorPalette?.[versionName]?.[config.twoColor.palette] || [
67
+ '#1D6ABF',
68
+ '#935586'
69
+ ]
70
+
71
+ const labelBelow = {
72
+ datum: 'X',
73
+ index: 0,
74
+ text: `Below ${config.xAxis.targetLabel}`,
75
+ value: belowColor
76
+ }
77
+ const labelAbove = {
78
+ datum: 'X',
79
+ index: 1,
80
+ text: `Above ${config.xAxis.targetLabel}`,
81
+ value: aboveColor
38
82
  }
39
83
 
40
- const orderDynamicLabels = labels => {
41
- // Handle different ordering configurations
42
- switch (config.legend.order) {
43
- case 'dataColumn':
44
- return labels
45
- case 'asc':
46
- case 'desc':
47
- return labels.sort((a, b) => {
48
- const valA = a.datum || a.text
49
- const valB = b.datum || b.text
50
- const numA = parseFloat(valA)
51
- const numB = parseFloat(valB)
52
- if (!isNaN(numA) && !isNaN(numB)) {
53
- return config.legend.order === 'asc' ? numA - numB : numB - numA
54
- } else {
55
- return config.legend.order === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA)
56
- }
57
- })
58
-
59
- default:
60
- return labels // Default case to handle any unexpected config.legend.order values
84
+ return reverseLabels([labelBelow, labelAbove])
85
+ }
86
+ if (visualizationType === 'Bar' && visualizationSubType === 'regular' && colorCode && series?.length === 1) {
87
+ const currentPaletteName = getCurrentPaletteName(config) || getFallbackColorPalette(config)
88
+ const paletteName = migratePaletteWithMap(currentPaletteName, chartPaletteMigrationMap, true)
89
+ let palette = getPaletteAccessor(colorPalettes, config, paletteName)
90
+
91
+ const numberOfKeys = data.length
92
+
93
+ // Check if we should use v2 distribution logic for better contrast
94
+ const version = getColorPaletteVersion(config)
95
+ const isSequentialOrDivergent =
96
+ paletteName && (paletteName.includes('sequential') || paletteName.includes('divergent'))
97
+ const isPairedBarOrDeviation = ['Paired Bar', 'Deviation Bar'].includes(config.visualizationType)
98
+ const useV2Distribution =
99
+ version === 2 && isSequentialOrDivergent && palette.length === 9 && numberOfKeys <= 9 && !isPairedBarOrDeviation
100
+
101
+ if (useV2Distribution && v2ColorDistribution[numberOfKeys]) {
102
+ // Use strategic color distribution for v2 sequential palettes
103
+ const distributionIndices = v2ColorDistribution[numberOfKeys]
104
+ palette = distributionIndices.map(index => palette[index])
105
+ } else {
106
+ // Use existing logic for v1 palettes and other cases
107
+ while (tableData.length > palette?.length) {
108
+ palette = palette.concat(palette)
61
109
  }
110
+ palette = palette?.slice(0, data.length)
62
111
  }
63
- const colorCode = config.legend?.colorCode
64
- if (visualizationType === 'Deviation Bar') {
65
- let versionName = isV1Palette(config) ? 'v1' : 'v2'
66
- const [belowColor, aboveColor] = twoColorPalette?.[versionName]?.[config.twoColor.palette] || [
67
- '#1D6ABF',
68
- '#935586'
69
- ]
70
-
71
- const labelBelow = {
72
- datum: 'X',
73
- index: 0,
74
- text: `Below ${config.xAxis.targetLabel}`,
75
- value: belowColor
76
- }
77
- const labelAbove = {
78
- datum: 'X',
79
- index: 1,
80
- text: `Above ${config.xAxis.targetLabel}`,
81
- value: aboveColor
82
- }
112
+ //store unique values to Set by colorCode
113
+ const set = new Set()
83
114
 
84
- return reverseLabels([labelBelow, labelAbove])
85
- }
86
- if (visualizationType === 'Bar' && visualizationSubType === 'regular' && colorCode && series?.length === 1) {
87
- const currentPaletteName = getCurrentPaletteName(config) || getFallbackColorPalette(config)
88
- const paletteName = migratePaletteWithMap(currentPaletteName, chartPaletteMigrationMap, true)
89
- let palette = getPaletteAccessor(colorPalettes, config, paletteName)
90
-
91
- const numberOfKeys = data.length
92
-
93
- // Check if we should use v2 distribution logic for better contrast
94
- const version = getColorPaletteVersion(config)
95
- const isSequentialOrDivergent =
96
- paletteName && (paletteName.includes('sequential') || paletteName.includes('divergent'))
97
- const isPairedBarOrDeviation = ['Paired Bar', 'Deviation Bar'].includes(config.visualizationType)
98
- const useV2Distribution =
99
- version === 2 && isSequentialOrDivergent && palette.length === 9 && numberOfKeys <= 9 && !isPairedBarOrDeviation
100
-
101
- if (useV2Distribution && v2ColorDistribution[numberOfKeys]) {
102
- // Use strategic color distribution for v2 sequential palettes
103
- const distributionIndices = v2ColorDistribution[numberOfKeys]
104
- palette = distributionIndices.map(index => palette[index])
105
- } else {
106
- // Use existing logic for v1 palettes and other cases
107
- while (tableData.length > palette?.length) {
108
- palette = palette.concat(palette)
109
- }
110
- palette = palette?.slice(0, data.length)
115
+ tableData.forEach(d => set.add(d[colorCode]))
116
+
117
+ // create labels with unique values
118
+ const uniqueLabels = Array.from(set).map((val, i) => {
119
+ const newLabel = {
120
+ datum: val,
121
+ index: i,
122
+ text: val,
123
+ value: palette?.[i]
111
124
  }
112
- //store unique values to Set by colorCode
113
- const set = new Set()
125
+ return newLabel
126
+ })
114
127
 
115
- tableData.forEach(d => set.add(d[colorCode]))
128
+ return reverseLabels(uniqueLabels)
129
+ }
116
130
 
117
- // create labels with unique values
118
- const uniqueLabels = Array.from(set).map((val, i) => {
119
- const newLabel = {
120
- datum: val,
121
- index: i,
122
- text: val,
123
- value: palette?.[i]
131
+ // get forecasting items inside of combo
132
+ if (runtime?.forecastingSeriesKeys?.length > 0) {
133
+ let seriesLabels = []
134
+
135
+ // Create palette lookup map - use version-specific palettes
136
+ // Forecasting charts use sequentialPalettes for v1, sequential-only palettes for v2
137
+ const paletteVersion = getColorPaletteVersion(config)
138
+
139
+ let forecastPalettes
140
+ if (paletteVersion === 1) {
141
+ // V1: Use original sequential palettes
142
+ forecastPalettes = sequentialPalettes
143
+ } else {
144
+ // V2: Only use sequential palettes (filter out divergent and qualitative)
145
+ const allV2Palettes = colorPalettesChartV2
146
+ forecastPalettes = {}
147
+ Object.keys(allV2Palettes).forEach(key => {
148
+ if (key.startsWith('sequential')) {
149
+ forecastPalettes[key] = allV2Palettes[key]
124
150
  }
125
- return newLabel
126
151
  })
127
-
128
- return reverseLabels(uniqueLabels)
129
152
  }
130
153
 
131
- // get forecasting items inside of combo
132
- if (runtime?.forecastingSeriesKeys?.length > 0) {
133
- let seriesLabels = []
134
-
135
- // Create palette lookup map - use version-specific palettes
136
- // Forecasting charts use sequentialPalettes for v1, sequential-only palettes for v2
137
- const paletteVersion = getColorPaletteVersion(config)
138
-
139
- let forecastPalettes
140
- if (paletteVersion === 1) {
141
- // V1: Use original sequential palettes
142
- forecastPalettes = sequentialPalettes
143
- } else {
144
- // V2: Only use sequential palettes (filter out divergent and qualitative)
145
- const allV2Palettes = colorPalettesChartV2
146
- forecastPalettes = {}
147
- Object.keys(allV2Palettes).forEach(key => {
148
- if (key.startsWith('sequential')) {
149
- forecastPalettes[key] = allV2Palettes[key]
150
- }
151
- })
152
- }
154
+ const processedPalettes = updatePaletteNames(forecastPalettes)
155
+ const forecastingPalettes = buildForecastPaletteMappings(processedPalettes, paletteVersion)
153
156
 
154
- const processedPalettes = updatePaletteNames(forecastPalettes)
155
- const forecastingPalettes = buildForecastPaletteMappings(processedPalettes, paletteVersion)
156
-
157
- //store unique values to Set by colorCode
158
- // loop through each stage/group/area on the chart and create a label
159
- config.runtime?.forecastingSeriesKeys?.map((outerGroup, index) => {
160
- return outerGroup?.stages?.map((stage, index) => {
161
- const palette = forecastingPalettes[stage.color] || false
162
- let colorValue = palette?.[2] || '#ccc'
163
-
164
- const newLabel = {
165
- datum: stage.key,
166
- index: index,
167
- text: stage.key,
168
- value: colorValue
169
- }
157
+ //store unique values to Set by colorCode
158
+ // loop through each stage/group/area on the chart and create a label
159
+ config.runtime?.forecastingSeriesKeys?.map((outerGroup, index) => {
160
+ return outerGroup?.stages?.map((stage, index) => {
161
+ const palette = forecastingPalettes[stage.color] || false
162
+ let colorValue = palette?.[2] || '#ccc'
170
163
 
171
- seriesLabels.push(newLabel)
172
- })
164
+ const newLabel = {
165
+ datum: stage.key,
166
+ index: index,
167
+ text: stage.key,
168
+ value: colorValue
169
+ }
170
+
171
+ seriesLabels.push(newLabel)
173
172
  })
173
+ })
174
174
 
175
- // loop through bars for now to meet requirements.
176
- config.runtime.barSeriesKeys &&
177
- config.runtime.barSeriesKeys.forEach((bar, index) => {
178
- const currentPaletteName = getCurrentPaletteName(config) || getFallbackColorPalette(config)
179
- const migratedPaletteName = migratePaletteWithMap(currentPaletteName, chartPaletteMigrationMap, true)
180
- const palette = getPaletteAccessor(colorPalettes, config, migratedPaletteName)
181
- let colorValue = palette?.[index] || '#ccc'
182
-
183
- const newLabel = {
184
- datum: bar,
185
- index: index,
186
- text: bar,
187
- value: colorValue
188
- }
175
+ // loop through bars for now to meet requirements.
176
+ config.runtime.barSeriesKeys &&
177
+ config.runtime.barSeriesKeys.forEach((bar, index) => {
178
+ const currentPaletteName = getCurrentPaletteName(config) || getFallbackColorPalette(config)
179
+ const migratedPaletteName = migratePaletteWithMap(currentPaletteName, chartPaletteMigrationMap, true)
180
+ const palette = getPaletteAccessor(colorPalettes, config, migratedPaletteName)
181
+ let colorValue = palette?.[index] || '#ccc'
189
182
 
190
- seriesLabels.push(newLabel)
191
- })
183
+ const newLabel = {
184
+ datum: bar,
185
+ index: index,
186
+ text: bar,
187
+ value: colorValue
188
+ }
192
189
 
193
- return reverseLabels(seriesLabels)
194
- }
190
+ seriesLabels.push(newLabel)
191
+ })
195
192
 
196
- if (config.series.some(item => item.name)) {
197
- const uniqueLabels = Array.from(new Set(config.series.map(d => d.name || d.dataKey))).map((val, i) => ({
198
- datum: val,
199
- index: i,
200
- text: val,
201
- value: colorScale(val)
202
- }))
203
- return reverseLabels(uniqueLabels)
204
- }
193
+ return reverseLabels(seriesLabels)
194
+ }
205
195
 
206
- if (
207
- (config.visualizationType === 'Bar' || config.visualizationType === 'Combo') &&
208
- config.visualizationSubType === 'regular' &&
209
- config.suppressedData
210
- ) {
211
- const lastIndex = defaultLabels.length - 1
212
- let newLabels = []
213
-
214
- config.suppressedData?.forEach(({ label, icon }, index) => {
215
- if (label && icon) {
216
- const newLabel = {
217
- datum: label,
218
- index: lastIndex + index,
219
- text: label,
220
- icon: <FaStar color='#000' size={15} />
221
- }
222
- newLabels.push(newLabel)
223
- }
224
- })
196
+ if (config.series.some(item => item.name)) {
197
+ const uniqueLabels = Array.from(new Set(config.series.map(d => d.name || d.dataKey))).map((val, i) => ({
198
+ datum: val,
199
+ index: i,
200
+ text: val,
201
+ value: colorScale(val)
202
+ }))
203
+ return reverseLabels(uniqueLabels)
204
+ }
225
205
 
226
- return [...defaultLabels, ...newLabels]
227
- }
206
+ if (
207
+ (config.visualizationType === 'Bar' || config.visualizationType === 'Combo') &&
208
+ config.visualizationSubType === 'regular' &&
209
+ config.suppressedData
210
+ ) {
211
+ const lastIndex = defaultLabels.length - 1
212
+ let newLabels = []
213
+
214
+ config.suppressedData?.forEach(({ label, icon }, index) => {
215
+ if (label && icon) {
216
+ const newLabel = {
217
+ datum: label,
218
+ index: lastIndex + index,
219
+ text: label,
220
+ icon: <FaStar color='#000' size={15} />
221
+ }
222
+ newLabels.push(newLabel)
223
+ }
224
+ })
228
225
 
229
- return reverseLabels(defaultLabels)
226
+ return [...defaultLabels, ...newLabels]
230
227
  }
228
+
229
+ return reverseLabels(defaultLabels)
230
+ }
@@ -38,4 +38,3 @@ export const getLegendClasses = (config: ChartConfig) => {
38
38
  innerClasses
39
39
  }
40
40
  }
41
- export default getLegendClasses
@@ -21,9 +21,6 @@ export interface DataItem {
21
21
  [key: string]: any
22
22
  }
23
23
 
24
- export interface Config {
25
- preliminaryData: PreliminaryDataItem[] | []
26
- }
27
24
  export interface StyleProps {
28
25
  data: DataItem[]
29
26
  handleLineType: Function
@@ -210,7 +210,7 @@ const handleLastIndex = ({
210
210
  return result
211
211
  }
212
212
 
213
- export const handleMiddleIndices = ({
213
+ const handleMiddleIndices = ({
214
214
  data,
215
215
  seriesKey,
216
216
  preliminaryData,
@@ -79,6 +79,21 @@ const LineChart = (props: LineChartProps) => {
79
79
  ? data.filter(d => d[seriesData.dynamicCategory] === seriesKey)
80
80
  : data
81
81
  const circleData = filterCircles(config?.preliminaryData, tableData, _seriesKey)
82
+
83
+ // Prepare sorted data for line and area rendering
84
+ const sortedData =
85
+ config.visualizationType == 'Bump Chart'
86
+ ? _data
87
+ : config.xAxis.type === 'date-time' || config.xAxis.type === 'date'
88
+ ? _data.sort((d1, d2) => {
89
+ let x1 = getXAxisData(d1)
90
+ let x2 = getXAxisData(d2)
91
+ if (x1 < x2) return -1
92
+ if (x2 < x1) return 1
93
+ return 0
94
+ })
95
+ : _data
96
+
82
97
  return (
83
98
  <Group
84
99
  key={`series-${seriesKey}-${index}`}
@@ -310,19 +325,7 @@ const LineChart = (props: LineChartProps) => {
310
325
  {/* STANDARD LINE */}
311
326
  <LinePath
312
327
  curve={allCurves[seriesData.lineType]}
313
- data={
314
- config.visualizationType == 'Bump Chart'
315
- ? _data
316
- : config.xAxis.type === 'date-time' || config.xAxis.type === 'date'
317
- ? _data.sort((d1, d2) => {
318
- let x1 = getXAxisData(d1)
319
- let x2 = getXAxisData(d2)
320
- if (x1 < x2) return -1
321
- if (x2 < x1) return 1
322
- return 0
323
- })
324
- : _data
325
- }
328
+ data={sortedData}
326
329
  x={d => xPos(d)}
327
330
  y={d =>
328
331
  seriesAxis === 'Right'
@@ -338,6 +341,26 @@ const LineChart = (props: LineChartProps) => {
338
341
  return item[_seriesKey] !== '' && item[_seriesKey] !== null && item[_seriesKey] !== undefined
339
342
  }}
340
343
  />
344
+
345
+ {/* SHADED AREA UNDER LINE */}
346
+ {config.showAreaUnderLine && (
347
+ <AreaClosed
348
+ curve={allCurves[seriesData.lineType]}
349
+ data={sortedData}
350
+ x={d => xPos(d)}
351
+ y={d =>
352
+ seriesAxis === 'Right'
353
+ ? yScaleRight(getYAxisData(d, _seriesKey))
354
+ : yScale(Number(getYAxisData(d, _seriesKey)))
355
+ }
356
+ yScale={seriesAxis === 'Right' ? yScaleRight : yScale}
357
+ fill={colorScale(config.runtime.seriesLabels[seriesKey])}
358
+ fillOpacity={0.3}
359
+ defined={(item, i) => {
360
+ return item[_seriesKey] !== '' && item[_seriesKey] !== null && item[_seriesKey] !== undefined
361
+ }}
362
+ />
363
+ )}
341
364
  </>
342
365
  )}
343
366