Skip to content

Commit

Permalink
feat(g-base): add some member functions for Group, close #260
Browse files Browse the repository at this point in the history
  • Loading branch information
dengfuping committed Nov 10, 2019
1 parent 41208eb commit fdc0ac7
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 176 deletions.
81 changes: 80 additions & 1 deletion packages/g-base/src/abstract/group.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IGroup } from '../interfaces';
import { IElement, IGroup } from '../interfaces';
import { ElementFilterFn } from '../types';
import Container from './container';
import { each } from '../util/util';

Expand Down Expand Up @@ -49,6 +50,84 @@ abstract class AbstractGroup extends Container implements IGroup {
}
return clone;
}

/**
* 获取 Group 的第一个子元素
* @return {IElement} 第一个元素
*/
getFirst(): IElement {
const children = this.getChildren();
return children[0];
}

/**
* 获取 Group 的最后一个子元素
* @return {IElement} 元素
*/
getLast(): IElement {
const children = this.getChildren();
return children[children.length - 1];
}

/**
* 子元素的数量
* @return {number} 子元素数量
*/
getCount(): number {
const children = this.getChildren();
return children.length;
}

/**
* 查找所有匹配的元素
* @param {ElementFilterFn} fn 匹配函数
* @return {IElement[]} 元素数组
*/
findAll(fn: ElementFilterFn): IElement[] {
let rst: IElement[] = [];
const children = this.getChildren();
each(children, (element: IElement) => {
if (fn(element)) {
rst.push(element);
}
if (element.isGroup()) {
rst = rst.concat((element as IGroup).findAll(fn));
}
});
return rst;
}

/**
* 根据 ID 查找元素
* @param {string} id 元素 id
* @return {IElement|null} 元素
*/
findById(id: string): IElement {
return this.find((element) => {
return element.get('id') === id;
});
}

/**
* 查找元素,找到第一个返回
* @param {ElementFilterFn} fn 匹配函数
* @return {IElement|null} 元素,可以为空
*/
find(fn: ElementFilterFn): IElement {
let rst: IElement = null;
const children = this.getChildren();
each(children, (element: IElement) => {
if (fn(element)) {
rst = element;
} else if (element.isGroup()) {
rst = (element as IGroup).find(fn);
}
if (rst) {
return false;
}
});
return rst;
}
}

export default AbstractGroup;
40 changes: 40 additions & 0 deletions packages/g-base/src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
OnFrame,
ShapeBase,
BBox,
ElementFilterFn,
} from './types';

export interface ICtor<T> {
Expand Down Expand Up @@ -355,6 +356,45 @@ export interface IGroup extends IElement, IContainer {
* @return {boolean} 是否是实体分组
*/
isEntityGroup(): boolean;

/**
* 获取 Group 的第一个子元素
* @return {IElement} 第一个元素
*/
getFirst(): IElement;

/**
* 获取 Group 的最后一个子元素
* @return {IElement} 元素
*/
getLast(): IElement;

/**
* 子元素的数量
* @return {number} 子元素数量
*/
getCount(): number;

/**
* 查找所有匹配的元素
* @param {ElementFilterFn} fn 匹配函数
* @return {IElement[]} 元素数组
*/
findAll(fn: ElementFilterFn): IElement[];

/**
* 根据 ID 查找元素
* @param {string} id 元素 id
* @return {IElement | null} 元素
*/
findById(id: string): IElement;

/**
* 查找元素,找到第一个返回
* @param {ElementFilterFn} fn 匹配函数
* @return {IElement|null} 元素,可以为空
*/
find(fn: ElementFilterFn): IElement;
}

export interface IShape extends IElement {
Expand Down
2 changes: 2 additions & 0 deletions packages/g-base/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ export type ShapeBase = {
[key: string]: ICtor<IShape>;
};

export type ElementFilterFn = (IElement) => boolean;

type A = ['a' | 'A', number, number, number, number, number, number, number];
type C = ['c' | 'C', number, number, number, number, number, number];
type O = ['o' | 'O', number, number];
Expand Down
87 changes: 0 additions & 87 deletions packages/g-base/src/util/group.ts

This file was deleted.

58 changes: 58 additions & 0 deletions packages/g-base/tests/unit/group-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,3 +219,61 @@ describe('test with matrix', () => {
expect(group.invertFromMatrix(v)).eqls(v);
});
});

describe('test group member function', () => {
const group = new Group({
children: [
new MyShape({ id: '01', text: '01' }),
new MyShape({ id: '02', text: '02' }),
new Group({
children: [new MyShape({ id: '04', text: '04' }), new MyShape({ id: 'test', text: '02' })],
}),
new MyShape({ id: '03', text: '03' }),
],
});

it('getFirst', () => {
expect(group.getFirst().get('id')).eqls('01');
});

it('getLast', () => {
expect(group.getLast().get('id')).eqls('03');
});

it('getCount', () => {
expect(group.getCount()).eqls(group.getChildren().length);
});

it('findAll', () => {
expect(
group.findAll((item) => {
return item.get('text') === '02';
}).length
).eqls(2);

expect(
group.findAll((item) => {
return item.get('text') === '05';
}).length
).eqls(0);
});

it('findById', () => {
expect(group.findById('01')).not.eqls(null);
expect(group.findById('05')).eqls(null);
expect(group.findById('04')).not.eqls(null);
});

it('find', () => {
expect(
group.find((item) => {
return item.get('text') === '02';
}).id
).eqls('02');
expect(
group.find((item) => {
return item.get('text') === '05';
})
).eqls(null);
});
});
88 changes: 0 additions & 88 deletions packages/g-base/tests/unit/group-util-spec.js

This file was deleted.

0 comments on commit fdc0ac7

Please sign in to comment.