Skip to content

Commit 27b9582

Browse files
committed
fix(rose): clamp the area-proportion radicand against negative cumulatives
Difference-style comparisons can drive the running total negative, which turned the area-mode sqrt into a NaN radius. Clamp the radicand at 0 so a negative cumulative collapses to the center instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent cc3d49c commit 27b9582

2 files changed

Lines changed: 25 additions & 1 deletion

File tree

superset-frontend/plugins/plugin-chart-echarts/src/Rose/transformProps.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,12 @@ export default function transformProps(
9292
let previousOuter = 0;
9393
const entries = (datum[time] ?? []).map(entry => {
9494
cumulative += entry.value;
95+
// Area encoding is undefined for a negative cumulative (possible
96+
// with difference-style comparisons); clamp the radicand at 0 so a
97+
// negative running total collapses to the center rather than
98+
// producing a NaN radius.
9599
const outer = roseAreaProportion
96-
? Math.sqrt(cumulative / maxSum)
100+
? Math.sqrt(Math.max(0, cumulative / maxSum))
97101
: cumulative;
98102
const increment = outer - previousOuter;
99103
previousOuter = outer;

superset-frontend/plugins/plugin-chart-echarts/test/Rose/transformProps.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,23 @@ test('handles empty results without crashing', () => {
149149
expect(periods).toEqual([]);
150150
expect((echartOptions as any).series).toEqual([]);
151151
});
152+
153+
test('area proportion clamps negative cumulatives instead of yielding NaN', () => {
154+
// difference-style comparisons can produce negative values
155+
const negatives = [
156+
{ __timestamp: T1, 'sum__num, East': -30, 'sum__num, West': 10 },
157+
];
158+
const props = new ChartProps({
159+
width: 800,
160+
height: 600,
161+
formData: { ...formData, roseAreaProportion: true },
162+
theme: supersetTheme,
163+
queriesData: [{ data: negatives }],
164+
hooks: {},
165+
}) as unknown as EchartsRoseChartProps;
166+
const { echartOptions } = transformProps(props);
167+
const { series } = echartOptions as any;
168+
series.forEach((s: any) =>
169+
s.data.forEach((d: any) => expect(Number.isNaN(d.value)).toBe(false)),
170+
);
171+
});

0 commit comments

Comments
 (0)