@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.
- package/dist/{cdcchart-1a1724a1.es.js → cdcchart-dgT_1dIT.es.js} +136 -151
- package/dist/cdcchart.js +36258 -34658
- package/examples/feature/__data__/planet-example-data.json +1 -1
- package/examples/feature/boxplot/valid-boxplot.csv +38 -17
- package/examples/private/DEV-11825.json +573 -0
- package/examples/private/na.json +913 -0
- package/examples/private/test-data.csv +28 -0
- package/index.html +2 -121
- package/package.json +4 -4
- package/src/CdcChart.tsx +8 -11
- package/src/CdcChartComponent.tsx +256 -87
- package/src/_stories/Chart.Combo.stories.tsx +18 -0
- package/src/_stories/Chart.Forecast.stories.tsx +36 -0
- package/src/_stories/Chart.HTMLInDataTable.stories.tsx +520 -0
- package/src/_stories/Chart.Patterns.stories.tsx +2 -1
- package/src/_stories/Chart.PreserveDecimals.stories.tsx +220 -0
- package/src/_stories/Chart.SmallMultiples.stories.tsx +47 -0
- package/src/_stories/ChartAnnotation.stories.tsx +6 -3
- package/src/_stories/ChartBar.Editor.stories.tsx +3580 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +658 -0
- package/src/_stories/ChartEditor.stories.tsx +1 -2
- package/src/_stories/_mock/combo.json +451 -0
- package/src/_stories/_mock/editor-test-configs.json +376 -0
- package/src/_stories/_mock/editor-test-datasets.json +477 -0
- package/src/_stories/_mock/editor-tests/bar-chart-editor-test.json +255 -0
- package/src/_stories/_mock/editor-tests/bar-chart-general-test.json +267 -0
- package/src/_stories/_mock/editor-tests/bar-chart-test.json +237 -0
- package/src/_stories/_mock/forecast_combo_with_gaps.json +913 -0
- package/src/_stories/_mock/pie_config.json +257 -62
- package/src/_stories/_mock/small_multiples/small_multiples_bars.json +1944 -0
- package/src/_stories/_mock/small_multiples/small_multiples_big_data_bars.json +1114 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +2646 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines_colors.json +1305 -0
- package/src/_stories/_mock/small_multiples/small_multiples_stacked_bars.json +1936 -0
- package/src/components/Annotations/components/findNearestDatum.ts +6 -41
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -6
- package/src/components/AreaChart/index.tsx +1 -2
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +4 -4
- package/src/components/BarChart/components/BarChart.Vertical.tsx +3 -2
- package/src/components/BoxPlot/helpers/index.ts +3 -3
- package/src/components/Brush/BrushChart.tsx +1 -1
- package/src/components/EditorPanel/EditorPanel.tsx +199 -190
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +96 -111
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +19 -1
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +102 -55
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +54 -49
- package/src/components/EditorPanel/components/Panels/Panel.SmallMultiples.tsx +422 -0
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +75 -21
- package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
- package/src/components/EditorPanel/editor-panel.scss +0 -20
- package/src/components/EditorPanel/useEditorPermissions.ts +7 -15
- package/src/components/Forecasting/Forecasting.tsx +139 -21
- package/src/components/Legend/Legend.Component.tsx +16 -9
- package/src/components/Legend/helpers/createFormatLabels.tsx +181 -181
- package/src/components/Legend/helpers/getLegendClasses.ts +0 -1
- package/src/components/LineChart/LineChartProps.ts +0 -3
- package/src/components/LineChart/helpers.ts +1 -1
- package/src/components/LineChart/index.tsx +36 -13
- package/src/components/LinearChart.tsx +75 -80
- package/src/components/Regions/components/Regions.tsx +3 -24
- package/src/components/Sankey/types/index.ts +1 -1
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +198 -0
- package/src/components/SmallMultiples/SmallMultiples.css +32 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +271 -0
- package/src/components/SmallMultiples/index.ts +2 -0
- package/src/data/initial-state.js +13 -1
- package/src/helpers/buildForecastPaletteOptions.ts +0 -38
- package/src/helpers/getColorScale.ts +10 -0
- package/src/{hooks/useMinMax.ts → helpers/getMinMax.ts} +14 -7
- package/src/helpers/getYAxisAutoPadding.ts +53 -0
- package/src/helpers/smallMultiplesHelpers.ts +529 -0
- package/src/hooks/useProgrammaticTooltip.ts +96 -0
- package/src/hooks/useScales.ts +88 -34
- package/src/hooks/useSmallMultipleSynchronization.ts +59 -0
- package/src/hooks/useTooltip.tsx +60 -15
- package/src/scss/main.scss +1 -80
- package/src/store/chart.actions.ts +2 -0
- package/src/store/chart.reducer.ts +4 -0
- package/src/types/ChartConfig.ts +24 -6
- package/src/types/ChartContext.ts +3 -0
- package/src/_stories/_mock/pie_data.json +0 -218
- package/src/components/AreaChart/components/AreaChart.jsx +0 -109
- package/src/helpers/sort.ts +0 -7
- package/src/hooks/useActiveElement.js +0 -19
- 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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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
|
-
|
|
113
|
-
|
|
125
|
+
return newLabel
|
|
126
|
+
})
|
|
114
127
|
|
|
115
|
-
|
|
128
|
+
return reverseLabels(uniqueLabels)
|
|
129
|
+
}
|
|
116
130
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
132
|
-
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
-
|
|
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
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
191
|
-
|
|
183
|
+
const newLabel = {
|
|
184
|
+
datum: bar,
|
|
185
|
+
index: index,
|
|
186
|
+
text: bar,
|
|
187
|
+
value: colorValue
|
|
188
|
+
}
|
|
192
189
|
|
|
193
|
-
|
|
194
|
-
|
|
190
|
+
seriesLabels.push(newLabel)
|
|
191
|
+
})
|
|
195
192
|
|
|
196
|
-
|
|
197
|
-
|
|
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
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
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
|
|
226
|
+
return [...defaultLabels, ...newLabels]
|
|
230
227
|
}
|
|
228
|
+
|
|
229
|
+
return reverseLabels(defaultLabels)
|
|
230
|
+
}
|
|
@@ -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
|
|