@cdc/chart 4.25.8 → 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 (145) hide show
  1. package/.claude/settings.local.json +9 -0
  2. package/dist/{cdcchart-1a1724a1.es.js → cdcchart-dgT_1dIT.es.js} +136 -151
  3. package/dist/cdcchart.js +44236 -40355
  4. package/examples/feature/__data__/planet-example-data.json +0 -30
  5. package/examples/feature/boxplot/valid-boxplot.csv +38 -17
  6. package/examples/grouped-bar-test.json +400 -0
  7. package/examples/private/DEV-11825.json +573 -0
  8. package/examples/private/d.json +382 -0
  9. package/examples/private/example-2.json +49784 -0
  10. package/examples/private/f2.json +1 -0
  11. package/examples/private/f4.json +1577 -0
  12. package/examples/private/forecast.json +1180 -0
  13. package/examples/private/lollipop.json +468 -0
  14. package/examples/private/na.json +913 -0
  15. package/examples/private/new.json +48756 -0
  16. package/examples/private/pie-chart-legend.json +904 -0
  17. package/examples/private/test-data.csv +28 -0
  18. package/examples/suppressed_tooltip.json +480 -0
  19. package/index.html +2 -133
  20. package/package.json +25 -7
  21. package/src/CdcChart.tsx +9 -13
  22. package/src/CdcChartComponent.tsx +403 -92
  23. package/src/_stories/Chart.Anchors.stories.tsx +2 -2
  24. package/src/_stories/Chart.BoxPlot.stories.tsx +1 -1
  25. package/src/_stories/Chart.CI.stories.tsx +1 -1
  26. package/src/_stories/Chart.Combo.stories.tsx +18 -0
  27. package/src/_stories/Chart.CustomColors.stories.tsx +1 -1
  28. package/src/_stories/Chart.DynamicSeries.stories.tsx +2 -2
  29. package/src/_stories/Chart.Filters.stories.tsx +2 -2
  30. package/src/_stories/Chart.Forecast.stories.tsx +36 -0
  31. package/src/_stories/Chart.HTMLInDataTable.stories.tsx +520 -0
  32. package/src/_stories/Chart.Legend.Gradient.stories.tsx +2 -2
  33. package/src/_stories/Chart.Patterns.stories.tsx +20 -0
  34. package/src/_stories/Chart.PreserveDecimals.stories.tsx +220 -0
  35. package/src/_stories/Chart.ScatterPlot.stories.tsx +1 -1
  36. package/src/_stories/Chart.SmallMultiples.stories.tsx +47 -0
  37. package/src/_stories/Chart.stories.tsx +8 -5
  38. package/src/_stories/Chart.tooltip.stories.tsx +1 -1
  39. package/src/_stories/ChartAnnotation.stories.tsx +7 -4
  40. package/src/_stories/ChartAxisLabels.stories.tsx +2 -2
  41. package/src/_stories/ChartAxisTitles.stories.tsx +2 -2
  42. package/src/_stories/ChartBar.Editor.stories.tsx +3580 -0
  43. package/src/_stories/ChartEditor.Editor.stories.tsx +658 -0
  44. package/src/_stories/ChartEditor.stories.tsx +59 -60
  45. package/src/_stories/ChartLine.Suppression.stories.tsx +1 -1
  46. package/src/_stories/ChartLine.Symbols.stories.tsx +1 -1
  47. package/src/_stories/ChartPrefixSuffix.stories.tsx +2 -2
  48. package/src/_stories/_mock/combo.json +451 -0
  49. package/src/_stories/_mock/editor-test-configs.json +376 -0
  50. package/src/_stories/_mock/editor-test-datasets.json +477 -0
  51. package/src/_stories/_mock/editor-tests/bar-chart-editor-test.json +255 -0
  52. package/src/_stories/_mock/editor-tests/bar-chart-general-test.json +267 -0
  53. package/src/_stories/_mock/editor-tests/bar-chart-test.json +237 -0
  54. package/src/_stories/_mock/forecast_combo_with_gaps.json +913 -0
  55. package/src/_stories/_mock/pie_config.json +257 -62
  56. package/src/_stories/_mock/small_multiples/small_multiples_bars.json +1944 -0
  57. package/src/_stories/_mock/small_multiples/small_multiples_big_data_bars.json +1114 -0
  58. package/src/_stories/_mock/small_multiples/small_multiples_lines.json +2646 -0
  59. package/src/_stories/_mock/small_multiples/small_multiples_lines_colors.json +1305 -0
  60. package/src/_stories/_mock/small_multiples/small_multiples_stacked_bars.json +1936 -0
  61. package/src/_stories/_mock/stacked-pattern-test.json +520 -0
  62. package/src/components/Annotations/components/AnnotationDraggable.tsx +1 -0
  63. package/src/components/Annotations/components/AnnotationDropdown.tsx +1 -1
  64. package/src/components/Annotations/components/findNearestDatum.ts +6 -41
  65. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -6
  66. package/src/components/AreaChart/index.tsx +1 -2
  67. package/src/components/BarChart/components/BarChart.Horizontal.tsx +161 -22
  68. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +138 -5
  69. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +215 -73
  70. package/src/components/BarChart/components/BarChart.Vertical.tsx +155 -22
  71. package/src/components/BarChart/helpers/index.ts +43 -4
  72. package/src/components/BarChart/helpers/lollipopColors.ts +27 -0
  73. package/src/components/BarChart/helpers/useBarChart.ts +25 -3
  74. package/src/components/BoxPlot/BoxPlot.Vertical.tsx +2 -1
  75. package/src/components/BoxPlot/helpers/index.ts +3 -3
  76. package/src/components/Brush/BrushChart.tsx +1 -1
  77. package/src/components/DeviationBar.jsx +9 -6
  78. package/src/components/EditorPanel/EditorPanel.tsx +563 -229
  79. package/src/components/EditorPanel/EditorPanelContext.ts +3 -0
  80. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +96 -111
  81. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +19 -1
  82. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +461 -0
  83. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +80 -67
  84. package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +422 -0
  85. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +188 -139
  86. package/src/components/EditorPanel/components/Panels/index.tsx +5 -1
  87. package/src/components/EditorPanel/components/Panels/panelVisual.styles.css +0 -8
  88. package/src/components/EditorPanel/editor-panel.scss +0 -20
  89. package/src/components/EditorPanel/helpers/updateFieldRankByValue.ts +49 -48
  90. package/src/components/EditorPanel/useEditorPermissions.ts +7 -15
  91. package/src/components/Forecasting/Forecasting.tsx +175 -27
  92. package/src/components/ForestPlot/ForestPlot.tsx +11 -7
  93. package/src/components/ForestPlot/ForestPlotProps.ts +1 -1
  94. package/src/components/Legend/Legend.Component.tsx +114 -14
  95. package/src/components/Legend/helpers/createFormatLabels.tsx +230 -171
  96. package/src/components/Legend/helpers/getLegendClasses.ts +0 -1
  97. package/src/components/LegendWrapper.tsx +1 -1
  98. package/src/components/LineChart/LineChartProps.ts +0 -3
  99. package/src/components/LineChart/components/LineChart.Circle.tsx +2 -2
  100. package/src/components/LineChart/helpers.ts +1 -1
  101. package/src/components/LineChart/index.tsx +38 -15
  102. package/src/components/LinearChart.tsx +96 -84
  103. package/src/components/PairedBarChart.jsx +6 -4
  104. package/src/components/PieChart/PieChart.tsx +170 -54
  105. package/src/components/Regions/components/Regions.tsx +3 -24
  106. package/src/components/Sankey/components/Sankey.tsx +7 -1
  107. package/src/components/Sankey/types/index.ts +1 -1
  108. package/src/components/ScatterPlot/ScatterPlot.jsx +32 -4
  109. package/src/components/SmallMultiples/SmallMultipleTile.tsx +198 -0
  110. package/src/components/SmallMultiples/SmallMultiples.css +32 -0
  111. package/src/components/SmallMultiples/SmallMultiples.tsx +271 -0
  112. package/src/components/SmallMultiples/index.ts +2 -0
  113. package/src/data/initial-state.js +327 -293
  114. package/src/helpers/buildForecastPaletteMappings.ts +112 -0
  115. package/src/helpers/buildForecastPaletteOptions.ts +71 -0
  116. package/src/helpers/getColorScale.ts +82 -8
  117. package/src/{hooks/useMinMax.ts → helpers/getMinMax.ts} +14 -7
  118. package/src/helpers/getNewRuntime.ts +1 -1
  119. package/src/helpers/getTransformedData.ts +1 -1
  120. package/src/helpers/getYAxisAutoPadding.ts +53 -0
  121. package/src/helpers/smallMultiplesHelpers.ts +529 -0
  122. package/src/hooks/useChartHoverAnalytics.tsx +44 -0
  123. package/src/hooks/useProgrammaticTooltip.ts +96 -0
  124. package/src/hooks/useReduceData.ts +105 -70
  125. package/src/hooks/useScales.ts +88 -34
  126. package/src/hooks/useSmallMultipleSynchronization.ts +59 -0
  127. package/src/hooks/useTooltip.tsx +116 -29
  128. package/src/index.jsx +0 -2
  129. package/src/scss/main.scss +13 -80
  130. package/src/store/chart.actions.ts +2 -0
  131. package/src/store/chart.reducer.ts +5 -1
  132. package/src/test/CdcChart.test.jsx +8 -3
  133. package/src/types/ChartConfig.ts +53 -11
  134. package/src/types/ChartContext.ts +4 -0
  135. package/vite.config.js +1 -1
  136. package/vitest.config.ts +16 -0
  137. package/src/_stories/_mock/pie_data.json +0 -218
  138. package/src/components/AreaChart/components/AreaChart.jsx +0 -109
  139. package/src/coreStyles_chart.scss +0 -3
  140. package/src/helpers/configHelpers.ts +0 -28
  141. package/src/helpers/generateColorsArray.ts +0 -8
  142. package/src/helpers/sort.ts +0 -7
  143. package/src/hooks/useActiveElement.js +0 -19
  144. package/src/hooks/useChartClasses.js +0 -41
  145. package/src/hooks/useColorPalette.js +0 -76
@@ -1,171 +1,230 @@
1
- import { colorPalettesChart as colorPalettes, sequentialPalettes, twoColorPalette } from '@cdc/core/data/colorPalettes'
2
- import { FaStar } from 'react-icons/fa'
3
- import { Label } from '../../../types/Label'
4
- import { ColorScale, TransformedData } from '../../../types/ChartContext'
5
- import { ChartConfig } from '../../../types/ChartConfig'
6
- import _ from 'lodash'
7
-
8
- export const createFormatLabels =
9
- (config: ChartConfig, tableData: Object[], data: TransformedData[], colorScale: ColorScale) =>
10
- (defaultLabels: Label[]): Label[] => {
11
- const { visualizationType, visualizationSubType, series, runtime, legend } = config
12
- const sortVertical = labels =>
13
- legend.verticalSorted
14
- ? _.sortBy(_.cloneDeep(labels), label => {
15
- const match = label.datum?.match(/-?\d+(\.\d+)?/)
16
- return match ? parseFloat(match[0]) : Number.MAX_SAFE_INTEGER
17
- })
18
- : labels
19
- const reverseLabels = labels => {
20
- if (config.series.some(series => series.dynamicCategory)) {
21
- return orderDynamicLabels(labels)
22
- }
23
-
24
- return config.legend.reverseLabelOrder ? sortVertical(labels).reverse() : sortVertical(labels)
25
- }
26
-
27
- const orderDynamicLabels = labels => {
28
- // Handle different ordering configurations
29
- switch (config.legend.order) {
30
- case 'dataColumn':
31
- return labels
32
- case 'asc':
33
- case 'desc':
34
- return labels.sort((a, b) => {
35
- const valA = a.datum || a.text
36
- const valB = b.datum || b.text
37
- const numA = parseFloat(valA)
38
- const numB = parseFloat(valB)
39
- if (!isNaN(numA) && !isNaN(numB)) {
40
- return config.legend.order === 'asc' ? numA - numB : numB - numA
41
- } else {
42
- return config.legend.order === 'asc' ? valA.localeCompare(valB) : valB.localeCompare(valA)
43
- }
44
- })
45
-
46
- default:
47
- return labels // Default case to handle any unexpected config.legend.order values
48
- }
49
- }
50
- const colorCode = config.legend?.colorCode
51
- if (visualizationType === 'Deviation Bar') {
52
- const [belowColor, aboveColor] = twoColorPalette[config.twoColor.palette]
53
- const labelBelow = {
54
- datum: 'X',
55
- index: 0,
56
- text: `Below ${config.xAxis.targetLabel}`,
57
- value: belowColor
58
- }
59
- const labelAbove = {
60
- datum: 'X',
61
- index: 1,
62
- text: `Above ${config.xAxis.targetLabel}`,
63
- value: aboveColor
64
- }
65
-
66
- return reverseLabels([labelBelow, labelAbove])
67
- }
68
- if (visualizationType === 'Bar' && visualizationSubType === 'regular' && colorCode && series?.length === 1) {
69
- let palette = colorPalettes[config.palette]
70
-
71
- while (tableData.length > palette.length) {
72
- palette = palette.concat(palette)
73
- }
74
- palette = palette.slice(0, data.length)
75
- //store unique values to Set by colorCode
76
- const set = new Set()
77
-
78
- tableData.forEach(d => set.add(d[colorCode]))
79
-
80
- // create labels with unique values
81
- const uniqueLabels = Array.from(set).map((val, i) => {
82
- const newLabel = {
83
- datum: val,
84
- index: i,
85
- text: val,
86
- value: palette[i]
87
- }
88
- return newLabel
89
- })
90
-
91
- return reverseLabels(uniqueLabels)
92
- }
93
-
94
- // get forecasting items inside of combo
95
- if (runtime?.forecastingSeriesKeys?.length > 0) {
96
- let seriesLabels = []
97
-
98
- //store unique values to Set by colorCode
99
- // loop through each stage/group/area on the chart and create a label
100
- config.runtime?.forecastingSeriesKeys?.map((outerGroup, index) => {
101
- return outerGroup?.stages?.map((stage, index) => {
102
- let colorValue = sequentialPalettes[stage.color]?.[2]
103
- ? sequentialPalettes[stage.color]?.[2]
104
- : colorPalettes[stage.color]?.[2]
105
- ? colorPalettes[stage.color]?.[2]
106
- : '#ccc'
107
-
108
- const newLabel = {
109
- datum: stage.key,
110
- index: index,
111
- text: stage.key,
112
- value: colorValue
113
- }
114
-
115
- seriesLabels.push(newLabel)
116
- })
117
- })
118
-
119
- // loop through bars for now to meet requirements.
120
- config.runtime.barSeriesKeys &&
121
- config.runtime.barSeriesKeys.forEach((bar, index) => {
122
- let colorValue = colorPalettes[config.palette][index] ? colorPalettes[config.palette][index] : '#ccc'
123
-
124
- const newLabel = {
125
- datum: bar,
126
- index: index,
127
- text: bar,
128
- value: colorValue
129
- }
130
-
131
- seriesLabels.push(newLabel)
132
- })
133
-
134
- return reverseLabels(seriesLabels)
135
- }
136
-
137
- if (config.series.some(item => item.name)) {
138
- const uniqueLabels = Array.from(new Set(config.series.map(d => d.name || d.dataKey))).map((val, i) => ({
139
- datum: val,
140
- index: i,
141
- text: val,
142
- value: colorScale(val)
143
- }))
144
- return reverseLabels(uniqueLabels)
145
- }
146
-
147
- if (
148
- (config.visualizationType === 'Bar' || config.visualizationType === 'Combo') &&
149
- config.visualizationSubType === 'regular' &&
150
- config.suppressedData
151
- ) {
152
- const lastIndex = defaultLabels.length - 1
153
- let newLabels = []
154
-
155
- config.suppressedData?.forEach(({ label, icon }, index) => {
156
- if (label && icon) {
157
- const newLabel = {
158
- datum: label,
159
- index: lastIndex + index,
160
- text: label,
161
- icon: <FaStar color='#000' size={15} />
162
- }
163
- newLabels.push(newLabel)
164
- }
165
- })
166
-
167
- return [...defaultLabels, ...newLabels]
168
- }
169
-
170
- return reverseLabels(defaultLabels)
171
- }
1
+ import {
2
+ colorPalettesChart as colorPalettes,
3
+ colorPalettesChartV2,
4
+ sequentialPalettes,
5
+ twoColorPalette
6
+ } from '@cdc/core/data/colorPalettes'
7
+ import { getCurrentPaletteName, getFallbackColorPalette, migratePaletteWithMap } from '@cdc/core/helpers/palettes/utils'
8
+ import { chartPaletteMigrationMap } from '@cdc/core/helpers/palettes/migratePaletteName'
9
+ import { getPaletteAccessor } from '@cdc/core/helpers/getPaletteAccessor'
10
+ import { getColorPaletteVersion } from '@cdc/core/helpers/getColorPaletteVersion'
11
+ import { isV1Palette } from '@cdc/core/helpers/palettes/utils'
12
+ import { v2ColorDistribution } from '@cdc/core/helpers/palettes/colorDistributions'
13
+ import { updatePaletteNames } from '@cdc/core/helpers/updatePaletteNames'
14
+ import { buildForecastPaletteMappings } from '../../../helpers/buildForecastPaletteMappings'
15
+ import { FaStar } from 'react-icons/fa'
16
+ import { Label } from '../../../types/Label'
17
+ import { ColorScale, TransformedData } from '../../../types/ChartContext'
18
+ import { ChartConfig } from '../../../types/ChartConfig'
19
+ import _ from 'lodash'
20
+
21
+ export const createFormatLabels =
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 => {
28
+ const match = label.datum?.match(/-?\d+(\.\d+)?/)
29
+ return match ? parseFloat(match[0]) : Number.MAX_SAFE_INTEGER
30
+ })
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
+ })
58
+
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
82
+ }
83
+
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)
111
+ }
112
+ //store unique values to Set by colorCode
113
+ const set = new Set()
114
+
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]
124
+ }
125
+ return newLabel
126
+ })
127
+
128
+ return reverseLabels(uniqueLabels)
129
+ }
130
+
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
+ }
153
+
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
+ }
170
+
171
+ seriesLabels.push(newLabel)
172
+ })
173
+ })
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
+ }
189
+
190
+ seriesLabels.push(newLabel)
191
+ })
192
+
193
+ return reverseLabels(seriesLabels)
194
+ }
195
+
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
+ }
205
+
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
+ })
225
+
226
+ return [...defaultLabels, ...newLabels]
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
@@ -22,7 +22,7 @@ const LegendWrapper: React.FC<LegendWrapperProps> = props => {
22
22
  return classes.join(' ')
23
23
  }
24
24
 
25
- return <div className={getLegendWrappingClasses()}>{...children}</div>
25
+ return <div className={getLegendWrappingClasses()}>{children}</div>
26
26
  }
27
27
 
28
28
  export default LegendWrapper
@@ -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
@@ -105,7 +105,7 @@ const LineChartCircle = (props: LineChartCircleProps) => {
105
105
  <g
106
106
  transform={transformShape(pointData[config.xAxis.dataKey], pointData[filtered?.dataKey])}
107
107
  className={`visx-glyph-group${displayArea ? '' : '-hidden'}`}
108
- data-seriesIndex={seriesIndex}
108
+ data-seriesindex={seriesIndex}
109
109
  >
110
110
  <Shape
111
111
  fillOpacity={mode === 'ALWAYS_SHOW_POINTS' ? 1 : 0}
@@ -142,7 +142,7 @@ const LineChartCircle = (props: LineChartCircleProps) => {
142
142
  <g
143
143
  transform={transformShape(pointData[config.xAxis?.dataKey], pointData[filtered?.dataKey])}
144
144
  className={`visx-glyph-group${displayArea ? '' : '-hidden'}`}
145
- data-seriesIndex={seriesIndex}
145
+ data-seriesindex={seriesIndex}
146
146
  >
147
147
  <Shape size={dotSize} stroke={color} fill={color} />
148
148
  </g>
@@ -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}`}
@@ -228,10 +243,10 @@ const LineChart = (props: LineChartProps) => {
228
243
  />
229
244
 
230
245
  {suppressedSegments.map((segment, index) => {
231
- return Object.entries(segment.data).map(([key, value]) => {
246
+ return Object.entries(segment.data).map(([key, value], entryIndex) => {
232
247
  return (
233
248
  <LinePath
234
- key={index}
249
+ key={`${index}-${key}-${entryIndex}`}
235
250
  data={value}
236
251
  x={d => xPos(d)}
237
252
  y={d =>
@@ -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