1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace';
17fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow';
18fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker';
19fb726d48Sopenharmony_ciimport { SampleStruct, SampleRender } from '../../database/ui-worker/ProcedureWorkerBpftrace';
20fb726d48Sopenharmony_ciimport { queryStartTime } from '../../database/sql/SqlLite.sql';
21fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil';
22fb726d48Sopenharmony_ci
23fb726d48Sopenharmony_ciexport class SpUserFileChart {
24fb726d48Sopenharmony_ci    private trace: SpSystemTrace;
25fb726d48Sopenharmony_ci    private currentFile: undefined;
26fb726d48Sopenharmony_ci    static userPluginData: [];
27fb726d48Sopenharmony_ci
28fb726d48Sopenharmony_ci    constructor(trace: SpSystemTrace) {
29fb726d48Sopenharmony_ci        this.trace = trace;
30fb726d48Sopenharmony_ci    }
31fb726d48Sopenharmony_ci
32fb726d48Sopenharmony_ci    async init(file: File | null) {
33fb726d48Sopenharmony_ci        if (!file) {
34fb726d48Sopenharmony_ci            let startTime = await queryStartTime();
35fb726d48Sopenharmony_ci            //@ts-ignore
36fb726d48Sopenharmony_ci            let folder = await this.initSample(startTime[0].start_ts, file);
37fb726d48Sopenharmony_ci            this.trace.rowsEL?.appendChild(folder);
38fb726d48Sopenharmony_ci        } else {
39fb726d48Sopenharmony_ci            let folder = await this.initSample(-1, file);
40fb726d48Sopenharmony_ci            this.trace.rowsEL?.appendChild(folder);
41fb726d48Sopenharmony_ci        }
42fb726d48Sopenharmony_ci    }
43fb726d48Sopenharmony_ci
44fb726d48Sopenharmony_ci    async initSample(start_ts: number, file: unknown): Promise<TraceRow<SampleStruct>> {
45fb726d48Sopenharmony_ci        let traceRow = TraceRow.skeleton<SampleStruct>();
46fb726d48Sopenharmony_ci        traceRow.rowId = 'userPlugin';
47fb726d48Sopenharmony_ci        traceRow.index = 0;
48fb726d48Sopenharmony_ci        traceRow.rowType = TraceRow.ROW_TYPE_SAMPLE;
49fb726d48Sopenharmony_ci        traceRow.rowParentId = '';
50fb726d48Sopenharmony_ci        traceRow.folder = false;
51fb726d48Sopenharmony_ci        traceRow.style.height = '40px';
52fb726d48Sopenharmony_ci        traceRow.name = 'UserPluginRow';
53fb726d48Sopenharmony_ci        traceRow.selectChangeHandler = this.trace.selectChangeHandler;
54fb726d48Sopenharmony_ci        traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
55fb726d48Sopenharmony_ci        traceRow.findHoverStruct = () => {
56fb726d48Sopenharmony_ci            SampleStruct.hoverSampleStruct = traceRow.getHoverStruct();
57fb726d48Sopenharmony_ci        };
58fb726d48Sopenharmony_ci        //添加上传按钮
59fb726d48Sopenharmony_ci        traceRow.addRowSampleUpload();
60fb726d48Sopenharmony_ci        this.addTraceRowEventListener(traceRow, start_ts);
61fb726d48Sopenharmony_ci        //单独上传
62fb726d48Sopenharmony_ci        if (file) {
63fb726d48Sopenharmony_ci            this.getJsonData(file).then((res: unknown) => {
64fb726d48Sopenharmony_ci                //@ts-ignore
65fb726d48Sopenharmony_ci                const propertyData = res.data;
66fb726d48Sopenharmony_ci                //@ts-ignore
67fb726d48Sopenharmony_ci                const treeNodes = res.relation.children || [res.relation.RS.children[0]];
68fb726d48Sopenharmony_ci                SpUserFileChart.userPluginData = treeNodes.data[0] || [];
69fb726d48Sopenharmony_ci                const uniqueProperty = this.removeDuplicates(propertyData);
70fb726d48Sopenharmony_ci                const flattenTreeArray = this.getFlattenTreeData(treeNodes);
71fb726d48Sopenharmony_ci                //@ts-ignore
72fb726d48Sopenharmony_ci                const height = (Math.max(...flattenTreeArray.map((obj: unknown) => obj.depth)) + 1) * 20;
73fb726d48Sopenharmony_ci                const sampleProperty = this.setRelationDataProperty(flattenTreeArray, uniqueProperty);
74fb726d48Sopenharmony_ci                //@ts-ignore
75fb726d48Sopenharmony_ci                const startTS = flattenTreeArray[0].property[0].begin;
76fb726d48Sopenharmony_ci                traceRow.supplier = () =>
77fb726d48Sopenharmony_ci                    new Promise((resolve): void => {
78fb726d48Sopenharmony_ci                        //@ts-ignore
79fb726d48Sopenharmony_ci                        resolve(sampleProperty)
80fb726d48Sopenharmony_ci                    })
81fb726d48Sopenharmony_ci                traceRow.onThreadHandler = (useCache) => {
82fb726d48Sopenharmony_ci                    let context: CanvasRenderingContext2D;
83fb726d48Sopenharmony_ci                    if (traceRow.currentContext) {
84fb726d48Sopenharmony_ci                        context = traceRow.currentContext;
85fb726d48Sopenharmony_ci                    } else {
86fb726d48Sopenharmony_ci                        context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
87fb726d48Sopenharmony_ci                    }
88fb726d48Sopenharmony_ci                    traceRow.canvasSave(context);
89fb726d48Sopenharmony_ci                    (renders.sample as SampleRender).renderMainThread(
90fb726d48Sopenharmony_ci                        {
91fb726d48Sopenharmony_ci                            context: context,
92fb726d48Sopenharmony_ci                            useCache: useCache,
93fb726d48Sopenharmony_ci                            type: 'bpftrace',
94fb726d48Sopenharmony_ci                            start_ts: startTS,
95fb726d48Sopenharmony_ci                            uniqueProperty: uniqueProperty,
96fb726d48Sopenharmony_ci                            //@ts-ignore
97fb726d48Sopenharmony_ci                            flattenTreeArray: flattenTreeArray
98fb726d48Sopenharmony_ci                        },
99fb726d48Sopenharmony_ci                        traceRow
100fb726d48Sopenharmony_ci                    );
101fb726d48Sopenharmony_ci                    traceRow.canvasRestore(context)
102fb726d48Sopenharmony_ci                };
103fb726d48Sopenharmony_ci                traceRow.style.height = `${height}px`;
104fb726d48Sopenharmony_ci            })
105fb726d48Sopenharmony_ci        } else {
106fb726d48Sopenharmony_ci            traceRow.supplier = () =>
107fb726d48Sopenharmony_ci                new Promise((resolve): void => {
108fb726d48Sopenharmony_ci                    resolve([]);
109fb726d48Sopenharmony_ci                });
110fb726d48Sopenharmony_ci            traceRow.onThreadHandler = (useCache) => {
111fb726d48Sopenharmony_ci                let context: CanvasRenderingContext2D;
112fb726d48Sopenharmony_ci                if (traceRow.currentContext) {
113fb726d48Sopenharmony_ci                    context = traceRow.currentContext;
114fb726d48Sopenharmony_ci                } else {
115fb726d48Sopenharmony_ci                    context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
116fb726d48Sopenharmony_ci                }
117fb726d48Sopenharmony_ci                traceRow.canvasSave(context);
118fb726d48Sopenharmony_ci                (renders.sample as SampleRender).renderMainThread(
119fb726d48Sopenharmony_ci                    {
120fb726d48Sopenharmony_ci                        context: context,
121fb726d48Sopenharmony_ci                        useCache: useCache,
122fb726d48Sopenharmony_ci                        type: 'bpftrace',
123fb726d48Sopenharmony_ci                        start_ts: 0,
124fb726d48Sopenharmony_ci                        uniqueProperty: [],
125fb726d48Sopenharmony_ci                        flattenTreeArray: [],
126fb726d48Sopenharmony_ci                    },
127fb726d48Sopenharmony_ci                    traceRow
128fb726d48Sopenharmony_ci                );
129fb726d48Sopenharmony_ci                traceRow.canvasRestore(context);
130fb726d48Sopenharmony_ci            };
131fb726d48Sopenharmony_ci        }
132fb726d48Sopenharmony_ci        return traceRow;
133fb726d48Sopenharmony_ci    }
134fb726d48Sopenharmony_ci
135fb726d48Sopenharmony_ci    /**
136fb726d48Sopenharmony_ci     * 监听文件上传事件
137fb726d48Sopenharmony_ci     * @param row 
138fb726d48Sopenharmony_ci     * @param start_ts 
139fb726d48Sopenharmony_ci     */
140fb726d48Sopenharmony_ci
141fb726d48Sopenharmony_ci    //@ts-ignore
142fb726d48Sopenharmony_ci    addTraceRowEventListener(row: TraceRow<unknown>, start_ts: number) {
143fb726d48Sopenharmony_ci        row.uploadEl?.addEventListener('sample-file-change', (e: unknown) => {
144fb726d48Sopenharmony_ci            this.getJsonData(e).then((res: unknown) => {
145fb726d48Sopenharmony_ci                this.resetChartData(row);
146fb726d48Sopenharmony_ci                if (!res) {
147fb726d48Sopenharmony_ci                    row.supplier = () =>
148fb726d48Sopenharmony_ci                        new Promise((resolve): void => {
149fb726d48Sopenharmony_ci                            resolve([])
150fb726d48Sopenharmony_ci                        })
151fb726d48Sopenharmony_ci                    this.trace.traceSheetEL?.setMode('hidden');
152fb726d48Sopenharmony_ci                    row.style.height = '40px';
153fb726d48Sopenharmony_ci                    row.name = 'UserPluginRow'
154fb726d48Sopenharmony_ci                } else {
155fb726d48Sopenharmony_ci                    //@ts-ignore
156fb726d48Sopenharmony_ci                    const propertyData = res.data;
157fb726d48Sopenharmony_ci                    //@ts-ignore
158fb726d48Sopenharmony_ci                    SpUserFileChart.userPluginData = res.data[0];
159fb726d48Sopenharmony_ci                    //@ts-ignore
160fb726d48Sopenharmony_ci                    const treeNodes = res.relation.children || [res.relation.RS.children[0]];
161fb726d48Sopenharmony_ci                    const uniqueProperty = this.removeDuplicates(propertyData);
162fb726d48Sopenharmony_ci                    const flattenTreeArray = this.getFlattenTreeData(treeNodes);
163fb726d48Sopenharmony_ci                    //@ts-ignore
164fb726d48Sopenharmony_ci                    const height = (Math.max(...flattenTreeArray.map((obj: unknown) => obj.depth)) + 1) * 20;
165fb726d48Sopenharmony_ci                    const sampleProperty = this.setRelationDataProperty(flattenTreeArray, uniqueProperty);
166fb726d48Sopenharmony_ci                    //@ts-ignore
167fb726d48Sopenharmony_ci                    const startTS = start_ts > 0 ? start_ts : flattenTreeArray[0].property[0].begin;
168fb726d48Sopenharmony_ci                    row.supplier = () =>
169fb726d48Sopenharmony_ci                        new Promise((resolve): void => {
170fb726d48Sopenharmony_ci                            resolve(sampleProperty)
171fb726d48Sopenharmony_ci                        })
172fb726d48Sopenharmony_ci                    row.onThreadHandler = (useCache) => {
173fb726d48Sopenharmony_ci                        let context: CanvasRenderingContext2D;
174fb726d48Sopenharmony_ci                        if (row.currentContext) {
175fb726d48Sopenharmony_ci                            context = row.currentContext;
176fb726d48Sopenharmony_ci                        } else {
177fb726d48Sopenharmony_ci                            context = row.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
178fb726d48Sopenharmony_ci                        }
179fb726d48Sopenharmony_ci                        row.canvasSave(context);
180fb726d48Sopenharmony_ci                        (renders.sample as SampleRender).renderMainThread(
181fb726d48Sopenharmony_ci                            {
182fb726d48Sopenharmony_ci                                context: context,
183fb726d48Sopenharmony_ci                                useCache: useCache,
184fb726d48Sopenharmony_ci                                type: 'bpftrace',
185fb726d48Sopenharmony_ci                                start_ts: startTS,
186fb726d48Sopenharmony_ci                                uniqueProperty: uniqueProperty,
187fb726d48Sopenharmony_ci                                //@ts-ignore
188fb726d48Sopenharmony_ci                                flattenTreeArray: flattenTreeArray
189fb726d48Sopenharmony_ci                            },
190fb726d48Sopenharmony_ci                            row
191fb726d48Sopenharmony_ci                        );
192fb726d48Sopenharmony_ci                        row.canvasRestore(context)
193fb726d48Sopenharmony_ci                    };
194fb726d48Sopenharmony_ci                    //@ts-ignore
195fb726d48Sopenharmony_ci                    row.name = `${res.relation.detail}(${res.relation.function_name})`;
196fb726d48Sopenharmony_ci                    row.style.height = `${height}px`;
197fb726d48Sopenharmony_ci                }
198fb726d48Sopenharmony_ci                this.trace.refreshCanvas(false)
199fb726d48Sopenharmony_ci            })
200fb726d48Sopenharmony_ci        })
201fb726d48Sopenharmony_ci    }
202fb726d48Sopenharmony_ci
203fb726d48Sopenharmony_ci    /**
204fb726d48Sopenharmony_ci     * 清空缓存
205fb726d48Sopenharmony_ci     * @param row 
206fb726d48Sopenharmony_ci     */
207fb726d48Sopenharmony_ci    //@ts-ignore
208fb726d48Sopenharmony_ci    resetChartData(row: TraceRow<unknown>) {
209fb726d48Sopenharmony_ci        row.dataList = [];
210fb726d48Sopenharmony_ci        row.dataList2 = [];
211fb726d48Sopenharmony_ci        row.dataListCache = [];
212fb726d48Sopenharmony_ci        row.isComplete = false;
213fb726d48Sopenharmony_ci    }
214fb726d48Sopenharmony_ci
215fb726d48Sopenharmony_ci    /**
216fb726d48Sopenharmony_ci     * 获取上传的文件内容 转为json格式
217fb726d48Sopenharmony_ci     * @param file 
218fb726d48Sopenharmony_ci     * @returns 
219fb726d48Sopenharmony_ci     */
220fb726d48Sopenharmony_ci    getJsonData(file: unknown): Promise<unknown> {
221fb726d48Sopenharmony_ci        return new Promise((resolve, reject) => {
222fb726d48Sopenharmony_ci            let reader = new FileReader();
223fb726d48Sopenharmony_ci            //@ts-ignore
224fb726d48Sopenharmony_ci            reader.readAsText(file.detail || file);
225fb726d48Sopenharmony_ci            reader.onloadend = (e: unknown) => {
226fb726d48Sopenharmony_ci                //@ts-ignore
227fb726d48Sopenharmony_ci                const fileContent = e.target?.result;
228fb726d48Sopenharmony_ci                if (fileContent === this.currentFile) {
229fb726d48Sopenharmony_ci                    this.currentFile = undefined;
230fb726d48Sopenharmony_ci                    resolve(false)
231fb726d48Sopenharmony_ci                } else {
232fb726d48Sopenharmony_ci                    this.currentFile = fileContent;
233fb726d48Sopenharmony_ci                }
234fb726d48Sopenharmony_ci                try {
235fb726d48Sopenharmony_ci                    resolve(JSON.parse(fileContent));
236fb726d48Sopenharmony_ci                    document.dispatchEvent(
237fb726d48Sopenharmony_ci                        new CustomEvent('file-correct')
238fb726d48Sopenharmony_ci                    )
239fb726d48Sopenharmony_ci                    SpStatisticsHttpUtil.addOrdinaryVisitAction({
240fb726d48Sopenharmony_ci                        event: 'bpftrace',
241fb726d48Sopenharmony_ci                        action: 'bpftrace',
242fb726d48Sopenharmony_ci                    });
243fb726d48Sopenharmony_ci                } catch (error) {
244fb726d48Sopenharmony_ci                    document.dispatchEvent(
245fb726d48Sopenharmony_ci                        new CustomEvent('file-error')
246fb726d48Sopenharmony_ci                    )
247fb726d48Sopenharmony_ci                }
248fb726d48Sopenharmony_ci            }
249fb726d48Sopenharmony_ci        })
250fb726d48Sopenharmony_ci    }
251fb726d48Sopenharmony_ci
252fb726d48Sopenharmony_ci    /**
253fb726d48Sopenharmony_ci     * 树结构扁平化
254fb726d48Sopenharmony_ci     * @param treeData 
255fb726d48Sopenharmony_ci     * @param depth 
256fb726d48Sopenharmony_ci     * @param parentName 
257fb726d48Sopenharmony_ci     * @returns 
258fb726d48Sopenharmony_ci     */
259fb726d48Sopenharmony_ci    getFlattenTreeData(treeData: Array<unknown>, depth: number = 0, parentName: string = ''): Array<unknown> {
260fb726d48Sopenharmony_ci        let result: Array<object> = [];
261fb726d48Sopenharmony_ci        treeData.forEach(node => {
262fb726d48Sopenharmony_ci            //@ts-ignore
263fb726d48Sopenharmony_ci            const name: string = node['function_name'];
264fb726d48Sopenharmony_ci            const newNode: unknown = {};
265fb726d48Sopenharmony_ci            if (name && name.indexOf('unknown') > -1) {
266fb726d48Sopenharmony_ci                //@ts-ignore
267fb726d48Sopenharmony_ci                newNode['children'] = this.getUnknownAllChildrenNames(node);
268fb726d48Sopenharmony_ci            }
269fb726d48Sopenharmony_ci            //@ts-ignore
270fb726d48Sopenharmony_ci            newNode['detail'] = node['detail'];
271fb726d48Sopenharmony_ci            //@ts-ignore
272fb726d48Sopenharmony_ci            newNode['depth'] = depth;
273fb726d48Sopenharmony_ci            //@ts-ignore
274fb726d48Sopenharmony_ci            newNode['name'] = name;
275fb726d48Sopenharmony_ci            //@ts-ignore
276fb726d48Sopenharmony_ci            newNode['parentName'] = parentName;
277fb726d48Sopenharmony_ci            //@ts-ignore
278fb726d48Sopenharmony_ci            newNode['property'] = [];
279fb726d48Sopenharmony_ci            //@ts-ignore
280fb726d48Sopenharmony_ci            result.push(newNode);
281fb726d48Sopenharmony_ci            //@ts-ignore
282fb726d48Sopenharmony_ci            if (node.children) {
283fb726d48Sopenharmony_ci                //@ts-ignore
284fb726d48Sopenharmony_ci                result = result.concat(this.getFlattenTreeData(node.children, depth + 1, node['function_name']))
285fb726d48Sopenharmony_ci            }
286fb726d48Sopenharmony_ci        })
287fb726d48Sopenharmony_ci        return result
288fb726d48Sopenharmony_ci    }
289fb726d48Sopenharmony_ci
290fb726d48Sopenharmony_ci    /**
291fb726d48Sopenharmony_ci     * 查找重复项
292fb726d48Sopenharmony_ci     * @param propertyData 
293fb726d48Sopenharmony_ci     * @returns 
294fb726d48Sopenharmony_ci     */
295fb726d48Sopenharmony_ci    removeDuplicates(propertyData: Array<unknown>): Array<unknown> {
296fb726d48Sopenharmony_ci        const result: Array<unknown> = [];
297fb726d48Sopenharmony_ci        propertyData.forEach(propertyGroup => {
298fb726d48Sopenharmony_ci            const groups: Array<unknown> = [];
299fb726d48Sopenharmony_ci            //@ts-ignore
300fb726d48Sopenharmony_ci            propertyGroup.forEach((property: unknown) => {
301fb726d48Sopenharmony_ci                //@ts-ignore
302fb726d48Sopenharmony_ci                const duplicateObj = groups.find(group => group['func_name'] === property['func_name']);
303fb726d48Sopenharmony_ci                if (duplicateObj) {
304fb726d48Sopenharmony_ci                    //@ts-ignore
305fb726d48Sopenharmony_ci                    duplicateObj['begin'] = Math.min(duplicateObj['begin'], property['begin']);
306fb726d48Sopenharmony_ci                    //@ts-ignore
307fb726d48Sopenharmony_ci                    duplicateObj['end'] = Math.max(duplicateObj['end'], property['end']);
308fb726d48Sopenharmony_ci                } else {
309fb726d48Sopenharmony_ci                    groups.push(property)
310fb726d48Sopenharmony_ci                }
311fb726d48Sopenharmony_ci            })
312fb726d48Sopenharmony_ci            result.push(groups);
313fb726d48Sopenharmony_ci        })
314fb726d48Sopenharmony_ci        return result
315fb726d48Sopenharmony_ci    }
316fb726d48Sopenharmony_ci
317fb726d48Sopenharmony_ci    /**
318fb726d48Sopenharmony_ci     * 关系树赋值
319fb726d48Sopenharmony_ci     * @param relationData 
320fb726d48Sopenharmony_ci     * @param propertyData 
321fb726d48Sopenharmony_ci     */
322fb726d48Sopenharmony_ci    setRelationDataProperty(relationData: Array<unknown>, propertyData: Array<unknown>): Array<unknown> {
323fb726d48Sopenharmony_ci        const sampleProperty = relationData;
324fb726d48Sopenharmony_ci        //数组每一项进行比对
325fb726d48Sopenharmony_ci        propertyData.forEach(propertyGroup => {
326fb726d48Sopenharmony_ci            //@ts-ignore
327fb726d48Sopenharmony_ci            propertyGroup.forEach((property: unknown) => {
328fb726d48Sopenharmony_ci                //@ts-ignore
329fb726d48Sopenharmony_ci                const relation = sampleProperty.find(relation => relation['name'] === property['func_name']);
330fb726d48Sopenharmony_ci                //property属性存储每帧数据
331fb726d48Sopenharmony_ci                //@ts-ignore
332fb726d48Sopenharmony_ci                relation?.property.push({
333fb726d48Sopenharmony_ci                    //@ts-ignore
334fb726d48Sopenharmony_ci                    name: property['func_name'],
335fb726d48Sopenharmony_ci                    //@ts-ignore
336fb726d48Sopenharmony_ci                    detail: relation['detail'],
337fb726d48Sopenharmony_ci                    //@ts-ignore
338fb726d48Sopenharmony_ci                    end: property['end'],
339fb726d48Sopenharmony_ci                    //@ts-ignore
340fb726d48Sopenharmony_ci                    begin: property['begin'],
341fb726d48Sopenharmony_ci                    //@ts-ignore
342fb726d48Sopenharmony_ci                    depth: relation['depth'],
343fb726d48Sopenharmony_ci                    //@ts-ignore
344fb726d48Sopenharmony_ci                    instructions: property['instructions'],
345fb726d48Sopenharmony_ci                    //@ts-ignore
346fb726d48Sopenharmony_ci                    cycles: property['cycles']
347fb726d48Sopenharmony_ci                })
348fb726d48Sopenharmony_ci            })
349fb726d48Sopenharmony_ci        })
350fb726d48Sopenharmony_ci
351fb726d48Sopenharmony_ci        //获取所有名字为unknown的数据
352fb726d48Sopenharmony_ci        //@ts-ignore
353fb726d48Sopenharmony_ci        const unknownRelation = sampleProperty.filter(relation => relation['name'].indexOf('unknown') > -1);
354fb726d48Sopenharmony_ci        //二维数组 用于存放unknown下所有子节点的数据
355fb726d48Sopenharmony_ci        let twoDimensionalArray: Array<unknown> = [];
356fb726d48Sopenharmony_ci        let result: Array<unknown> = [];
357fb726d48Sopenharmony_ci        unknownRelation.forEach(unknownItem => {
358fb726d48Sopenharmony_ci            result = [];
359fb726d48Sopenharmony_ci            twoDimensionalArray = [];
360fb726d48Sopenharmony_ci            //@ts-ignore
361fb726d48Sopenharmony_ci            const children = unknownItem['children'];
362fb726d48Sopenharmony_ci            //先获取到unknwon节点下每个子节点的property
363fb726d48Sopenharmony_ci            Object.keys(children).forEach(key => {
364fb726d48Sopenharmony_ci                //@ts-ignore
365fb726d48Sopenharmony_ci                unknownItem.children[key] = (sampleProperty.find(relation => relation['name'] === key)).property;
366fb726d48Sopenharmony_ci            })
367fb726d48Sopenharmony_ci            //将每个子节点的property加到二维数组中
368fb726d48Sopenharmony_ci            Object.values(children).forEach((value: unknown) => {
369fb726d48Sopenharmony_ci                //@ts-ignore
370fb726d48Sopenharmony_ci                if (value.length > 0) {
371fb726d48Sopenharmony_ci                    twoDimensionalArray.push(value)
372fb726d48Sopenharmony_ci                }
373fb726d48Sopenharmony_ci            })
374fb726d48Sopenharmony_ci            if (twoDimensionalArray.length > 0) {
375fb726d48Sopenharmony_ci                //取每列的最大值和最小值
376fb726d48Sopenharmony_ci                //@ts-ignore
377fb726d48Sopenharmony_ci                for (let i = 0; i < twoDimensionalArray[0].length; i++) {
378fb726d48Sopenharmony_ci                    const data = {
379fb726d48Sopenharmony_ci                        //@ts-ignore
380fb726d48Sopenharmony_ci                        name: unknownItem['name'],
381fb726d48Sopenharmony_ci                        //@ts-ignore
382fb726d48Sopenharmony_ci                        detail: unknownItem['detail'],
383fb726d48Sopenharmony_ci                        //@ts-ignore
384fb726d48Sopenharmony_ci                        begin: (twoDimensionalArray[0][i]).begin,
385fb726d48Sopenharmony_ci                        end: 0,
386fb726d48Sopenharmony_ci                        //@ts-ignore
387fb726d48Sopenharmony_ci                        depth: unknownItem['depth']
388fb726d48Sopenharmony_ci                    }
389fb726d48Sopenharmony_ci                    for (let j = 0; j < twoDimensionalArray.length; j++) {
390fb726d48Sopenharmony_ci                        //@ts-ignore
391fb726d48Sopenharmony_ci                        data['end'] = Math.max((twoDimensionalArray[j][i])['end'], data['end']);
392fb726d48Sopenharmony_ci                        //@ts-ignore
393fb726d48Sopenharmony_ci                        data['begin'] = Math.min((twoDimensionalArray[j][i])['begin'], data['begin']);
394fb726d48Sopenharmony_ci                    }
395fb726d48Sopenharmony_ci                    result.push(data);
396fb726d48Sopenharmony_ci                }
397fb726d48Sopenharmony_ci                //@ts-ignore
398fb726d48Sopenharmony_ci                unknownItem.property = result;
399fb726d48Sopenharmony_ci            }
400fb726d48Sopenharmony_ci        })
401fb726d48Sopenharmony_ci        return sampleProperty;
402fb726d48Sopenharmony_ci    }
403fb726d48Sopenharmony_ci
404fb726d48Sopenharmony_ci    /**
405fb726d48Sopenharmony_ci     * 获取unknown节点下所有孩子节点的名称
406fb726d48Sopenharmony_ci     * @param node 
407fb726d48Sopenharmony_ci     * @param names 
408fb726d48Sopenharmony_ci     */
409fb726d48Sopenharmony_ci    getUnknownAllChildrenNames(node: unknown, names: unknown = {}): object {
410fb726d48Sopenharmony_ci        //@ts-ignore
411fb726d48Sopenharmony_ci        if (node['children']) {
412fb726d48Sopenharmony_ci            //@ts-ignore
413fb726d48Sopenharmony_ci            node['children'].forEach((child: unknown) => {
414fb726d48Sopenharmony_ci                //@ts-ignore
415fb726d48Sopenharmony_ci                if (child['function_name'].indexOf('unknown') < 0) {
416fb726d48Sopenharmony_ci                    //@ts-ignore
417fb726d48Sopenharmony_ci                    names[child['function_name']] = []
418fb726d48Sopenharmony_ci                } else {
419fb726d48Sopenharmony_ci                    this.getUnknownAllChildrenNames(child, names)
420fb726d48Sopenharmony_ci                }
421fb726d48Sopenharmony_ci            })
422fb726d48Sopenharmony_ci        }
423fb726d48Sopenharmony_ci        //@ts-ignore
424fb726d48Sopenharmony_ci        return names
425fb726d48Sopenharmony_ci    }
426fb726d48Sopenharmony_ci}
427