Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,13 @@ export function transformSeries(
return formatter(numericValue);
}
if (!onlyTotal) {
// A zero value occupies no space in a stacked series, so its label
// would render on top of the adjacent segment's label. Skip it
// regardless of the threshold.
if (
numericValue !== 0 &&
numericValue >=
(thresholdValues[dataIndex] || Number.MIN_SAFE_INTEGER)
(thresholdValues[dataIndex] || Number.MIN_SAFE_INTEGER)
) {
Comment on lines 473 to 477

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The zero-value guard is reached for non-stacked series when legendState marks the series as unselected, because those series bypass the earlier !stack && isSelectedLegend branch. This changes the existing behavior and suppresses zero labels even though the overlap problem only applies to stacked segments. Restrict the zero suppression to stacked series or preserve the non-stacked label path. [incorrect condition logic]

Severity Level: Minor 🧹
- ⚠️ Isolated unstacked series can lose zero-value labels.
- ⚠️ Legend double-click filtering affects label rendering.
- ⚠️ Stacked-chart overlap fix changes unstacked chart behavior.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformers.ts
**Line:** 473:477
**Comment:**
	*Incorrect Condition Logic: The zero-value guard is reached for non-stacked series when `legendState` marks the series as unselected, because those series bypass the earlier `!stack && isSelectedLegend` branch. This changes the existing behavior and suppresses zero labels even though the overlap problem only applies to stacked segments. Restrict the zero suppression to stacked series or preserve the non-stacked label path.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

return formatter(numericValue);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ import { supersetTheme } from '@apache-superset/core/theme';
import type { SeriesOption } from 'echarts';
import type { ScatterSeriesOption } from 'echarts/charts';
import { EchartsTimeseriesSeriesType } from '../../src';
import { TIMESERIES_CONSTANTS } from '../../src/constants';
import {
TIMESERIES_CONSTANTS,
StackControlsValue,
} from '../../src/constants';
import {
LegendOrientation,
EchartsTimeseriesChartProps,
Expand Down Expand Up @@ -87,6 +90,70 @@ describe('transformSeries', () => {
);
});

describe('stacked value labels', () => {
// Two series stacked on one category: A is 32, B is 0. The zero-height
// B segment must not render a label over A's label.
const buildFormatter = (thresholdValues: number[]) => {
const result = transformSeries(series, mockColorScale, 'test-key', {
showValue: true,
stack: StackControlsValue.Stack,
onlyTotal: false,
formatter: (v: any) => String(v),
totalStackedValues: [32],
thresholdValues,
});
return (result as any).label.formatter;
};

test('hides the label for a zero value when the threshold is 0', () => {
const formatter = buildFormatter([0]);
expect(
formatter({
value: [0, 0],
dataIndex: 0,
seriesIndex: 1,
seriesName: 'B',
}),
).toBe('');
});

test('still shows the label for a non-zero value when the threshold is 0', () => {
const formatter = buildFormatter([0]);
expect(
formatter({
value: [0, 32],
dataIndex: 0,
seriesIndex: 0,
seriesName: 'A',
}),
).toBe('32');
});

test('still shows the label for a negative value when the threshold is 0', () => {
const formatter = buildFormatter([0]);
expect(
formatter({
value: [0, -5],
dataIndex: 0,
seriesIndex: 0,
seriesName: 'A',
}),
).toBe('-5');
});

test('keeps hiding values below a non-zero threshold', () => {
const formatter = buildFormatter([16]);
expect(
formatter({
value: [0, 4],
dataIndex: 0,
seriesIndex: 0,
seriesName: 'A',
}),
).toBe('');
});
});

test('should not apply border styles for non-bar series', () => {
const opts = {
seriesType: EchartsTimeseriesSeriesType.Line,
Expand Down