Skip to content

Commit 883de0f

Browse files
zhangtengjinwewoor
authored andcommitted
feat: extract TreeViewUtil to help file
extract TreeViewUtil to help file
1 parent 03791e7 commit 883de0f

File tree

5 files changed

+225
-225
lines changed

5 files changed

+225
-225
lines changed

src/components/tree/index.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ export interface ITreeProps {
5252
expandedKeys?: Key[];
5353
defaultCheckedKeys?: Key[];
5454
checkedKeys?:
55-
| Key[]
56-
| {
57-
checked: Key[];
58-
halfChecked: Key[];
59-
};
55+
| Key[]
56+
| {
57+
checked: Key[];
58+
halfChecked: Key[];
59+
};
6060
defaultSelectedKeys?: Key[];
6161
selectedKeys?: Key[];
6262
titleRender?: (node: DataNode) => React.ReactNode;

src/services/helper.ts

+212
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,215 @@
11
export function searchById(id) {
22
return (item) => item.id === id;
33
}
4+
5+
6+
export interface IIndex<T> {
7+
id?: number;
8+
node?: T;
9+
parent?: number;
10+
prev?: number;
11+
next?: number;
12+
[x: string]: any; // default: children: []
13+
}
14+
export interface IIndexs<T> {
15+
[index: number]: IIndex<T>;
16+
}
17+
export interface ITreeInterface<T> {
18+
count: number;
19+
obj: T;
20+
indexes: IIndexs<T>;
21+
childNodeName: string;
22+
}
23+
24+
export class TreeViewUtil<T = any> implements ITreeInterface<T> {
25+
count: number;
26+
obj: T;
27+
indexes: IIndexs<T>;
28+
childNodeName: string;
29+
30+
/**
31+
*
32+
* @param obj // tree object
33+
* @param childNodeName // loop properties
34+
* @example indexes data structure example:
35+
* {
36+
[2]: {
37+
id: 2,
38+
node: {},
39+
parent: 1,
40+
prev: null,
41+
next: 3
42+
},
43+
...
44+
}
45+
*/
46+
constructor(obj, childNodeName = 'children') {
47+
this.count = 1; // nodes count
48+
this.obj = obj || { [childNodeName]: [] };
49+
this.indexes = {};
50+
this.childNodeName = childNodeName;
51+
this.generate(this.obj);
52+
}
53+
54+
generate(obj) {
55+
const indexes = this.indexes;
56+
const startId = obj.id;
57+
const self = this;
58+
59+
const index: IIndex<T> = { id: startId, node: obj };
60+
indexes[startId + ''] = index;
61+
this.count++;
62+
63+
if (obj[this.childNodeName]?.length) {
64+
walk(obj[this.childNodeName], index);
65+
}
66+
67+
function walk(objs, parent) {
68+
const children: number[] = []; // current children ids
69+
objs.forEach(function (obj: any, i) {
70+
const index: IIndex<T> = {};
71+
index.id = obj.id;
72+
index.node = obj;
73+
74+
if (parent) index.parent = parent.id;
75+
76+
indexes[obj.id + ''] = index;
77+
children.push(obj.id as number);
78+
self.count++;
79+
80+
if (obj[self.childNodeName]?.length) {
81+
walk(obj[self.childNodeName], index);
82+
}
83+
});
84+
parent[self.childNodeName] = children;
85+
86+
children.forEach(function (id, i) {
87+
const index = indexes[id + ''];
88+
if (i > 0) index.prev = children[i - 1];
89+
if (i < children.length - 1) index.next = children[i + 1];
90+
});
91+
}
92+
93+
return index;
94+
}
95+
96+
getIndex(id: number) {
97+
const index = this.indexes[id + ''];
98+
if (index) return index;
99+
}
100+
101+
removeIndex(index: number) {
102+
const self = this;
103+
del(index);
104+
105+
function del(index) {
106+
delete self.indexes[index.id + ''];
107+
if (index[self.childNodeName]?.length) {
108+
index[self.childNodeName].forEach(function (child) {
109+
del(self.getIndex(child));
110+
});
111+
}
112+
}
113+
}
114+
115+
get(id: number) {
116+
const index = this.getIndex(id);
117+
if (index?.node) return index.node;
118+
return null;
119+
}
120+
121+
remove(id: number) {
122+
const index = this.getIndex(id);
123+
const node = this.get(id);
124+
const parentIndex = this.getIndex(index.parent);
125+
const parentNode = this.get(index.parent);
126+
127+
parentNode[this.childNodeName].splice(
128+
parentNode[this.childNodeName].indexOf(node),
129+
1
130+
);
131+
parentIndex[this.childNodeName].splice(
132+
parentIndex[this.childNodeName].indexOf(id),
133+
1
134+
);
135+
this.removeIndex(index);
136+
this.updateChildren(parentIndex[this.childNodeName]);
137+
138+
return node;
139+
}
140+
141+
update(id: number, extra = {}) {
142+
const index = this.getIndex(id);
143+
const node = this.get(id);
144+
const parentIndex = this.getIndex(index.parent);
145+
const parentNode = this.get(index.parent);
146+
parentNode[this.childNodeName].splice(
147+
parentNode[this.childNodeName].indexOf(node),
148+
1,
149+
{
150+
...node,
151+
...extra,
152+
}
153+
);
154+
this.updateChildren(parentIndex[this.childNodeName]);
155+
156+
return node;
157+
}
158+
159+
updateChildren(children: IIndex<T>) {
160+
const self = this;
161+
children.forEach(function (id, i) {
162+
const index = self.getIndex(id);
163+
index.prev = index.next = null;
164+
if (i > 0) index.prev = children[i - 1];
165+
if (i < children.length - 1) index.next = children[i + 1];
166+
});
167+
}
168+
169+
insert(obj: T, parentId: number, i: number) {
170+
const parentIndex = this.getIndex(parentId);
171+
const parentNode = this.get(parentId);
172+
173+
const index = this.generate(obj);
174+
index.parent = parentId;
175+
176+
parentNode[this.childNodeName] = parentNode[this.childNodeName] || [];
177+
parentIndex[this.childNodeName] = parentIndex[this.childNodeName] || [];
178+
179+
parentNode[this.childNodeName].splice(i, 0, obj);
180+
parentIndex[this.childNodeName].splice(i, 0, index.id);
181+
182+
this.updateChildren(parentIndex[this.childNodeName]);
183+
if (parentIndex.parent) {
184+
this.updateChildren(
185+
this.getIndex(parentIndex.parent)[this.childNodeName]
186+
);
187+
}
188+
189+
return index;
190+
}
191+
192+
insertBefore(obj: T, destId: number) {
193+
const destIndex = this.getIndex(destId);
194+
const parentId = destIndex.parent;
195+
const i = this.getIndex(parentId)[this.childNodeName].indexOf(destId);
196+
return this.insert(obj, parentId, i);
197+
}
198+
199+
insertAfter(obj: T, destId: number) {
200+
const destIndex = this.getIndex(destId);
201+
const parentId = destIndex.parent;
202+
const i = this.getIndex(parentId)[this.childNodeName].indexOf(destId);
203+
return this.insert(obj, parentId, i + 1);
204+
}
205+
206+
prepend(obj: T, destId: number) {
207+
return this.insert(obj, destId, 0);
208+
}
209+
210+
append(obj: T, destId: number) {
211+
const destIndex = this.getIndex(destId);
212+
destIndex[this.childNodeName] = destIndex[this.childNodeName] || [];
213+
return this.insert(obj, destId, destIndex[this.childNodeName].length);
214+
}
215+
}

0 commit comments

Comments
 (0)