Skip to content

Commit ee63a70

Browse files
authored
fix: rounding values on stacked w percentage charts (#1039)
Due to floating-point errors, values computed on a stack could fall out of the currently defined domain boundaries. This, in particular, causes issues with the percent stack mode, where the domain is hardcoded to [0,1] and some value can fall outside that domain.
1 parent be9bea0 commit ee63a70

8 files changed

Lines changed: 4742 additions & 28 deletions

.playground/tsconfig.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"extends": "../tsconfig",
33
"compilerOptions": {
44
"downlevelIteration": true,
5-
"target": "es5"
5+
"target": "es5",
6+
"resolveJsonModule": true
67
},
78
"include": ["../src/**/*", "./**/*"],
89
"exclude": ["../**/*.test.*"]
Loading
20 KB
Loading

src/chart_types/xy_chart/utils/stacked_series_utils.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929

3030
import { SeriesKey } from '../../../common/series_id';
3131
import { ScaleType } from '../../../scales/constants';
32+
import { clamp } from '../../../utils/common';
3233
import { DataSeries, DataSeriesDatum } from './series';
3334
import { StackMode } from './specs';
3435

@@ -137,8 +138,14 @@ export function formatStackedDataSeriesValues(
137138
const { initialY0, initialY1, mark, datum, filled } = originalData;
138139
return {
139140
x,
140-
y1,
141-
y0,
141+
/**
142+
* Due to floating point errors, values computed on a stack
143+
* could falls out of the current defined domain boundaries.
144+
* This in particular cause issues with percent stack, where the domain
145+
* is hardcoded to [0,1] and some value can fall outside that domain.
146+
*/
147+
y1: clampIfStackedAsPercentage(y1, stackMode),
148+
y0: clampIfStackedAsPercentage(y0, stackMode),
142149
initialY0,
143150
initialY1,
144151
mark,
@@ -154,6 +161,10 @@ export function formatStackedDataSeriesValues(
154161
});
155162
}
156163

164+
function clampIfStackedAsPercentage(value: number, stackMode?: StackMode) {
165+
return stackMode === StackMode.Percentage ? clamp(value, 0, 1) : value;
166+
}
167+
157168
function getOffsetBasedOnStackMode(stackMode?: StackMode) {
158169
switch (stackMode) {
159170
case StackMode.Percentage:

src/utils/common.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ export function compareByValueAsc(a: number | string, b: number | string): numbe
126126
return a > b ? 1 : -1;
127127
}
128128

129+
export function clamp(value: number, lowerBound: number, upperBound: number) {
130+
return minValueWithLowerLimit(value, upperBound, lowerBound);
131+
}
132+
129133
/**
130134
* Return the minimum value between val1 and val2. The value is bounded from below by lowerLimit
131135
* @param val1 a numeric value

0 commit comments

Comments
 (0)