Skip to content

Commit e213ddc

Browse files
liuzhenyingaiyin.lzy
and
aiyin.lzy
authored
feat/duax: 关闭多个图例 (#1888)
* feat: 支持关闭多个图例 * fix: remove console & unit destory Co-authored-by: aiyin.lzy <[email protected]>
1 parent 2d33fbb commit e213ddc

File tree

2 files changed

+124
-24
lines changed

2 files changed

+124
-24
lines changed

__tests__/unit/plots/dual-axes/legend-spec.ts

+116-22
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,8 @@ describe('Legend', () => {
144144
dualAxes.destroy();
145145
});
146146

147-
it('Legend with option', () => {
148-
const dualAxes = new DualAxes(createDiv('test DualAxes doubal line'), {
147+
it('Legend with click', () => {
148+
const dualAxes = new DualAxes(createDiv('test DualAxes doubal line', undefined, 'click_legend'), {
149149
width: 400,
150150
height: 500,
151151
data: [PV_DATA, UV_DATA_MULTI],
@@ -168,26 +168,28 @@ describe('Legend', () => {
168168
},
169169
],
170170
legend: {
171-
layout: 'vertical',
172-
position: 'right',
171+
itemName: {
172+
formatter: (val) => `${val}_test`,
173+
},
173174
},
174175
});
175176

176177
dualAxes.render();
177178

178179
const legendController = dualAxes.chart.getController('legend');
179180
const legendComponent = legendController.getComponents()[0];
180-
const cfg = legendComponent.component.cfg;
181-
182-
expect(legendComponent.direction).toEqual('right');
183-
expect(cfg.items.length).toBe(4);
184-
expect(cfg.items[0].name).toBe('页面访问量');
185-
expect(cfg.items[1].name).toBe('a');
186-
expect(cfg.items[2].name).toBe('b');
187-
expect(cfg.items[3].name).toBe('c');
181+
const legendContainer = legendComponent.component.get('container');
182+
const cfgItems = legendComponent.component.cfg.items;
183+
expect(cfgItems.length).toBe(4);
184+
expect(cfgItems[0].name).toBe('页面访问量');
185+
expect(cfgItems[1].name).toBe('a');
186+
expect(cfgItems[2].name).toBe('b');
187+
expect(cfgItems[3].name).toBe('c');
188188

189189
dualAxes.chart.once('afterrender', () => {
190+
// 点击页面访问量,期望单折线图 visible 隐藏, 图例 unchecked 为 true
190191
dualAxes.chart.emit('legend-item:click', {
192+
target: legendContainer.findById('-legend-item-页面访问量-name'),
191193
gEvent: {
192194
delegateObject: {
193195
item: {
@@ -200,9 +202,71 @@ describe('Legend', () => {
200202
},
201203
},
202204
});
205+
203206
expect(dualAxes.chart.views[0].geometries[0].visible).toEqual(false);
207+
expect(cfgItems.find((item) => item.id === '页面访问量').unchecked).toEqual(true);
208+
209+
// 点击分类数据 A,期望多折线图 view 过滤掉数据 a
210+
dualAxes.chart.emit('legend-item:click', {
211+
target: legendContainer.findById('-legend-item-a-name'),
212+
gEvent: {
213+
delegateObject: {
214+
item: {
215+
id: 'a',
216+
name: 'a',
217+
value: 'a',
218+
viewId: RIGHT_AXES_VIEW,
219+
unchecked: true,
220+
},
221+
},
222+
},
223+
});
224+
225+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'a').length === 0).toEqual(true);
226+
expect(cfgItems.find((item) => item.id === 'a').unchecked).toEqual(true);
227+
228+
// 点击分类数据 B,期望多折线图 view 过滤掉数据 b
229+
dualAxes.chart.emit('legend-item:click', {
230+
target: legendContainer.findById('-legend-item-b-name'),
231+
gEvent: {
232+
delegateObject: {
233+
item: {
234+
id: 'b',
235+
name: 'b',
236+
value: 'b',
237+
viewId: RIGHT_AXES_VIEW,
238+
unchecked: true,
239+
},
240+
},
241+
},
242+
});
243+
244+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'b').length === 0).toEqual(true);
245+
expect(cfgItems.find((item) => item.id === 'b').unchecked).toEqual(true);
204246

247+
// 点击分类数据 C,期望多折线图 view 过滤掉数据 c, yaxis 右侧仅留 0 一个刻度
205248
dualAxes.chart.emit('legend-item:click', {
249+
target: legendContainer.findById('-legend-item-c-name'),
250+
gEvent: {
251+
delegateObject: {
252+
item: {
253+
id: 'c',
254+
name: 'c',
255+
value: 'c',
256+
viewId: RIGHT_AXES_VIEW,
257+
unchecked: true,
258+
},
259+
},
260+
},
261+
});
262+
263+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'c').length === 0).toEqual(true);
264+
expect(cfgItems.find((item) => item.id === 'c').unchecked).toEqual(true);
265+
expect(dualAxes.chart.views[1].getController('axis').getComponents()[0].component.cfg.ticks.length).toBe(1);
266+
267+
// 再次点击页面访问量,期望单折线图 visible 出现, 图例 unchecked 为 false
268+
dualAxes.chart.emit('legend-item:click', {
269+
target: legendContainer.findById('-legend-item-页面访问量-name'),
206270
gEvent: {
207271
delegateObject: {
208272
item: {
@@ -216,43 +280,71 @@ describe('Legend', () => {
216280
},
217281
});
218282
expect(dualAxes.chart.views[0].geometries[0].visible).toEqual(true);
283+
expect(cfgItems.find((item) => item.id === '页面访问量').unchecked).toEqual(false);
284+
expect(dualAxes.chart.views[1].getController('axis').getComponents()[0].component.cfg.ticks.length).toBe(1);
219285

286+
// 再次点击分类数据 A,期望多折线图 view 重新包含数据 a,右轴出现多个刻度
220287
dualAxes.chart.emit('legend-item:click', {
288+
target: legendContainer.findById('-legend-item-a-name'),
221289
gEvent: {
222290
delegateObject: {
223291
item: {
224292
id: 'a',
225293
name: 'a',
226294
value: 'a',
227295
viewId: RIGHT_AXES_VIEW,
228-
unchecked: true,
296+
unchecked: false,
229297
},
230298
},
231299
},
232300
});
301+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'a').length > 0).toEqual(true);
302+
expect(cfgItems.find((item) => item.id === 'a').unchecked).toEqual(false);
303+
expect(
304+
dualAxes.chart.views[1].getController('axis').getComponents()[0].component.cfg.ticks.length > 1
305+
).toBeTruthy();
233306

234-
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'a').length === 0).toEqual(true);
235-
307+
// 再次点击分类数据 B,期望多折线图 view 重新包含数据 B
236308
dualAxes.chart.emit('legend-item:click', {
309+
target: legendContainer.findById('-legend-item-b-name'),
237310
gEvent: {
238311
delegateObject: {
239312
item: {
240-
id: 'a',
241-
name: 'a',
242-
value: 'a',
313+
id: 'b',
314+
name: 'b',
315+
value: 'b',
243316
viewId: RIGHT_AXES_VIEW,
244317
unchecked: false,
245318
},
246319
},
247320
},
248321
});
322+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'b').length > 0).toEqual(true);
323+
expect(cfgItems.find((item) => item.id === 'b').unchecked).toEqual(false);
249324

250-
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'a').length > 0).toEqual(true);
325+
// 再次点击分类数据 C,期望多折线图 view 重新包含数据 C
326+
dualAxes.chart.emit('legend-item:click', {
327+
target: legendContainer.findById('-legend-item-c-name'),
328+
gEvent: {
329+
delegateObject: {
330+
item: {
331+
id: 'c',
332+
name: 'c',
333+
value: 'c',
334+
viewId: RIGHT_AXES_VIEW,
335+
unchecked: false,
336+
},
337+
},
338+
},
339+
});
340+
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'c').length > 0).toEqual(true);
341+
expect(cfgItems.find((item) => item.id === 'c').unchecked).toEqual(false);
251342

343+
// 提高if else 覆盖率,事件为空,不受影响
252344
dualAxes.chart.emit('legend-item:click', {});
253-
254345
expect(dualAxes.chart.views[1].geometries[0].data.filter((item) => item.site === 'a').length > 0).toEqual(true);
255346

347+
// 提高if else 覆盖率,传入一个 id 错误的 item,不受影响
256348
dualAxes.chart.emit('legend-item:click', {
257349
gEvent: {
258350
delegateObject: {
@@ -270,6 +362,7 @@ describe('Legend', () => {
270362

271363
expect(dualAxes.chart.views[0].geometries[0].visible).toEqual(true);
272364

365+
// 提高if else 覆盖率,传入一个 id 错误的 item,不受影响
273366
dualAxes.chart.emit('legend-item:click', {
274367
gEvent: {
275368
delegateObject: {
@@ -299,7 +392,8 @@ describe('Legend', () => {
299392
yField: ['pv', 'uv'],
300393
legend: {
301394
custom: true,
302-
position: 'bottom',
395+
layout: 'vertical',
396+
position: 'right',
303397
items: [
304398
{
305399
value: 'test',
@@ -326,7 +420,7 @@ describe('Legend', () => {
326420
expect(cfg.items[0].marker.symbol).toBe('square');
327421
expect(cfg.items[1].name).toBe('测试2');
328422
expect(cfg.items[1].marker.symbol).toBe('square');
329-
423+
expect(legendComponent.direction).toEqual('right');
330424
dualAxes.destroy();
331425
});
332426
});

src/plots/dual-axes/adaptor.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { each, findIndex, get, isObject, every } from '@antv/util';
1+
import { each, findIndex, get, find, isObject, every } from '@antv/util';
22
import { Scale } from '@antv/g2/lib/dependents';
3+
import { LegendItem } from '@antv/g2/lib/interface';
34
import {
45
theme as commonTheme,
56
animation as commonAnimation,
@@ -275,13 +276,18 @@ export function legend(params: Params<DualAxesOptions>): Params<DualAxesOptions>
275276
});
276277
}
277278
} else {
279+
const legendItem = get(chart.getController('legend'), 'option.items', []);
278280
// 分组柱线图
279281
each(chart.views, (view) => {
280282
// 单折柱图
281283
const groupScale = view.getGroupScales();
282284
each(groupScale, (scale: Scale) => {
283285
if (scale.values && scale.values.indexOf(field) > -1) {
284-
view.filter(scale.field, (value) => !delegateObject.item.unchecked || value !== field);
286+
view.filter(scale.field, (value) => {
287+
const curLegendItem: LegendItem = find(legendItem, (item: LegendItem) => item.value === value);
288+
// 使用 legend 中的 unchecked 来判断,使得支持关闭多个图例
289+
return !curLegendItem.unchecked;
290+
});
285291
}
286292
});
287293
chart.render(true);

0 commit comments

Comments
 (0)