• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { BaseElement, element } from '../../../../../base-ui/BaseElement';
17import { LitTable } from '../../../../../base-ui/table/lit-table';
18import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar';
19import { FrameChart } from '../../../chart/FrameChart';
20import '../../../chart/FrameChart';
21import { SelectionParam } from '../../../../bean/BoxSelection';
22import { ChartMode } from '../../../../bean/FrameChartStruct';
23import { FilterData, TabPaneFilter } from '../TabPaneFilter';
24import '../TabPaneFilter';
25import { procedurePool } from '../../../../database/Procedure';
26import { FileMerageBean } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem';
27import { showButtonMenu } from '../SheetUtils';
28import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct';
29import '../../../../../base-ui/headline/lit-headline';
30import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline';
31import { TabPaneFileSystemCalltreeHtml } from './TabPaneFileSystemCalltree.html';
32
33const InvertOptionIndex: number = 0;
34const hideEventOptionIndex: number = 2;
35const hideThreadOptionIndex: number = 3;
36
37@element('tabpane-filesystem-calltree')
38export class TabpaneFilesystemCalltree extends BaseElement {
39  private fsCallTreeTbl: LitTable | null | undefined;
40  private fsCallTreeTbr: LitTable | null | undefined;
41  private fsCallTreeProgressEL: LitProgressBar | null | undefined;
42  private fsCallTreeRightSource: Array<FileMerageBean> = [];
43  private fsCallTreeFilter: unknown;
44  private fsCallTreeDataSource: unknown[] = [];
45  private fsCallTreeSortKey = 'weight';
46  private fsCallTreeSortType: number = 0;
47  private fsCallTreeCurrentSelectedData: unknown = undefined;
48  private frameChart: FrameChart | null | undefined;
49  private isChartShow: boolean = false;
50  private systmeRuleName: string = '/system/';
51  private fsCallTreeNumRuleName: string = '/max/min/';
52  private needShowMenu: boolean = true;
53  private searchValue: string = '';
54  private loadingList: number[] = [];
55  private loadingPage: unknown;
56  private currentSelection: SelectionParam | undefined;
57  private currentFsCallTreeDataSource: Array<FileMerageBean> = [];
58
59  private currentRowClickData: unknown;
60  private initWidth: number = 0;
61  private _pieTitle: string = '';
62  private _cWidth: number = 0;
63  private _currentFsCallTreeLevel: number = 0;
64  private _fsRowClickData: unknown = undefined;
65  private FsCallTreeLevel: CallTreeLevelStruct | undefined | null;
66  private fileSystemHeadLine: LitHeadLine | null | undefined;
67
68  set pieTitle(value: string) {
69    this._pieTitle = value;
70    if (this._pieTitle.length > 0) {
71      this.fileSystemHeadLine!.isShow = true;
72      this.fileSystemHeadLine!.titleTxt = this._pieTitle;
73      this.fileSystemHeadLine!.closeCallback = (): void => {
74        this.restore();
75      };
76    }
77  }
78
79  set cWidth(value: number) {
80    this._cWidth = value;
81  }
82
83  set currentFsCallTreeLevel(value: number) {
84    this._currentFsCallTreeLevel = value;
85  }
86
87  set fsRowClickData(value: unknown) {
88    this._fsRowClickData = value;
89  }
90
91  set data(fsCallTreeSelection: SelectionParam | unknown) {
92    if (fsCallTreeSelection !== this.currentSelection && this._fsRowClickData === this.currentRowClickData) {
93      this._fsRowClickData = undefined;
94    }
95    if (fsCallTreeSelection === this.currentSelection && !this.currentSelection?.isRowClick) {
96      return;
97    }
98    this.searchValue = ''; // @ts-ignore
99    this.currentSelection = fsCallTreeSelection;
100    this.currentRowClickData = this._fsRowClickData;
101    this.fsCallTreeTbl!.style.visibility = 'visible'; // @ts-ignore
102    if (this.parentElement!.clientHeight > this.fsCallTreeFilter!.clientHeight) {
103      // @ts-ignore
104      this.fsCallTreeFilter!.style.display = 'flex';
105    } else {
106      // @ts-ignore
107      this.fsCallTreeFilter!.style.display = 'none';
108    }
109    procedurePool.submitWithName('logic0', 'fileSystem-reset', [], undefined, (): void => {}); // @ts-ignore
110    this.fsCallTreeFilter!.initializeFilterTree(true, true, true); // @ts-ignore
111    this.fsCallTreeFilter!.filterValue = '';
112    this.fsCallTreeProgressEL!.loading = true; // @ts-ignore
113    this.loadingPage.style.visibility = 'visible'; // @ts-ignore
114    this.getDataByWorkAndUpDateCanvas(fsCallTreeSelection);
115  }
116
117  getDataByWorkAndUpDateCanvas(fsCallTreeSelection: SelectionParam): void {
118    if (this.clientWidth === 0) {
119      this.initWidth = this._cWidth;
120    } else {
121      this.initWidth = this.clientWidth;
122    }
123    if (this._fsRowClickData && this.currentRowClickData !== undefined && this.currentSelection?.isRowClick) {
124      this.getFsCallTreeDataByPieLevel();
125    } else {
126      this.fileSystemHeadLine!.isShow = false;
127      this.getFsCallTreeData(fsCallTreeSelection, this.initWidth);
128    }
129  }
130
131  private getFsCallTreeData(fsCallTreeSelection: SelectionParam | unknown, initWidth: number): void {
132    this.getDataByWorker(
133      [
134        {
135          funcName: 'setSearchValue',
136          funcArgs: [''],
137        },
138        {
139          funcName: 'getCurrentDataFromDb', // @ts-ignore
140          funcArgs: [{ queryFuncName: 'fileSystem', ...fsCallTreeSelection }],
141        },
142      ],
143      (fsCallTreeResults: unknown[]): void => {
144        this.setLTableData(fsCallTreeResults);
145        this.fsCallTreeTbr!.recycleDataSource = [];
146        this.frameChart!.mode = ChartMode.Duration;
147        this.frameChart?.updateCanvas(true, initWidth); // @ts-ignore
148        this.frameChart!.data = this.fsCallTreeDataSource; // @ts-ignore
149        this.currentFsCallTreeDataSource = this.fsCallTreeDataSource;
150        this.switchFlameChart(); // @ts-ignore
151        this.fsCallTreeFilter.icon = 'block';
152      }
153    );
154  }
155
156  /**
157   * 根据Analysis Tab饼图跳转过来的层级绘制对应的CallTree Tab火焰图和表格
158   */
159  private getFsCallTreeDataByPieLevel(): void {
160    this.FsCallTreeLevel = new CallTreeLevelStruct();
161    this.FsCallTreeLevel = {
162      // @ts-ignore
163      processId: this._fsRowClickData.pid, // @ts-ignore
164      threadId: this._fsRowClickData.tid, // @ts-ignore
165      typeId: this._fsRowClickData.type, // @ts-ignore
166      libId: this._fsRowClickData.libId, // @ts-ignore
167      symbolId: this._fsRowClickData.symbolId,
168    };
169    let args = [];
170    args.push({
171      funcName: 'getCurrentDataFromDb',
172      funcArgs: [this.currentSelection, this.FsCallTreeLevel],
173    });
174    // @ts-ignore
175    if (this._fsRowClickData && this._fsRowClickData.libId !== undefined && this._currentFsCallTreeLevel === 3) {
176      // @ts-ignore
177      this.FsCallTreeLevel.libName = this._fsRowClickData.tableName;
178      args.push({
179        funcName: 'showLibLevelData',
180        funcArgs: [this.FsCallTreeLevel.libId, this.FsCallTreeLevel.libName],
181      });
182    } else if (
183      this._fsRowClickData && // @ts-ignore
184      this._fsRowClickData.symbolId !== undefined &&
185      this._currentFsCallTreeLevel === 4
186    ) {
187      // @ts-ignore
188      this.FsCallTreeLevel.symbolName = this._fsRowClickData.tableName;
189      args.push({
190        funcName: 'showFunLevelData',
191        funcArgs: [this.FsCallTreeLevel.symbolId, this.FsCallTreeLevel.symbolName],
192      });
193    }
194
195    this.getDataByWorker(args, (fsCallTreeResults: unknown[]) => {
196      this.setLTableData(fsCallTreeResults);
197      this.fsCallTreeTbr!.recycleDataSource = [];
198      this.frameChart!.mode = ChartMode.Duration;
199      this.frameChart?.updateCanvas(true, this.initWidth); // @ts-ignore
200      this.frameChart!.data = this.fsCallTreeDataSource; // @ts-ignore
201      this.currentFsCallTreeDataSource = this.fsCallTreeDataSource;
202      this.switchFlameChart(); // @ts-ignore
203      this.fsCallTreeFilter.icon = 'block';
204    });
205  }
206
207  private restore(): void {
208    this.searchValue = ''; // @ts-ignore
209    this.fsCallTreeFilter.filterValue = '';
210    this.fileSystemHeadLine!.isShow = false;
211    this._fsRowClickData = undefined;
212    this.getFsCallTreeData(this.currentSelection, this.initWidth);
213  }
214
215  getParentTree(
216    fsCallTreeSrc: Array<FileMerageBean>,
217    fsCallTreeTarget: FileMerageBean,
218    parents: Array<FileMerageBean>
219  ): boolean {
220    for (let fsCallTreeBean of fsCallTreeSrc) {
221      if (fsCallTreeBean.id === fsCallTreeTarget.id) {
222        parents.push(fsCallTreeBean);
223        return true;
224      } else {
225        if (this.getParentTree(fsCallTreeBean.children as Array<FileMerageBean>, fsCallTreeTarget, parents)) {
226          parents.push(fsCallTreeBean);
227          return true;
228        }
229      }
230    }
231    return false;
232  }
233
234  getChildTree(fsCallTreeSrc: Array<FileMerageBean>, id: string, children: Array<FileMerageBean>): boolean {
235    for (let fsCallTreeBean of fsCallTreeSrc) {
236      if (fsCallTreeBean.id === id && fsCallTreeBean.children.length === 0) {
237        children.push(fsCallTreeBean);
238        return true;
239      } else {
240        if (this.getChildTree(fsCallTreeBean.children as Array<FileMerageBean>, id, children)) {
241          children.push(fsCallTreeBean);
242          return true;
243        }
244      }
245    }
246    return false;
247  }
248
249  setRightTableData(merageBean: FileMerageBean): void {
250    let parents: Array<FileMerageBean> = [];
251    let children: Array<FileMerageBean> = []; // @ts-ignore
252    this.getParentTree(this.fsCallTreeDataSource, merageBean, parents);
253    let maxId: string = merageBean.id;
254    let maxDur: number = 0;
255
256    function findMaxStack(fsMerageBean: FileMerageBean): void {
257      if (fsMerageBean.children.length === 0) {
258        if (fsMerageBean.dur > maxDur) {
259          maxDur = fsMerageBean.dur;
260          maxId = fsMerageBean.id;
261        }
262      } else {
263        fsMerageBean.children.map((callChild: unknown): void => {
264          findMaxStack(<FileMerageBean>callChild);
265        });
266      }
267    }
268
269    findMaxStack(merageBean);
270    this.getChildTree(merageBean.children as Array<FileMerageBean>, maxId, children);
271    let fsMerageParentsList = parents.reverse().concat(children.reverse());
272    for (let data of fsMerageParentsList) {
273      data.type = data.lib.endsWith('.so.1') || data.lib.endsWith('.dll') || data.lib.endsWith('.so') ? 0 : 1;
274    }
275    let len = fsMerageParentsList.length;
276    this.fsCallTreeRightSource = fsMerageParentsList;
277    this.fsCallTreeTbr!.dataSource = len === 0 ? [] : fsMerageParentsList;
278  }
279
280  initElements(): void {
281    this.fileSystemHeadLine = this.shadowRoot?.querySelector('.titleBox');
282    this.fsCallTreeTbl = this.shadowRoot?.querySelector<LitTable>('#tb-filesystem-calltree');
283    this.fsCallTreeProgressEL = this.shadowRoot?.querySelector('.fs-call-tree-progress') as LitProgressBar;
284    this.frameChart = this.shadowRoot?.querySelector<FrameChart>('#framechart');
285    this.loadingPage = this.shadowRoot?.querySelector('.fs-call-tree-loading');
286    this.addEventListener('contextmenu', (event) => {
287      event.preventDefault(); // 阻止默认的上下文菜单弹框
288    });
289    this.frameChart!.addChartClickListener((needShowMenu: boolean) => {
290      this.parentElement!.scrollTo(0, 0);
291      showButtonMenu(this.fsCallTreeFilter, needShowMenu);
292      this.needShowMenu = needShowMenu;
293    });
294    this.fsCallTreeTbl!.rememberScrollTop = true;
295    this.fsCallTreeFilter = this.shadowRoot?.querySelector<TabPaneFilter>('#filter'); // @ts-ignore
296    this.fsCallTreeFilter!.disabledTransfer(true);
297    this.tblRowClickEvent();
298    this.fsCallTreeTbr = this.shadowRoot?.querySelector<LitTable>('#tb-filesystem-list');
299    this.tbrRowClickEvent();
300    let boundFilterFunc = this.filterFunc.bind(this); // @ts-ignore
301    this.fsCallTreeFilter!.getDataLibrary(boundFilterFunc); // @ts-ignore
302    this.fsCallTreeFilter!.getDataMining(boundFilterFunc);
303    this.handleCallTreeData();
304    this.handleConstraintsData();
305    this.handleFilterData();
306    this.callTreeColumnClick();
307  }
308
309  private filterFunc(data: unknown): void {
310    let fsCallTreeFuncArgs: unknown[] = []; // @ts-ignore
311    if (data.type === 'check') {
312      this.handleCheckType(data, fsCallTreeFuncArgs); // @ts-ignore
313    } else if (data.type === 'select') {
314      this.handleSelectType(fsCallTreeFuncArgs, data); // @ts-ignore
315    } else if (data.type === 'button') {
316      // @ts-ignore
317      if (data.item === 'symbol') {
318        // @ts-ignore
319        if (this.fsCallTreeCurrentSelectedData && !this.fsCallTreeCurrentSelectedData.canCharge) {
320          return;
321        }
322        if (this.fsCallTreeCurrentSelectedData !== undefined) {
323          this.handleSymbolCase(data, fsCallTreeFuncArgs);
324        } else {
325          return;
326        } // @ts-ignore
327      } else if (data.item === 'library') {
328        // @ts-ignore
329        if (this.fsCallTreeCurrentSelectedData && !this.fsCallTreeCurrentSelectedData.canCharge) {
330          return;
331        } // @ts-ignore
332        if (this.fsCallTreeCurrentSelectedData !== undefined && this.fsCallTreeCurrentSelectedData.lib !== '') {
333          this.handleLibraryCase(data, fsCallTreeFuncArgs);
334        } else {
335          return;
336        } // @ts-ignore
337      } else if (data.item === 'restore') {
338        this.handleRestoreCase(data, fsCallTreeFuncArgs);
339      }
340    }
341    this.performDataProcessing(fsCallTreeFuncArgs);
342  }
343
344  private handleSymbolCase(data: unknown, fsCallTreeFuncArgs: unknown[]): void {
345    // @ts-ignore
346    this.fsCallTreeFilter!.addDataMining({ name: this.fsCallTreeCurrentSelectedData.symbol }, data.item);
347    fsCallTreeFuncArgs.push({
348      funcName: 'splitTree', // @ts-ignore
349      funcArgs: [this.fsCallTreeCurrentSelectedData.symbol, false, true],
350    });
351  }
352
353  private handleLibraryCase(data: unknown, fsCallTreeFuncArgs: unknown[]): void {
354    // @ts-ignore
355    this.fsCallTreeFilter!.addDataMining({ name: this.fsCallTreeCurrentSelectedData.lib }, data.item);
356    fsCallTreeFuncArgs.push({
357      funcName: 'splitTree', // @ts-ignore
358      funcArgs: [this.fsCallTreeCurrentSelectedData.lib, false, false],
359    });
360  }
361
362  private callTreeColumnClick(): void {
363    this.fsCallTreeTbl!.addEventListener('column-click', (evt): void => {
364      // @ts-ignore
365      this.fsCallTreeSortKey = evt.detail.key;
366      // @ts-ignore
367      this.fsCallTreeSortType = evt.detail.sort;
368      // @ts-ignore
369      this.setLTableData(this.fsCallTreeDataSource); // @ts-ignore
370      this.frameChart!.data = this.fsCallTreeDataSource;
371    });
372  }
373
374  private handleFilterData(): void {
375    // @ts-ignore
376    this.fsCallTreeFilter!.getFilterData((data: FilterData): void => {
377      if ((this.isChartShow && data.icon === 'tree') || (!this.isChartShow && data.icon === 'block')) {
378        this.switchFlameChart(data); // @ts-ignore
379      } else if (this.searchValue !== this.fsCallTreeFilter!.filterValue) {
380        // @ts-ignore
381        this.searchValue = this.fsCallTreeFilter!.filterValue;
382        let fileArgs = [
383          {
384            funcName: 'setSearchValue',
385            funcArgs: [this.searchValue],
386          },
387          {
388            funcName: 'resetAllNode',
389            funcArgs: [],
390          },
391        ];
392        this.getDataByWorker(fileArgs, (result: unknown[]): void => {
393          this.fsCallTreeTbl!.isSearch = true;
394          this.fsCallTreeTbl!.setStatus(result, true);
395          this.setLTableData(result); // @ts-ignore
396          this.frameChart!.data = this.fsCallTreeDataSource;
397          this.switchFlameChart(data);
398        });
399      } else {
400        this.fsCallTreeTbl!.setStatus(this.fsCallTreeDataSource, true);
401        this.setLTableData(this.fsCallTreeDataSource);
402        this.switchFlameChart(data);
403      }
404    });
405  }
406
407  private handleConstraintsData(): void {
408    // @ts-ignore
409    this.fsCallTreeFilter!.getCallTreeConstraintsData((data: unknown): void => {
410      let fsCallTreeConstraintsArgs: unknown[] = [
411        {
412          funcName: 'resotreAllNode',
413          funcArgs: [[this.fsCallTreeNumRuleName]],
414        },
415        {
416          funcName: 'clearSplitMapData',
417          funcArgs: [this.fsCallTreeNumRuleName],
418        },
419      ]; // @ts-ignore
420      if (data.checked) {
421        fsCallTreeConstraintsArgs.push({
422          funcName: 'hideNumMaxAndMin', // @ts-ignore
423          funcArgs: [parseInt(data.min), data.max],
424        });
425      }
426      fsCallTreeConstraintsArgs.push({
427        funcName: 'resetAllNode',
428        funcArgs: [],
429      });
430      this.getDataByWorker(fsCallTreeConstraintsArgs, (result: unknown[]): void => {
431        this.setLTableData(result); // @ts-ignore
432        this.frameChart!.data = this.fsCallTreeDataSource;
433        if (this.isChartShow) {
434          this.frameChart?.calculateChartData();
435        }
436      });
437    });
438  }
439
440  private handleCallTreeData(): void {
441    // @ts-ignore
442    this.fsCallTreeFilter!.getCallTreeData((data: unknown): void => {
443      // @ts-ignore
444      if ([InvertOptionIndex, hideThreadOptionIndex, hideEventOptionIndex].includes(data.value)) {
445        this.refreshAllNode({
446          // @ts-ignore
447          ...this.fsCallTreeFilter!.getFilterTreeData(), // @ts-ignore
448          callTree: data.checks,
449        });
450      } else {
451        let fileSysCallTreeArgs: unknown[] = []; // @ts-ignore
452        if (data.checks[1]) {
453          fileSysCallTreeArgs.push({
454            funcName: 'hideSystemLibrary',
455            funcArgs: [],
456          });
457          fileSysCallTreeArgs.push({
458            funcName: 'resetAllNode',
459            funcArgs: [],
460          });
461        } else {
462          fileSysCallTreeArgs.push({
463            funcName: 'resotreAllNode',
464            funcArgs: [[this.systmeRuleName]],
465          });
466          fileSysCallTreeArgs.push({
467            funcName: 'resetAllNode',
468            funcArgs: [],
469          });
470          fileSysCallTreeArgs.push({
471            funcName: 'clearSplitMapData',
472            funcArgs: [this.systmeRuleName],
473          });
474        }
475        this.getDataByWorker(fileSysCallTreeArgs, (result: unknown[]): void => {
476          this.setLTableData(result); // @ts-ignore
477          this.frameChart!.data = this.fsCallTreeDataSource;
478          if (this.isChartShow) {
479            this.frameChart?.calculateChartData();
480          }
481        });
482      }
483    });
484  }
485
486  private performDataProcessing(fsCallTreeFuncArgs: unknown[]): void {
487    this.getDataByWorker(fsCallTreeFuncArgs, (result: unknown[]): void => {
488      this.setLTableData(result); // @ts-ignore
489      this.frameChart!.data = this.fsCallTreeDataSource;
490      if (this.isChartShow) {
491        this.frameChart?.calculateChartData();
492      }
493      this.fsCallTreeTbl!.move1px();
494      if (this.fsCallTreeCurrentSelectedData) {
495        // @ts-ignore
496        this.fsCallTreeCurrentSelectedData.isSelected = false;
497        this.fsCallTreeTbl?.clearAllSelection(this.fsCallTreeCurrentSelectedData);
498        this.fsCallTreeTbr!.recycleDataSource = [];
499        this.fsCallTreeCurrentSelectedData = undefined;
500      }
501    });
502  }
503
504  private handleRestoreCase(data: unknown, fsCallTreeFuncArgs: unknown[]): void {
505    // @ts-ignore
506    if (data.remove !== undefined && data.remove.length > 0) {
507      // @ts-ignore
508      let list = data.remove.map((item: unknown) => {
509        // @ts-ignore
510        return item.name;
511      });
512      fsCallTreeFuncArgs.push({
513        funcName: 'resotreAllNode',
514        funcArgs: [list],
515      });
516      fsCallTreeFuncArgs.push({
517        funcName: 'resetAllNode',
518        funcArgs: [],
519      });
520      list.forEach((symbol: string): void => {
521        fsCallTreeFuncArgs.push({
522          funcName: 'clearSplitMapData',
523          funcArgs: [symbol],
524        });
525      });
526    }
527  }
528
529  private handleSelectType(fsCallTreeFuncArgs: unknown[], data: unknown): void {
530    fsCallTreeFuncArgs.push({
531      funcName: 'resotreAllNode', // @ts-ignore
532      funcArgs: [[data.item.name]],
533    });
534    fsCallTreeFuncArgs.push({
535      funcName: 'clearSplitMapData', // @ts-ignore
536      funcArgs: [data.item.name],
537    });
538    fsCallTreeFuncArgs.push({
539      funcName: 'splitTree', // @ts-ignore
540      funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'],
541    });
542  }
543
544  private handleCheckType(data: unknown, fsCallTreeFuncArgs: unknown[]): void {
545    // @ts-ignore
546    if (data.item.checked) {
547      fsCallTreeFuncArgs.push({
548        funcName: 'splitTree', // @ts-ignore
549        funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'],
550      });
551    } else {
552      fsCallTreeFuncArgs.push({
553        funcName: 'resotreAllNode', // @ts-ignore
554        funcArgs: [[data.item.name]],
555      });
556      fsCallTreeFuncArgs.push({
557        funcName: 'resetAllNode',
558        funcArgs: [],
559      });
560      fsCallTreeFuncArgs.push({
561        funcName: 'clearSplitMapData', // @ts-ignore
562        funcArgs: [data.item.name],
563      });
564    }
565  }
566
567  private tbrRowClickEvent(): void {
568    this.fsCallTreeTbr!.addEventListener('row-click', (evt: unknown): void => {
569      // @ts-ignore
570      let data = evt.detail.data as FileMerageBean;
571      this.fsCallTreeTbl?.clearAllSelection(data); // @ts-ignore
572      (data as unknown).isSelected = true;
573      this.fsCallTreeTbl!.scrollToData(data);
574      // @ts-ignore
575      if ((evt.detail as unknown).callBack) {
576        // @ts-ignore
577        (evt.detail as unknown).callBack(true);
578      }
579    });
580  }
581
582  private tblRowClickEvent(): void {
583    this.fsCallTreeTbl!.addEventListener('row-click', (evt: unknown): void => {
584      // @ts-ignore
585      let data = evt.detail.data as FileMerageBean;
586      document.dispatchEvent(
587        new CustomEvent('number_calibration', {
588          detail: { time: data.tsArray, durations: data.durArray },
589        })
590      );
591      this.setRightTableData(data);
592      data.isSelected = true;
593      this.fsCallTreeCurrentSelectedData = data;
594      this.fsCallTreeTbr?.clearAllSelection(data);
595      this.fsCallTreeTbr?.setCurrentSelection(data);
596      // @ts-ignore
597      if ((evt.detail as unknown).callBack) {
598        // @ts-ignore
599        (evt.detail as unknown).callBack(true);
600      }
601    });
602  }
603
604  connectedCallback(): void {
605    super.connectedCallback();
606    let filterHeight = 0;
607    new ResizeObserver((entries: ResizeObserverEntry[]): void => {
608      let fsCallTreeTabFilter = this.shadowRoot!.querySelector('#filter') as HTMLElement;
609      if (fsCallTreeTabFilter.clientHeight > 0) {
610        filterHeight = fsCallTreeTabFilter.clientHeight;
611      }
612      if (this.parentElement!.clientHeight > filterHeight) {
613        fsCallTreeTabFilter.style.display = 'flex';
614      } else {
615        fsCallTreeTabFilter.style.display = 'none';
616      }
617      if (this.fsCallTreeTbl!.style.visibility === 'hidden') {
618        fsCallTreeTabFilter.style.display = 'none';
619      }
620      if (this.parentElement?.clientHeight !== 0) {
621        if (this.isChartShow) {
622          this.frameChart?.updateCanvas(false, entries[0].contentRect.width);
623          this.frameChart?.calculateChartData();
624        }
625        let headLineHeight = 0;
626        if (this.fileSystemHeadLine?.isShow) {
627          headLineHeight = this.fileSystemHeadLine!.clientHeight;
628        }
629        if (this.fsCallTreeTbl) {
630          // @ts-ignore
631          this.fsCallTreeTbl.shadowRoot.querySelector('.table').style.height = `${
632            this.parentElement!.clientHeight - 10 - 35 - headLineHeight
633          }px`;
634          this.fsCallTreeTbl.reMeauseHeight();
635        }
636        if (this.fsCallTreeTbr) {
637          // @ts-ignore
638          this.fsCallTreeTbr.shadowRoot.querySelector('.table').style.height = `${
639            this.parentElement!.clientHeight - 45 - 21 - headLineHeight
640          }px`;
641          this.fsCallTreeTbr.reMeauseHeight();
642        } // @ts-ignore
643        this.loadingPage.style.height = `${this.parentElement!.clientHeight - 24}px`;
644      }
645    }).observe(this.parentElement!);
646    this.parentElement!.onscroll = (): void => {
647      this.frameChart!.tabPaneScrollTop = this.parentElement!.scrollTop;
648    };
649  }
650
651  switchFlameChart(data?: unknown): void {
652    let fsCallTreePageTab = this.shadowRoot?.querySelector('#show_table');
653    let fsCallTreePageChart = this.shadowRoot?.querySelector('#show_chart'); // @ts-ignore
654    if (!data || data.icon === 'block') {
655      fsCallTreePageChart?.setAttribute('class', 'show');
656      fsCallTreePageTab?.setAttribute('class', '');
657      this.isChartShow = true; // @ts-ignore
658      this.fsCallTreeFilter!.disabledMining = true;
659      showButtonMenu(this.fsCallTreeFilter, this.needShowMenu);
660      this.frameChart?.calculateChartData(); // @ts-ignore
661    } else if (data.icon === 'tree') {
662      fsCallTreePageChart?.setAttribute('class', '');
663      fsCallTreePageTab?.setAttribute('class', 'show');
664      showButtonMenu(this.fsCallTreeFilter, true);
665      this.isChartShow = false; // @ts-ignore
666      this.fsCallTreeFilter!.disabledMining = false;
667      this.frameChart!.clearCanvas();
668      this.fsCallTreeTbl!.reMeauseHeight();
669    }
670  }
671
672  refreshAllNode(filterData: unknown): void {
673    let fileSysCallTreeArgs: unknown[] = []; // @ts-ignore
674    let isTopDown: boolean = !filterData.callTree[0]; // @ts-ignore
675    let isHideSystemLibrary = filterData.callTree[1]; // @ts-ignore
676    let isHideEvent: boolean = filterData.callTree[2]; // @ts-ignore
677    let isHideThread: boolean = filterData.callTree[3]; // @ts-ignore
678    let list = filterData.dataMining.concat(filterData.dataLibrary);
679    fileSysCallTreeArgs.push({ funcName: 'hideThread', funcArgs: [isHideThread] });
680    fileSysCallTreeArgs.push({ funcName: 'hideEvent', funcArgs: [isHideEvent] });
681    fileSysCallTreeArgs.push({ funcName: 'getCallChainsBySampleIds', funcArgs: [isTopDown, 'fileSystem'] });
682    this.fsCallTreeTbr!.recycleDataSource = [];
683    if (isHideSystemLibrary) {
684      fileSysCallTreeArgs.push({ funcName: 'hideSystemLibrary', funcArgs: [] });
685    } // @ts-ignore
686    if (filterData.callTreeConstraints.checked) {
687      fileSysCallTreeArgs.push({
688        funcName: 'hideNumMaxAndMin', // @ts-ignore
689        funcArgs: [parseInt(filterData.callTreeConstraints.inputs[0]), filterData.callTreeConstraints.inputs[1]],
690      });
691    }
692    fileSysCallTreeArgs.push({ funcName: 'splitAllProcess', funcArgs: [list] });
693    fileSysCallTreeArgs.push({ funcName: 'resetAllNode', funcArgs: [] }); // @ts-ignore
694    if (this._fsRowClickData && this._fsRowClickData.libId !== undefined && this._currentFsCallTreeLevel === 3) {
695      fileSysCallTreeArgs.push({
696        funcName: 'showLibLevelData',
697        funcArgs: [this.FsCallTreeLevel!.libId, this.FsCallTreeLevel!.libName],
698      });
699    } else if (
700      this._fsRowClickData && // @ts-ignore
701      this._fsRowClickData.symbolId !== undefined &&
702      this._currentFsCallTreeLevel === 4
703    ) {
704      fileSysCallTreeArgs.push({
705        funcName: 'showFunLevelData',
706        funcArgs: [this.FsCallTreeLevel!.symbolId, this.FsCallTreeLevel!.symbolName],
707      });
708    }
709    this.getDataByWorker(fileSysCallTreeArgs, (result: unknown[]): void => {
710      this.setLTableData(result); // @ts-ignore
711      this.frameChart!.data = this.fsCallTreeDataSource;
712      if (this.isChartShow) {
713        this.frameChart?.calculateChartData();
714      }
715    });
716  }
717
718  setLTableData(resultData: unknown[]): void {
719    this.fsCallTreeDataSource = this.sortTree(resultData);
720    this.fsCallTreeTbl!.recycleDataSource = this.fsCallTreeDataSource;
721  }
722
723  sortTree(arr: Array<unknown>): Array<unknown> {
724    let fsCallTreeSortArr = arr.sort((fsCallTreeA, fsCallTreeB) => {
725      if (this.fsCallTreeSortKey === 'self') {
726        if (this.fsCallTreeSortType === 0) {
727          // @ts-ignore
728          return fsCallTreeB.dur - fsCallTreeA.dur;
729        } else if (this.fsCallTreeSortType === 1) {
730          // @ts-ignore
731          return fsCallTreeA.selfDur - fsCallTreeB.selfDur;
732        } else {
733          // @ts-ignore
734          return fsCallTreeB.selfDur - fsCallTreeA.selfDur;
735        }
736      } else {
737        if (this.fsCallTreeSortType === 0) {
738          // @ts-ignore
739          return fsCallTreeB.dur - fsCallTreeA.dur;
740        } else if (this.fsCallTreeSortType === 1) {
741          // @ts-ignore
742          return fsCallTreeA.dur - fsCallTreeB.dur;
743        } else {
744          // @ts-ignore
745          return fsCallTreeB.dur - fsCallTreeA.dur;
746        }
747      }
748    });
749    fsCallTreeSortArr.map((call): void => {
750      // @ts-ignore
751      call.children = this.sortTree(call.children);
752    });
753    return fsCallTreeSortArr;
754  }
755
756  getDataByWorker(args: unknown[], handler: Function): void {
757    this.loadingList.push(1);
758    this.fsCallTreeProgressEL!.loading = true; // @ts-ignore
759    this.loadingPage.style.visibility = 'visible';
760    procedurePool.submitWithName(
761      'logic0',
762      'fileSystem-action',
763      { args, callType: 'fileSystem' },
764      undefined,
765      (fsCallTreeResults: unknown): void => {
766        handler(fsCallTreeResults);
767        this.loadingList.splice(0, 1);
768        if (this.loadingList.length === 0) {
769          this.fsCallTreeProgressEL!.loading = false; // @ts-ignore
770          this.loadingPage.style.visibility = 'hidden';
771        }
772      }
773    );
774  }
775
776  initHtml(): string {
777    return TabPaneFileSystemCalltreeHtml;
778  }
779}
780