• 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.js';
17import { LitTable } from '../../../../../base-ui/table/lit-table.js';
18import { LitChartPie } from '../../../../../base-ui/chart/pie/LitChartPie.js';
19import { SelectionParam } from '../../../../bean/BoxSelection.js';
20import '../../../../../base-ui/chart/pie/LitChartPie.js';
21import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar';
22import { Utils } from '../../base/Utils.js';
23import { procedurePool } from '../../../../database/Procedure.js';
24
25@element('tabpane-file-statistics-analysis')
26export class TabPaneFilesystemStatisticsAnalysis extends BaseElement {
27  private fileStatisticsAnalysisPie: LitChartPie | null | undefined;
28  private fileStatisticsAnalysisCurrentSelection: SelectionParam | null | undefined;
29  private fileStatisticsAnalysisProcessData: any;
30  private fileStatisticsAnalysisThreadData!: any[];
31  private fileStatisticsAnalysisSoData!: any[];
32  private fileStatisticsAnalysisPidData!: any[];
33  private fileStatisticsAnalysisTypeData!: any[];
34  private fileStatisticsAnalysisFunctionData!: any[];
35  private fileStatisticsAnalysisTableProcess: LitTable | null | undefined;
36  private fileStatisticsAnalysisTableType: LitTable | null | undefined;
37  private fileStatisticsAnalysisTableThread: LitTable | null | undefined;
38  private fileStatisticsAnalysisTableSo: LitTable | null | undefined;
39  private fileStatisticsAnalysisTableFunction: LitTable | null | undefined;
40  private sumDur: number = 0;
41  private fileStatisticsAnalysisRange: HTMLLabelElement | null | undefined;
42  private back: HTMLDivElement | null | undefined;
43  private tabName: HTMLDivElement | null | undefined;
44  private fileStatisticsAnalysisProgressEL: LitProgressBar | null | undefined;
45  private fileStatisticsAnalysisProcessName: string = '';
46  private fileStatisticsAnalysisThreadName: string = '';
47  private fileStatisticsAnalysisSortColumn: string = '';
48  private fileStatisticsAnalysisSortType: number = 0;
49  private typeName: string = '';
50  private currentLevel = -1;
51  private currentLevelData!: Array<any>;
52  private processStatisticsData!: {};
53  private typeStatisticsData!: {};
54  private threadStatisticsData!: {};
55  private libStatisticsData!: {};
56  private functionStatisticsData!: {};
57  set data(val: SelectionParam) {
58    if (val === this.fileStatisticsAnalysisCurrentSelection) {
59      this.fileStatisticsAnalysisPidData.unshift(this.processStatisticsData);
60      this.fileStatisticsAnalysisTableProcess!.recycleDataSource = this.fileStatisticsAnalysisPidData;
61      // @ts-ignore
62      this.fileStatisticsAnalysisPidData.shift(this.processStatisticsData);
63      return;
64    }
65    this.clearData();
66    this.fileStatisticsAnalysisCurrentSelection = val;
67    this.fileStatisticsAnalysisTableProcess!.style.display = 'grid';
68    this.fileStatisticsAnalysisTableThread!.style.display = 'none';
69    this.fileStatisticsAnalysisTableSo!.style.display = 'none';
70    this.fileStatisticsAnalysisTableType!.style.display = 'none';
71    this.fileStatisticsAnalysisTableFunction!.style.display = 'none';
72    this.back!.style.visibility = 'hidden';
73    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent = '';
74    this.tabName!.textContent = '';
75    this.fileStatisticsAnalysisRange!.textContent =
76      'Selected range: ' + parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) + ' ms';
77    this.fileStatisticsAnalysisProgressEL!.loading = true;
78    this.getDataByWorker(
79      [
80        {
81          funcName: 'setSearchValue',
82          funcArgs: [''],
83        },
84        {
85          funcName: 'getCurrentDataFromDb',
86          funcArgs: [{ queryFuncName: 'fileSystem', ...val }],
87        },
88      ],
89      (results: any[]) => {
90        this.getFilesystemProcess(results);
91      }
92    );
93  }
94  initElements(): void {
95    this.fileStatisticsAnalysisRange = this.shadowRoot?.querySelector('#time-range');
96    this.fileStatisticsAnalysisPie = this.shadowRoot!.querySelector<LitChartPie>('#fs-chart-pie');
97    this.fileStatisticsAnalysisTableProcess = this.shadowRoot!.querySelector<LitTable>('#tb-process-usage');
98    this.fileStatisticsAnalysisTableThread = this.shadowRoot!.querySelector<LitTable>('#tb-thread-usage');
99    this.fileStatisticsAnalysisTableSo = this.shadowRoot!.querySelector<LitTable>('#tb-so-usage');
100    this.fileStatisticsAnalysisTableFunction = this.shadowRoot!.querySelector<LitTable>('#tb-function-usage');
101    this.back = this.shadowRoot!.querySelector<HTMLDivElement>('.fs-go-back');
102    this.tabName = this.shadowRoot!.querySelector<HTMLDivElement>('.fs-subheading');
103    this.fileStatisticsAnalysisTableType = this.shadowRoot!.querySelector<LitTable>('#tb-type-usage');
104    this.fileStatisticsAnalysisProgressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar;
105    this.goBack();
106  }
107  clearData(): void {
108    this.fileStatisticsAnalysisPie!.dataSource = [];
109    this.fileStatisticsAnalysisTableProcess!.recycleDataSource = [];
110    this.fileStatisticsAnalysisTableThread!.recycleDataSource = [];
111    this.fileStatisticsAnalysisTableType!.recycleDataSource = [];
112    this.fileStatisticsAnalysisTableSo!.recycleDataSource = [];
113    this.fileStatisticsAnalysisTableFunction!.recycleDataSource = [];
114  }
115  goBack(): void {
116    this.back!.addEventListener('click', () => {
117      if (this.tabName!.textContent === 'Statistic By type AllDuration') {
118        this.fileStatisticsAnalysisTableProcess!.style.display = 'grid';
119        this.fileStatisticsAnalysisTableType!.style.display = 'none';
120        this.back!.style.visibility = 'hidden';
121        this.fileStatisticsAnalysisTableType!.setAttribute('hideDownload', '');
122        this.fileStatisticsAnalysisTableProcess?.removeAttribute('hideDownload');
123        this.currentLevel = 0;
124        this.processPieChart();
125      } else if (this.tabName!.textContent === 'Statistic By Thread AllDuration') {
126        this.fileStatisticsAnalysisTableType!.style.display = 'grid';
127        this.fileStatisticsAnalysisTableThread!.style.display = 'none';
128        this.fileStatisticsAnalysisTableThread!.setAttribute('hideDownload', '');
129        this.fileStatisticsAnalysisTableType?.removeAttribute('hideDownload');
130        this.currentLevel = 1;
131        this.typePieChart();
132      } else if (this.tabName!.textContent === 'Statistic By Library AllDuration') {
133        this.fileStatisticsAnalysisTableThread!.style.display = 'grid';
134        this.fileStatisticsAnalysisTableSo!.style.display = 'none';
135        this.fileStatisticsAnalysisTableSo!.setAttribute('hideDownload', '');
136        this.fileStatisticsAnalysisTableThread?.removeAttribute('hideDownload');
137        this.currentLevel = 2;
138        this.threadPieChart();
139      } else if (this.tabName!.textContent === 'Statistic By Function AllDuration') {
140        this.fileStatisticsAnalysisTableSo!.style.display = 'grid';
141        this.fileStatisticsAnalysisTableFunction!.style.display = 'none';
142        this.fileStatisticsAnalysisTableFunction!.setAttribute('hideDownload', '');
143        this.fileStatisticsAnalysisTableSo?.removeAttribute('hideDownload');
144        this.currentLevel = 3;
145        this.libraryPieChart();
146      }
147    });
148  }
149  processPieChart(): void {
150    // @ts-ignore
151    this.sumDur = this.processStatisticsData.allDuration;
152    this.fileStatisticsAnalysisPie!.config = {
153      appendPadding: 0,
154      data: this.getFsPieChartData(this.fileStatisticsAnalysisPidData),
155      angleField: 'duration',
156      colorField: 'tableName',
157      radius: 1,
158      label: {
159        type: 'outer',
160      },
161      tip: this.getFsTip(),
162      angleClick: (fsPieClickItem): void => {
163        // @ts-ignore
164        if (fsPieClickItem.tableName != 'other') {
165          this.fileProcessLevelClickEvent(fsPieClickItem);
166        }
167      },
168      hoverHandler: (fsPieData): void => {
169        if (fsPieData) {
170          this.fileStatisticsAnalysisTableProcess!.setCurrentHover(fsPieData);
171        } else {
172          this.fileStatisticsAnalysisTableProcess!.mouseOut();
173        }
174      },
175      interactions: [
176        {
177          type: 'element-active',
178        },
179      ],
180    };
181    this.fileStatisticsAnalysisTableProcess!.addEventListener('row-hover', (evt) => {
182      // @ts-ignore
183      let processData = evt.detail;
184      if (processData.data) {
185        let fspData = processData.data;
186        fspData.isHover = true;
187        if (processData.callBack) {
188          processData.callBack(true);
189        }
190      }
191      this.fileStatisticsAnalysisPie?.showHover();
192      this.fileStatisticsAnalysisPie?.hideTip();
193    });
194    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent = '';
195    this.tabName!.textContent = 'Statistic By Process AllDuration';
196    this.fileStatisticsAnalysisPidData.unshift(this.processStatisticsData);
197    this.fileStatisticsAnalysisTableProcess!.recycleDataSource = this.fileStatisticsAnalysisPidData;
198    // @ts-ignore
199    this.fileStatisticsAnalysisPidData.shift(this.processStatisticsData);
200    this.currentLevelData = this.fileStatisticsAnalysisPidData;
201    this.fileStatisticsAnalysisTableProcess?.reMeauseHeight();
202    this.fileStatisticsAnalysisTableProcess!.addEventListener('column-click', (evt) => {
203      // @ts-ignore
204      this.sortByColumn(evt.detail.key, evt.detail.sort);
205    });
206    this.fileStatisticsAnalysisTableProcess!.addEventListener('row-click', (evt) => {
207      // @ts-ignore
208      let data = evt.detail.data;
209      if (data.tableName !== '' && data.duration !== 0) {
210        this.fileProcessLevelClickEvent(data);
211      }
212    });
213  }
214  fileProcessLevelClickEvent(it: any): void {
215    this.clearData();
216    this.back!.style.visibility = 'visible';
217    this.fileStatisticsAnalysisTableProcess!.style.display = 'none';
218    this.fileStatisticsAnalysisTableType!.style.display = 'grid';
219    this.fileStatisticsAnalysisTableProcess!.setAttribute('hideDownload', '');
220    this.fileStatisticsAnalysisTableType?.removeAttribute('hideDownload');
221    this.getFilesystemType(it);
222    // @ts-ignore
223    this.fileStatisticsAnalysisProcessName = it.tableName;
224    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent = this.fileStatisticsAnalysisProcessName;
225    this.fileStatisticsAnalysisPie?.hideTip();
226  }
227  typePieChart(): void {
228    this.fileStatisticsAnalysisPie!.config = {
229      appendPadding: 0,
230      data: this.fileStatisticsAnalysisTypeData,
231      angleField: 'duration',
232      colorField: 'tableName',
233      radius: 1,
234      label: {
235        type: 'outer',
236      },
237      tip: this.getFileTypeTip(),
238      angleClick: (it): void => {
239        this.fileTypeLevelClickEvent(it);
240      },
241      hoverHandler: (data): void => {
242        if (data) {
243          this.fileStatisticsAnalysisTableType!.setCurrentHover(data);
244        } else {
245          this.fileStatisticsAnalysisTableType!.mouseOut();
246        }
247      },
248      interactions: [
249        {
250          type: 'element-active',
251        },
252      ],
253    };
254    this.fileStatisticsAnalysisTableType!.addEventListener('row-hover', (evt) => {
255      // @ts-ignore
256      let typeData = evt.detail;
257      if (typeData.data) {
258        let fsaData = typeData.data;
259        fsaData.isHover = true;
260        if (typeData.callBack) {
261          typeData.callBack(true);
262        }
263      }
264      this.fileStatisticsAnalysisPie?.showHover();
265      this.fileStatisticsAnalysisPie?.hideTip();
266    });
267    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent = this.fileStatisticsAnalysisProcessName;
268    this.tabName!.textContent = 'Statistic By type AllDuration';
269    this.fileStatisticsAnalysisTypeData.unshift(this.typeStatisticsData);
270    this.fileStatisticsAnalysisTableType!.recycleDataSource = this.fileStatisticsAnalysisTypeData;
271    // @ts-ignore
272    this.fileStatisticsAnalysisTypeData.shift(this.typeStatisticsData);
273    this.currentLevelData = this.fileStatisticsAnalysisTypeData;
274    this.fileStatisticsAnalysisTableType?.reMeauseHeight();
275    this.fileStatisticsAnalysisTableType!.addEventListener('column-click', (evt) => {
276      // @ts-ignore
277      this.sortByColumn(evt.detail.key, evt.detail.sort);
278    });
279    this.fileStatisticsAnalysisTableType!.addEventListener('row-click', (evt) => {
280      // @ts-ignore
281      let data = evt.detail.data;
282      if (data.tableName !== '' && data.duration !== 0) {
283        this.fileTypeLevelClickEvent(data);
284      }
285    });
286  }
287  private getFileTypeTip() {
288    return (obj: { obj: { tableName: any; durFormat: any; percent: any; }; }): string => {
289      return `<div>
290                    <div>Type:${ obj.obj.tableName }</div>
291                    <div>Duration:${ obj.obj.durFormat }</div>
292                    <div>Percent:${ obj.obj.percent }%</div>
293                </div>
294                `;
295    };
296  }
297  fileTypeLevelClickEvent(it: any): void {
298    this.clearData();
299    this.fileStatisticsAnalysisTableType!.style.display = 'none';
300    this.fileStatisticsAnalysisTableThread!.style.display = 'grid';
301    this.fileStatisticsAnalysisTableType!.setAttribute('hideDownload', '');
302    this.fileStatisticsAnalysisTableThread?.removeAttribute('hideDownload');
303    this.getFilesystemThread(it);
304    // @ts-ignore
305    this.typeName = it.tableName;
306    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent =
307      this.fileStatisticsAnalysisProcessName + ' / ' + this.typeName;
308    this.fileStatisticsAnalysisPie?.hideTip();
309  }
310  threadPieChart(): void {
311    // @ts-ignore
312    this.sumDur = this.threadStatisticsData.allDuration;
313    this.fileStatisticsAnalysisPie!.config = {
314      appendPadding: 0,
315      data: this.getFsPieChartData(this.fileStatisticsAnalysisThreadData),
316      angleField: 'duration',
317      colorField: 'tableName',
318      radius: 1,
319      label: {
320        type: 'outer',
321      },
322      tip: this.getFileTypeTip(),
323      angleClick: (it): void => {
324        // @ts-ignore
325        if (it.tableName != 'other') {
326          this.fileThreadLevelClickEvent(it);
327        }
328      },
329      hoverHandler: (data): void => {
330        if (data) {
331          this.fileStatisticsAnalysisTableThread!.setCurrentHover(data);
332        } else {
333          this.fileStatisticsAnalysisTableThread!.mouseOut();
334        }
335      },
336      interactions: [
337        {
338          type: 'element-active',
339        },
340      ],
341    };
342    this.fileStatisticsAnalysisTableThread!.addEventListener('row-hover', (evt) => {
343      // @ts-ignore
344      let threadData = evt.detail;
345      if (threadData.data) {
346        let tableData = threadData.data;
347        tableData.isHover = true;
348        if (threadData.callBack) {
349          threadData.callBack(true);
350        }
351      }
352      this.fileStatisticsAnalysisPie?.showHover();
353      this.fileStatisticsAnalysisPie?.hideTip();
354    });
355    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent =
356      this.fileStatisticsAnalysisProcessName + ' / ' + this.typeName;
357    this.tabName!.textContent = 'Statistic By Thread AllDuration';
358    this.fileStatisticsAnalysisThreadData.unshift(this.threadStatisticsData);
359    this.fileStatisticsAnalysisTableThread!.recycleDataSource = this.fileStatisticsAnalysisThreadData;
360    // @ts-ignore
361    this.fileStatisticsAnalysisThreadData.shift(this.threadStatisticsData);
362    this.currentLevelData = this.fileStatisticsAnalysisThreadData;
363    this.fileStatisticsAnalysisTableThread?.reMeauseHeight();
364    this.fileStatisticsAnalysisTableThread!.addEventListener('column-click', (evt) => {
365      // @ts-ignore
366      this.sortByColumn(evt.detail.key, evt.detail.sort);
367    });
368    this.fileStatisticsAnalysisTableThread!.addEventListener('row-click', (evt) => {
369      // @ts-ignore
370      let data = evt.detail.data;
371      if (data.tableName !== '' && data.duration !== 0) {
372        this.fileThreadLevelClickEvent(data);
373      }
374    });
375  }
376  private getFsTip() {
377    return (obj: { obj: { tableName: any; durFormat: any; percent: any; }; }): string => {
378      return `<div>
379                                <div>ThreadName:${ obj.obj.tableName }</div>
380                                <div>Duration:${ obj.obj.durFormat }</div>
381                                <div>Percent:${ obj.obj.percent }%</div>
382                            </div>
383                                `;
384    };
385  }
386  fileThreadLevelClickEvent(it: any): void {
387    this.clearData();
388    this.back!.style.visibility = 'visible';
389    this.fileStatisticsAnalysisTableThread!.style.display = 'none';
390    this.fileStatisticsAnalysisTableSo!.style.display = 'grid';
391    this.fileStatisticsAnalysisTableThread!.setAttribute('hideDownload', '');
392    this.fileStatisticsAnalysisTableSo?.removeAttribute('hideDownload');
393    this.getFilesystemSo(it);
394    // @ts-ignore
395    this.fileStatisticsAnalysisThreadName = it.tableName;
396    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent =
397      this.fileStatisticsAnalysisProcessName + ' / ' + this.typeName + ' / ' + this.fileStatisticsAnalysisThreadName;
398    this.fileStatisticsAnalysisPie?.hideTip();
399  }
400  libraryPieChart(): void {
401    // @ts-ignore
402    this.sumDur = this.libStatisticsData.allDuration;
403    this.fileStatisticsAnalysisPie!.config = {
404      appendPadding: 0,
405      data: this.getFsPieChartData(this.fileStatisticsAnalysisSoData),
406      angleField: 'duration',
407      colorField: 'tableName',
408      radius: 1,
409      label: {
410        type: 'outer',
411      },
412      tip: (fileSysObj): string => {
413        return `<div>
414                                <div>Library:${ fileSysObj.obj.tableName }</div>
415                                <div>Duration:${ fileSysObj.obj.durFormat }</div>
416                                <div>Percent:${ fileSysObj.obj.percent }%</div>
417                            </div>
418                                `;
419      },
420      angleClick: (fileSysBean): void => {
421        // @ts-ignore
422        if (fileSysBean.tableName != 'other') {
423          this.fileSoLevelClickEvent(fileSysBean);
424        }
425      },
426      hoverHandler: (data): void => {
427        if (data) {
428          this.fileStatisticsAnalysisTableSo!.setCurrentHover(data);
429        } else {
430          this.fileStatisticsAnalysisTableSo!.mouseOut();
431        }
432      },
433      interactions: [
434        {
435          type: 'element-active',
436        },
437      ],
438    };
439    this.fileStatisticsAnalysisTableSo!.addEventListener('row-hover', (evt) => {
440      // @ts-ignore
441      let soData = evt.detail;
442      if (soData.data) {
443        let fsSoData = soData.data;
444        fsSoData.isHover = true;
445        if (soData.callBack) {
446          soData.callBack(true);
447        }
448      }
449      this.fileStatisticsAnalysisPie?.showHover();
450      this.fileStatisticsAnalysisPie?.hideTip();
451    });
452    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent =
453      this.fileStatisticsAnalysisProcessName + ' / ' + this.typeName + ' / ' + this.fileStatisticsAnalysisThreadName;
454    this.tabName!.textContent = 'Statistic By Library AllDuration';
455    this.fileStatisticsAnalysisSoData.unshift(this.libStatisticsData);
456    this.fileStatisticsAnalysisTableSo!.recycleDataSource = this.fileStatisticsAnalysisSoData;
457    // @ts-ignore
458    this.fileStatisticsAnalysisSoData.shift(this.libStatisticsData);
459    this.currentLevelData = this.fileStatisticsAnalysisSoData;
460    this.fileStatisticsAnalysisTableSo?.reMeauseHeight();
461    this.fileStatisticsAnalysisTableSo!.addEventListener('column-click', (evt) => {
462      // @ts-ignore
463      this.sortByColumn(evt.detail.key, evt.detail.sort);
464    });
465    this.fileStatisticsAnalysisTableSo!.addEventListener('row-click', (evt) => {
466      // @ts-ignore
467      let data = evt.detail.data;
468      if (data.tableName !== '' && data.duration !== 0) {
469        this.fileSoLevelClickEvent(data);
470      }
471    });
472  }
473  fileSoLevelClickEvent(it: any): void {
474    this.clearData();
475    this.back!.style.visibility = 'visible';
476    this.fileStatisticsAnalysisTableSo!.style.display = 'none';
477    this.fileStatisticsAnalysisTableFunction!.style.display = 'grid';
478    this.fileStatisticsAnalysisTableSo!.setAttribute('hideDownload', '');
479    this.fileStatisticsAnalysisTableFunction?.removeAttribute('hideDownload');
480    this.getFilesystemFunction(it);
481    this.shadowRoot!.querySelector<HTMLDivElement>('.title')!.textContent =
482      // @ts-ignore
483      this.fileStatisticsAnalysisProcessName +
484      ' / ' +
485      this.typeName +
486      ' / ' +
487      this.fileStatisticsAnalysisThreadName +
488      ' / ' +
489      it.tableName;
490    this.fileStatisticsAnalysisPie?.hideTip();
491  }
492  sortByColumn(column: string, fsaSort: number): void {
493    this.fileStatisticsAnalysisSortColumn = column;
494    this.fileStatisticsAnalysisSortType = fsaSort;
495    let fsaCurrentTable: LitTable | null | undefined;
496    switch (this.currentLevel) {
497      case 0:
498        fsaCurrentTable = this.fileStatisticsAnalysisTableProcess;
499        break;
500      case 1:
501        fsaCurrentTable = this.fileStatisticsAnalysisTableType;
502        break;
503      case 2:
504        fsaCurrentTable = this.fileStatisticsAnalysisTableThread;
505        break;
506      case 3:
507        fsaCurrentTable = this.fileStatisticsAnalysisTableSo;
508        break;
509      case 4:
510        fsaCurrentTable = this.fileStatisticsAnalysisTableFunction;
511        break;
512    }
513    if (!fsaCurrentTable) {
514      return;
515    }
516    if (fsaSort === 0) {
517      let fsaArr = [...this.currentLevelData];
518      switch (this.currentLevel) {
519        case 0:
520          fsaArr.unshift(this.processStatisticsData);
521          break;
522        case 1:
523          fsaArr.unshift(this.typeStatisticsData);
524          break;
525        case 2:
526          fsaArr.unshift(this.threadStatisticsData);
527          break;
528        case 3:
529          fsaArr.unshift(this.libStatisticsData);
530          break;
531        case 4:
532          fsaArr.unshift(this.functionStatisticsData);
533          break;
534      }
535      fsaCurrentTable!.recycleDataSource = fsaArr;
536    } else {
537      let fsaArray = [...this.currentLevelData];
538      if (column === 'tableName') {
539        fsaCurrentTable!.recycleDataSource = fsaArray.sort((firstElement, secondElement) => {
540          if (fsaSort === 1) {
541            if (firstElement.tableName > secondElement.tableName) {
542              return 1;
543            } else if (firstElement.tableName === secondElement.tableName) {
544              return 0;
545            } else {
546              return -1;
547            }
548          } else {
549            if (secondElement.tableName > firstElement.tableName) {
550              return 1;
551            } else if (firstElement.tableName === secondElement.tableName) {
552              return 0;
553            } else {
554              return -1;
555            }
556          }
557        });
558      } else if (column === 'durFormat' || column === 'percent') {
559        fsaCurrentTable!.recycleDataSource = fsaArray.sort((a, b) => {
560          return fsaSort === 1 ? a.duration - b.duration : b.duration - a.duration;
561        });
562      }
563      switch (this.currentLevel) {
564        case 0:
565          fsaArray.unshift(this.processStatisticsData);
566          break;
567        case 1:
568          fsaArray.unshift(this.typeStatisticsData);
569          break;
570        case 2:
571          fsaArray.unshift(this.threadStatisticsData);
572          break;
573        case 3:
574          fsaArray.unshift(this.libStatisticsData);
575          break;
576        case 4:
577          fsaArray.unshift(this.functionStatisticsData);
578          break;
579      }
580      fsaCurrentTable!.recycleDataSource = fsaArray;
581    }
582  }
583  getFilesystemProcess(result: Array<any>): void {
584    this.fileStatisticsAnalysisProcessData = JSON.parse(JSON.stringify(result));
585    if (!this.fileStatisticsAnalysisProcessData || this.fileStatisticsAnalysisProcessData.length === 0) {
586      this.fileStatisticsAnalysisPidData = [];
587      this.processStatisticsData = [];
588      this.processPieChart();
589      return;
590    }
591    let allDur = 0;
592    let pidMap = new Map<string, Array<number | string>>();
593    for (let itemData of result) {
594      allDur += itemData.dur;
595      if (pidMap.has(itemData.pid)) {
596        pidMap.get(itemData.pid)?.push(itemData);
597      } else {
598        let itemArray = new Array<number | string>();
599        itemArray.push(itemData);
600        pidMap.set(itemData.pid, itemArray);
601      }
602    }
603    this.fileStatisticsAnalysisPidData = [];
604    pidMap.forEach((value: Array<any>, key: string) => {
605      let analysisPidDataDur = 0;
606      let pName = '';
607      for (let fileSysStatPidItem of value) {
608        pName = fileSysStatPidItem.processName =
609          fileSysStatPidItem.processName === null || fileSysStatPidItem.processName === undefined ?
610            `Process(${ fileSysStatPidItem.pid })` : `${ fileSysStatPidItem.processName }(${ fileSysStatPidItem.pid })`;
611        analysisPidDataDur += fileSysStatPidItem.dur;
612      }
613      this.fileStatisticsAnalysisPidData.push({
614        tableName: pName,
615        pid: key,
616        percent: ((analysisPidDataDur / allDur) * 100).toFixed(2),
617        durFormat: Utils.getProbablyTime(analysisPidDataDur),
618        duration: analysisPidDataDur,
619      });
620    });
621    this.fileStatisticsAnalysisPidData.sort((a, b) => b.duration - a.duration);
622    this.processStatisticsData = this.totalDurationData(allDur);
623    this.currentLevel = 0;
624    this.fileStatisticsAnalysisProgressEL!.loading = false;
625    this.processPieChart();
626    new ResizeObserver(() => {
627      if (this.parentElement?.clientHeight != 0) {
628        this.fileStatisticsAnalysisTableProcess!.style.height = this.parentElement!.clientHeight - 50 + 'px';
629        this.fileStatisticsAnalysisTableProcess?.reMeauseHeight();
630        this.fileStatisticsAnalysisTableThread!.style.height = this.parentElement!.clientHeight - 50 + 'px';
631        this.fileStatisticsAnalysisTableThread?.reMeauseHeight();
632        this.fileStatisticsAnalysisTableSo!.style.height = this.parentElement!.clientHeight - 50 + 'px';
633        this.fileStatisticsAnalysisTableSo?.reMeauseHeight();
634        this.fileStatisticsAnalysisTableFunction!.style.height = this.parentElement!.clientHeight - 50 + 'px';
635        this.fileStatisticsAnalysisTableFunction?.reMeauseHeight();
636        this.fileStatisticsAnalysisTableType!.style.height = this.parentElement!.clientHeight - 50 + 'px';
637        this.fileStatisticsAnalysisTableType?.reMeauseHeight();
638      }
639    }).observe(this.parentElement!);
640  }
641
642  getFilesystemType(fileSysStatTypeItem: any): void {
643    this.fileStatisticsAnalysisProgressEL!.loading = true;
644    let typeMap = new Map<number, Array<number | string>>();
645    let pid = fileSysStatTypeItem.pid;
646    let allDur = 0;
647    if (!this.fileStatisticsAnalysisProcessData || this.fileStatisticsAnalysisProcessData.length == 0) {
648      return;
649    }
650    for (let fsItem of this.fileStatisticsAnalysisProcessData) {
651      if (fsItem.pid !== pid) {
652        continue;
653      }
654      allDur += fsItem.dur;
655      if (typeMap.has(fsItem.type)) {
656        typeMap.get(fsItem.type)?.push(fsItem);
657      } else {
658        let itemArray = new Array<number | string>();
659        itemArray.push(fsItem);
660        typeMap.set(fsItem.type, itemArray);
661      }
662    }
663    this.fileStatisticsAnalysisTypeData = [];
664    typeMap.forEach((value: Array<any>, key: number) => {
665      let dur = 0;
666      for (let item of value) {
667        dur += item.dur;
668      }
669      const typeData = {
670        tableName: this.typeIdToString(key),
671        pid: fileSysStatTypeItem.pid,
672        type: key,
673        percent: ((dur / allDur) * 100).toFixed(2),
674        durFormat: Utils.getProbablyTime(dur),
675        duration: dur,
676      };
677      this.fileStatisticsAnalysisTypeData.push(typeData);
678    });
679    this.fileStatisticsAnalysisTypeData.sort((a, b) => b.duration - a.duration);
680    this.typeStatisticsData = this.totalDurationData(allDur);
681    this.currentLevel = 1;
682    this.typePieChart();
683    this.fileStatisticsAnalysisProgressEL!.loading = false;
684  }
685
686  getFilesystemThread(fileSysStatThreadItem: any): void {
687    this.fileStatisticsAnalysisProgressEL!.loading = true;
688    let threadMap = new Map<string, Array<number | string>>();
689    let pid = fileSysStatThreadItem.pid;
690    let type = fileSysStatThreadItem.type;
691    let allDur = 0;
692    if (!this.fileStatisticsAnalysisProcessData || this.fileStatisticsAnalysisProcessData.length === 0) {
693      return;
694    }
695    for (let fspItem of this.fileStatisticsAnalysisProcessData) {
696      if (fspItem.pid !== pid || fspItem.type !== type) {
697        continue;
698      }
699      allDur += fspItem.dur;
700      if (threadMap.has(fspItem.tid)) {
701        threadMap.get(fspItem.tid)?.push(fspItem);
702      } else {
703        let itemArray = new Array<number | string>();
704        itemArray.push(fspItem);
705        threadMap.set(fspItem.tid, itemArray);
706      }
707    }
708    this.fileStatisticsAnalysisThreadData = [];
709    threadMap.forEach((value: Array<any>, key: string) => {
710      let dur = 0;
711      let tName = '';
712      for (let fileSysStatThreadItem of value) {
713        dur += fileSysStatThreadItem.dur;
714        tName = fileSysStatThreadItem.threadName =
715          fileSysStatThreadItem.threadName === null || fileSysStatThreadItem.threadName === undefined ? `Thread(${ fileSysStatThreadItem.tid })` : `${ fileSysStatThreadItem.threadName }`;
716      }
717      const threadData = {
718        tableName: tName,
719        pid: fileSysStatThreadItem.pid,
720        type: fileSysStatThreadItem.type,
721        tid: key,
722        percent: ((dur / allDur) * 100).toFixed(2),
723        durFormat: Utils.getProbablyTime(dur),
724        duration: dur,
725      };
726      this.fileStatisticsAnalysisThreadData.push(threadData);
727    });
728    this.fileStatisticsAnalysisThreadData.sort((a, b) => b.duration - a.duration);
729    this.threadStatisticsData = this.totalDurationData(allDur);
730    this.currentLevel = 2;
731    this.fileStatisticsAnalysisProgressEL!.loading = false;
732    this.threadPieChart();
733  }
734
735  getFilesystemSo(item: any): void {
736    this.fileStatisticsAnalysisProgressEL!.loading = true;
737    let tid = item.tid;
738    let pid = item.pid;
739    let type = item.type;
740    let allDur = 0;
741    let libMap = new Map<number, Array<number | string>>();
742    if (!this.fileStatisticsAnalysisProcessData || this.fileStatisticsAnalysisProcessData.length === 0) {
743      return;
744    }
745    for (let itemData of this.fileStatisticsAnalysisProcessData) {
746      if (itemData.pid !== pid || itemData.tid !== tid || itemData.type !== type) {
747        continue;
748      }
749      allDur += itemData.dur;
750      if (libMap.has(itemData.libId)) {
751        libMap.get(itemData.libId)?.push(itemData);
752      } else {
753        let dataArray = new Array<number | string>();
754        dataArray.push(itemData);
755        libMap.set(itemData.libId, dataArray);
756      }
757    }
758    this.fileStatisticsAnalysisSoData = [];
759    libMap.forEach((value: any[], key: number) => {
760      let dur = 0;
761      let soName = '';
762      for (let item of value) {
763        dur += item.dur;
764        if (key === null) {
765          item.libName = 'unknown';
766        }
767        soName = item.libName;
768      }
769      let libPath = soName?.split('/');
770      if (libPath) {
771        soName = libPath[libPath.length - 1];
772      }
773      const soData = {
774        tableName: soName,
775        pid: item.pid,
776        type: item.type,
777        tid: item.tid,
778        libId: key,
779        percent: ((dur / allDur) * 100).toFixed(2),
780        durFormat: Utils.getProbablyTime(dur),
781        duration: dur,
782      };
783      this.fileStatisticsAnalysisSoData.push(soData);
784    });
785    this.fileStatisticsAnalysisSoData.sort((a, b) => b.duration - a.duration);
786    this.libStatisticsData = this.totalDurationData(allDur);
787    this.currentLevel = 3;
788    this.fileStatisticsAnalysisProgressEL!.loading = false;
789    this.libraryPieChart();
790  }
791
792  getFilesystemFunction(item: any): void {
793    this.fileStatisticsAnalysisProgressEL!.loading = true;
794    this.shadowRoot!.querySelector<HTMLDivElement>('.fs-subheading')!.textContent = 'Statistic By Function AllDuration';
795    let tid = item.tid;
796    let pid = item.pid;
797    let type = item.type;
798    let libId = item.libId;
799    let allDur = 0;
800    let symbolMap = new Map<number, Array<any>>();
801    if (!this.fileStatisticsAnalysisProcessData || this.fileStatisticsAnalysisProcessData.length === 0) {
802      return;
803    }
804    for (let fsProcessData of this.fileStatisticsAnalysisProcessData) {
805      if (
806        fsProcessData.pid !== pid ||
807        fsProcessData.tid !== tid ||
808        fsProcessData.type !== type ||
809        fsProcessData.libId !== libId
810      ) {
811        continue;
812      }
813      allDur += fsProcessData.dur;
814      if (symbolMap.has(fsProcessData.symbolId)) {
815        symbolMap.get(fsProcessData.symbolId)?.push(fsProcessData);
816      } else {
817        let dataArray = new Array<number | string>();
818        dataArray.push(fsProcessData);
819        symbolMap.set(fsProcessData.symbolId, dataArray);
820      }
821    }
822    this.fileStatisticsAnalysisFunctionData = [];
823    symbolMap.forEach((symbolItems, key) => {
824      let dur = 0;
825      let fsSymbolName = '';
826      for (let symbolItem of symbolItems) {
827        fsSymbolName = symbolItem.symbolName;
828        dur += symbolItem.dur;
829      }
830      let symbolPath = fsSymbolName?.split('/');
831      if (symbolPath) {
832        fsSymbolName = symbolPath[symbolPath.length - 1];
833      }
834      const symbolData = {
835        pid: item.pid,
836        tid: item.tid,
837        percent: ((dur / allDur) * 100).toFixed(2),
838        tableName: fsSymbolName,
839        durFormat: Utils.getProbablyTime(dur),
840        duration: dur,
841      };
842      this.fileStatisticsAnalysisFunctionData.push(symbolData);
843    });
844    this.fileStatisticsAnalysisFunctionData.sort((a, b) => b.duration - a.duration);
845    this.functionStatisticsData = this.totalDurationData(allDur);
846    this.currentLevel = 4;
847    this.fileStatisticsAnalysisProgressEL!.loading = false;
848    // @ts-ignore
849    this.sumDur = this.functionStatisticsData.allDuration;
850    this.fileStatisticsAnalysisPie!.config = {
851      appendPadding: 0,
852      data: this.getFsPieChartData(this.fileStatisticsAnalysisFunctionData),
853      angleField: 'duration',
854      colorField: 'tableName',
855      radius: 1,
856      label: {
857        type: 'outer',
858      },
859      tip: (fsaObj): string => {
860        return `<div>
861                                    <div>Function:${ fsaObj.obj.tableName }</div>
862                                    <div>Duration:${ fsaObj.obj.durFormat }</div>
863                                    <div>percent:${ fsaObj.obj.percent }</div>
864                                        </div>
865                                                `;
866      },
867      hoverHandler: (data): void => {
868        if (data) {
869          this.fileStatisticsAnalysisTableFunction!.setCurrentHover(data);
870        } else {
871          this.fileStatisticsAnalysisTableFunction!.mouseOut();
872        }
873      },
874      interactions: [
875        {
876          type: 'element-active',
877        },
878      ],
879    };
880    this.fileStatisticsAnalysisTableFunction!.addEventListener('row-hover', (fsStatRowClickEvent) => {
881      // @ts-ignore
882      let fsFunctionData = fsStatRowClickEvent.detail;
883      if (fsFunctionData.data) {
884        let data = fsFunctionData.data;
885        data.isHover = true;
886        if (fsFunctionData.callBack) {
887          fsFunctionData.callBack(true);
888        }
889      }
890      this.fileStatisticsAnalysisPie?.showHover();
891      this.fileStatisticsAnalysisPie?.hideTip();
892    });
893    this.fileStatisticsAnalysisFunctionData.unshift(this.functionStatisticsData);
894    this.fileStatisticsAnalysisTableFunction!.recycleDataSource = this.fileStatisticsAnalysisFunctionData;
895    this.fileStatisticsAnalysisTableFunction?.reMeauseHeight();
896    // @ts-ignore
897    this.fileStatisticsAnalysisFunctionData.shift(this.functionStatisticsData);
898    this.currentLevelData = this.fileStatisticsAnalysisFunctionData;
899    this.fileStatisticsAnalysisTableFunction!.addEventListener('column-click', (evt) => {
900      // @ts-ignore
901      this.sortByColumn(evt.detail.key, evt.detail.sort);
902    });
903  }
904  typeIdToString(transformType: number): string {
905    let fsReleaseType: string;
906    if (transformType === 0) {
907      fsReleaseType = 'OPEN';
908    } else if (transformType === 2) {
909      fsReleaseType = 'READ';
910    } else if (transformType === 3) {
911      fsReleaseType = 'WRITE';
912    } else if (transformType === 1) {
913      fsReleaseType = 'CLOSE';
914    }
915    // @ts-ignore
916    return fsReleaseType;
917  }
918  totalDurationData(durationTS: number): { durFormat: string; percent: string; tableName: string; duration: number; } {
919    return {
920      durFormat: Utils.getProbablyTime(durationTS),
921      percent: ((durationTS / durationTS) * 100).toFixed(2),
922      tableName: '',
923      duration: 0,
924    };
925  }
926  getFsPieChartData(fsPieChartData: any[]): unknown[] {
927    if (fsPieChartData.length > 20) {
928      let fsPieChartArr: string[] = [];
929      let other: any = {
930        tableName: 'other',
931        duration: 0,
932        percent: 0,
933        durFormat: 0,
934      };
935      for (let pieDataIndex = 0 ; pieDataIndex < fsPieChartData.length ; pieDataIndex++) {
936        if (pieDataIndex < 19) {
937          fsPieChartArr.push(fsPieChartData[pieDataIndex]);
938        } else {
939          other.duration += fsPieChartData[pieDataIndex].duration;
940          other.durFormat = Utils.getProbablyTime(other.duration);
941          other.percent = ((other.duration / this.sumDur) * 100).toFixed(2);
942        }
943      }
944      fsPieChartArr.push(other);
945      return fsPieChartArr;
946    }
947    return fsPieChartData;
948  }
949
950  getDataByWorker(args: any[], handler: Function): void {
951    procedurePool.submitWithName(
952      'logic0',
953      'fileSystem-action',
954      { args, callType: 'fileSystem', isAnalysis: true },
955      undefined,
956      (results: any) => {
957        handler(results);
958        this.fileStatisticsAnalysisProgressEL!.loading = false;
959      }
960    );
961  }
962
963  initHtml(): string {
964    return `
965        <style>
966        :host {
967            display: flex;
968            flex-direction: column;
969        }
970        #fs-chart-pie{
971             height: 300px;
972        }
973        .fs-table-box{
974            width: 60%;
975            border-left: solid 1px var(--dark-border1,#e0e0e0);
976            border-radius: 5px;
977            padding: 10px;
978        }
979        .fs-go-back{
980            display:flex;
981            align-items: center;
982            cursor: pointer;
983            margin-left: 20px;
984            visibility: hidden;
985        }
986        .fs-back-box{
987            width: 40px;
988            height: 20px;
989            background-color: var(--bark-expansion,#0C65D1);
990            border-radius: 5px;
991            color: #fff;
992            display: flex;
993            margin-right: 10px;
994            justify-content: center;
995            align-items: center;
996        }
997        .fs-subheading{
998            font-weight: bold;
999            text-align: center;
1000        }
1001        .fs-stat-analysis-progress{
1002            position: absolute;
1003            height: 1px;
1004            left: 0;
1005            right: 0;
1006        }
1007        </style>
1008        <label id="time-range" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;margin-bottom: 5px">Selected range:0.0 ms</label>
1009        <div style="display: flex;flex-direction: row;" class="d-box">
1010            <lit-progress-bar class="progress fs-stat-analysis-progress"></lit-progress-bar>
1011                     <div id="left_table" style="width: 40%;height:auto;">
1012                         <div style="display: flex;margin-bottom: 10px">
1013                           <div class="fs-go-back">
1014                              <div class="fs-back-box">
1015                                  <lit-icon class="file-analysis" name="arrowleft"></lit-icon>
1016                              </div>
1017                           </div>
1018                         <div class="title"></div>
1019                        </div>
1020                         <div class="fs-subheading"></div>
1021                         <lit-chart-pie  id="fs-chart-pie"></lit-chart-pie>
1022                     </div>
1023                     <div class="fs-table-box" style="height:auto;overflow: auto">
1024                    <lit-table id="tb-process-usage"class="file-analysis" style="max-height:565px;min-height: 350px">
1025                        <lit-table-column width="1fr" title="ProcessName" data-index="tableName" key="tableName" align="flex-start" order></lit-table-column>
1026                        <lit-table-column width="1fr" title="Duration" data-index="durFormat" key="durFormat" align="flex-start" order></lit-table-column>
1027                        <lit-table-column width="1fr" title="%" data-index="percent" key="percent" align="flex-start"order></lit-table-column>
1028                    </lit-table>
1029                    <lit-table id="tb-type-usage" class="file-analysis" style="max-height:565px;min-height: 350px"hideDownload>
1030                        <lit-table-column width="1fr" title="Type" data-index="tableName" key="tableName" align="flex-start"order></lit-table-column>
1031                        <lit-table-column width="1fr" title="Duration" data-index="durFormat" key="durFormat" align="flex-start" order></lit-table-column>
1032                        <lit-table-column width="1fr" title="%" data-index="percent" key="percent" align="flex-start"order></lit-table-column>
1033                    </lit-table>
1034                    <lit-table id="tb-thread-usage" class="file-analysis" style="max-height:565px;display: none;min-height: 350px"hideDownload>
1035                        <lit-table-column width="1fr" title="ThreadName" data-index="tableName" key="tableName" align="flex-start"order></lit-table-column>
1036                        <lit-table-column width="1fr" title="Duration" data-index="durFormat" key="durFormat" align="flex-start" order></lit-table-column>
1037                        <lit-table-column width="1fr" title="%" data-index="percent" key="percent" align="flex-start"order></lit-table-column>
1038                    </lit-table>
1039                     <lit-table id="tb-so-usage" class="file-analysis" style="max-height:565px;display: none;min-height: 350px"hideDownload>
1040                        <lit-table-column width="1fr" title="Library" data-index="tableName" key="tableName" align="flex-start"order></lit-table-column>
1041                        <lit-table-column width="1fr" title="Duration" data-index="durFormat" key="durFormat" align="flex-start" order></lit-table-column>
1042                        <lit-table-column width="1fr" title="%" data-index="percent" key="percent" align="flex-start"order></lit-table-column>
1043                    </lit-table>
1044                    <lit-table id="tb-function-usage" class="file-analysis" style="max-height:565px;display: none;min-height: 350px"hideDownload>
1045                        <lit-table-column width="1fr" title="Function" data-index="tableName" key="tableName" align="flex-start"order></lit-table-column>
1046                        <lit-table-column width="1fr" title="Duration" data-index="durFormat" key="durFormat" align="flex-start" order></lit-table-column>
1047                        <lit-table-column width="1fr" title="%" data-index="percent" key="percent" align="flex-start"order></lit-table-column>
1048                    </lit-table>
1049                    </div>
1050
1051        </div>
1052`;
1053  }
1054}
1055