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