Skip to content

Commit 3e04555

Browse files
committed
fix(charts): use brushEnd event instead of brushSelected
The brushSelected event requires brushLink configuration and doesn't fire properly with programmatic brush activation. The brushEnd event fires when the brush interaction ends and provides areas directly in params.areas instead of params.batch[0].areas.
1 parent 676ce98 commit 3e04555

File tree

2 files changed

+28
-38
lines changed

2 files changed

+28
-38
lines changed

superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/EchartsTimeseries.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ export default function EchartsTimeseries({
213213
}
214214

215215
// Get the brush areas from the event
216-
const brushAreas = params.batch?.[0]?.areas || [];
216+
// brushEnd event has areas directly in params.areas
217+
const brushAreas = params.areas || [];
217218
if (brushAreas.length === 0) {
218219
// Brush was cleared, reset the filter
219220
setDataMask({
@@ -355,7 +356,7 @@ export default function EchartsTimeseries({
355356
});
356357
}
357358
},
358-
brushSelected: handleBrushSelected,
359+
brushEnd: handleBrushSelected,
359360
};
360361

361362
const zrEventHandlers: EventHandlers = {

superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/EchartsTimeseries.test.tsx

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import { AxisType, DTTM_ALIAS } from '@superset-ui/core';
2020
import { EchartsTimeseriesFormData } from '../../src/Timeseries/types';
2121

22-
describe('EchartsTimeseries handleBrushSelected', () => {
22+
describe('EchartsTimeseries handleBrushEnd', () => {
2323
const mockSetDataMask = jest.fn();
2424
const mockXValueFormatter = jest.fn((val: number) => new Date(val).toISOString());
2525

@@ -37,9 +37,9 @@ describe('EchartsTimeseries handleBrushSelected', () => {
3737
mockXValueFormatter.mockClear();
3838
});
3939

40-
describe('handleBrushSelected logic', () => {
40+
describe('handleBrushEnd logic', () => {
4141
// Simulating the handler logic since we can't easily test React hooks directly
42-
const handleBrushSelected = (
42+
const handleBrushEnd = (
4343
params: any,
4444
xAxis: { label: string; type: AxisType },
4545
formData: Partial<EchartsTimeseriesFormData>,
@@ -58,7 +58,8 @@ describe('EchartsTimeseries handleBrushSelected', () => {
5858
}
5959

6060
// Get the brush areas from the event
61-
const brushAreas = params.batch?.[0]?.areas || [];
61+
// brushEnd event has areas directly in params.areas
62+
const brushAreas = params.areas || [];
6263
if (brushAreas.length === 0) {
6364
// Brush was cleared, reset the filter
6465
setDataMask({
@@ -77,7 +78,7 @@ describe('EchartsTimeseries handleBrushSelected', () => {
7778
return;
7879
}
7980

80-
const [startValue, endValue] = coordRange[0];
81+
const [startValue, endValue] = coordRange[0].map(Number);
8182

8283
const col =
8384
xAxis.label === DTTM_ALIAS ? formData.granularitySqla : xAxis.label;
@@ -101,10 +102,10 @@ describe('EchartsTimeseries handleBrushSelected', () => {
101102

102103
it('should not process brush events when x-axis type is not time', () => {
103104
const params = {
104-
batch: [{ areas: [{ coordRange: [[1000, 2000], [0, 100]] }] }],
105+
areas: [{ coordRange: [[1000, 2000], [0, 100]] }],
105106
};
106107

107-
handleBrushSelected(
108+
handleBrushEnd(
108109
params,
109110
{ label: 'category', type: AxisType.Category },
110111
baseFormData,
@@ -117,10 +118,10 @@ describe('EchartsTimeseries handleBrushSelected', () => {
117118

118119
it('should not process brush events on touch devices', () => {
119120
const params = {
120-
batch: [{ areas: [{ coordRange: [[1000, 2000], [0, 100]] }] }],
121+
areas: [{ coordRange: [[1000, 2000], [0, 100]] }],
121122
};
122123

123-
handleBrushSelected(
124+
handleBrushEnd(
124125
params,
125126
baseXAxis,
126127
baseFormData,
@@ -134,10 +135,10 @@ describe('EchartsTimeseries handleBrushSelected', () => {
134135

135136
it('should reset filter when brush is cleared (no areas)', () => {
136137
const params = {
137-
batch: [{ areas: [] }],
138+
areas: [],
138139
};
139140

140-
handleBrushSelected(
141+
handleBrushEnd(
141142
params,
142143
baseXAxis,
143144
baseFormData,
@@ -159,21 +160,17 @@ describe('EchartsTimeseries handleBrushSelected', () => {
159160
const endTime = 1609545600000; // 2021-01-02
160161

161162
const params = {
162-
batch: [
163+
areas: [
163164
{
164-
areas: [
165-
{
166-
coordRange: [
167-
[startTime, endTime],
168-
[0, 100],
169-
],
170-
},
165+
coordRange: [
166+
[startTime, endTime],
167+
[0, 100],
171168
],
172169
},
173170
],
174171
};
175172

176-
handleBrushSelected(
173+
handleBrushEnd(
177174
params,
178175
baseXAxis,
179176
baseFormData,
@@ -201,21 +198,17 @@ describe('EchartsTimeseries handleBrushSelected', () => {
201198
const endTime = 1609545600000;
202199

203200
const params = {
204-
batch: [
201+
areas: [
205202
{
206-
areas: [
207-
{
208-
coordRange: [
209-
[startTime, endTime],
210-
[0, 100],
211-
],
212-
},
203+
coordRange: [
204+
[startTime, endTime],
205+
[0, 100],
213206
],
214207
},
215208
],
216209
};
217210

218-
handleBrushSelected(
211+
handleBrushEnd(
219212
params,
220213
{ label: 'custom_time_column', type: AxisType.Time },
221214
baseFormData,
@@ -237,18 +230,14 @@ describe('EchartsTimeseries handleBrushSelected', () => {
237230

238231
it('should not process when coordRange is invalid', () => {
239232
const params = {
240-
batch: [
233+
areas: [
241234
{
242-
areas: [
243-
{
244-
coordRange: null,
245-
},
246-
],
235+
coordRange: null,
247236
},
248237
],
249238
};
250239

251-
handleBrushSelected(
240+
handleBrushEnd(
252241
params,
253242
baseXAxis,
254243
baseFormData,

0 commit comments

Comments
 (0)