• 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 './trace/TimerShaftElement.js';
18import './trace/base/TraceRow.js';
19import {
20  queryBySelectAllocationOrReturn,
21  queryBySelectExecute,
22  queryEbpfSamplesCount,
23  querySceneSearchFunc,
24  querySearchFunc,
25  threadPool,
26} from '../database/SqlLite.js';
27import { RangeSelectStruct, TraceRow } from './trace/base/TraceRow.js';
28import { TimerShaftElement } from './trace/TimerShaftElement.js';
29import './trace/base/TraceSheet.js';
30import { TraceSheet } from './trace/base/TraceSheet.js';
31import { RangeSelect } from './trace/base/RangeSelect.js';
32import { SelectionParam } from '../bean/BoxSelection.js';
33import { procedurePool } from '../database/Procedure.js';
34import { SpApplication } from '../SpApplication.js';
35import { Flag } from './trace/timer-shaft/Flag.js';
36import { SlicesTime, SportRuler } from './trace/timer-shaft/SportRuler.js';
37import { SpHiPerf } from './chart/SpHiPerf.js';
38import { SearchSdkBean, SearchThreadProcessBean } from '../bean/SearchFuncBean.js';
39import { error, info } from '../../log/Log.js';
40import {
41  drawFlagLineSegment,
42  drawLines,
43  drawLinkLines,
44  drawWakeUp,
45  drawWakeUpList,
46  isFrameContainPoint,
47  LineType,
48  ns2x,
49  ns2xByTimeShaft,
50  PairPoint,
51  Rect,
52} from '../database/ui-worker/ProcedureWorkerCommon.js';
53import { SpChartManager } from './chart/SpChartManager.js';
54import { CpuStruct, WakeupBean } from '../database/ui-worker/ProcedureWorkerCPU.js';
55import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess.js';
56import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq.js';
57import { CpuFreqLimitsStruct } from '../database/ui-worker/ProcedureWorkerCpuFreqLimits.js';
58import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread.js';
59import { func, FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc.js';
60import { CpuStateStruct } from '../database/ui-worker/ProcedureWorkerCpuState.js';
61import { HiPerfCpuStruct } from '../database/ui-worker/ProcedureWorkerHiPerfCPU.js';
62import { HiPerfProcessStruct } from '../database/ui-worker/ProcedureWorkerHiPerfProcess.js';
63import { HiPerfThreadStruct } from '../database/ui-worker/ProcedureWorkerHiPerfThread.js';
64import { HiPerfEventStruct } from '../database/ui-worker/ProcedureWorkerHiPerfEvent.js';
65import { HiPerfReportStruct } from '../database/ui-worker/ProcedureWorkerHiPerfReport.js';
66import { FpsStruct } from '../database/ui-worker/ProcedureWorkerFPS.js';
67import { CpuAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerCpuAbility.js';
68import { DiskAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerDiskIoAbility.js';
69import { MemoryAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerMemoryAbility.js';
70import { NetworkAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerNetworkAbility.js';
71import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock.js';
72import { Utils } from './trace/base/Utils.js';
73import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq.js';
74import { JanksStruct } from '../bean/JanksStruct.js';
75import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank.js';
76import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent.js';
77import { HeapStruct } from '../database/ui-worker/ProcedureWorkerHeap.js';
78import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil.js';
79import { HeapSnapshotStruct } from '../database/ui-worker/ProcedureWorkerHeapSnapshot.js';
80import { HeapDataInterface } from '../../js-heap/HeapDataInterface.js';
81import { LitTabs } from '../../base-ui/tabs/lit-tabs.js';
82import { TraceRowConfig } from './trace/base/TraceRowConfig.js';
83import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection.js';
84import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup.js';
85import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit.js';
86import { TabPaneTaskFrames } from './trace/sheet/task/TabPaneTaskFrames.js';
87import { FlagsConfig } from './SpFlags.js';
88import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic.js';
89import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation.js';
90import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing.js';
91import { JsCpuProfilerStruct } from '../database/ui-worker/ProcedureWorkerCpuProfiler.js';
92import { TabPaneSummary } from './trace/sheet/ark-ts/TabPaneSummary.js';
93import { JsCpuProfilerChartFrame } from '../bean/JsStruct.js';
94import { FileInfo } from '../../js-heap/model/UiStruct.js';
95import { SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot.js';
96import { setSelectState, intersectData } from './Utils.js';
97
98function dpr() {
99  return window.devicePixelRatio || 1;
100}
101//节流处理
102function throttle(fn: any, t: number, ev: any): any {
103  let timer: any = null;
104  return function () {
105    if (!timer) {
106      timer = setTimeout(function () {
107        if (ev) {
108          fn(ev);
109        } else {
110          fn();
111        }
112        timer = null;
113      }, t);
114    }
115  };
116}
117
118export class CurrentSlicesTime {
119  startTime: number | undefined;
120  endTime: number | undefined;
121}
122
123@element('sp-system-trace')
124export class SpSystemTrace extends BaseElement {
125  static mouseCurrentPosition = 0;
126  static offsetMouse = 0;
127  static moveable = true;
128  static scrollViewWidth = 0;
129  static isCanvasOffScreen = true;
130  static DATA_DICT: Map<number, string> = new Map<number, string>();
131  static DATA_TASK_POOL_CALLSTACK: Map<number, { id: number; ts: number; dur: number; name: string }> = new Map<
132    number,
133    { id: number; ts: number; dur: number; name: string }
134  >();
135  static SDK_CONFIG_MAP: any;
136  static sliceRangeMark: any;
137  static wakeupList: Array<WakeupBean> = [];
138  currentSlicesTime: CurrentSlicesTime = new CurrentSlicesTime();
139  intersectionObserver: IntersectionObserver | undefined;
140  tipEL: HTMLDivElement | undefined | null;
141  rowsEL: HTMLDivElement | undefined | null;
142  rowsPaneEL: HTMLDivElement | undefined | null;
143  spacerEL: HTMLDivElement | undefined | null;
144  favoriteRowsEL: HTMLDivElement | undefined | null;
145  visibleRows: Array<TraceRow<any>> = [];
146  collectRows: Array<TraceRow<any>> = [];
147  currentRow: TraceRow<any> | undefined | null;
148  keyboardEnable = true;
149  mouseEventEnable = true;
150  currentRowType = ''; /*保存当前鼠标所在行的类型*/
151  observerScrollHeightEnable: boolean = false;
152  observerScrollHeightCallback: Function | undefined;
153  // @ts-ignore
154  observer = new ResizeObserver((entries) => {
155    if (this.observerScrollHeightEnable && this.observerScrollHeightCallback) {
156      this.observerScrollHeightCallback();
157    }
158  });
159  static btnTimer: any = null;
160  isMousePointInSheet = false;
161  hoverFlag: Flag | undefined | null = undefined;
162  selectFlag: Flag | undefined | null;
163  slicestime: SlicesTime | undefined | null = null;
164  public timerShaftEL: TimerShaftElement | null | undefined;
165  private traceSheetEL: TraceSheet | undefined | null;
166  private rangeSelect!: RangeSelect;
167  chartManager: SpChartManager | undefined | null;
168  private loadTraceCompleted: boolean = false;
169  private rangeTraceRow: Array<TraceRow<any>> | undefined = [];
170  canvasFavoritePanel: HTMLCanvasElement | null | undefined; //绘制收藏泳道图
171  canvasFavoritePanelCtx: CanvasRenderingContext2D | null | undefined;
172  canvasPanel: HTMLCanvasElement | null | undefined; //绘制取消收藏后泳道图
173  canvasPanelCtx: CanvasRenderingContext2D | undefined | null;
174  linkNodes: PairPoint[][] = [];
175  public currentClickRow: HTMLDivElement | undefined | null;
176  private litTabs: LitTabs | undefined | null;
177  eventMap: any = {};
178  private isSelectClick: boolean = false;
179  private selectionParam: SelectionParam | undefined;
180  private snapshotFiles: FileInfo | null | undefined;
181
182  set snapshotFile(data: FileInfo) {
183    this.snapshotFiles = data;
184  }
185
186  addPointPair(startPoint: PairPoint, endPoint: PairPoint) {
187    if (startPoint.rowEL.collect) {
188      startPoint.rowEL.translateY = startPoint.rowEL.getBoundingClientRect().top - 195;
189    } else {
190      startPoint.rowEL.translateY = startPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
191    }
192    if (endPoint.rowEL.collect) {
193      endPoint.rowEL.translateY = endPoint.rowEL.getBoundingClientRect().top - 195;
194    } else {
195      endPoint.rowEL.translateY = endPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
196    }
197    startPoint.y = startPoint.rowEL!.translateY! + startPoint.offsetY;
198    endPoint.y = endPoint.rowEL!.translateY! + endPoint.offsetY;
199    this.linkNodes.push([startPoint, endPoint]);
200  }
201
202  clearPointPair() {
203    this.linkNodes.length = 0;
204  }
205
206  removeLinkLinesByBusinessType(...businessTypes: string[]) {
207    this.linkNodes = this.linkNodes.filter((pointPair) => {
208      return !(businessTypes.indexOf(pointPair[0].business) > -1);
209    });
210  }
211
212  hiddenLinkLinesByBusinessType(...businessTypes: string[]) {
213    this.linkNodes.map((value) => {
214      if (businessTypes.indexOf(value[0].business) !== -1) {
215        value[0].hidden = true;
216        value[1].hidden = true;
217      }
218    });
219  }
220
221  showLinkLinesByBusinessType(...businessTypes: string[]) {
222    this.linkNodes.map((value) => {
223      if (businessTypes.indexOf(value[0].business) !== -1) {
224        value[0].hidden = false;
225        value[1].hidden = false;
226      }
227    });
228  }
229
230  initElements(): void {
231    let sideColor =
232      document!.querySelector('body > sp-application')?.shadowRoot?.querySelector!(
233        '#main-menu'
234      )?.shadowRoot?.querySelector('div.bottom > div.color');
235    this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet');
236    let rightButton: HTMLElement | null | undefined = this.traceSheetEL?.shadowRoot
237      ?.querySelector('#current-selection > tabpane-current-selection')
238      ?.shadowRoot?.querySelector('#rightButton');
239    let rightStar: HTMLElement | null | undefined = this.traceSheetEL?.shadowRoot
240      ?.querySelector('#current-selection > tabpane-current-selection')
241      ?.shadowRoot?.querySelector('#right-star');
242    this.rowsEL = this.shadowRoot?.querySelector<HTMLDivElement>('.rows');
243    this.tipEL = this.shadowRoot?.querySelector<HTMLDivElement>('.tip');
244    this.rowsPaneEL = this.shadowRoot?.querySelector<HTMLDivElement>('.rows-pane');
245    this.spacerEL = this.shadowRoot?.querySelector<HTMLDivElement>('.spacer');
246    this.canvasFavoritePanel = this.shadowRoot?.querySelector<HTMLCanvasElement>('.panel-canvas-favorite');
247    this.timerShaftEL = this.shadowRoot?.querySelector('.timer-shaft');
248    this.favoriteRowsEL = this.shadowRoot?.querySelector('.favorite-rows');
249    this.rangeSelect = new RangeSelect(this);
250    rightButton?.addEventListener('click', (event: any) => {
251      if (SpSystemTrace.btnTimer) {
252        return;
253      }
254      this.wakeupListNull();
255      SpSystemTrace.wakeupList.unshift(CpuStruct.wakeupBean!);
256      this.queryCPUWakeUpList(CpuStruct.wakeupBean!);
257      setTimeout(() => {
258        requestAnimationFrame(() => this.refreshCanvas(false));
259      }, 300);
260      rightStar!.style.visibility = 'visible';
261      rightStar!.style.cursor = 'pointer';
262      SpSystemTrace.btnTimer = setTimeout(() => {
263        SpSystemTrace.btnTimer = null; // 2.清空节流阀,方便下次开启定时器
264      }, 2000);
265    });
266    rightStar?.addEventListener('click', () => {
267      let wakeupLists = [];
268      for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) {
269        wakeupLists.unshift(CpuStruct.selectCpuStruct?.cpu);
270        wakeupLists.push(SpSystemTrace.wakeupList[i].cpu);
271      }
272      let wakeupCpuLists = Array.from(new Set(wakeupLists)).sort();
273      for (let i = 0; i < wakeupCpuLists.length; i++) {
274        let cpuFavoriteRow: any = this.shadowRoot?.querySelector<TraceRow<any>>(
275          `trace-row[row-type='cpu-data'][row-id='${wakeupCpuLists[i]}']`
276        );
277        cpuFavoriteRow!.setAttribute('collect-type', '');
278        let replaceRow = document.createElement('div');
279        replaceRow.setAttribute('row-id', cpuFavoriteRow.rowId + '-' + cpuFavoriteRow.rowType);
280        replaceRow.setAttribute('type', 'replaceRow');
281        replaceRow.setAttribute('row-parent-id', cpuFavoriteRow.rowParentId);
282        replaceRow.style.display = 'none';
283        cpuFavoriteRow.rowHidden = !cpuFavoriteRow.hasAttribute('scene');
284        if (this.rowsEL!.contains(cpuFavoriteRow)) {
285          this.rowsEL!.replaceChild(replaceRow, cpuFavoriteRow);
286        }
287        this.favoriteRowsEL!.append(cpuFavoriteRow);
288        this.currentClickRow = null;
289        cpuFavoriteRow.setAttribute('draggable', 'true');
290        cpuFavoriteRow.addEventListener('dragstart', () => {
291          this.currentClickRow = cpuFavoriteRow;
292        });
293        cpuFavoriteRow.addEventListener('dragover', (ev: any) => {
294          ev.preventDefault();
295          ev.dataTransfer.dropEffect = 'move';
296        });
297        cpuFavoriteRow.addEventListener('drop', (ev: any) => {
298          if (this.favoriteRowsEL != null && this.currentClickRow != null && this.currentClickRow !== cpuFavoriteRow) {
299            let rect = cpuFavoriteRow.getBoundingClientRect();
300            if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) {
301              //向上移动
302              this.favoriteRowsEL.insertBefore(this.currentClickRow, cpuFavoriteRow);
303            } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) {
304              //向下移动
305              this.favoriteRowsEL.insertBefore(this.currentClickRow, cpuFavoriteRow.nextSibling);
306            }
307            this.refreshFavoriteCanvas();
308          }
309        });
310        cpuFavoriteRow.addEventListener('dragend', () => {
311          this.linkNodes.forEach((itln) => {
312            if (itln[0].rowEL.collect) {
313              itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195;
314            } else {
315              itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
316            }
317            if (itln[1].rowEL.collect) {
318              itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195;
319            } else {
320              itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
321            }
322            itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY;
323            itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY;
324          });
325          this.currentClickRow = null;
326        });
327      }
328      this.refreshFavoriteCanvas();
329      this.refreshCanvas(true);
330    });
331    sideColor?.addEventListener('click', (event: any) => {
332      requestAnimationFrame(() => this.refreshCanvas(true));
333    });
334    document?.addEventListener('triangle-flag', (event: any) => {
335      let temporaryTime = this.timerShaftEL?.drawTriangle(event.detail.time, event.detail.type);
336      if (event.detail.timeCallback && temporaryTime) event.detail.timeCallback(temporaryTime);
337    });
338    document?.addEventListener('flag-change', (event: any) => {
339      this.timerShaftEL?.modifyFlagList(event.detail);
340      if (event.detail.hidden) {
341        this.selectFlag = undefined;
342        this.traceSheetEL?.setAttribute('mode', 'hidden');
343        this.refreshCanvas(true);
344      }
345    });
346    document?.addEventListener('slices-change', (event: any) => {
347      this.timerShaftEL?.modifySlicesList(event.detail);
348      if (event.detail.hidden) {
349        this.slicestime = null;
350        this.traceSheetEL?.setAttribute('mode', 'hidden');
351        this.refreshCanvas(true);
352      }
353    });
354    if (this.timerShaftEL?.collecBtn) {
355      this.timerShaftEL.collecBtn.onclick = () => {
356        if (this.timerShaftEL!.collecBtn!.hasAttribute('close')) {
357          this.timerShaftEL!.collecBtn!.removeAttribute('close');
358        } else {
359          this.timerShaftEL!.collecBtn!.setAttribute('close', '');
360        }
361        if (this.collectRows.length > 0) {
362          this.collectRows.forEach((row) => {
363            row?.collectEL?.onclick?.(new MouseEvent('auto-collect', undefined));
364          });
365        }
366      };
367    }
368    document?.addEventListener('collect', (event: any) => {
369      let currentRow = event.detail.row;
370      if (currentRow.collect) {
371        if (
372          !this.collectRows.find((find) => {
373            return find === currentRow;
374          })
375        ) {
376          this.collectRows.push(currentRow);
377        }
378        if (event.detail.type !== 'auto-collect' && this.timerShaftEL!.collecBtn!.hasAttribute('close')) {
379          currentRow.collect = false;
380          this.timerShaftEL!.collecBtn!.click();
381          return;
382        }
383        let replaceRow = document.createElement('div');
384        replaceRow.setAttribute('row-id', currentRow.rowId + '-' + currentRow.rowType);
385        replaceRow.setAttribute('type', 'replaceRow');
386        replaceRow.setAttribute('row-parent-id', currentRow.rowParentId);
387        replaceRow.style.display = 'none';
388        currentRow.rowHidden = !currentRow.hasAttribute('scene');
389        // 添加收藏时,在线程名前面追加父亲ID
390        let rowParentId = currentRow.rowParentId;
391        if (rowParentId) {
392          let parentRows = this.shadowRoot?.querySelectorAll<TraceRow<any>>(`trace-row[row-id='${rowParentId}']`);
393          parentRows?.forEach((parentRow) => {
394            if (
395              parentRow?.name &&
396              parentRow?.name != currentRow.name &&
397              !parentRow.rowType!.startsWith('cpu') &&
398              !parentRow.rowType!.startsWith('thread') &&
399              !parentRow.rowType!.startsWith('func')
400            ) {
401              currentRow.name += '(' + parentRow.name + ')';
402            }
403          });
404        }
405        if (this.rowsEL!.contains(currentRow)) {
406          this.rowsEL!.replaceChild(replaceRow, currentRow);
407        } else {
408          if (currentRow.hasParentRowEl) {
409            let parent = currentRow.parentRowEl;
410            parent!.replaceTraceRow(replaceRow, currentRow);
411          }
412        }
413        this.favoriteRowsEL!.append(currentRow);
414      } else {
415        this.favoriteRowsEL!.removeChild(currentRow);
416        if (event.detail.type !== 'auto-collect') {
417          let rowIndex = this.collectRows.indexOf(currentRow);
418          if (rowIndex !== -1) {
419            this.collectRows.splice(rowIndex, 1);
420          }
421        }
422        let row = currentRow;
423        let allowExpansionRow = [];
424        while (row.hasParentRowEl) {
425          let parent = row.parentRowEl;
426          allowExpansionRow.push(parent);
427          row = parent;
428        }
429        for (let index: number = allowExpansionRow.length - 1; index >= 0; index--) {
430          if (!allowExpansionRow[index]?.expansion && allowExpansionRow[index]?.hasAttribute('scene')) {
431            allowExpansionRow[index].expansion = true;
432          }
433        }
434        allowExpansionRow.length = 0;
435        let replaceRow = this.rowsEL!.querySelector<HTMLCanvasElement>(
436          `div[row-id='${currentRow.rowId}-${currentRow.rowType}']`
437        );
438        if (replaceRow != null) {
439          // 取消收藏时,删除父亲ID
440          let rowNameArr = currentRow.name.split('(');
441          if (rowNameArr.length > 1) {
442            let tempName = '';
443            tempName += rowNameArr[0];
444            currentRow.name = tempName;
445          } else {
446            currentRow.name = rowNameArr[0];
447          }
448          this.rowsEL!.replaceChild(currentRow, replaceRow);
449          currentRow.style.boxShadow = `0 10px 10px #00000000`;
450        }
451        this.canvasFavoritePanel!.style.transform = `translateY(${
452          this.favoriteRowsEL!.scrollTop - currentRow.clientHeight
453        }px)`;
454      }
455      this.timerShaftEL?.displayCollect(this.collectRows.length !== 0);
456      this.refreshFavoriteCanvas();
457      this.refreshCanvas(true);
458      this.linkNodes.forEach((itln) => {
459        if (itln[0].rowEL === currentRow) {
460          if (itln[0].rowEL.collect) {
461            itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195;
462          } else {
463            itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
464          }
465          itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY;
466        } else if (itln[1].rowEL === currentRow) {
467          if (itln[1].rowEL.collect) {
468            itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195;
469          } else {
470            itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
471          }
472          itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY;
473        }
474      });
475      // 收藏夹元素拖动排序功能
476      this.currentClickRow = null;
477      currentRow.setAttribute('draggable', 'true');
478      currentRow.addEventListener('dragstart', () => {
479        this.currentClickRow = currentRow;
480      });
481      currentRow.addEventListener('dragover', (ev: any) => {
482        ev.preventDefault();
483        ev.dataTransfer.dropEffect = 'move';
484      });
485      currentRow.addEventListener('drop', (ev: any) => {
486        if (this.favoriteRowsEL != null && this.currentClickRow != null && this.currentClickRow !== currentRow) {
487          let rect = currentRow.getBoundingClientRect();
488          if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) {
489            //向上移动
490            this.favoriteRowsEL.insertBefore(this.currentClickRow, currentRow);
491          } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) {
492            //向下移动
493            this.favoriteRowsEL.insertBefore(this.currentClickRow, currentRow.nextSibling);
494          }
495          this.refreshFavoriteCanvas();
496        }
497      });
498      currentRow.addEventListener('dragend', () => {
499        this.linkNodes.forEach((itln) => {
500          if (itln[0].rowEL.collect) {
501            itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195;
502          } else {
503            itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
504          }
505          if (itln[1].rowEL.collect) {
506            itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195;
507          } else {
508            itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
509          }
510          itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY;
511          itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY;
512        });
513        this.currentClickRow = null;
514      });
515    });
516    SpSystemTrace.scrollViewWidth = this.getScrollWidth();
517    this.rangeSelect.selectHandler = (rows, refreshCheckBox) => {
518      rows.forEach((item) => {
519        this.setAttribute('clickRow', item.rowType!);
520        this.setAttribute('rowName', item.name);
521        this.setAttribute('rowId', item.rowId!);
522      });
523      if (rows.length == 0) {
524        this.shadowRoot!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
525          it.checkType = '-1';
526          if (it.folder) {
527            it.childrenList.forEach((item) => {
528              it.checkType = '-1';
529            });
530          }
531        });
532        this.refreshCanvas(true);
533        this.traceSheetEL?.setAttribute('mode', 'hidden');
534        return;
535      }
536      if (refreshCheckBox) {
537        if (rows.length > 0) {
538          this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((row) => {
539            row.checkType = '0';
540            if (row.folder) {
541              row.childrenList.forEach((ite) => {
542                ite.checkType = '0';
543              });
544            }
545          });
546          rows.forEach((it) => {
547            it.checkType = '2';
548          });
549        } else {
550          this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((row) => {
551            row.checkType = '-1';
552            if (row.folder) {
553              row.childrenList.forEach((it) => {
554                it.checkType = '-1';
555              });
556            }
557          });
558          return;
559        }
560      }
561      if (!this.isSelectClick) {
562        this.rangeTraceRow = [];
563      }
564      let selection = new SelectionParam();
565      selection.leftNs = TraceRow.rangeSelectObject?.startNS || 0;
566      selection.rightNs = TraceRow.rangeSelectObject?.endNS || 0;
567      selection.recordStartNs = (window as any).recordStartNS;
568      let native_memory = ['All Heap & Anonymous VM', 'All Heap', 'All Anonymous VM'];
569      rows.forEach((it) => {
570        if (it.rowType == TraceRow.ROW_TYPE_CPU) {
571          selection.cpus.push(parseInt(it.rowId!));
572          info('load CPU traceRow id is : ', it.rowId);
573        } else if (it.rowType == TraceRow.ROW_TYPE_CPU_STATE) {
574          let filterId = parseInt(it.rowId!);
575          if (selection.cpuStateFilterIds.indexOf(filterId) == -1) {
576            selection.cpuStateFilterIds.push(filterId);
577          }
578        } else if (it.rowType == TraceRow.ROW_TYPE_CPU_FREQ) {
579          let filterId = parseInt(it.rowId!);
580          if (selection.cpuFreqFilterIds.indexOf(filterId) == -1) {
581            selection.cpuFreqFilterIds.push(filterId);
582          }
583        } else if (it.rowType == TraceRow.ROW_TYPE_CPU_FREQ_LIMIT) {
584          selection.cpuFreqLimitDatas.push(it.dataList!);
585        } else if (it.rowType == TraceRow.ROW_TYPE_PROCESS) {
586          this.pushPidToSelection(selection, it.rowId!);
587          if (it.getAttribute('hasStartup') === 'true') {
588            selection.startup = true;
589          }
590          if (it.getAttribute('hasStaticInit') === 'true') {
591            selection.staticInit = true;
592          }
593          let processChildRows: Array<TraceRow<any>> = [
594            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
595          ];
596          if (!it.expansion) {
597            processChildRows = [...it.childrenList];
598          }
599          selection.processIds.push(parseInt(it.rowId!));
600          processChildRows.forEach((th) => {
601            th.rangeSelect = true;
602            th.checkType = '2';
603            if (th.rowType == TraceRow.ROW_TYPE_THREAD) {
604              selection.threadIds.push(parseInt(th.rowId!));
605            } else if (th.rowType == TraceRow.ROW_TYPE_FUNC) {
606              if (th.asyncFuncName) {
607                selection.funAsync.push({
608                  name: th.asyncFuncName,
609                  pid: th.asyncFuncNamePID || 0,
610                });
611              } else {
612                selection.funTids.push(parseInt(th.rowId!));
613              }
614            } else if (th.rowType == TraceRow.ROW_TYPE_MEM) {
615              selection.processTrackIds.push(parseInt(th.rowId!));
616            }
617          });
618          info('load process traceRow id is : ', it.rowId);
619        } else if (it.rowType == TraceRow.ROW_TYPE_NATIVE_MEMORY) {
620          let memoryRows: Array<TraceRow<any>> = [
621            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
622          ];
623          if (!it.expansion) {
624            memoryRows = [...it.childrenList];
625          }
626          memoryRows.forEach((th) => {
627            th.rangeSelect = true;
628            th.checkType = '2';
629            if (th.getAttribute('heap-type') === 'native_hook_statistic') {
630              selection.nativeMemoryStatistic.push(th.rowId!);
631            } else {
632              selection.nativeMemory.push(th.rowId!);
633            }
634          });
635          info('load nativeMemory traceRow id is : ', it.rowId);
636        } else if (it.rowType == TraceRow.ROW_TYPE_STATIC_INIT) {
637          selection.staticInit = true;
638          this.pushPidToSelection(selection, it.rowParentId!);
639          info('load thread traceRow id is : ', it.rowId);
640        } else if (it.rowType == TraceRow.ROW_TYPE_APP_STARTUP) {
641          selection.startup = true;
642          this.pushPidToSelection(selection, it.rowParentId!);
643          info('load thread traceRow id is : ', it.rowId);
644        } else if (it.rowType == TraceRow.ROW_TYPE_THREAD) {
645          this.pushPidToSelection(selection, it.rowParentId!);
646          selection.threadIds.push(parseInt(it.rowId!));
647          info('load thread traceRow id is : ', it.rowId);
648        } else if (it.rowType == TraceRow.ROW_TYPE_FUNC) {
649          TabPaneTaskFrames.TaskArray = [];
650          this.pushPidToSelection(selection, it.rowParentId!);
651          if (it.asyncFuncName) {
652            selection.funAsync.push({
653              name: it.asyncFuncName,
654              pid: it.asyncFuncNamePID || 0,
655            });
656          } else {
657            selection.funTids.push(parseInt(it.rowId!));
658          }
659
660          let isIntersect = (filterFunc: FuncStruct, rangeData: RangeSelectStruct) =>
661            Math.max(filterFunc.startTs! + filterFunc.dur!, rangeData!.endNS || 0) - Math.min(filterFunc.startTs!, rangeData!.startNS || 0) <
662              filterFunc.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0) && filterFunc.funName!.indexOf('H:Task ') >= 0;
663          let taskData = it.dataList.filter((taskData: FuncStruct) => {
664            taskData!.tid = parseInt(it.rowId!);
665            return isIntersect(taskData, TraceRow.rangeSelectObject!);
666          });
667          if (taskData.length > 0) {
668            selection.taskFramesData.push(...taskData);
669          }
670          info('load func traceRow id is : ', it.rowId);
671        } else if (it.rowType == TraceRow.ROW_TYPE_MEM || it.rowType == TraceRow.ROW_TYPE_VIRTUAL_MEMORY) {
672          if (it.rowType == TraceRow.ROW_TYPE_MEM) {
673            selection.processTrackIds.push(parseInt(it.rowId!));
674          } else {
675            selection.virtualTrackIds.push(parseInt(it.rowId!));
676          }
677          info('load memory traceRow id is : ', it.rowId);
678        } else if (it.rowType == TraceRow.ROW_TYPE_FPS) {
679          selection.hasFps = true;
680          info('load FPS traceRow id is : ', it.rowId);
681        } else if (it.rowType == TraceRow.ROW_TYPE_HEAP) {
682          if (it.getAttribute('heap-type') === 'native_hook_statistic') {
683            selection.nativeMemoryStatistic.push(it.rowId!);
684          } else {
685            selection.nativeMemory.push(it.rowId!);
686          }
687          info('load nativeMemory traceRow id is : ', it.rowId);
688        } else if (it.rowType == TraceRow.ROW_TYPE_MONITOR) {
689          let abilityChildRows: Array<TraceRow<any>> = [
690            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
691          ];
692          if (!it.expansion) {
693            abilityChildRows = [...it.childrenList];
694          }
695          abilityChildRows.forEach((th) => {
696            th.rangeSelect = true;
697            th.checkType = '2';
698            if (th.rowType == TraceRow.ROW_TYPE_CPU_ABILITY) {
699              selection.cpuAbilityIds.push(th.rowId!);
700            } else if (th.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY) {
701              selection.memoryAbilityIds.push(th.rowId!);
702            } else if (th.rowType == TraceRow.ROW_TYPE_DISK_ABILITY) {
703              selection.diskAbilityIds.push(th.rowId!);
704            } else if (th.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY) {
705              selection.networkAbilityIds.push(th.rowId!);
706            } else if (th.rowType == TraceRow.ROW_TYPE_DMA_ABILITY) {
707              selection.dmaAbilityData.push(...intersectData(th)!);
708            } else if (th.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY) {
709              selection.gpuMemoryAbilityData.push(...intersectData(th)!);
710            } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY) {
711              selection.purgeableTotalAbility.push(...intersectData(th));
712            } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY) {
713              selection.purgeablePinAbility.push(...intersectData(th));
714            }
715          });
716        } else if (it.rowType == TraceRow.ROW_TYPE_CPU_ABILITY) {
717          selection.cpuAbilityIds.push(it.rowId!);
718          info('load CPU Ability traceRow id is : ', it.rowId);
719        } else if (it.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY) {
720          selection.memoryAbilityIds.push(it.rowId!);
721          info('load Memory Ability traceRow id is : ', it.rowId);
722        } else if (it.rowType == TraceRow.ROW_TYPE_DISK_ABILITY) {
723          selection.diskAbilityIds.push(it.rowId!);
724          info('load DiskIo Ability traceRow id is : ', it.rowId);
725        } else if (it.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY) {
726          selection.networkAbilityIds.push(it.rowId!);
727          info('load Network Ability traceRow id is : ', it.rowId);
728        } else if (it.rowType == TraceRow.ROW_TYPE_DMA_ABILITY) {
729          selection.dmaAbilityData.push(...intersectData(it)!);
730        } else if (it.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY) {
731          selection.gpuMemoryAbilityData.push(...intersectData(it)!);
732        } else if (it.rowType?.startsWith(TraceRow.ROW_TYPE_SDK)) {
733          if (it.rowType == TraceRow.ROW_TYPE_SDK) {
734            let sdkRows: Array<TraceRow<any>> = [
735              ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
736            ];
737            if (!it.expansion) {
738              sdkRows = [...it.childrenList];
739            }
740            sdkRows.forEach((th) => {
741              th.rangeSelect = true;
742              th.checkType = '2';
743            });
744          }
745          if (it.rowType == TraceRow.ROW_TYPE_SDK_COUNTER) {
746            selection.sdkCounterIds.push(it.rowId!);
747          }
748          if (it.rowType == TraceRow.ROW_TYPE_SDK_SLICE) {
749            selection.sdkSliceIds.push(it.rowId!);
750          }
751        } else if (it.rowType?.startsWith('hiperf')) {
752          if (it.rowType == TraceRow.ROW_TYPE_HIPERF_EVENT || it.rowType == TraceRow.ROW_TYPE_HIPERF_REPORT) {
753            return;
754          }
755          selection.perfSampleIds.push(1);
756          if (it.rowType == TraceRow.ROW_TYPE_HIPERF_PROCESS) {
757            let hiperfProcessRows: Array<TraceRow<any>> = [
758              ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
759            ];
760            if (!it.expansion) {
761              hiperfProcessRows = [...it.childrenList];
762            }
763            hiperfProcessRows.forEach((th) => {
764              th.rangeSelect = true;
765              th.checkType = '2';
766            });
767          }
768          if (it.rowType == TraceRow.ROW_TYPE_HIPERF || it.rowId == 'HiPerf-cpu-merge') {
769            selection.perfAll = true;
770          }
771          if (it.rowType == TraceRow.ROW_TYPE_HIPERF_CPU) {
772            selection.perfCpus.push(it.index);
773          }
774          if (it.rowType == TraceRow.ROW_TYPE_HIPERF_PROCESS) {
775            selection.perfProcess.push(parseInt(it.rowId!.split('-')[0]));
776          }
777          if (it.rowType == TraceRow.ROW_TYPE_HIPERF_THREAD) {
778            selection.perfThread.push(parseInt(it.rowId!.split('-')[0]));
779          }
780        } else if (it.rowType == TraceRow.ROW_TYPE_FILE_SYSTEM) {
781          if (it.rowId == 'FileSystemLogicalWrite') {
782            if (selection.fileSystemType.length == 0) {
783              selection.fileSystemType = [0, 1, 3];
784            } else {
785              if (selection.fileSystemType.indexOf(3) == -1) {
786                selection.fileSystemType.push(3);
787              }
788            }
789          } else if (it.rowId == 'FileSystemLogicalRead') {
790            if (selection.fileSystemType.length == 0) {
791              selection.fileSystemType = [0, 1, 2];
792            } else {
793              if (selection.fileSystemType.indexOf(2) == -1) {
794                selection.fileSystemType.push(2);
795              }
796            }
797          } else if (it.rowId == 'FileSystemVirtualMemory') {
798            selection.fileSysVirtualMemory = true;
799          } else if (it.rowId == 'FileSystemDiskIOLatency') {
800            selection.diskIOLatency = true;
801          } else {
802            if (!selection.diskIOLatency) {
803              let arr = it.rowId!.split('-').reverse();
804              let ipid = parseInt(arr[0]);
805              if (selection.diskIOipids.indexOf(ipid) == -1) {
806                selection.diskIOipids.push(ipid);
807              }
808              if (arr[1] == 'read') {
809                selection.diskIOReadIds.indexOf(ipid) == -1 ? selection.diskIOReadIds.push(ipid) : '';
810              } else if (arr[1] == 'write') {
811                selection.diskIOWriteIds.indexOf(ipid) == -1 ? selection.diskIOWriteIds.push(ipid) : '';
812              }
813            }
814          }
815        } else if (it.rowType == TraceRow.ROW_TYPE_POWER_ENERGY) {
816          selection.powerEnergy.push(it.rowId!);
817        } else if (it.rowType == TraceRow.ROW_TYPE_SYSTEM_ENERGY) {
818          selection.systemEnergy.push(it.rowId!);
819        } else if (it.rowType == TraceRow.ROW_TYPE_ANOMALY_ENERGY) {
820          selection.anomalyEnergy.push(it.rowId!);
821        } else if (it.rowType == TraceRow.ROW_TYPE_SYSTEM_ENERGY) {
822          info('load anomaly Energy traceRow id is : ', it.rowId);
823        } else if (it.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) {
824          selection.smapsType.push(...intersectData(it)!);
825          let sMapsChildRows: Array<TraceRow<any>> = [
826            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
827          ];
828          if (!it.expansion) {
829            sMapsChildRows = [...it.childrenList];
830          }
831          sMapsChildRows.forEach((item) => {
832            item.rangeSelect = true;
833            if (item.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) {
834              selection.smapsType.push(...intersectData(item)!);
835            }
836          });
837        } else if (it.rowType == TraceRow.ROW_TYPE_VMTRACKER_SHM) {
838          selection.vmtrackershm.push(...intersectData(it)!);
839        } else if (it.rowType == TraceRow.ROW_TYPE_CLOCK) {
840          selection.clockMapData.set(
841            it.rowId || '',
842            it.dataList.filter((clockData) => {
843              return Utils.getTimeIsCross(
844                clockData.startNS,
845                clockData.startNS + clockData.dur,
846                TraceRow.rangeSelectObject?.startNS || 0,
847                TraceRow.rangeSelectObject?.endNS || 0
848              );
849            })
850          );
851        } else if (it.rowType == TraceRow.ROW_TYPE_IRQ) {
852          it.dataList.forEach((irqData) => {
853            if (
854              Utils.getTimeIsCross(
855                irqData.startNS,
856                irqData.startNS + irqData.dur,
857                TraceRow.rangeSelectObject?.startNS || 0,
858                TraceRow.rangeSelectObject?.endNS || 0
859              )
860            ) {
861              if (selection.irqMapData.has(irqData.name)) {
862                selection.irqMapData.get(irqData.name)?.push(irqData);
863              } else {
864                selection.irqMapData.set(irqData.name, [irqData]);
865              }
866            }
867          });
868        } else if (it.rowType === TraceRow.ROW_TYPE_VM_TRACKER) {
869          let vMTrackerChildRows: Array<TraceRow<any>> = [
870            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
871          ];
872          if (!it.expansion) {
873            vMTrackerChildRows = [...it.childrenList];
874          }
875          vMTrackerChildRows.forEach((th) => {
876            th.rangeSelect = true;
877            if (th.rowType === TraceRow.ROW_TYPE_DMA_VMTRACKER) {
878              selection.dmaVmTrackerData.push(...intersectData(th)!);
879            } else if (th.rowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU) {
880              let vMTrackerGpuChildRows: Array<TraceRow<any>> = [
881                ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${th.rowId}']`),
882              ];
883              if (!th.expansion) {
884                vMTrackerGpuChildRows = [...th.childrenList];
885              }
886              vMTrackerGpuChildRows.forEach((item) => {
887                item.rangeSelect = true;
888                if (item.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) {
889                  selection.gpuMemoryTrackerData.push(...intersectData(item)!);
890                } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) {
891                  selection.gpu.gl =
892                    item.dataList.filter(
893                      (it) =>
894                        (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
895                        (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
896                    ).length > 0;
897                } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) {
898                  selection.gpu.gpuTotal =
899                    item.dataList.filter(
900                      (it) =>
901                        (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
902                        (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
903                    ).length > 0;
904                } else if (item.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) {
905                  selection.gpu.gpuWindow =
906                    item.dataList.filter(
907                      (it) =>
908                        (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
909                        (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
910                    ).length > 0;
911                }
912              });
913            } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM) {
914              selection.purgeableTotalVM.push(...intersectData(th));
915            } else if (th.rowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_VM) {
916              selection.purgeablePinVM.push(...intersectData(th));
917            } else if (th.rowType === TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) {
918              let sMapsChildRows: Array<TraceRow<any>> = [
919                ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${th.rowId}']`),
920              ];
921              if (!th.expansion) {
922                sMapsChildRows = [...th.childrenList];
923              }
924              sMapsChildRows.forEach((item) => {
925                item.rangeSelect = true;
926                if (item.rowType == TraceRow.ROW_TYPE_VM_TRACKER_SMAPS) {
927                  selection.smapsType.push(...intersectData(item)!);
928                }
929              });
930            } else if (th.rowType == TraceRow.ROW_TYPE_VMTRACKER_SHM) {
931              selection.vmtrackershm.push(...intersectData(th)!);
932            }
933          });
934        } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU) {
935          let vMTrackerGpuChildRows: Array<TraceRow<any>> = [
936            ...this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${it.rowId}']`),
937          ];
938          if (!it.expansion) {
939            vMTrackerGpuChildRows = [...it.childrenList];
940          }
941          vMTrackerGpuChildRows.forEach((th) => {
942            th.rangeSelect = true;
943            if (th.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) {
944              selection.gpuMemoryTrackerData.push(...intersectData(th)!);
945            } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) {
946              selection.gpu.gl =
947                th.dataList.filter(
948                  (it) =>
949                    (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
950                    (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
951                ).length > 0;
952            } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) {
953              selection.gpu.gpuTotal =
954                th.dataList.filter(
955                  (it) =>
956                    (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
957                    (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
958                ).length > 0;
959            } else if (th.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) {
960              selection.gpu.gpuWindow =
961                th.dataList.filter(
962                  (it) =>
963                    (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
964                    (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
965                ).length > 0;
966            }
967          });
968        } else if (it.rowType == TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER) {
969          selection.gpuMemoryTrackerData.push(...intersectData(it)!);
970        } else if (it.rowType == TraceRow.ROW_TYPE_DMA_VMTRACKER) {
971          selection.dmaVmTrackerData.push(...intersectData(it)!);
972        } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_GL) {
973          selection.gpu.gl =
974            it.dataList.filter(
975              (it) =>
976                (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
977                (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
978            ).length > 0;
979        } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL) {
980          selection.gpu.gpuTotal =
981            it.dataList.filter(
982              (it) =>
983                (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
984                (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
985            ).length > 0;
986        } else if (it.rowType == TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW) {
987          selection.gpu.gpuWindow =
988            it.dataList.filter(
989              (it) =>
990                (it.startNs >= selection.leftNs && it.startNs <= selection.rightNs) ||
991                (it.endNs >= selection.leftNs && it.endNs <= selection.rightNs)
992            ).length > 0;
993        } else if (it.rowType == TraceRow.ROW_TYPE_JANK) {
994          let isIntersect = (filterJank: JanksStruct, rangeData: RangeSelectStruct) =>
995            Math.max(filterJank.ts! + filterJank.dur!, rangeData!.endNS || 0) - Math.min(filterJank.ts!, rangeData!.startNS || 0) <
996            filterJank.dur! + (rangeData!.endNS || 0) - (rangeData!.startNS || 0);
997          if (it.name == 'Actual Timeline') {
998            selection.jankFramesData = [];
999            let jankDatas = it.dataList.filter((jankData: any) => {
1000              return isIntersect(jankData, TraceRow.rangeSelectObject!);
1001            });
1002            selection.jankFramesData.push(jankDatas);
1003          } else if (it.folder) {
1004            selection.jankFramesData = [];
1005            it.childrenList.forEach((child) => {
1006              if (child.rowType == TraceRow.ROW_TYPE_JANK && child.name == 'Actual Timeline') {
1007                let jankDatas = child.dataList.filter((jankData: any) => {
1008                  return isIntersect(jankData, TraceRow.rangeSelectObject!);
1009                });
1010                selection.jankFramesData.push(jankDatas);
1011              }
1012            });
1013          }
1014        } else if (it.rowType == TraceRow.ROW_TYPE_HEAP_TIMELINE) {
1015          let endNS = TraceRow.rangeSelectObject?.endNS ? TraceRow.rangeSelectObject?.endNS : TraceRow.range?.endNS;
1016          let startNS = TraceRow.rangeSelectObject?.startNS
1017            ? TraceRow.rangeSelectObject?.startNS
1018            : TraceRow.range?.startNS;
1019          let minNodeId, maxNodeId;
1020          if (!it.dataList || it.dataList.length === 0) {
1021            return;
1022          }
1023          for (let sample of it.dataList) {
1024            if (sample.timestamp * 1000 <= startNS!) {
1025              minNodeId = sample.lastAssignedId;
1026            }
1027            if (sample.timestamp * 1000 >= endNS!) {
1028              if (maxNodeId === undefined) {
1029                maxNodeId = sample.lastAssignedId;
1030              }
1031            }
1032          }
1033
1034          // If the start time range of the selected box is greater than the end time of the sampled data
1035          if (startNS! >= it.dataList[it.dataList.length - 1].timestamp * 1000) {
1036            minNodeId = it.dataList[it.dataList.length - 1].lastAssignedId;
1037          }
1038          // If you select the box from the beginning
1039          if (startNS! <= TraceRow.range?.startNS!) {
1040            minNodeId = HeapDataInterface.getInstance().getMinNodeId(this.snapshotFiles!.id);
1041          }
1042          //If you select the box from the ending
1043          if (endNS! >= TraceRow.range?.endNS! || endNS! >= it.dataList[it.dataList.length - 1].timestampUs * 1000) {
1044            maxNodeId = HeapDataInterface.getInstance().getMaxNodeId(this.snapshotFiles!.id);
1045          }
1046          let summary = (this.traceSheetEL?.shadowRoot?.querySelector('#tabs') as LitTabs)
1047            ?.querySelector('#box-heap-summary')
1048            ?.querySelector('tabpane-summary') as TabPaneSummary;
1049          summary.initSummaryData(this.snapshotFiles!, minNodeId, maxNodeId);
1050          selection.jsMemory.push(1);
1051        } else if (it.rowType == TraceRow.ROW_TYPE_JS_CPU_PROFILER) {
1052          let isIntersect = (a: JsCpuProfilerStruct, b: RangeSelectStruct) =>
1053            Math.max(a.startTime! + a.totalTime!, b!.endNS || 0) - Math.min(a.startTime!, b!.startNS || 0) <
1054            a.totalTime! + (b!.endNS || 0) - (b!.startNS || 0);
1055          let frameSelectData = it.dataList.filter((frameSelectData: any) => {
1056            return isIntersect(frameSelectData, TraceRow.rangeSelectObject!);
1057          });
1058          let copyFrameSelectData = JSON.parse(JSON.stringify(frameSelectData));
1059          let frameSelectDataIdArr: Array<number> = [];
1060          for (let data of copyFrameSelectData) {
1061            frameSelectDataIdArr.push(data.id);
1062          }
1063          let jsCpuProfilerData = copyFrameSelectData.filter((item: any) => {
1064            if (item.depth == 0) {
1065              setSelectState(item, frameSelectDataIdArr);
1066              return item;
1067            }
1068          });
1069          selection.jsCpuProfilerData = jsCpuProfilerData;
1070        } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_ANIMATION) {
1071          let isIntersect = (animationStruct: FrameAnimationStruct, selectStruct: RangeSelectStruct) =>
1072            Math.max(animationStruct.ts! + animationStruct.dur!, selectStruct!.endNS || 0) -
1073              Math.min(animationStruct.ts!, selectStruct!.startNS || 0) <
1074            animationStruct.dur! + (selectStruct!.endNS || 0) - (selectStruct!.startNS || 0);
1075          let frameAnimationList = it.dataList.filter((frameAnimationBean: FrameAnimationStruct) => {
1076            return isIntersect(frameAnimationBean, TraceRow.rangeSelectObject!);
1077          });
1078          selection.frameAnimation.push(...frameAnimationList);
1079        } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_DYNAMIC) {
1080          let appName = it.getAttribute('model-name');
1081          let isSelect = (dynamicStruct: FrameDynamicStruct, b: RangeSelectStruct) =>
1082            dynamicStruct.ts >= b.startNS! && dynamicStruct.ts <= b.endNS!;
1083          let frameDynamicList = it.dataList.filter(
1084            (frameAnimationBean: FrameDynamicStruct) =>
1085              isSelect(frameAnimationBean, TraceRow.rangeSelectObject!) &&
1086              frameAnimationBean.groupId !== -1 &&
1087              frameAnimationBean.appName === appName
1088          );
1089          selection.frameDynamic.push(...frameDynamicList);
1090        } else if (it.rowType == TraceRow.ROW_TYPE_FRAME_SPACING) {
1091          let appName = it.getAttribute('model-name');
1092          let isSelect = (a: FrameSpacingStruct, b: RangeSelectStruct) =>
1093            a.currentTs >= b.startNS! && a.currentTs <= b.endNS!;
1094          let frameDatas = it.dataList.filter((frameData: FrameSpacingStruct) => {
1095            return (
1096              isSelect(frameData, TraceRow.rangeSelectObject!) &&
1097              frameData.groupId !== -1 &&
1098              frameData.frameSpacingResult !== -1 &&
1099              frameData.nameId === appName
1100            );
1101          });
1102          selection.frameSpacing.push(...frameDatas);
1103        } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY) {
1104          selection.purgeableTotalAbility.push(...intersectData(it));
1105        } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY) {
1106          selection.purgeablePinAbility.push(...intersectData(it));
1107        } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM) {
1108          selection.purgeableTotalVM.push(...intersectData(it));
1109        } else if (it.rowType == TraceRow.ROW_TYPE_PURGEABLE_PIN_VM) {
1110          selection.purgeablePinVM.push(...intersectData(it));
1111        }
1112        if (this.rangeTraceRow!.length !== rows.length) {
1113          let event = this.createPointEvent(it);
1114          SpStatisticsHttpUtil.addOrdinaryVisitAction({
1115            action: 'trace_row',
1116            event: event,
1117          });
1118        }
1119      });
1120      this.rangeTraceRow = rows;
1121      this.isSelectClick = false;
1122      if (selection.diskIOipids.length > 0 && !selection.diskIOLatency) {
1123        selection.promiseList.push(
1124          queryEbpfSamplesCount(
1125            TraceRow.rangeSelectObject?.startNS || 0,
1126            TraceRow.rangeSelectObject?.endNS || 0,
1127            selection.diskIOipids
1128          ).then((res) => {
1129            if (res.length > 0) {
1130              selection.fsCount = res[0].fsCount;
1131              selection.vmCount = res[0].vmCount;
1132            }
1133            return new Promise((resolve) => resolve(1));
1134          })
1135        );
1136      }
1137      this.selectStructNull();
1138      this.timerShaftEL?.removeTriangle('inverted');
1139      if (selection.promiseList.length > 0) {
1140        Promise.all(selection.promiseList).then(() => {
1141          selection.promiseList = [];
1142          this.traceSheetEL?.rangeSelect(selection);
1143        });
1144      } else {
1145        this.traceSheetEL?.rangeSelect(selection);
1146      }
1147      this.timerShaftEL!.selectionList.push(selection); // 保持选中对象,为后面的再次选中该框选区域做准备。
1148      this.selectionParam = selection;
1149    };
1150    // @ts-ignore
1151    new ResizeObserver((entries) => {
1152      TraceRow.FRAME_WIDTH = this.clientWidth - 249 - this.getScrollWidth();
1153      requestAnimationFrame(() => {
1154        this.timerShaftEL?.updateWidth(this.clientWidth - 1 - this.getScrollWidth());
1155        this.shadowRoot!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
1156          it.updateWidth(this.clientWidth);
1157        });
1158      });
1159    }).observe(this);
1160
1161    new ResizeObserver((entries) => {
1162      this.canvasPanelConfig();
1163      if (this.traceSheetEL!.getAttribute('mode') == 'hidden') {
1164        this.timerShaftEL?.removeTriangle('triangle');
1165      }
1166      this.refreshFavoriteCanvas();
1167      this.refreshCanvas(true);
1168    }).observe(this.rowsPaneEL!);
1169    new MutationObserver((mutations, observer) => {
1170      for (const mutation of mutations) {
1171        if (mutation.type === 'attributes') {
1172          if (this.style.visibility === 'visible') {
1173            if (TraceRow.rangeSelectObject && SpSystemTrace.sliceRangeMark) {
1174              this.timerShaftEL?.setSlicesMark(
1175                TraceRow.rangeSelectObject.startNS || 0,
1176                TraceRow.rangeSelectObject.endNS || 0,
1177                false
1178              );
1179              SpSystemTrace.sliceRangeMark = undefined;
1180              window.publish(window.SmartEvent.UI.RefreshCanvas, {});
1181            }
1182          }
1183        }
1184      }
1185    }).observe(this, {
1186      attributes: true,
1187      childList: false,
1188      subtree: false,
1189    });
1190
1191    this.intersectionObserver = new IntersectionObserver((entries) => {
1192      entries.forEach((it) => {
1193        let tr = it.target as TraceRow<any>;
1194        if (!it.isIntersecting) {
1195          tr.sleeping = true;
1196          this.visibleRows = this.visibleRows.filter((it) => !it.sleeping);
1197        } else {
1198          if (
1199            !this.visibleRows.find(
1200              (vr) => vr.rowId === tr.rowId && vr.rowType === tr.rowType && vr.rowParentId === tr.rowParentId
1201            )
1202          ) {
1203            this.visibleRows.push(tr);
1204          }
1205          tr.sleeping = false;
1206        }
1207        if (this.handler) clearTimeout(this.handler);
1208        this.handler = setTimeout(() => this.refreshCanvas(false), 100);
1209      });
1210    });
1211    window.addEventListener('keydown', (ev) => {
1212      if (ev.key.toLocaleLowerCase() === 'escape') {
1213        this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
1214          it.checkType = '-1';
1215        });
1216        TraceRow.rangeSelectObject = undefined;
1217        this.rangeSelect.rangeTraceRow = [];
1218        this.selectStructNull();
1219        this.timerShaftEL?.setSlicesMark();
1220        this.traceSheetEL?.setAttribute('mode', 'hidden');
1221        this.removeLinkLinesByBusinessType('janks', 'task');
1222      }
1223    });
1224    this.chartManager = new SpChartManager(this);
1225    this.canvasPanel = this.shadowRoot!.querySelector<HTMLCanvasElement>('#canvas-panel')!;
1226    this.canvasFavoritePanel = this.shadowRoot!.querySelector<HTMLCanvasElement>('#canvas-panel-favorite')!;
1227    this.canvasPanelCtx = this.canvasPanel.getContext('2d');
1228
1229    this.canvasFavoritePanelCtx = this.canvasFavoritePanel.getContext('2d');
1230    this.canvasPanelConfig();
1231    window.subscribe(window.SmartEvent.UI.SliceMark, (data) => {
1232      this.sliceMarkEventHandler(data);
1233    });
1234    window.subscribe(window.SmartEvent.UI.TraceRowComplete, (tr) => {});
1235    window.subscribe(window.SmartEvent.UI.RefreshCanvas, () => {
1236      this.refreshCanvas(false);
1237    });
1238    window.subscribe(window.SmartEvent.UI.KeyboardEnable, (tr) => {
1239      this.keyboardEnable = tr.enable;
1240      if (!this.keyboardEnable) {
1241        this.stopWASD();
1242      }
1243    });
1244    window.subscribe(window.SmartEvent.UI.MouseEventEnable, (tr) => {
1245      this.mouseEventEnable = tr.mouseEnable;
1246      if (this.mouseEventEnable) {
1247        this.removeAttribute('disable');
1248      } else {
1249        this.setAttribute('disable', '');
1250      }
1251    });
1252  }
1253
1254  pushPidToSelection(selection: SelectionParam, id: string) {
1255    let pid = parseInt(id);
1256    if (!selection.processIds.includes(pid)) {
1257      selection.processIds.push(pid);
1258    }
1259  }
1260
1261  private createPointEvent(it: TraceRow<any>) {
1262    let event = this.eventMap[it.rowType + ''];
1263    if (event) {
1264      return event;
1265    } else {
1266      if (it.rowType === TraceRow.ROW_TYPE_HEAP) {
1267        event = it.name;
1268      } else if (it.rowType === TraceRow.ROW_TYPE_HIPERF_CPU) {
1269        event = 'HiPerf Cpu';
1270        if (it.rowId === 'HiPerf-cpu-merge') {
1271          event = 'HiPerf';
1272        }
1273      } else if (it.rowType === TraceRow.ROW_TYPE_FILE_SYSTEM) {
1274        if (it.rowId === 'FileSystemLogicalWrite') {
1275          event = 'FileSystem Logical Write';
1276        } else if (it.rowId === 'FileSystemLogicalRead') {
1277          event = 'FileSystem Logical Read';
1278        } else if (it.rowId === 'FileSystemVirtualMemory') {
1279          event = 'Page Fault Trace';
1280        } else if (it.rowId!.startsWith('FileSystemDiskIOLatency')) {
1281          event = 'Disk I/O Latency';
1282          if (it.rowId!.startsWith('FileSystemDiskIOLatency-')) {
1283            event = 'Bio Process';
1284          }
1285        }
1286      } else if (it.rowType === TraceRow.ROW_TYPE_STATE_ENERGY) {
1287        event = it.name;
1288      } else if (it.rowType === TraceRow.ROW_TYPE_VM_TRACKER) {
1289        if (it.rowParentId === '') {
1290          event = 'VM Tracker';
1291        } else {
1292          event = it.name;
1293        }
1294      } else if (it.rowType === TraceRow.ROW_TYPE_JANK) {
1295        if (it.rowId === 'frameTime' || it.rowParentId === 'frameTime') {
1296          event = 'FrameTimeLine';
1297        } else if (it.hasAttribute('frame_type')) {
1298          event = it.getAttribute('frame_type') + '';
1299        }
1300      } else if (it.rowType === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) {
1301        event = 'DeliverInputEvent';
1302        if (it.rowParentId === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) {
1303          event = 'DeliverInputEvent Func';
1304        }
1305      } else {
1306        event = it.name;
1307      }
1308      return event;
1309    }
1310  }
1311
1312  refreshFavoriteCanvas() {
1313    let collectList = this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[collect-type]`) || [];
1314    let height = 0;
1315    collectList.forEach((row, index) => {
1316      height += row.offsetHeight;
1317      if (index == collectList.length - 1) {
1318        row.style.boxShadow = `0 10px 10px #00000044`;
1319      } else {
1320        row.style.boxShadow = `0 10px 10px #00000000`;
1321      }
1322    });
1323    if (height > this.rowsPaneEL!.offsetHeight) {
1324      this.favoriteRowsEL!.style.height = this.rowsPaneEL!.offsetHeight + 'px';
1325    } else {
1326      this.favoriteRowsEL!.style.height = height + 'px';
1327    }
1328    this.favoriteRowsEL!.style.width = this.canvasPanel?.offsetWidth + 'px';
1329    this.spacerEL!.style.height = height + 'px';
1330    this.canvasFavoritePanel!.style.height = this.favoriteRowsEL!.style.height;
1331    this.canvasFavoritePanel!.style.width = this.canvasPanel?.offsetWidth + 'px';
1332    this.canvasFavoritePanel!.width = this.canvasFavoritePanel!.offsetWidth * dpr();
1333    this.canvasFavoritePanel!.height = this.canvasFavoritePanel!.offsetHeight * dpr();
1334    this.canvasFavoritePanel!.getContext('2d')!.scale(dpr(), dpr());
1335  }
1336
1337  expansionAllParentRow(currentRow: TraceRow<any>) {
1338    let parentRow = this.rowsEL!.querySelector<TraceRow<any>>(
1339      `trace-row[row-id='${currentRow.rowParentId}'][folder][scene]`
1340    );
1341    if (parentRow) {
1342      parentRow.expansion = true;
1343      if (this.rowsEL!.querySelector<TraceRow<any>>(`trace-row[row-id='${parentRow.rowParentId}'][folder]`)) {
1344        this.expansionAllParentRow(parentRow);
1345      }
1346    }
1347  }
1348
1349  canvasPanelConfig() {
1350    this.canvasPanel!.style.left = `${this.timerShaftEL!.canvas!.offsetLeft!}px`;
1351    this.canvasPanel!.width = this.canvasPanel!.offsetWidth * dpr();
1352    this.canvasPanel!.height = this.canvasPanel!.offsetHeight * dpr();
1353    this.canvasPanelCtx!.scale(dpr(), dpr());
1354
1355    this.canvasFavoritePanel!.style.left = `${this.timerShaftEL!.canvas!.offsetLeft!}px`;
1356    this.canvasFavoritePanel!.width = this.canvasFavoritePanel!.offsetWidth * dpr();
1357    this.canvasFavoritePanel!.height = this.canvasFavoritePanel!.offsetHeight * dpr();
1358    this.canvasFavoritePanelCtx!.scale(dpr(), dpr());
1359  }
1360
1361  getScrollWidth() {
1362    let totalScrollDiv,
1363      scrollDiv,
1364      overflowDiv = document.createElement('div');
1365    overflowDiv.style.cssText = 'position:absolute; top:-2000px;width:200px; height:200px; overflow:hidden;';
1366    totalScrollDiv = document.body.appendChild(overflowDiv).clientWidth;
1367    overflowDiv.style.overflowY = 'scroll';
1368    scrollDiv = overflowDiv.clientWidth;
1369    document.body.removeChild(overflowDiv);
1370    return totalScrollDiv - scrollDiv;
1371  }
1372
1373  timerShaftELFlagClickHandler = (flag: Flag | undefined | null) => {
1374    if (flag) {
1375      setTimeout(() => {
1376        this.traceSheetEL?.displayFlagData(flag);
1377      }, 100);
1378    }
1379  };
1380
1381  timerShaftELFlagChange = (hoverFlag: Flag | undefined | null, selectFlag: Flag | undefined | null) => {
1382    this.hoverFlag = hoverFlag;
1383    this.selectFlag = selectFlag;
1384    this.refreshCanvas(true, 'flagChange');
1385  };
1386
1387  timerShaftELRangeClick = (sliceTime: SlicesTime | undefined | null) => {
1388    if (sliceTime) {
1389      setTimeout(() => {
1390        this.traceSheetEL?.displayCurrent(sliceTime); // 给当前pane准备数据
1391        let selection = this.timerShaftEL!.selectionMap.get(sliceTime.id);
1392        if (selection) {
1393          selection.isCurrentPane = true; // 设置当前面板为可以显示的状态
1394          this.traceSheetEL?.rangeSelect(selection); // 显示选中区域对应的面板
1395        }
1396      }, 0);
1397    }
1398  };
1399
1400  timerShaftELRangeChange = (e: any) => {
1401    TraceRow.range = e;
1402    if (TraceRow.rangeSelectObject) {
1403      TraceRow.rangeSelectObject!.startX = Math.floor(
1404        ns2x(
1405          TraceRow.rangeSelectObject!.startNS!,
1406          TraceRow.range?.startNS!,
1407          TraceRow.range?.endNS!,
1408          TraceRow.range?.totalNS!,
1409          this.timerShaftEL!.sportRuler!.frame
1410        )
1411      );
1412      TraceRow.rangeSelectObject!.endX = Math.floor(
1413        ns2x(
1414          TraceRow.rangeSelectObject!.endNS!,
1415          TraceRow.range?.startNS!,
1416          TraceRow.range?.endNS!,
1417          TraceRow.range?.totalNS!,
1418          this.timerShaftEL!.sportRuler!.frame
1419        )
1420      );
1421    }
1422    //在rowsEL显示范围内的 trace-row组件将收到时间区间变化通知
1423    this.linkNodes.forEach((it) => {
1424      it[0].x = ns2xByTimeShaft(it[0].ns, this.timerShaftEL!);
1425      it[1].x = ns2xByTimeShaft(it[1].ns, this.timerShaftEL!);
1426    });
1427    this.refreshCanvas(false, 'rangeChange');
1428  };
1429  tim: number = -1;
1430  top: number = 0;
1431  handler: any = undefined;
1432  rowsElOnScroll = (e: any) => {
1433    this.linkNodes.forEach((itln) => {
1434      if (itln[0].rowEL.collect) {
1435        itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195;
1436      } else {
1437        itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
1438      }
1439      if (itln[1].rowEL.collect) {
1440        itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195;
1441      } else {
1442        itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
1443      }
1444      itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY;
1445      itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY;
1446    });
1447    if (this.scrollTimer) {
1448      clearTimeout(this.scrollTimer);
1449    }
1450    this.scrollTimer = setTimeout(() => {
1451      TraceRow.range!.refresh = true;
1452      requestAnimationFrame(() => this.refreshCanvas(false));
1453    }, 200);
1454    requestAnimationFrame(() => this.refreshCanvas(false));
1455  };
1456
1457  private scrollTimer: any;
1458
1459  favoriteRowsElOnScroll = (e: any) => {
1460    this.rowsElOnScroll(e);
1461  };
1462
1463  offset = 147;
1464
1465  getRowsContentHeight(): number {
1466    return [...this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row:not([sleeping])`)]
1467      .map((it) => it.clientHeight)
1468      .reduce((acr, cur) => acr + cur, 0);
1469  }
1470
1471  // refresh main canvas and favorite canvas
1472  refreshCanvas(cache: boolean, from?: string) {
1473    if (this.visibleRows.length == 0) {
1474      return;
1475    }
1476    //clear main canvas
1477    this.canvasPanelCtx?.clearRect(0, 0, this.canvasPanel!.offsetWidth, this.canvasPanel!.offsetHeight);
1478    //clear favorite canvas
1479    this.canvasFavoritePanelCtx?.clearRect(
1480      0,
1481      0,
1482      this.canvasFavoritePanel!.offsetWidth,
1483      this.canvasFavoritePanel!.offsetHeight
1484    );
1485    //draw lines for main canvas
1486    let rowsContentHeight = this.getRowsContentHeight();
1487    let canvasHeight =
1488      rowsContentHeight > this.canvasPanel!.clientHeight ? this.canvasPanel!.clientHeight : rowsContentHeight;
1489    canvasHeight += this.canvasFavoritePanel!.clientHeight;
1490    drawLines(this.canvasPanelCtx!, TraceRow.range?.xs || [], canvasHeight, this.timerShaftEL!.lineColor());
1491    //draw lines for favorite canvas
1492    drawLines(
1493      this.canvasFavoritePanelCtx!,
1494      TraceRow.range?.xs || [],
1495      this.canvasFavoritePanel!.clientHeight,
1496      this.timerShaftEL!.lineColor()
1497    );
1498    //canvas translate
1499    this.canvasPanel!.style.transform = `translateY(${this.rowsPaneEL!.scrollTop}px)`;
1500    this.canvasFavoritePanel!.style.transform = `translateY(${this.favoriteRowsEL!.scrollTop}px)`;
1501    //draw trace row
1502    this.visibleRows.forEach((v, i) => {
1503      if (v.collect) {
1504        v.translateY = v.getBoundingClientRect().top - 195;
1505      } else {
1506        v.translateY = v.offsetTop - this.rowsPaneEL!.scrollTop;
1507      }
1508      v.draw(cache);
1509    });
1510    //draw flag line segment for canvas
1511    drawFlagLineSegment(
1512      this.canvasPanelCtx,
1513      this.hoverFlag,
1514      this.selectFlag,
1515      {
1516        x: 0,
1517        y: 0,
1518        width: this.timerShaftEL?.canvas?.clientWidth,
1519        height: this.canvasPanel?.clientHeight,
1520      },
1521      this.timerShaftEL!
1522    );
1523    //draw flag line segment for favorite canvas
1524    drawFlagLineSegment(
1525      this.canvasFavoritePanelCtx,
1526      this.hoverFlag,
1527      this.selectFlag,
1528      {
1529        x: 0,
1530        y: 0,
1531        width: this.timerShaftEL?.canvas?.clientWidth,
1532        height: this.canvasFavoritePanel?.clientHeight,
1533      },
1534      this.timerShaftEL!
1535    );
1536    //draw wakeup for main canvas
1537    drawWakeUp(
1538      this.canvasPanelCtx,
1539      CpuStruct.wakeupBean,
1540      TraceRow.range!.startNS,
1541      TraceRow.range!.endNS,
1542      TraceRow.range!.totalNS,
1543      {
1544        x: 0,
1545        y: 0,
1546        width: TraceRow.FRAME_WIDTH,
1547        height: this.canvasPanel!.clientHeight!,
1548      } as Rect
1549    );
1550    //draw wakeup for favorite canvas
1551    drawWakeUp(
1552      this.canvasFavoritePanelCtx,
1553      CpuStruct.wakeupBean,
1554      TraceRow.range!.startNS,
1555      TraceRow.range!.endNS,
1556      TraceRow.range!.totalNS,
1557      {
1558        x: 0,
1559        y: 0,
1560        width: TraceRow.FRAME_WIDTH,
1561        height: this.canvasFavoritePanel!.clientHeight!,
1562      } as Rect
1563    );
1564    // draw wakeuplist for main canvas
1565    for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) {
1566      if (i + 1 == SpSystemTrace.wakeupList.length) {
1567        return;
1568      }
1569      drawWakeUpList(
1570        this.canvasPanelCtx,
1571        SpSystemTrace.wakeupList[i + 1],
1572        TraceRow.range!.startNS,
1573        TraceRow.range!.endNS,
1574        TraceRow.range!.totalNS,
1575        {
1576          x: 0,
1577          y: 0,
1578          width: this.timerShaftEL!.canvas!.clientWidth,
1579          height: this.canvasPanel!.clientHeight!,
1580        } as Rect
1581      );
1582      drawWakeUpList(
1583        this.canvasFavoritePanelCtx,
1584        SpSystemTrace.wakeupList[i + 1],
1585        TraceRow.range!.startNS,
1586        TraceRow.range!.endNS,
1587        TraceRow.range!.totalNS,
1588        {
1589          x: 0,
1590          y: 0,
1591          width: this.timerShaftEL!.canvas!.clientWidth,
1592          height: this.canvasFavoritePanel!.clientHeight!,
1593        } as Rect
1594      );
1595    }
1596    // Draw the connection curve
1597    if (this.linkNodes) {
1598      drawLinkLines(this.canvasPanelCtx!, this.linkNodes, this.timerShaftEL!, false);
1599      drawLinkLines(this.canvasFavoritePanelCtx!, this.linkNodes, this.timerShaftEL!, true);
1600    }
1601  }
1602
1603  documentOnMouseDown = (ev: MouseEvent) => {
1604    if (!this.loadTraceCompleted || !this.mouseEventEnable) return;
1605    if (this.isWASDKeyPress()) {
1606      ev.preventDefault();
1607      ev.stopPropagation();
1608      return;
1609    }
1610    TraceRow.isUserInteraction = true;
1611    if (this.isMouseInSheet(ev)) return;
1612    this.observerScrollHeightEnable = false;
1613    if (ev.offsetX > this.timerShaftEL!.canvas!.offsetLeft) {
1614      let x = ev.offsetX - this.timerShaftEL!.canvas!.offsetLeft;
1615      let y = ev.offsetY;
1616      this.timerShaftEL?.documentOnMouseDown(ev);
1617      if (
1618        this.timerShaftEL!.sportRuler!.frame.contains(x, y) &&
1619        x > (TraceRow.rangeSelectObject?.startX || 0) &&
1620        x < (TraceRow.rangeSelectObject?.endX || 0)
1621      ) {
1622        let findSlicestime = this.timerShaftEL!.sportRuler?.findSlicesTime(x, y); // 查找帽子
1623        if (!findSlicestime) {
1624          // 如果没有找到帽子,则绘制一个三角形的旗子
1625          let time = Math.round(
1626            (x * (TraceRow.range?.endNS! - TraceRow.range?.startNS!)) / this.timerShaftEL!.canvas!.offsetWidth +
1627              TraceRow.range?.startNS!
1628          );
1629          this.timerShaftEL!.sportRuler!.drawTriangle(time, 'triangle');
1630        }
1631      } else {
1632        this.rangeSelect.mouseDown(ev);
1633        this.rangeSelect.drag = true;
1634      }
1635    } else {
1636      this.rangeSelect.drag = false;
1637    }
1638  };
1639
1640  onContextMenuHandler = (e: Event) => {
1641    setTimeout(() => {
1642      for (let key of this.keyPressMap.keys()) {
1643        if (this.keyPressMap.get(key)) {
1644          this.timerShaftEL?.stopWASD({ key: key });
1645          this.keyPressMap.set(key, false);
1646        }
1647      }
1648    }, 100);
1649  };
1650
1651  documentOnMouseUp = (ev: MouseEvent) => {
1652    if (!this.loadTraceCompleted || !this.mouseEventEnable) return;
1653    if (this.isWASDKeyPress()) {
1654      ev.preventDefault();
1655      ev.stopPropagation();
1656      return;
1657    }
1658    TraceRow.isUserInteraction = false;
1659    this.rangeSelect.isMouseDown = false;
1660    if ((window as any).isSheetMove) return;
1661    if (this.isMouseInSheet(ev)) return;
1662    this.rangeSelect.mouseUp(ev);
1663    this.timerShaftEL?.documentOnMouseUp(ev);
1664    ev.preventDefault();
1665    ev.stopPropagation();
1666  };
1667
1668  documentOnMouseOut = (ev: MouseEvent) => {
1669    if (!this.loadTraceCompleted) return;
1670    TraceRow.isUserInteraction = false;
1671    if (this.isMouseInSheet(ev)) return;
1672    if (ev.offsetX > this.timerShaftEL!.canvas!.offsetLeft) {
1673      this.rangeSelect.mouseOut(ev);
1674      this.timerShaftEL?.documentOnMouseOut(ev);
1675    }
1676  };
1677
1678  private keyPressMap: Map<string, boolean> = new Map([
1679    ['w', false],
1680    ['s', false],
1681    ['a', false],
1682    ['d', false],
1683    ['f', false],
1684  ]);
1685  documentOnKeyPress = (ev: KeyboardEvent) => {
1686    if (!this.loadTraceCompleted) return;
1687    let keyPress = ev.key.toLocaleLowerCase();
1688    TraceRow.isUserInteraction = true;
1689    if (this.isMousePointInSheet) {
1690      return;
1691    }
1692    this.observerScrollHeightEnable = false;
1693    if (this.keyboardEnable) {
1694      if (keyPress == 'm') {
1695        this.slicestime = this.setSLiceMark(ev.shiftKey);
1696        // 设置currentPane可以显示,并且修改调色板颜色和刚刚绘制的帽子颜色保持一致。
1697        this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet');
1698        let currentPane = this.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current');
1699        if (this.slicestime) {
1700          currentPane?.setCurrentSlicesTime(this.slicestime);
1701        }
1702        // 显示对应的面板信息
1703        this.timerShaftEL!.selectionList.forEach((selection, index) => {
1704          if (this.timerShaftEL!.selectionList.length - 1 == index) {
1705            // 把最新添加的 SelectionParam 对象设置为可以显示当前面板
1706            selection.isCurrentPane = true;
1707            this.traceSheetEL?.rangeSelect(selection);
1708          } else {
1709            // 其他 SelectionParam 对象设置为不显示当前面板
1710            selection.isCurrentPane = false;
1711          }
1712        });
1713      }
1714      if (keyPress === 'f') {
1715        // 设置当前的slicesTime
1716        this.setCurrentSlicesTime();
1717      }
1718      let keyPressWASD = keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd';
1719      if (keyPressWASD) {
1720        this.keyPressMap.set(keyPress, true);
1721        this.hoverFlag = null;
1722      }
1723      this.timerShaftEL!.documentOnKeyPress(ev, this.currentSlicesTime);
1724      if (keyPress === 'f') {
1725        this.verticalScrollToRow();
1726      }
1727    } else {
1728      this.stopWASD();
1729    }
1730  };
1731
1732  verticalScrollToRow() {
1733    if (this.currentRow) {
1734      this.currentRow.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
1735    }
1736  }
1737
1738  setCurrentSlicesTime() {
1739    if (CpuStruct.selectCpuStruct) {
1740      if (CpuStruct.selectCpuStruct.startTime && CpuStruct.selectCpuStruct.dur) {
1741        this.currentSlicesTime.startTime = CpuStruct.selectCpuStruct.startTime;
1742        this.currentSlicesTime.endTime = CpuStruct.selectCpuStruct.startTime + CpuStruct.selectCpuStruct.dur;
1743      }
1744    } else if (ThreadStruct.selectThreadStruct) {
1745      if (ThreadStruct.selectThreadStruct.startTime && ThreadStruct.selectThreadStruct.dur) {
1746        this.currentSlicesTime.startTime = ThreadStruct.selectThreadStruct.startTime;
1747        this.currentSlicesTime.endTime =
1748          ThreadStruct.selectThreadStruct.startTime + ThreadStruct.selectThreadStruct.dur;
1749      }
1750    } else if (FuncStruct.selectFuncStruct) {
1751      if (FuncStruct.selectFuncStruct.startTs && FuncStruct.selectFuncStruct.dur) {
1752        this.currentSlicesTime.startTime = FuncStruct.selectFuncStruct.startTs;
1753        this.currentSlicesTime.endTime = FuncStruct.selectFuncStruct.startTs + FuncStruct.selectFuncStruct.dur;
1754      }
1755    } else if (IrqStruct.selectIrqStruct) {
1756      if (IrqStruct.selectIrqStruct.startNS && IrqStruct.selectIrqStruct.dur) {
1757        this.currentSlicesTime.startTime = IrqStruct.selectIrqStruct.startNS;
1758        this.currentSlicesTime.endTime = IrqStruct.selectIrqStruct.startNS + IrqStruct.selectIrqStruct.dur;
1759      }
1760    } else if (TraceRow.rangeSelectObject) {
1761      if (TraceRow.rangeSelectObject.startNS && TraceRow.rangeSelectObject.endNS) {
1762        this.currentSlicesTime.startTime = TraceRow.rangeSelectObject.startNS;
1763        this.currentSlicesTime.endTime = TraceRow.rangeSelectObject.endNS;
1764      }
1765    } else if (JankStruct.selectJankStruct) {
1766      if (JankStruct.selectJankStruct.ts && JankStruct.selectJankStruct.dur) {
1767        this.currentSlicesTime.startTime = JankStruct.selectJankStruct.ts;
1768        this.currentSlicesTime.endTime = JankStruct.selectJankStruct.ts + JankStruct.selectJankStruct.dur;
1769      }
1770    } else {
1771      this.currentSlicesTime.startTime = 0;
1772      this.currentSlicesTime.endTime = 0;
1773    }
1774  }
1775
1776  setSLiceMark(shiftKey: boolean): SlicesTime | null | undefined {
1777    if (CpuStruct.selectCpuStruct) {
1778      this.slicestime = this.timerShaftEL?.setSlicesMark(
1779        CpuStruct.selectCpuStruct.startTime || 0,
1780        (CpuStruct.selectCpuStruct.startTime || 0) + (CpuStruct.selectCpuStruct.dur || 0),
1781        shiftKey
1782      );
1783    } else if (ThreadStruct.selectThreadStruct) {
1784      this.slicestime = this.timerShaftEL?.setSlicesMark(
1785        ThreadStruct.selectThreadStruct.startTime || 0,
1786        (ThreadStruct.selectThreadStruct.startTime || 0) + (ThreadStruct.selectThreadStruct.dur || 0),
1787        shiftKey
1788      );
1789    } else if (FuncStruct.selectFuncStruct) {
1790      this.slicestime = this.timerShaftEL?.setSlicesMark(
1791        FuncStruct.selectFuncStruct.startTs || 0,
1792        (FuncStruct.selectFuncStruct.startTs || 0) + (FuncStruct.selectFuncStruct.dur || 0),
1793        shiftKey
1794      );
1795    } else if (IrqStruct.selectIrqStruct) {
1796      this.slicestime = this.timerShaftEL?.setSlicesMark(
1797        IrqStruct.selectIrqStruct.startNS || 0,
1798        (IrqStruct.selectIrqStruct.startNS || 0) + (IrqStruct.selectIrqStruct.dur || 0),
1799        shiftKey
1800      );
1801    } else if (TraceRow.rangeSelectObject) {
1802      this.slicestime = this.timerShaftEL?.setSlicesMark(
1803        TraceRow.rangeSelectObject.startNS || 0,
1804        TraceRow.rangeSelectObject.endNS || 0,
1805        shiftKey
1806      );
1807    } else if (JankStruct.selectJankStruct) {
1808      this.slicestime = this.timerShaftEL?.setSlicesMark(
1809        JankStruct.selectJankStruct.ts || 0,
1810        (JankStruct.selectJankStruct.ts || 0) + (JankStruct.selectJankStruct.dur || 0),
1811        shiftKey
1812      );
1813    } else if (AppStartupStruct.selectStartupStruct) {
1814      this.slicestime = this.timerShaftEL?.setSlicesMark(
1815        AppStartupStruct.selectStartupStruct.startTs || 0,
1816        (AppStartupStruct.selectStartupStruct.startTs || 0) + (AppStartupStruct.selectStartupStruct.dur || 0),
1817        shiftKey
1818      );
1819    } else if (SoStruct.selectSoStruct) {
1820      this.slicestime = this.timerShaftEL?.setSlicesMark(
1821        SoStruct.selectSoStruct.startTs || 0,
1822        (SoStruct.selectSoStruct.startTs || 0) + (SoStruct.selectSoStruct.dur || 0),
1823        shiftKey
1824      );
1825    } else if (FrameAnimationStruct.selectFrameAnimationStruct) {
1826      this.timerShaftEL?.setSlicesMark(
1827        FrameAnimationStruct.selectFrameAnimationStruct.ts || 0,
1828        (FrameAnimationStruct.selectFrameAnimationStruct.ts || 0) +
1829          (FrameAnimationStruct.selectFrameAnimationStruct.dur || 0)
1830      );
1831    } else if (JsCpuProfilerStruct.selectJsCpuProfilerStruct) {
1832      this.timerShaftEL?.setSlicesMark(
1833        JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0,
1834        (JsCpuProfilerStruct.selectJsCpuProfilerStruct.startTime || 0) +
1835          (JsCpuProfilerStruct.selectJsCpuProfilerStruct.totalTime || 0)
1836      );
1837    } else {
1838      this.slicestime = this.timerShaftEL?.setSlicesMark();
1839    }
1840    return this.slicestime;
1841  }
1842
1843  stopWASD = () => {
1844    setTimeout(() => {
1845      for (let key of this.keyPressMap.keys()) {
1846        if (this.keyPressMap.get(key)) {
1847          this.timerShaftEL?.stopWASD({ key: key });
1848          this.keyPressMap.set(key, false);
1849        }
1850      }
1851    }, 100);
1852  };
1853
1854  documentOnKeyUp = (ev: KeyboardEvent) => {
1855    if (!this.loadTraceCompleted) return;
1856    let keyPress = ev.key.toLocaleLowerCase();
1857    if (keyPress === 'w' || keyPress === 'a' || keyPress === 's' || keyPress === 'd') {
1858      this.keyPressMap.set(keyPress, false);
1859    }
1860    TraceRow.isUserInteraction = false;
1861    this.observerScrollHeightEnable = false;
1862    this.keyboardEnable && this.timerShaftEL!.documentOnKeyUp(ev);
1863    if (ev.code == 'Enter') {
1864      if (ev.shiftKey) {
1865        this.dispatchEvent(
1866          new CustomEvent('previous-data', {
1867            detail: {},
1868            composed: false,
1869          })
1870        );
1871      } else {
1872        this.dispatchEvent(
1873          new CustomEvent('next-data', {
1874            detail: {},
1875            composed: false,
1876          })
1877        );
1878      }
1879    }
1880  };
1881
1882  isMouseInSheet = (ev: MouseEvent) => {
1883    this.isMousePointInSheet =
1884      this.traceSheetEL?.getAttribute('mode') != 'hidden' &&
1885      ev.offsetX > this.traceSheetEL!.offsetLeft &&
1886      ev.offsetY > this.traceSheetEL!.offsetTop;
1887    return this.isMousePointInSheet;
1888  };
1889
1890  favoriteChangeHandler = (row: TraceRow<any>) => {
1891    info('favoriteChangeHandler', row.frame, row.offsetTop, row.offsetHeight);
1892  };
1893
1894  verticalScrollHandler = (row: TraceRow<any>) => {
1895    row.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
1896  };
1897  selectChangeHandler = (rows: Array<TraceRow<any>>) => {
1898    this.isSelectClick = true;
1899    this.rangeSelect.rangeTraceRow = rows;
1900    let changeTraceRows: Array<TraceRow<any>> = [];
1901    if (this.rangeTraceRow!.length < rows.length) {
1902      rows!.forEach((currentTraceRow: TraceRow<any>) => {
1903        let changeFilter = this.rangeTraceRow!.filter(
1904          (prevTraceRow: TraceRow<any>) => prevTraceRow === currentTraceRow
1905        );
1906        if (changeFilter.length < 1) {
1907          changeTraceRows.push(currentTraceRow);
1908        }
1909      });
1910      if (changeTraceRows.length > 0) {
1911        changeTraceRows!.forEach((changeTraceRow: TraceRow<any>) => {
1912          let pointEvent = this.createPointEvent(changeTraceRow);
1913          SpStatisticsHttpUtil.addOrdinaryVisitAction({
1914            action: 'trace_row',
1915            event: pointEvent,
1916          });
1917        });
1918      }
1919    }
1920    this.rangeTraceRow = rows;
1921    this.rangeSelect.selectHandler?.(this.rangeSelect.rangeTraceRow, false);
1922  };
1923  inFavoriteArea: boolean | undefined;
1924  documentOnMouseMove = (ev: MouseEvent) => {
1925    if (!this.loadTraceCompleted || (window as any).flagInputFocus || !this.mouseEventEnable) return;
1926    if (this.isWASDKeyPress()) {
1927      this.hoverFlag = null;
1928      ev.preventDefault();
1929      return;
1930    }
1931    this.inFavoriteArea = this.favoriteRowsEL?.containPoint(ev);
1932    if ((window as any).isSheetMove) return;
1933    if (this.isMouseInSheet(ev)) {
1934      this.hoverStructNull();
1935      return;
1936    }
1937    let isMouseInTimeShaft = this.timerShaftEL?.containPoint(ev);
1938    if (isMouseInTimeShaft) {
1939      this.tipEL!.style.display = 'none';
1940      this.hoverStructNull();
1941    }
1942    let rows = this.visibleRows;
1943    if (this.timerShaftEL?.isScaling()) {
1944      return;
1945    }
1946    this.timerShaftEL?.documentOnMouseMove(ev);
1947    if (isMouseInTimeShaft) {
1948      return;
1949    }
1950    this.rangeSelect.mouseMove(rows, ev);
1951    if (this.rangeSelect.isMouseDown) {
1952      this.refreshCanvas(true);
1953    } else {
1954      if (!this.rowsPaneEL!.containPoint(ev, { left: 248 })) {
1955        this.tipEL!.style.display = 'none';
1956        this.hoverStructNull();
1957      }
1958      rows
1959        .filter((it) => it.focusContain(ev, this.inFavoriteArea!) && it.collect === this.inFavoriteArea)
1960        .filter((it) => {
1961          if (it.collect) {
1962            return true;
1963          } else {
1964            return (
1965              it.getBoundingClientRect().bottom + it.getBoundingClientRect().height >
1966              this.favoriteRowsEL!.getBoundingClientRect().bottom
1967            );
1968          }
1969        })
1970        .forEach((tr) => {
1971          if (this.currentRowType != tr.rowType) {
1972            this.hoverStructNull();
1973            this.tipEL!.style.display = 'none';
1974            this.currentRowType = tr.rowType || '';
1975          }
1976          if (tr.rowType == TraceRow.ROW_TYPE_CPU) {
1977            CpuStruct.hoverCpuStruct = undefined;
1978            for (let re of tr.dataListCache) {
1979              if (re.frame && isFrameContainPoint(re.frame, tr.hoverX, tr.hoverY)) {
1980                CpuStruct.hoverCpuStruct = re;
1981                break;
1982              }
1983            }
1984          } else {
1985            CpuStruct.hoverCpuStruct = undefined;
1986          }
1987          tr.focusHandler?.(ev);
1988        });
1989      requestAnimationFrame(() => this.refreshCanvas(true));
1990    }
1991  };
1992
1993  hoverStructNull() {
1994    CpuStruct.hoverCpuStruct = undefined;
1995    CpuFreqStruct.hoverCpuFreqStruct = undefined;
1996    ThreadStruct.hoverThreadStruct = undefined;
1997    FuncStruct.hoverFuncStruct = undefined;
1998    HiPerfCpuStruct.hoverStruct = undefined;
1999    HiPerfProcessStruct.hoverStruct = undefined;
2000    HiPerfThreadStruct.hoverStruct = undefined;
2001    HiPerfEventStruct.hoverStruct = undefined;
2002    HiPerfReportStruct.hoverStruct = undefined;
2003    CpuStateStruct.hoverStateStruct = undefined;
2004    CpuAbilityMonitorStruct.hoverCpuAbilityStruct = undefined;
2005    DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined;
2006    MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = undefined;
2007    NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = undefined;
2008    CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = undefined;
2009    FpsStruct.hoverFpsStruct = undefined;
2010    ClockStruct.hoverClockStruct = undefined;
2011    IrqStruct.hoverIrqStruct = undefined;
2012    HeapStruct.hoverHeapStruct = undefined;
2013    JankStruct.hoverJankStruct = undefined;
2014    AppStartupStruct.hoverStartupStruct = undefined;
2015    SoStruct.hoverSoStruct = undefined;
2016    HeapSnapshotStruct.hoverSnapshotStruct = undefined;
2017    FrameAnimationStruct.hoverFrameAnimationStruct = undefined;
2018    FrameDynamicStruct.hoverFrameDynamicStruct = undefined;
2019    FrameSpacingStruct.hoverFrameSpacingStruct = undefined;
2020    JsCpuProfilerStruct.hoverJsCpuProfilerStruct = undefined;
2021    SnapshotStruct.hoverSnapshotStruct = undefined;
2022  }
2023
2024  selectStructNull() {
2025    CpuStruct.selectCpuStruct = undefined;
2026    CpuStruct.wakeupBean = null;
2027    CpuFreqStruct.selectCpuFreqStruct = undefined;
2028    ThreadStruct.selectThreadStruct = undefined;
2029    FuncStruct.selectFuncStruct = undefined;
2030    SpHiPerf.selectCpuStruct = undefined;
2031    CpuStateStruct.selectStateStruct = undefined;
2032    CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = undefined;
2033    ClockStruct.selectClockStruct = undefined;
2034    IrqStruct.selectIrqStruct = undefined;
2035    JankStruct.selectJankStruct = undefined;
2036    HeapStruct.selectHeapStruct = undefined;
2037    AppStartupStruct.selectStartupStruct = undefined;
2038    SoStruct.selectSoStruct = undefined;
2039    HeapSnapshotStruct.selectSnapshotStruct = undefined;
2040    FrameSpacingStruct.selectFrameSpacingStruct = undefined;
2041    FrameAnimationStruct.selectFrameAnimationStruct = undefined;
2042    FrameDynamicStruct.selectFrameDynamicStruct = undefined;
2043    JsCpuProfilerStruct.selectJsCpuProfilerStruct = undefined;
2044    SnapshotStruct.selectSnapshotStruct = undefined;
2045  }
2046
2047  isWASDKeyPress() {
2048    return (
2049      this.keyPressMap.get('w') || this.keyPressMap.get('a') || this.keyPressMap.get('d') || this.keyPressMap.get('s')
2050    );
2051  }
2052
2053  documentOnClick = (ev: MouseEvent) => {
2054    if (!this.loadTraceCompleted) return;
2055    if (this.isWASDKeyPress()) {
2056      this.hoverFlag = null;
2057      ev.preventDefault();
2058      ev.stopPropagation();
2059      return;
2060    }
2061    if ((window as any).isSheetMove) return;
2062    if (this.isMouseInSheet(ev)) return;
2063    if ((window as any).isPackUpTable) {
2064      (window as any).isPackUpTable = false;
2065      return;
2066    }
2067    let x = ev.offsetX - this.timerShaftEL!.canvas!.offsetLeft;
2068    let y = ev.offsetY;
2069    if (this.timerShaftEL?.getRangeRuler()?.frame.contains(x, y)) {
2070      this.clickEmptyArea();
2071      return;
2072    }
2073    if (this.rangeSelect.isDrag()) {
2074      return;
2075    }
2076    if (
2077      this.timerShaftEL!.sportRuler!.frame.contains(x, y) &&
2078      x > (TraceRow.rangeSelectObject?.startX || 0) &&
2079      x < (TraceRow.rangeSelectObject?.endX || 0)
2080    ) {
2081    } else {
2082      let inFavoriteArea = this.favoriteRowsEL?.containPoint(ev);
2083      let rows = this.visibleRows.filter((it) => it.focusContain(ev, inFavoriteArea!) && it.collect == inFavoriteArea);
2084      if (JankStruct.delJankLineFlag) {
2085        this.removeLinkLinesByBusinessType('janks');
2086      }
2087      if (rows && rows[0] && this.traceRowClickJudgmentConditions.get(rows[0]!.rowType!)?.()) {
2088        this.onClickHandler(rows[0]!.rowType!, rows[0]);
2089        this.documentOnMouseMove(ev);
2090      } else {
2091        this.clickEmptyArea();
2092      }
2093    }
2094    ev.preventDefault();
2095  };
2096
2097  clickEmptyArea() {
2098    this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
2099      it.checkType = '-1';
2100      it.rangeSelect = false;
2101    });
2102    this.rangeSelect.rangeTraceRow = [];
2103    TraceRow.rangeSelectObject = undefined;
2104    this.selectStructNull();
2105    this.wakeupListNull();
2106    this.observerScrollHeightEnable = false;
2107    this.selectFlag = null;
2108    this.timerShaftEL?.removeTriangle('inverted');
2109    this.traceSheetEL?.setAttribute('mode', 'hidden');
2110    this.removeLinkLinesByBusinessType('task');
2111    this.refreshCanvas(true);
2112    JankStruct.delJankLineFlag = true;
2113  }
2114
2115  //泳道图点击判定条件
2116  private traceRowClickJudgmentConditions: Map<string, () => boolean> = new Map<string, () => boolean>([
2117    [TraceRow.ROW_TYPE_CPU, () => CpuStruct.hoverCpuStruct !== null && CpuStruct.hoverCpuStruct !== undefined],
2118    [
2119      TraceRow.ROW_TYPE_THREAD,
2120      () => ThreadStruct.hoverThreadStruct !== null && ThreadStruct.hoverThreadStruct !== undefined,
2121    ],
2122    [TraceRow.ROW_TYPE_FUNC, () => FuncStruct.hoverFuncStruct !== null && FuncStruct.hoverFuncStruct !== undefined],
2123    [
2124      TraceRow.ROW_TYPE_CPU_FREQ,
2125      () => CpuFreqStruct.hoverCpuFreqStruct !== null && CpuFreqStruct.hoverCpuFreqStruct !== undefined,
2126    ],
2127    [
2128      TraceRow.ROW_TYPE_CPU_STATE,
2129      () => CpuStateStruct.hoverStateStruct !== null && CpuStateStruct.hoverStateStruct !== undefined,
2130    ],
2131    [
2132      TraceRow.ROW_TYPE_CPU_FREQ_LIMIT,
2133      () =>
2134        CpuFreqLimitsStruct.selectCpuFreqLimitsStruct !== null &&
2135        CpuFreqLimitsStruct.selectCpuFreqLimitsStruct !== undefined,
2136    ],
2137    [
2138      TraceRow.ROW_TYPE_CLOCK,
2139      () => ClockStruct.hoverClockStruct !== null && ClockStruct.hoverClockStruct !== undefined,
2140    ],
2141    [TraceRow.ROW_TYPE_IRQ, () => IrqStruct.hoverIrqStruct !== null && IrqStruct.hoverIrqStruct !== undefined],
2142    [
2143      TraceRow.ROW_TYPE_APP_STARTUP,
2144      () => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined,
2145    ],
2146    [TraceRow.ROW_TYPE_STATIC_INIT, () => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined],
2147    [TraceRow.ROW_TYPE_JANK, () => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined],
2148    [TraceRow.ROW_TYPE_HEAP, () => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined],
2149    [
2150      TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL,
2151      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2152    ],
2153    [
2154      TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW,
2155      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2156    ],
2157    [
2158      TraceRow.ROW_TYPE_HEAP_SNAPSHOT,
2159      () => HeapSnapshotStruct.hoverSnapshotStruct !== null && HeapSnapshotStruct.hoverSnapshotStruct !== undefined,
2160    ],
2161    [
2162      TraceRow.ROW_TYPE_FRAME_ANIMATION,
2163      () =>
2164        FrameAnimationStruct.hoverFrameAnimationStruct !== null &&
2165        FrameAnimationStruct.hoverFrameAnimationStruct !== undefined,
2166    ],
2167    [
2168      TraceRow.ROW_TYPE_FRAME_DYNAMIC,
2169      () =>
2170        FrameDynamicStruct.hoverFrameDynamicStruct !== null && FrameDynamicStruct.hoverFrameDynamicStruct !== undefined,
2171    ],
2172    [
2173      TraceRow.ROW_TYPE_FRAME_SPACING,
2174      () =>
2175        FrameSpacingStruct.hoverFrameSpacingStruct !== null && FrameSpacingStruct.hoverFrameSpacingStruct !== undefined,
2176    ],
2177    [
2178      TraceRow.ROW_TYPE_JS_CPU_PROFILER,
2179      () =>
2180        JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== null &&
2181        JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== undefined,
2182    ],
2183    [
2184      TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY,
2185      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2186    ],
2187    [
2188      TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY,
2189      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2190    ],
2191    [
2192      TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM,
2193      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2194    ],
2195    [
2196      TraceRow.ROW_TYPE_PURGEABLE_PIN_VM,
2197      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2198    ],
2199    [
2200      TraceRow.ROW_TYPE_DMA_ABILITY,
2201      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2202    ],
2203    [
2204      TraceRow.ROW_TYPE_DMA_VMTRACKER,
2205      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2206    ],
2207    [
2208      TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY,
2209      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2210    ],
2211    [
2212      TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER,
2213      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2214    ],
2215    [
2216      TraceRow.ROW_TYPE_VMTRACKER_SHM,
2217      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2218    ],
2219    [
2220      TraceRow.ROW_TYPE_VM_TRACKER_SMAPS,
2221      () => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
2222    ],
2223  ]);
2224
2225  onClickHandler(clickRowType: string, row?: TraceRow<any>) {
2226    if (row) {
2227      this.currentRow = row;
2228      this.setAttribute('clickRow', clickRowType);
2229      this.setAttribute('rowName', row.name!);
2230      this.setAttribute('rowId', row.rowId!);
2231    }
2232    if (!this.loadTraceCompleted) return;
2233    this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => (it.rangeSelect = false));
2234    this.selectStructNull();
2235    this.wakeupListNull();
2236    let threadClickHandler: any;
2237    let threadClickPreviousHandler: any;
2238    let threadClickNextHandler: any;
2239    let cpuClickHandler: any;
2240    let jankClickHandler: any;
2241    let snapshotClickHandler: any;
2242    let scrollToFuncHandler: any;
2243    threadClickHandler = (d: ThreadStruct) => {
2244      this.observerScrollHeightEnable = false;
2245      this.scrollToProcess(`${d.cpu}`, '', 'cpu-data', true);
2246      let cpuRow = this.shadowRoot?.querySelectorAll<TraceRow<CpuStruct>>(
2247        `trace-row[row-id='${d.cpu}'][row-type='cpu-data']`
2248      )[0];
2249      let findEntry = cpuRow!.dataList!.find((dat: any) => dat.startTime === d.startTime);
2250      if (
2251        findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS ||
2252        findEntry!.startTime! > TraceRow.range!.endNS
2253      ) {
2254        this.timerShaftEL?.setRangeNS(
2255          findEntry!.startTime! - findEntry!.dur! * 2,
2256          findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2
2257        );
2258      }
2259      this.hoverStructNull();
2260      this.selectStructNull();
2261      this.wakeupListNull();
2262      CpuStruct.hoverCpuStruct = findEntry;
2263      CpuStruct.selectCpuStruct = findEntry;
2264      this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
2265      this.traceSheetEL?.displayCpuData(
2266        CpuStruct.selectCpuStruct!,
2267        (wakeUpBean) => {
2268          CpuStruct.wakeupBean = wakeUpBean;
2269          this.refreshCanvas(true);
2270        },
2271        cpuClickHandler
2272      );
2273    };
2274
2275    threadClickPreviousHandler = (d: ThreadStruct) => {
2276      this.observerScrollHeightEnable = false;
2277      let threadRow = this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(
2278        `trace-row[row-id='${d.tid}'][row-type='thread']`
2279      );
2280      threadRow?.dataList.forEach((item, index) => {
2281        if (item === d && index !== 0) {
2282          let findEntry = threadRow?.dataList[index - 1];
2283          this.hoverStructNull();
2284          this.selectStructNull();
2285          this.wakeupListNull();
2286          ThreadStruct.hoverThreadStruct = findEntry;
2287          ThreadStruct.selectThreadStruct = findEntry;
2288          this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
2289          this.traceSheetEL?.displayThreadData(
2290            ThreadStruct.selectThreadStruct!,
2291            threadClickHandler,
2292            cpuClickHandler,
2293            threadClickPreviousHandler,
2294            threadClickNextHandler
2295          );
2296        }
2297      });
2298    };
2299    threadClickNextHandler = (d: ThreadStruct) => {
2300      this.observerScrollHeightEnable = false;
2301      let threadRow = this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(
2302        `trace-row[row-id='${d.tid}'][row-type='thread']`
2303      );
2304      let findEntry = threadRow?.dataList.find((dat: any) => dat.startTime === d.startTime! + d.dur!);
2305      this.hoverStructNull();
2306      this.selectStructNull();
2307      this.wakeupListNull();
2308      ThreadStruct.hoverThreadStruct = findEntry;
2309      ThreadStruct.selectThreadStruct = findEntry;
2310      this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
2311      this.traceSheetEL?.displayThreadData(
2312        ThreadStruct.selectThreadStruct!,
2313        threadClickHandler,
2314        cpuClickHandler,
2315        threadClickPreviousHandler,
2316        threadClickNextHandler
2317      );
2318    };
2319    cpuClickHandler = (d: CpuStruct) => {
2320      let traceRow = this.shadowRoot?.querySelector<TraceRow<any>>(
2321        `trace-row[row-id='${d.processId}'][row-type='process']`
2322      );
2323      if (traceRow) {
2324        traceRow.expansion = true;
2325      }
2326      this.observerScrollHeightEnable = true;
2327      let threadRow = this.shadowRoot?.querySelectorAll<TraceRow<ThreadStruct>>(
2328        `trace-row[row-id='${d.tid}'][row-type='thread']`
2329      )[0];
2330      let task = () => {
2331        if (threadRow) {
2332          let findEntry = threadRow!.dataList!.find((dat) => dat.startTime === d.startTime);
2333          if (
2334            findEntry!.startTime! + findEntry!.dur! < TraceRow.range!.startNS ||
2335            findEntry!.startTime! > TraceRow.range!.endNS
2336          ) {
2337            this.timerShaftEL?.setRangeNS(
2338              findEntry!.startTime! - findEntry!.dur! * 2,
2339              findEntry!.startTime! + findEntry!.dur! + findEntry!.dur! * 2
2340            );
2341          }
2342          this.hoverStructNull();
2343          this.selectStructNull();
2344          this.wakeupListNull();
2345          ThreadStruct.hoverThreadStruct = findEntry;
2346          ThreadStruct.selectThreadStruct = findEntry;
2347          this.timerShaftEL?.drawTriangle(findEntry!.startTime || 0, 'inverted');
2348          this.traceSheetEL?.displayThreadData(
2349            ThreadStruct.selectThreadStruct!,
2350            threadClickHandler,
2351            cpuClickHandler,
2352            threadClickPreviousHandler,
2353            threadClickNextHandler
2354          );
2355          this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true);
2356        }
2357      };
2358      if (threadRow) {
2359        this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'process', false);
2360        this.scrollToProcess(`${d.tid}`, `${d.processId}`, 'thread', true);
2361        if (threadRow!.isComplete) {
2362          task();
2363        } else {
2364          threadRow!.onComplete = task;
2365        }
2366      }
2367    };
2368
2369    jankClickHandler = (d: any) => {
2370      this.observerScrollHeightEnable = true;
2371      let jankRowParent: any;
2372      if (d.rowId === 'actual frameTime') {
2373        jankRowParent = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(`trace-row[row-id='frameTime']`);
2374      } else {
2375        jankRowParent = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(`trace-row[row-id='${d.pid}']`);
2376      }
2377      // jankRowParent!.expansion = true;
2378      let jankRow: any;
2379      jankRowParent.childrenList.forEach((item: TraceRow<JankStruct>) => {
2380        if (item.rowId === `${d.rowId}` && item.rowType === 'janks') {
2381          jankRow = item;
2382        }
2383      });
2384      let task = () => {
2385        if (jankRow) {
2386          JankStruct.selectJankStructList.length = 0;
2387          let findJankEntry = jankRow!.dataList!.find((dat: any) => dat.name == d.name && dat.pid == d.pid);
2388          if (findJankEntry) {
2389            if (
2390              findJankEntry!.ts! + findJankEntry!.dur! < TraceRow.range!.startNS ||
2391              findJankEntry!.ts! > TraceRow.range!.endNS
2392            ) {
2393              this.timerShaftEL?.setRangeNS(
2394                findJankEntry!.ts! - findJankEntry!.dur! * 2,
2395                findJankEntry!.ts! + findJankEntry!.dur! + findJankEntry!.dur! * 2
2396              );
2397            }
2398            this.hoverStructNull();
2399            this.selectStructNull();
2400            this.wakeupListNull();
2401            JankStruct.hoverJankStruct = findJankEntry;
2402            JankStruct.selectJankStruct = findJankEntry;
2403            this.timerShaftEL?.drawTriangle(findJankEntry!.ts || 0, 'inverted');
2404            this.traceSheetEL?.displayJankData(
2405              JankStruct.selectJankStruct!,
2406              (datas) => {
2407                this.removeLinkLinesByBusinessType('janks');
2408                // 绘制跟自己关联的线
2409                datas.forEach((data) => {
2410                  let endParentRow = this.shadowRoot?.querySelector<TraceRow<any>>(
2411                    `trace-row[row-id='${data.pid}'][folder]`
2412                  );
2413                  this.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data);
2414                });
2415              },
2416              jankClickHandler
2417            );
2418          }
2419          this.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, true);
2420        }
2421      };
2422      if (jankRow) {
2423        this.scrollToProcess(jankRow.rowId!, jankRow.rowParentId!, jankRow.rowType!, false);
2424      }
2425      task();
2426    };
2427
2428    scrollToFuncHandler = (funcStract: any) => {
2429      this.observerScrollHeightEnable = true;
2430      this.moveRangeToCenter(funcStract.startTime!, funcStract.dur!);
2431      this.scrollToActFunc(funcStract, false);
2432    };
2433
2434    snapshotClickHandler = (d: HeapSnapshotStruct) => {
2435      this.observerScrollHeightEnable = true;
2436      let snapshotRow = this.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(
2437        `trace-row[row-id='heapsnapshot']`
2438      );
2439      let task = () => {
2440        if (snapshotRow) {
2441          let findEntry = snapshotRow!.dataList!.find((dat) => dat.startTs === d.startTs);
2442          this.hoverStructNull();
2443          this.selectStructNull();
2444          this.wakeupListNull();
2445          HeapSnapshotStruct.hoverSnapshotStruct = findEntry;
2446          HeapSnapshotStruct.selectSnapshotStruct = findEntry;
2447        }
2448      };
2449      if (snapshotRow) {
2450        if (snapshotRow!.isComplete) {
2451          task();
2452        } else {
2453          snapshotRow!.onComplete = task;
2454        }
2455      }
2456    };
2457    if (clickRowType === TraceRow.ROW_TYPE_CPU && CpuStruct.hoverCpuStruct) {
2458      CpuStruct.selectCpuStruct = CpuStruct.hoverCpuStruct;
2459      this.timerShaftEL?.drawTriangle(CpuStruct.selectCpuStruct!.startTime || 0, 'inverted');
2460      this.traceSheetEL?.displayCpuData(
2461        CpuStruct.selectCpuStruct,
2462        (wakeUpBean) => {
2463          CpuStruct.wakeupBean = wakeUpBean;
2464          this.refreshCanvas(false);
2465        },
2466        cpuClickHandler
2467      );
2468      this.timerShaftEL?.modifyFlagList(undefined);
2469    } else if (clickRowType === TraceRow.ROW_TYPE_THREAD && ThreadStruct.hoverThreadStruct) {
2470      ThreadStruct.selectThreadStruct = ThreadStruct.hoverThreadStruct;
2471      this.timerShaftEL?.drawTriangle(ThreadStruct.selectThreadStruct!.startTime || 0, 'inverted');
2472      this.traceSheetEL?.displayThreadData(
2473        ThreadStruct.selectThreadStruct,
2474        threadClickHandler,
2475        cpuClickHandler,
2476        threadClickPreviousHandler,
2477        threadClickNextHandler
2478      );
2479      this.timerShaftEL?.modifyFlagList(undefined);
2480    } else if (clickRowType === TraceRow.ROW_TYPE_FUNC && FuncStruct.hoverFuncStruct) {
2481      TabPaneTaskFrames.TaskArray = [];
2482      this.removeLinkLinesByBusinessType('task');
2483      FuncStruct.selectFuncStruct = FuncStruct.hoverFuncStruct;
2484      let hoverFuncStruct = FuncStruct.hoverFuncStruct;
2485      this.timerShaftEL?.drawTriangle(FuncStruct.selectFuncStruct!.startTs || 0, 'inverted');
2486      FuncStruct.selectFuncStruct = hoverFuncStruct;
2487      let flagConfig = FlagsConfig.getFlagsConfig('TaskPool');
2488      let showTabArray: Array<string> = ['current-selection'];
2489      if (flagConfig!.TaskPool === 'Enabled') {
2490        if (FuncStruct.selectFuncStruct !== undefined && FuncStruct.selectFuncStruct.funName !== undefined) {
2491          if (FuncStruct.selectFuncStruct.funName.indexOf('H:Task ') >= 0) {
2492            showTabArray.push('box-task-frames');
2493            this.drawTaskPollLine(row);
2494          }
2495        }
2496      }
2497      this.traceSheetEL?.displayFuncData(showTabArray, FuncStruct.selectFuncStruct, scrollToFuncHandler);
2498      this.timerShaftEL?.modifyFlagList(undefined);
2499    } else if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ && CpuFreqStruct.hoverCpuFreqStruct) {
2500      CpuFreqStruct.selectCpuFreqStruct = CpuFreqStruct.hoverCpuFreqStruct;
2501      this.traceSheetEL?.displayFreqData();
2502      this.timerShaftEL?.modifyFlagList(undefined);
2503    } else if (clickRowType === TraceRow.ROW_TYPE_CPU_STATE && CpuStateStruct.hoverStateStruct) {
2504      CpuStateStruct.selectStateStruct = CpuStateStruct.hoverStateStruct;
2505      this.traceSheetEL?.displayCpuStateData();
2506      this.timerShaftEL?.modifyFlagList(undefined);
2507    } else if (clickRowType === TraceRow.ROW_TYPE_CPU_FREQ_LIMIT && CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct) {
2508      CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct;
2509      this.traceSheetEL?.displayFreqLimitData();
2510      this.timerShaftEL?.modifyFlagList(undefined);
2511    } else if (clickRowType === TraceRow.ROW_TYPE_CLOCK && ClockStruct.hoverClockStruct) {
2512      ClockStruct.selectClockStruct = ClockStruct.hoverClockStruct;
2513      this.traceSheetEL?.displayClockData(ClockStruct.selectClockStruct);
2514      this.timerShaftEL?.modifyFlagList(undefined);
2515    } else if (clickRowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL && SnapshotStruct.hoverSnapshotStruct) {
2516      let gpuDumpTotalRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2517        `trace-row[row-id='Skia Gpu Dump Total']`
2518      );
2519      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2520      this.traceSheetEL?.displayGpuSelectedData(
2521        'total',
2522        SnapshotStruct.selectSnapshotStruct.startNs,
2523        gpuDumpTotalRow!.dataList
2524      );
2525      this.timerShaftEL?.modifyFlagList(undefined);
2526    } else if (clickRowType === TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW && SnapshotStruct.hoverSnapshotStruct) {
2527      let gpuDumpWindowRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2528        `trace-row[row-id='Skia Gpu Dump Window']`
2529      );
2530      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2531      this.traceSheetEL?.displayGpuSelectedData(
2532        'window',
2533        SnapshotStruct.selectSnapshotStruct.startNs,
2534        gpuDumpWindowRow!.dataList
2535      );
2536      this.timerShaftEL?.modifyFlagList(undefined);
2537    } else if (clickRowType === TraceRow.ROW_TYPE_IRQ && IrqStruct.hoverIrqStruct) {
2538      IrqStruct.selectIrqStruct = IrqStruct.hoverIrqStruct;
2539      this.traceSheetEL?.displayIrqData(IrqStruct.selectIrqStruct);
2540      this.timerShaftEL?.modifyFlagList(undefined);
2541    } else if (
2542      clickRowType === TraceRow.ROW_TYPE_HEAP &&
2543      row &&
2544      row.getAttribute('heap-type') === 'native_hook_statistic' &&
2545      HeapStruct.hoverHeapStruct
2546    ) {
2547      HeapStruct.selectHeapStruct = HeapStruct.hoverHeapStruct;
2548      this.traceSheetEL?.displayNativeHookData(HeapStruct.selectHeapStruct, row.rowId!);
2549      this.timerShaftEL?.modifyFlagList(undefined);
2550    } else if (clickRowType === TraceRow.ROW_TYPE_JANK && JankStruct.hoverJankStruct) {
2551      JankStruct.selectJankStructList.length = 0;
2552      this.removeLinkLinesByBusinessType('janks');
2553      JankStruct.selectJankStruct = JankStruct.hoverJankStruct;
2554      this.timerShaftEL?.drawTriangle(JankStruct.selectJankStruct!.ts || 0, 'inverted');
2555      this.traceSheetEL?.displayJankData(
2556        JankStruct.selectJankStruct,
2557        (datas) => {
2558          datas.forEach((data) => {
2559            let endParentRow;
2560            if (data.frame_type == 'frameTime') {
2561              endParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
2562                `trace-row[row-id='frameTime'][row-type='janks']`
2563              );
2564            } else {
2565              endParentRow = this.shadowRoot?.querySelector<TraceRow<any>>(`trace-row[row-id='${data.pid}'][folder]`);
2566            }
2567            this.drawJankLine(endParentRow, JankStruct.selectJankStruct!, data);
2568          });
2569        },
2570        jankClickHandler
2571      );
2572    } else if (clickRowType === TraceRow.ROW_TYPE_HEAP_SNAPSHOT && HeapSnapshotStruct.hoverSnapshotStruct) {
2573      let snapshotRow = this.shadowRoot?.querySelector<TraceRow<HeapSnapshotStruct>>(
2574        `trace-row[row-id='heapsnapshot']`
2575      );
2576      HeapSnapshotStruct.selectSnapshotStruct = HeapSnapshotStruct.hoverSnapshotStruct;
2577      this.traceSheetEL?.displaySnapshotData(
2578        HeapSnapshotStruct.selectSnapshotStruct!,
2579        snapshotRow!.dataList,
2580        snapshotClickHandler
2581      );
2582    } else if (clickRowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER && JsCpuProfilerStruct.hoverJsCpuProfilerStruct) {
2583      JsCpuProfilerStruct.selectJsCpuProfilerStruct = JsCpuProfilerStruct.hoverJsCpuProfilerStruct;
2584      let selectStruct = JsCpuProfilerStruct.selectJsCpuProfilerStruct;
2585      let dataArr: Array<JsCpuProfilerChartFrame> = [];
2586      let parentIdArr: Array<number> = [];
2587      let that = this;
2588      getTopJsCpuProfilerStruct(selectStruct.parentId);
2589      function getTopJsCpuProfilerStruct(parentId: number) {
2590        if (parentId === -1 && selectStruct.parentId === -1) {
2591          // 点击的函数是第一层,直接设置其children的isSelect为true,不用重新算totalTime
2592          let data = that.chartManager!.arkTsChart.chartFrameMap.get(selectStruct!.id);
2593          if (data && dataArr.length === 0) {
2594            let copyData = JSON.parse(JSON.stringify(data));
2595            setSelectChildrenState(copyData);
2596            dataArr.push(copyData);
2597          }
2598        } else {
2599          let parent = that.chartManager!.arkTsChart.chartFrameMap.get(parentId);
2600          if (parent) {
2601            parentIdArr.push(parent.id);
2602            getTopJsCpuProfilerStruct(parent.parentId!);
2603            if (parent.parentId === -1 && dataArr.length === 0) {
2604              let data = that.chartManager!.arkTsChart.chartFrameMap.get(parent.id);
2605              let copyParent = JSON.parse(JSON.stringify(data));
2606              copyParent.totalTime = selectStruct.totalTime;
2607              copyParent.selfTime = 0;
2608              // depth为0的isSelect改为true
2609              copyParent.isSelect = true;
2610              if (copyParent.children.length > 0) {
2611                getSelectStruct(copyParent);
2612              }
2613              dataArr.push(copyParent);
2614            }
2615          }
2616        }
2617      }
2618
2619      function getSelectStruct(data: JsCpuProfilerChartFrame) {
2620        for (let child of data.children) {
2621          if (child.id === selectStruct!.id) {
2622            // 将点击的函数的children的isSelect改为true
2623            setSelectChildrenState(child);
2624          } else {
2625            getSelectStruct(child);
2626          }
2627          if (parentIdArr.includes(child.id)) {
2628            child.isSelect = true;
2629            child.totalTime = selectStruct.totalTime;
2630            child.selfTime = 0;
2631          }
2632        }
2633      }
2634
2635      function setSelectChildrenState(data: JsCpuProfilerChartFrame) {
2636        data.isSelect = true;
2637        if (data.children.length > 0) {
2638          for (let child of data.children) {
2639            setSelectChildrenState(child);
2640          }
2641        }
2642      }
2643      that.traceSheetEL?.displayJsProfilerData(dataArr);
2644    } else if (clickRowType === TraceRow.ROW_TYPE_APP_STARTUP && AppStartupStruct.hoverStartupStruct) {
2645      AppStartupStruct.selectStartupStruct = AppStartupStruct.hoverStartupStruct;
2646      this.traceSheetEL?.displayStartupData(AppStartupStruct.selectStartupStruct, scrollToFuncHandler);
2647      this.timerShaftEL?.modifyFlagList(undefined);
2648    } else if (clickRowType === TraceRow.ROW_TYPE_STATIC_INIT && SoStruct.hoverSoStruct) {
2649      SoStruct.selectSoStruct = SoStruct.hoverSoStruct;
2650      this.traceSheetEL?.displayStaticInitData(SoStruct.selectSoStruct, scrollToFuncHandler);
2651      this.timerShaftEL?.modifyFlagList(undefined);
2652    } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_ANIMATION && FrameAnimationStruct.hoverFrameAnimationStruct) {
2653      FrameAnimationStruct.selectFrameAnimationStruct = FrameAnimationStruct.hoverFrameAnimationStruct;
2654      this.traceSheetEL?.displayFrameAnimationData(FrameAnimationStruct.selectFrameAnimationStruct);
2655      this.timerShaftEL?.modifyFlagList(undefined);
2656    } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_DYNAMIC && FrameDynamicStruct.hoverFrameDynamicStruct) {
2657      FrameDynamicStruct.selectFrameDynamicStruct = FrameDynamicStruct.hoverFrameDynamicStruct;
2658      this.traceSheetEL?.displayFrameDynamicData(row!, FrameDynamicStruct.selectFrameDynamicStruct);
2659      this.timerShaftEL?.modifyFlagList(undefined);
2660    } else if (clickRowType === TraceRow.ROW_TYPE_FRAME_SPACING && FrameSpacingStruct.hoverFrameSpacingStruct) {
2661      FrameSpacingStruct.selectFrameSpacingStruct = FrameSpacingStruct.hoverFrameSpacingStruct;
2662      this.traceSheetEL?.displayFrameSpacingData(FrameSpacingStruct.selectFrameSpacingStruct);
2663      this.timerShaftEL?.modifyFlagList(undefined);
2664    } else if (clickRowType === TraceRow.ROW_TYPE_VM_TRACKER_SMAPS && SnapshotStruct.hoverSnapshotStruct) {
2665      let smapsRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Dirty']`);
2666      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2667      this.traceSheetEL?.displaySmapsData(SnapshotStruct.selectSnapshotStruct!, smapsRow!.dataList);
2668    } else if (clickRowType === TraceRow.ROW_TYPE_VMTRACKER_SHM && SnapshotStruct.hoverSnapshotStruct) {
2669      let shmRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='SHM']`);
2670      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2671      this.traceSheetEL?.displayShmData(SnapshotStruct.selectSnapshotStruct!, shmRow!.dataList);
2672    } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY && SnapshotStruct.hoverSnapshotStruct) {
2673      let totalAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2674        `trace-row[row-id='System Purgeable Total']`
2675      );
2676      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2677      this.traceSheetEL?.displayPurgTotalAbilityData(SnapshotStruct.hoverSnapshotStruct, totalAbilityRow!.dataList);
2678    } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY && SnapshotStruct.hoverSnapshotStruct) {
2679      let pinAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2680        `trace-row[row-id='System Purgeable Pin']`
2681      );
2682      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2683      this.traceSheetEL?.displayPurgPinAbilityData(SnapshotStruct.hoverSnapshotStruct, pinAbilityRow!.dataList);
2684    } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM && SnapshotStruct.hoverSnapshotStruct) {
2685      let totalVMRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Purgeable Total']`);
2686      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2687      this.traceSheetEL?.displayPurgTotalVMData(SnapshotStruct.hoverSnapshotStruct, totalVMRow!.dataList);
2688    } else if (clickRowType === TraceRow.ROW_TYPE_PURGEABLE_PIN_VM && SnapshotStruct.hoverSnapshotStruct) {
2689      let pinVMRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(`trace-row[row-id='Purgeable Pin']`);
2690      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2691      this.traceSheetEL?.displayPurgPinVMData(SnapshotStruct.hoverSnapshotStruct, pinVMRow!.dataList);
2692    } else if (clickRowType === TraceRow.ROW_TYPE_DMA_ABILITY && SnapshotStruct.hoverSnapshotStruct) {
2693      let dmaAbilityRow = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2694        `trace-row[row-id='abilityMonitorDma']`
2695      );
2696      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2697      this.traceSheetEL?.displayDmaAbility(SnapshotStruct.selectSnapshotStruct.startNs, dmaAbilityRow!.dataList);
2698    } else if (clickRowType === TraceRow.ROW_TYPE_DMA_VMTRACKER && SnapshotStruct.hoverSnapshotStruct) {
2699      let dmaVmTracker = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2700        `trace-row[row-type='dma-vmTracker']`
2701      );
2702      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2703      this.traceSheetEL?.displayDmaVmTracker(SnapshotStruct.selectSnapshotStruct.startNs, dmaVmTracker!.dataList);
2704    } else if (clickRowType === TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY && SnapshotStruct.hoverSnapshotStruct) {
2705      let gpuMemoryAbilityMonitor = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2706        `trace-row[row-id='abilityMonitorGpuMemory']`
2707      );
2708      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2709      this.traceSheetEL?.displayGpuMemoryAbility(
2710        SnapshotStruct.selectSnapshotStruct.startNs,
2711        gpuMemoryAbilityMonitor!.dataList
2712      );
2713    } else if (clickRowType === TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER && SnapshotStruct.hoverSnapshotStruct) {
2714      let gpuMemoryVmTracker = this.shadowRoot?.querySelector<TraceRow<SnapshotStruct>>(
2715        `trace-row[row-id='Skia Gpu Memory']`
2716      );
2717      SnapshotStruct.selectSnapshotStruct = SnapshotStruct.hoverSnapshotStruct;
2718      this.traceSheetEL?.displayGpuMemoryVmTracker(
2719        SnapshotStruct.selectSnapshotStruct.startNs,
2720        gpuMemoryVmTracker!.dataList
2721      );
2722    } else {
2723      if (!JankStruct.hoverJankStruct && JankStruct.delJankLineFlag) {
2724        this.removeLinkLinesByBusinessType('janks');
2725      }
2726      this.observerScrollHeightEnable = false;
2727      this.selectFlag = null;
2728      this.timerShaftEL?.removeTriangle('inverted');
2729      if (!SportRuler.isMouseInSportRuler) {
2730        this.traceSheetEL?.setAttribute('mode', 'hidden');
2731        this.refreshCanvas(true);
2732      }
2733    }
2734    if (!JankStruct.selectJankStruct) {
2735      this.removeLinkLinesByBusinessType('janks');
2736    }
2737    if (row) {
2738      let pointEvent = this.createPointEvent(row);
2739      SpStatisticsHttpUtil.addOrdinaryVisitAction({
2740        action: 'trace_row',
2741        event: pointEvent,
2742      });
2743    }
2744  }
2745
2746  makePoint(
2747    ts: number,
2748    dur: number,
2749    translateY: number,
2750    rowStruct: any,
2751    offsetY: number,
2752    business: string,
2753    lineType: LineType,
2754    isRight: boolean
2755  ): PairPoint {
2756    return {
2757      x: ns2xByTimeShaft(ts + dur, this.timerShaftEL!),
2758      y: translateY!,
2759      offsetY: offsetY,
2760      ns: ts + dur,
2761      rowEL: rowStruct!,
2762      isRight: isRight,
2763      business: business,
2764      lineType: lineType,
2765    };
2766  }
2767
2768  drawTaskPollLine(row?: TraceRow<any>) {
2769    let executeID = TabPaneTaskFrames.getExecuteId(FuncStruct.selectFuncStruct!.funName!);
2770    TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!);
2771    if (!row) {
2772      return;
2773    }
2774    if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Perform:') >= 0) {
2775      TabPaneTaskFrames.IsShowConcurrency = true;
2776      queryBySelectExecute(executeID, FuncStruct.selectFuncStruct!.itid!).then((res) => {
2777        if (res.length === 1) {
2778          let allocationRowId = res[0].tid;
2779          let selectRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
2780            `trace-row[row-id='${allocationRowId}'][row-type=\'func\']`
2781          );
2782          selectRow!.dataList.forEach((value) => {
2783            // allocation to execute
2784            if (value.id === res[0].allocation_task_row) {
2785              TabPaneTaskFrames.TaskArray.push(value);
2786              this.addPointPair(
2787                this.makePoint(
2788                  value.startTs!,
2789                  0,
2790                  selectRow?.translateY!,
2791                  selectRow,
2792                  (value.depth! + 0.5) * 20,
2793                  'task',
2794                  LineType.bezierCurve,
2795                  true
2796                ),
2797                this.makePoint(
2798                  FuncStruct.selectFuncStruct!.startTs!,
2799                  0,
2800                  row?.translateY!,
2801                  row,
2802                  (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20,
2803                  'task',
2804                  LineType.bezierCurve,
2805                  true
2806                )
2807              );
2808            }
2809            // execute to return
2810            if (value.id === res[0].return_task_row) {
2811              TabPaneTaskFrames.TaskArray.push(value);
2812              this.addPointPair(
2813                this.makePoint(
2814                  FuncStruct.selectFuncStruct!.startTs!,
2815                  FuncStruct.selectFuncStruct!.dur!,
2816                  row?.translateY!,
2817                  row,
2818                  (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20,
2819                  'task',
2820                  LineType.bezierCurve,
2821                  false
2822                ),
2823                this.makePoint(
2824                  value.startTs!,
2825                  value.dur!,
2826                  selectRow?.translateY!,
2827                  selectRow,
2828                  (value.depth! + 0.5) * 20,
2829                  'task',
2830                  LineType.bezierCurve,
2831                  false
2832                )
2833              );
2834            }
2835          });
2836          this.refreshCanvas(true);
2837        }
2838      });
2839    } else {
2840      TabPaneTaskFrames.IsShowConcurrency = false;
2841      queryBySelectAllocationOrReturn(executeID, FuncStruct.selectFuncStruct!.itid!).then((res) => {
2842        if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task Allocation:') >= 0 && res.length > 0) {
2843          let executeRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
2844            `trace-row[row-id='${res[0].tid}'][row-type='func']`
2845          );
2846          let endStruct: FuncStruct;
2847          row!.dataList.forEach((value) => {
2848            if (value.id === res[0].return_task_row) {
2849              TabPaneTaskFrames.TaskArray.push(value);
2850              endStruct = value;
2851            }
2852          });
2853          if (!executeRow) {
2854            return;
2855          }
2856          executeRow!.dataList.forEach((value) => {
2857            if (value.id === res[0].execute_task_row) {
2858              TabPaneTaskFrames.TaskArray.push(value);
2859              this.addPointPair(
2860                this.makePoint(
2861                  FuncStruct.selectFuncStruct!.startTs!,
2862                  0,
2863                  row?.translateY!,
2864                  row,
2865                  (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20,
2866                  'task',
2867                  LineType.bezierCurve,
2868                  true
2869                ),
2870                this.makePoint(
2871                  value.startTs!,
2872                  0,
2873                  executeRow?.translateY!,
2874                  executeRow,
2875                  (value.depth! + 0.5) * 20,
2876                  'task',
2877                  LineType.bezierCurve,
2878                  true
2879                )
2880              );
2881              if (endStruct) {
2882                this.addPointPair(
2883                  this.makePoint(
2884                    value.startTs!,
2885                    value.dur!,
2886                    executeRow?.translateY!,
2887                    executeRow,
2888                    (value.depth! + 0.5) * 20,
2889                    'task',
2890                    LineType.bezierCurve,
2891                    false
2892                  ),
2893                  this.makePoint(
2894                    endStruct.startTs!,
2895                    endStruct.dur!,
2896                    row?.translateY!,
2897                    row,
2898                    (endStruct.depth! + 0.5) * 20,
2899                    'task',
2900                    LineType.bezierCurve,
2901                    false
2902                  )
2903                );
2904              }
2905            }
2906          });
2907        } else if (FuncStruct.selectFuncStruct!.funName!.indexOf('H:Task PerformTask End:') >= 0) {
2908          let executeRow = this.shadowRoot?.querySelector<TraceRow<FuncStruct>>(
2909            `trace-row[row-id='${res[0].tid}'][row-type='func']`
2910          );
2911          TabPaneTaskFrames.TaskArray.push(FuncStruct.selectFuncStruct!);
2912          let startStruct: FuncStruct;
2913          row!.dataList.forEach((value) => {
2914            if (value.id === res[0].allocation_task_row) {
2915              TabPaneTaskFrames.TaskArray.push(value);
2916              startStruct = value;
2917            }
2918          });
2919          executeRow!.dataList.forEach((value) => {
2920            if (value.id === res[0].execute_task_row) {
2921              TabPaneTaskFrames.TaskArray.push(value);
2922              this.addPointPair(
2923                this.makePoint(
2924                  startStruct!.startTs!,
2925                  0,
2926                  row?.translateY!,
2927                  row,
2928                  (startStruct!.depth! + 0.5) * 20,
2929                  'task',
2930                  LineType.bezierCurve,
2931                  true
2932                ),
2933                this.makePoint(
2934                  value.startTs!,
2935                  0,
2936                  executeRow?.translateY!,
2937                  executeRow,
2938                  (value.depth! + 0.5) * 20,
2939                  'task',
2940                  LineType.bezierCurve,
2941                  true
2942                )
2943              );
2944              this.addPointPair(
2945                this.makePoint(
2946                  value.startTs!,
2947                  value.dur!,
2948                  executeRow?.translateY!,
2949                  executeRow,
2950                  (value.depth! + 0.5) * 20,
2951                  'task',
2952                  LineType.bezierCurve,
2953                  false
2954                ),
2955                this.makePoint(
2956                  FuncStruct.selectFuncStruct!.startTs!,
2957                  FuncStruct.selectFuncStruct!.dur!,
2958                  row?.translateY!,
2959                  row,
2960                  (FuncStruct.selectFuncStruct!.depth! + 0.5) * 20,
2961                  'task',
2962                  LineType.bezierCurve,
2963                  false
2964                )
2965              );
2966            }
2967          });
2968        }
2969        this.refreshCanvas(true);
2970      });
2971    }
2972  }
2973  drawJankLine(endParentRow: any, selectJankStruct: JankStruct, data: any) {
2974    let collectList = this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[collect-type]`) || [];
2975    let startRow: any;
2976    if (selectJankStruct == undefined || selectJankStruct == null) {
2977      return;
2978    }
2979    if (selectJankStruct.frame_type == 'frameTime') {
2980      startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
2981        "trace-row[row-id='actual frameTime'][row-type='janks']"
2982      );
2983    } else {
2984      startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
2985        `trace-row[row-id='${`${selectJankStruct?.type}-${selectJankStruct?.pid}`}'][row-type='janks']`
2986      );
2987    }
2988
2989    function collectionHasJank(jankRow: any): boolean {
2990      for (let item of collectList!) {
2991        if (item.rowId === jankRow.rowId && item.rowType === jankRow.rowType) {
2992          return false;
2993        }
2994      }
2995      return true;
2996    }
2997
2998    if (endParentRow) {
2999      //终点的父泳道过滤出选中的Struct
3000      let endRowStruct: any;
3001      //泳道展开的情况,查找endRowStruct
3002      if (data.frame_type == 'frameTime') {
3003        endRowStruct = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3004          "trace-row[row-id='actual frameTime'][row-type='janks']"
3005        );
3006      } else {
3007        endRowStruct = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3008          `trace-row[row-id='${`${data.type}-${data.pid}`}'][row-type='janks']`
3009        );
3010      }
3011      //泳道未展开的情况,查找endRowStruct
3012      if (!endRowStruct) {
3013        if (data.frame_type == 'frameTime') {
3014          endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => {
3015            if (item.rowId === 'actual frameTime' && item.rowType === 'janks') {
3016              endRowStruct = item;
3017            }
3018          });
3019          //frameTime未展开
3020          if (!endRowStruct) {
3021            endParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3022              "trace-row[row-id='frameTime'][folder]"
3023            );
3024            endParentRow?.childrenList?.forEach((item: TraceRow<JankStruct>) => {
3025              if (item.rowId === 'actual frameTime' && item.rowType === 'janks') {
3026                endRowStruct = item;
3027              }
3028            });
3029          }
3030        } else {
3031          endParentRow.childrenList.forEach((item: TraceRow<JankStruct>) => {
3032            if (item.rowId === `${data.type}-${data.pid}` && item.rowType === 'janks') {
3033              endRowStruct = item;
3034            }
3035          });
3036        }
3037      }
3038      if (endRowStruct) {
3039        let findJankEntry = endRowStruct!.dataList!.find((dat: any) => dat.name == data.name && dat.pid == data.pid);
3040        //连线规则:frametimeline的头----app的头,app的尾----renderservice的头
3041        let tts: number = 0;
3042        if (findJankEntry) {
3043          if (selectJankStruct.frame_type == 'app') {
3044            tts =
3045              findJankEntry.frame_type == 'frameTime'
3046                ? selectJankStruct.ts!
3047                : selectJankStruct.ts! + selectJankStruct.dur!;
3048            let startParentRow: any;
3049            // startRow为子泳道,子泳道不存在,使用父泳道
3050            if (startRow) {
3051              startParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3052                `trace-row[row-id='${startRow.rowParentId}'][folder]`
3053              );
3054            } else {
3055              startRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3056                `trace-row[row-id='${selectJankStruct?.pid}'][folder]`
3057              );
3058            }
3059            let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5);
3060            let endRowEl = endRowStruct;
3061            let endOffSetY = 20 * (findJankEntry!.depth! + 0.5);
3062            let expansionFlag = collectionHasJank(endRowStruct);
3063            if (!endParentRow.expansion && expansionFlag) {
3064              endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5);
3065              endRowEl = endParentRow;
3066              endOffSetY = 10 * (findJankEntry!.depth! + 0.5);
3067            }
3068            let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5);
3069            let startRowEl = startRow;
3070            let startOffSetY = 20 * (selectJankStruct!.depth! + 0.5);
3071            expansionFlag = collectionHasJank(startRow);
3072            if (startParentRow && !startParentRow.expansion && expansionFlag) {
3073              startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5);
3074              startRowEl = startParentRow;
3075              startOffSetY = 10 * (selectJankStruct!.depth! + 0.5);
3076            }
3077            this.addPointPair(
3078              {
3079                x: ns2xByTimeShaft(tts, this.timerShaftEL!),
3080                y: startY,
3081                offsetY: startOffSetY,
3082                ns: tts,
3083                rowEL: startRowEl!,
3084                isRight: selectJankStruct.ts == tts,
3085                business: 'janks',
3086              },
3087              {
3088                x: ns2xByTimeShaft(findJankEntry.ts!, this.timerShaftEL!),
3089                y: endY,
3090                offsetY: endOffSetY,
3091                ns: findJankEntry.ts!,
3092                rowEL: endRowEl,
3093                isRight: true,
3094                business: 'janks',
3095              }
3096            );
3097          }
3098          if (findJankEntry.frame_type == 'app') {
3099            tts =
3100              selectJankStruct.frame_type == 'frameTime' ? findJankEntry.ts : findJankEntry.ts! + findJankEntry.dur!;
3101            let endY = endRowStruct!.translateY! + 20 * (findJankEntry!.depth! + 0.5);
3102            let endRowEl = endRowStruct;
3103            let endOffSetY = 20 * (findJankEntry!.depth! + 0.5);
3104            let expansionFlag = collectionHasJank(endRowStruct);
3105            if (!endParentRow.expansion && expansionFlag) {
3106              endY = endParentRow!.translateY! + 10 * (findJankEntry!.depth! + 0.5);
3107              endRowEl = endParentRow;
3108              endOffSetY = 10 * (findJankEntry!.depth! + 0.5);
3109            }
3110            let startY = startRow!.translateY! + 20 * (selectJankStruct!.depth! + 0.5);
3111            let startRowEl = startRow;
3112            expansionFlag = collectionHasJank(startRow);
3113            let startOffsetY = 20 * (selectJankStruct!.depth! + 0.5);
3114            let startParentRow = this.shadowRoot?.querySelector<TraceRow<JankStruct>>(
3115              `trace-row[row-id='${startRow.rowParentId}'][folder]`
3116            );
3117            if (startParentRow && !startParentRow.expansion && expansionFlag) {
3118              startY = startParentRow!.translateY! + 10 * (selectJankStruct!.depth! + 0.5);
3119              startRowEl = startParentRow;
3120              startOffsetY = 10 * (selectJankStruct!.depth! + 0.5);
3121            }
3122            this.addPointPair(
3123              {
3124                x: ns2xByTimeShaft(selectJankStruct.ts!, this.timerShaftEL!),
3125                y: startY,
3126                offsetY: startOffsetY,
3127                ns: selectJankStruct.ts!,
3128                rowEL: startRowEl!,
3129                isRight: true,
3130                business: 'janks',
3131              },
3132              {
3133                x: ns2xByTimeShaft(tts, this.timerShaftEL!),
3134                y: endY,
3135                offsetY: endOffSetY,
3136                ns: tts,
3137                rowEL: endRowEl!,
3138                isRight: selectJankStruct.ts == tts,
3139                business: 'janks',
3140              }
3141            );
3142          }
3143          if (data.children.length >= 1) {
3144            let endP;
3145            if (data.children[0].frame_type == 'frameTime') {
3146              endP = this.shadowRoot?.querySelector<TraceRow<any>>("trace-row[row-id='frameTime']");
3147            } else {
3148              endP = this.shadowRoot?.querySelector<TraceRow<any>>(
3149                `trace-row[row-id='${data.children[0].pid}'][folder]`
3150              );
3151            }
3152            this.drawJankLine(endP, findJankEntry, data.children[0]);
3153          }
3154          this.refreshCanvas(true);
3155        }
3156      }
3157    }
3158  }
3159
3160  myMouseMove = (ev: MouseEvent) => {
3161    if (ev.ctrlKey) {
3162      ev.preventDefault();
3163      SpSystemTrace.offsetMouse = ev.clientX - SpSystemTrace.mouseCurrentPosition;
3164      let eventA = new KeyboardEvent('keypress', {
3165        key: 'a',
3166        code: '65',
3167        keyCode: 65,
3168      });
3169      let eventD = new KeyboardEvent('keypress', {
3170        key: 'd',
3171        code: '68',
3172        keyCode: 68,
3173      });
3174      if (ev.button == 0) {
3175        if (SpSystemTrace.offsetMouse < 0 && SpSystemTrace.moveable) {
3176          // 向右拖动,则泳道图右移
3177          this.timerShaftEL!.documentOnKeyPress(eventD);
3178          setTimeout(() => {
3179            this.timerShaftEL!.documentOnKeyUp(eventD);
3180          }, 350);
3181        }
3182        if (SpSystemTrace.offsetMouse > 0 && SpSystemTrace.moveable) {
3183          // 向左拖动,则泳道图左移
3184          this.timerShaftEL!.documentOnKeyPress(eventA);
3185          setTimeout(() => {
3186            this.timerShaftEL!.documentOnKeyUp(eventA);
3187          }, 350);
3188        }
3189      }
3190      SpSystemTrace.moveable = false;
3191    }
3192  };
3193
3194  connectedCallback() {
3195    this.initPointToEvent();
3196    /**
3197     * 监听时间轴区间变化
3198     */
3199    this.timerShaftEL!.rangeChangeHandler = this.timerShaftELRangeChange;
3200    this.timerShaftEL!.rangeClickHandler = this.timerShaftELRangeClick;
3201    this.timerShaftEL!.flagChangeHandler = this.timerShaftELFlagChange;
3202    this.timerShaftEL!.flagClickHandler = this.timerShaftELFlagClickHandler;
3203    /**
3204     * 监听rowsEL的滚动时间,刷新可见区域的trace-row组件的时间区间(将触发trace-row组件重绘)
3205     */
3206    this.rowsPaneEL?.addEventListener('scroll', this.rowsElOnScroll, {
3207      passive: true,
3208    });
3209    this.favoriteRowsEL?.addEventListener('scroll', this.favoriteRowsElOnScroll, { passive: true });
3210    /**
3211     * 监听document的mousemove事件 坐标通过换算后找到当前鼠标所在的trace-row组件,将坐标传入
3212     */
3213    this.addEventListener('mousemove', this.documentOnMouseMove);
3214    this.addEventListener('click', this.documentOnClick);
3215    this.addEventListener('mousedown', this.documentOnMouseDown);
3216    this.addEventListener('mouseup', this.documentOnMouseUp);
3217    this.addEventListener('mouseout', this.documentOnMouseOut);
3218
3219    document.addEventListener('keypress', this.documentOnKeyPress);
3220    document.addEventListener('keyup', this.documentOnKeyUp);
3221    document.addEventListener('contextmenu', this.onContextMenuHandler);
3222
3223    /**
3224     * 获取并保存鼠标当前的x轴坐标位置,配合ctrl+鼠标左键拖动完成泳道图的左移或右移
3225     */
3226    this.addEventListener(
3227      'mousedown',
3228      (e) => {
3229        if (e.ctrlKey) {
3230          e.preventDefault();
3231          this.removeEventListener('mousemove', this.documentOnMouseMove);
3232          this.removeEventListener('click', this.documentOnClick);
3233          this.removeEventListener('mousedown', this.documentOnMouseDown);
3234          this.removeEventListener('mouseup', this.documentOnMouseUp);
3235          this.style.cursor = 'move';
3236          SpSystemTrace.moveable = true;
3237          SpSystemTrace.mouseCurrentPosition = e.clientX;
3238        }
3239      },
3240      { passive: false }
3241    );
3242    /**
3243     * ctrl+鼠标移动,实现泳道图左移或者右移。
3244     */
3245    this.addEventListener('mousemove', (ev) => throttle(this.myMouseMove, 350, ev)(), { passive: false });
3246
3247    this.addEventListener(
3248      'mouseup',
3249      (e) => {
3250        if (e.ctrlKey) {
3251          e.preventDefault();
3252          SpSystemTrace.offsetMouse = 0;
3253          SpSystemTrace.mouseCurrentPosition = 0;
3254          SpSystemTrace.moveable = false;
3255          this.style.cursor = 'default';
3256          this.addEventListener('mousemove', this.documentOnMouseMove);
3257          this.addEventListener('click', this.documentOnClick);
3258          this.addEventListener('mousedown', this.documentOnMouseDown);
3259          this.addEventListener('mouseup', this.documentOnMouseUp);
3260        }
3261      },
3262      { passive: false }
3263    );
3264
3265    /**
3266     * 泳道图中添加ctrl+鼠标滚轮事件,对泳道图进行放大缩小。
3267     * 鼠标滚轮事件转化为键盘事件,keyPress和keyUp两个事件需要配合使用,
3268     * 否则泳道图会一直放大或一直缩小。
3269     * setTimeout()函数中的时间参数可以控制鼠标滚轮的频率。
3270     */
3271    document.addEventListener(
3272      'wheel',
3273      (e) => {
3274        if (e.ctrlKey) {
3275          if (e.deltaY > 0) {
3276            e.preventDefault();
3277            e.stopPropagation();
3278            let eventS = new KeyboardEvent('keypress', {
3279              key: 's',
3280              code: '83',
3281              keyCode: 83,
3282            });
3283            this.timerShaftEL!.documentOnKeyPress(eventS);
3284            setTimeout(() => {
3285              this.timerShaftEL!.documentOnKeyUp(eventS);
3286            }, 200);
3287          }
3288          if (e.deltaY < 0) {
3289            e.preventDefault();
3290            e.stopPropagation();
3291            let eventW = new KeyboardEvent('keypress', {
3292              key: 'w',
3293              code: '87',
3294              keyCode: 87,
3295            });
3296            this.timerShaftEL!.documentOnKeyPress(eventW);
3297            setTimeout(() => {
3298              this.timerShaftEL!.documentOnKeyUp(eventW);
3299            }, 200);
3300          }
3301        }
3302      },
3303      { passive: false }
3304    );
3305
3306    SpApplication.skinChange2 = (val: boolean) => {
3307      this.timerShaftEL?.render();
3308    };
3309    window.subscribe(window.SmartEvent.UI.UploadSOFile, (data) => {
3310      this.chartManager?.importSoFileUpdate().then(() => {
3311        window.publish(window.SmartEvent.UI.Loading, false);
3312        let updateCanvas = this.traceSheetEL?.updateRangeSelect();
3313        if (updateCanvas) {
3314          this.refreshCanvas(true);
3315        }
3316      });
3317    });
3318    window.subscribe(window.SmartEvent.UI.CheckALL, (data) => {
3319      this.favoriteRowsEL?.querySelectorAll<TraceRow<any>>(`trace-row[row-parent-id='${data.rowId}']`).forEach((it) => {
3320        it.checkType = data.isCheck ? '2' : '0';
3321      });
3322    });
3323  }
3324
3325  scrollToProcess(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true) {
3326    let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowId}'][row-type='${rowType}']`);
3327    if (traceRow?.collect) {
3328      this.favoriteRowsEL!.scroll({
3329        top: (traceRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (traceRow?.offsetHeight || 0),
3330        left: 0,
3331        behavior: smooth ? 'smooth' : undefined,
3332      });
3333    } else {
3334      let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`);
3335      if (row && !row.expansion) {
3336        row.expansion = true;
3337      }
3338      if (traceRow && traceRow.offsetTop >= 0 && traceRow.offsetHeight >= 0) {
3339        this.rowsPaneEL!.scroll({
3340          top: (traceRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + (traceRow?.offsetHeight || 0),
3341          left: 0,
3342          behavior: smooth ? 'smooth' : undefined,
3343        });
3344      }
3345    }
3346  }
3347
3348  scrollToDepth(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true, depth: number) {
3349    let rootRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowId}'][row-type='${rowType}']`);
3350    if (rootRow && rootRow!.collect) {
3351      this.favoriteRowsEL!.scroll({
3352        top: (rootRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (++depth * 20 || 0),
3353        left: 0,
3354        behavior: smooth ? 'smooth' : undefined,
3355      });
3356    } else {
3357      let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`);
3358      if (row && !row.expansion) {
3359        row.expansion = true;
3360      }
3361      if (rootRow && rootRow.offsetTop >= 0 && rootRow.offsetHeight >= 0) {
3362        this.rowsPaneEL!.scroll({
3363          top: (rootRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + (++depth * 20 || 0),
3364          left: 0,
3365          behavior: smooth ? 'smooth' : undefined,
3366        });
3367      }
3368    }
3369  }
3370
3371  scrollToFunction(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true) {
3372    let condition = `trace-row[row-id='${rowId}'][row-type='${rowType}'][row-parent-id='${rowParentId}']`;
3373    let rootRow = this.shadowRoot!.querySelector<TraceRow<any>>(condition);
3374    if (rootRow?.collect) {
3375      this.favoriteRowsEL!.scroll({
3376        top: (rootRow?.offsetTop || 0) - this.canvasFavoritePanel!.offsetHeight + (rootRow?.offsetHeight || 0),
3377        left: 0,
3378        behavior: smooth ? 'smooth' : undefined,
3379      });
3380    } else {
3381      let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${rowParentId}'][folder]`);
3382      if (row && !row.expansion) {
3383        row.expansion = true;
3384      }
3385      if (rootRow && rootRow.offsetTop >= 0 && rootRow.offsetHeight >= 0) {
3386        this.rowsPaneEL!.scroll({
3387          top: (rootRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + 20,
3388          left: 0,
3389          behavior: smooth ? 'smooth' : undefined,
3390        });
3391      }
3392    }
3393  }
3394
3395  rowScrollTo(offset: number, callback: Function) {
3396    const fixedOffset = offset;
3397    const onScroll = () => {
3398      if (this.rowsPaneEL!.scrollTop === fixedOffset) {
3399        this.rowsEL!.removeEventListener('scroll', onScroll);
3400        callback();
3401      }
3402    };
3403
3404    this.rowsEL!.addEventListener('scroll', onScroll);
3405    onScroll();
3406    this.rowsPaneEL!.scrollTo({
3407      top: offset,
3408      behavior: 'smooth',
3409    });
3410  }
3411
3412  disconnectedCallback() {
3413    this.timerShaftEL?.removeEventListener('range-change', this.timerShaftELRangeChange);
3414    this.rowsPaneEL?.removeEventListener('scroll', this.rowsElOnScroll);
3415    this.favoriteRowsEL?.removeEventListener('scroll', this.favoriteRowsElOnScroll);
3416    this.removeEventListener('mousemove', this.documentOnMouseMove);
3417    this.removeEventListener('click', this.documentOnClick);
3418    this.removeEventListener('mousedown', this.documentOnMouseDown);
3419    this.removeEventListener('mouseup', this.documentOnMouseUp);
3420    this.removeEventListener('mouseout', this.documentOnMouseOut);
3421    document.removeEventListener('keypress', this.documentOnKeyPress);
3422    document.removeEventListener('keyup', this.documentOnKeyUp);
3423    document.removeEventListener('contextmenu', this.onContextMenuHandler);
3424    window.unsubscribe(window.SmartEvent.UI.SliceMark, this.sliceMarkEventHandler.bind(this));
3425  }
3426
3427  sliceMarkEventHandler(ev: any) {
3428    SpSystemTrace.sliceRangeMark = ev;
3429    let startNS = ev.timestamp - (window as any).recordStartNS;
3430    let endNS = ev.maxDuration + startNS;
3431    TraceRow.rangeSelectObject = {
3432      startX: 0,
3433      startNS: startNS,
3434      endNS: endNS,
3435      endX: 0,
3436    };
3437    window.publish(window.SmartEvent.UI.MenuTrace, {});
3438    window.publish(window.SmartEvent.UI.TimeRange, {
3439      startNS: startNS - ev.maxDuration,
3440      endNS: endNS + ev.maxDuration,
3441    });
3442    this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
3443      it.checkType = '-1';
3444    });
3445    this.rangeSelect.rangeTraceRow = [];
3446    this.selectStructNull();
3447    this.wakeupListNull();
3448    this.traceSheetEL?.setAttribute('mode', 'hidden');
3449    this.removeLinkLinesByBusinessType('janks');
3450    TraceRow.range!.refresh = true;
3451    this.refreshCanvas(false);
3452  }
3453
3454  loadDatabaseUrl(
3455    url: string,
3456    progress: Function,
3457    complete?: ((res: { status: boolean; msg: string }) => void) | undefined
3458  ) {
3459    this.observerScrollHeightEnable = false;
3460    this.init({ url: url }, '', progress).then((res) => {
3461      if (complete) {
3462        complete(res);
3463        window.publish(window.SmartEvent.UI.MouseEventEnable, {
3464          mouseEnable: true,
3465        });
3466      }
3467    });
3468  }
3469
3470  loadDatabaseArrayBuffer(
3471    buf: ArrayBuffer,
3472    thirdPartyWasmConfigUrl: string,
3473    progress: (name: string, percent: number) => void,
3474    complete?: ((res: { status: boolean; msg: string }) => void) | undefined
3475  ) {
3476    this.observerScrollHeightEnable = false;
3477    this.init({ buf }, thirdPartyWasmConfigUrl, progress).then((res) => {
3478      let scrollTop = this.rowsEL?.scrollTop || 0;
3479      let scrollHeight = this.rowsEL?.clientHeight || 0;
3480      this.rowsEL?.querySelectorAll('trace-row').forEach((it: any) => this.observer.observe(it));
3481      if (complete) {
3482        complete(res);
3483        window.publish(window.SmartEvent.UI.MouseEventEnable, {
3484          mouseEnable: true,
3485        });
3486      }
3487    });
3488  }
3489
3490  search(query: string) {
3491    this.shadowRoot?.querySelectorAll<TraceRow<any>>('trace-row').forEach((item) => {
3492      if (query == null || query == undefined || query == '') {
3493        if (
3494          item.rowType == TraceRow.ROW_TYPE_CPU ||
3495          item.rowType == TraceRow.ROW_TYPE_CPU_FREQ ||
3496          item.rowType == TraceRow.ROW_TYPE_NATIVE_MEMORY ||
3497          item.rowType == TraceRow.ROW_TYPE_FPS ||
3498          item.rowType == TraceRow.ROW_TYPE_PROCESS ||
3499          item.rowType == TraceRow.ROW_TYPE_CPU_ABILITY ||
3500          item.rowType == TraceRow.ROW_TYPE_MEMORY_ABILITY ||
3501          item.rowType == TraceRow.ROW_TYPE_DISK_ABILITY ||
3502          item.rowType == TraceRow.ROW_TYPE_NETWORK_ABILITY
3503        ) {
3504          item.expansion = false;
3505          item.rowHidden = false;
3506        } else {
3507          item.rowHidden = true;
3508        }
3509      } else {
3510        if (item.name.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
3511          item.rowHidden = false;
3512        } else {
3513          item.rowHidden = true;
3514        }
3515      }
3516    });
3517    this.visibleRows.forEach((it) => (it.rowHidden = false && it.draw(true)));
3518  }
3519
3520  searchCPU(query: string): Array<CpuStruct> {
3521    let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`);
3522    let dataAll = `trace-row[row-type='cpu-data']`;
3523    if (traceRow) {
3524      dataAll = `trace-row[row-type='cpu-data'][scene]`;
3525    }
3526    let searchResults: Array<CpuStruct> = [];
3527    this.shadowRoot!.querySelectorAll<TraceRow<any>>(`${dataAll}`).forEach((item) => {
3528      let res = item!.dataList!.filter(
3529        (it) =>
3530          (it.name && it.name.indexOf(query) >= 0) ||
3531          it.tid == query ||
3532          it.processId == query ||
3533          (it.processName && it.processName.indexOf(query) >= 0)
3534      );
3535      searchResults.push(...res);
3536    });
3537    searchResults.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
3538    return searchResults;
3539  }
3540
3541  async searchFunction(cpuList: Array<any>, query: string): Promise<Array<any>> {
3542    let processList: Array<string> = [];
3543    let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`);
3544    if (traceRow) {
3545      this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='process'][scene]`).forEach((row) => {
3546        processList.push(row.rowId!);
3547      });
3548      let list = await querySceneSearchFunc(query, processList);
3549      cpuList = cpuList.concat(list);
3550      cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
3551      return cpuList;
3552    } else {
3553      let list = await querySearchFunc(query);
3554      cpuList = cpuList.concat(list);
3555      cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
3556      return cpuList;
3557    }
3558  }
3559
3560  searchSdk(dataList: Array<any>, query: string): Array<any> {
3561    let traceRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[scene]`);
3562    let dataAll = `trace-row[row-type^='sdk']`;
3563    if (traceRow) {
3564      dataAll = `trace-row[row-type^='sdk'][scene]`;
3565    }
3566    let allTraceRow: any = [];
3567    let parentRows = this.shadowRoot!.querySelectorAll<TraceRow<any>>(`${dataAll}`);
3568    parentRows.forEach((parentRow: TraceRow<any>) => {
3569      allTraceRow.push(parentRow);
3570      if (parentRow.childrenList && parentRow.childrenList.length > 0) {
3571        allTraceRow.push(...parentRow.childrenList);
3572      }
3573    });
3574    allTraceRow.forEach((row: any) => {
3575      if (row!.name.indexOf(query) >= 0) {
3576        let searchSdkBean = new SearchSdkBean();
3577        searchSdkBean.startTime = TraceRow.range!.startNS;
3578        searchSdkBean.dur = TraceRow.range!.totalNS;
3579        searchSdkBean.name = row.name;
3580        searchSdkBean.rowId = row.rowId;
3581        searchSdkBean.type = 'sdk';
3582        searchSdkBean.rowType = row.rowType;
3583        searchSdkBean.rowParentId = row.rowParentId;
3584        dataList.push(searchSdkBean);
3585      }
3586    });
3587    return dataList;
3588  }
3589
3590  searchThreadsAndProcesses(query: string): Array<any> {
3591    let searchResults: Array<any> = [];
3592    this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='thread'][row-type='process']`).forEach((item) => {
3593      if (item!.name.indexOf(query) >= 0) {
3594        let searchBean = new SearchThreadProcessBean();
3595        searchBean.name = item.name;
3596        searchBean.rowId = item.rowId;
3597        searchBean.type = 'thread||process';
3598        searchBean.rowType = item.rowType;
3599        searchBean.rowParentId = item.rowParentId;
3600        searchResults.push(searchBean);
3601      }
3602    });
3603    return searchResults;
3604  }
3605
3606  showStruct(previous: boolean, currentIndex: number, structs: Array<any>) {
3607    if (structs.length == 0) {
3608      return 0;
3609    }
3610    let findIndex = -1;
3611    if (previous) {
3612      for (let i = structs.length - 1; i >= 0; i--) {
3613        let it = structs[i];
3614        if (
3615          i < currentIndex &&
3616          it.startTime! >= TraceRow.range!.startNS &&
3617          it.startTime! + it.dur! <= TraceRow.range!.endNS
3618        ) {
3619          findIndex = i;
3620          break;
3621        }
3622      }
3623    } else {
3624      findIndex = structs.findIndex((it, idx) => {
3625        return (
3626          idx > currentIndex &&
3627          it.startTime! >= TraceRow.range!.startNS &&
3628          it.startTime! + it.dur! <= TraceRow.range!.endNS
3629        );
3630      });
3631    }
3632    let findEntry: any;
3633    if (findIndex >= 0) {
3634      findEntry = structs[findIndex];
3635    } else {
3636      if (previous) {
3637        for (let i = structs.length - 1; i >= 0; i--) {
3638          let it = structs[i];
3639          if (it.startTime! + it.dur! < TraceRow.range!.startNS) {
3640            findIndex = i;
3641            break;
3642          }
3643        }
3644        if (findIndex == -1) {
3645          findIndex = structs.length - 1;
3646        }
3647      } else {
3648        findIndex = structs.findIndex((it) => it.startTime! > TraceRow.range!.endNS);
3649        if (findIndex == -1) {
3650          findIndex = 0;
3651        }
3652      }
3653      findEntry = structs[findIndex];
3654    }
3655    this.moveRangeToCenter(findEntry.startTime!, findEntry.dur!);
3656    this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((item) => {
3657      item.highlight = false;
3658    });
3659    if (findEntry.type == 'thread') {
3660      CpuStruct.selectCpuStruct = findEntry;
3661      CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct;
3662      this.shadowRoot!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => {
3663        item.highlight = item.rowId == `${findEntry.cpu}`;
3664        item.draw(true);
3665      });
3666      this.scrollToProcess(`${findEntry.cpu}`, '', 'cpu-data', true);
3667      this.onClickHandler(TraceRow.ROW_TYPE_CPU);
3668    } else if (findEntry.type == 'func') {
3669      this.observerScrollHeightEnable = true;
3670      this.scrollToActFunc(findEntry, true);
3671    } else if (findEntry.type == 'thread||process') {
3672      let threadProcessRow = this.rowsEL?.querySelectorAll<TraceRow<ThreadStruct>>('trace-row')[0];
3673      if (threadProcessRow) {
3674        let filterRow = threadProcessRow.childrenList.filter(
3675          (row) => row.rowId === findEntry.rowId && row.rowId === findEntry.rowType
3676        )[0];
3677        filterRow!.highlight = true;
3678        this.closeAllExpandRows(findEntry.rowParentId);
3679        this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true);
3680        let completeEntry = () => {
3681          let searchEntry = filterRow!.dataList!.find((dat) => dat.startTime === findEntry.startTime);
3682          this.hoverStructNull();
3683          this.selectStructNull();
3684          this.wakeupListNull();
3685          ThreadStruct.hoverThreadStruct = searchEntry;
3686          ThreadStruct.selectThreadStruct = searchEntry;
3687          this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true);
3688        };
3689        if (filterRow!.isComplete) {
3690          completeEntry();
3691        } else {
3692          filterRow!.onComplete = completeEntry;
3693        }
3694      }
3695    } else if (findEntry.type == 'sdk') {
3696      let parentRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-type='sdk'][folder]`);
3697      if (parentRow) {
3698        let sdkRow = parentRow.childrenList.filter(
3699          (child) => child.rowId === findEntry.rowId && child.rowType === findEntry.rowType
3700        )[0];
3701        sdkRow!.highlight = true;
3702      }
3703      this.hoverStructNull();
3704      this.selectStructNull();
3705      this.wakeupListNull();
3706      this.onClickHandler(findEntry.rowType!);
3707      this.closeAllExpandRows(findEntry.rowParentId);
3708      this.scrollToProcess(`${findEntry.rowId}`, `${findEntry.rowParentId}`, findEntry.rowType, true);
3709    }
3710    this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted');
3711    return findIndex;
3712  }
3713
3714  scrollToActFunc(funcStract: any, highlight: boolean) {
3715    const toTargetDepth = (entry: any) => {
3716      if (entry) {
3717        this.hoverStructNull();
3718        this.selectStructNull();
3719        this.wakeupListNull();
3720        FuncStruct.hoverFuncStruct = entry;
3721        FuncStruct.selectFuncStruct = entry;
3722        this.onClickHandler(TraceRow.ROW_TYPE_FUNC);
3723        this.scrollToDepth(`${funcRowID}`, `${funcStract.pid}`, funcStract.type, true, entry.depth || 0);
3724      }
3725    };
3726    let funcRowID = funcStract.cookie == null ? funcStract.tid : `${funcStract.funName}-${funcStract.pid}`;
3727    let targetRow = this.favoriteRowsEL!.querySelector<TraceRow<any>>(
3728      `trace-row[row-id='${funcRowID}'][row-type='func']`
3729    );
3730    if (targetRow) {
3731      targetRow.highlight = highlight;
3732      //如果目标泳道图在收藏上面,则跳转至收藏
3733      let searchEntry = targetRow!.dataList!.find((dat) => dat.startTs === funcStract.startTime);
3734      toTargetDepth(searchEntry);
3735      return;
3736    }
3737    let parentRow = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${funcStract.pid}'][folder]`);
3738    if (!parentRow) {
3739      return;
3740    }
3741    let filterRow = parentRow.childrenList.filter((child) => child.rowId == funcRowID && child.rowType == 'func')[0];
3742    if (filterRow == null) {
3743      let funcRow = this.shadowRoot?.querySelector<TraceRow<any>>(`trace-row[row-id='${funcRowID}'][row-type='func']`);
3744      if (funcRow) {
3745        filterRow = funcRow;
3746      } else {
3747        return;
3748      }
3749    }
3750    filterRow!.highlight = highlight;
3751    if (funcStract.keepOpen !== true) {
3752      this.closeAllExpandRows(funcStract.pid);
3753    }
3754    let row = this.shadowRoot!.querySelector<TraceRow<any>>(`trace-row[row-id='${funcStract.pid}'][folder]`);
3755    if (row && !row.expansion) {
3756      row.expansion = true;
3757    }
3758    const completeEntry = () => {
3759      let entry = filterRow!.dataList!.find((dat) => dat.startTs === funcStract.startTime);
3760      toTargetDepth(entry);
3761    };
3762    if (filterRow!.isComplete) {
3763      completeEntry();
3764    } else {
3765      FuncStruct.hoverFuncStruct = funcStract;
3766      FuncStruct.selectFuncStruct = funcStract;
3767      this.onClickHandler(TraceRow.ROW_TYPE_FUNC);
3768      this.scrollToProcess(`${funcStract.tid}`, `${funcStract.pid}`, 'process', false);
3769      this.scrollToFunction(`${funcStract.tid}`, `${funcStract.pid}`, 'func', true);
3770      filterRow!.onComplete = completeEntry;
3771    }
3772  }
3773
3774  closeAllExpandRows(pid: string) {
3775    let expandRows = this.rowsEL?.querySelectorAll<TraceRow<ProcessStruct>>(`trace-row[row-type='process'][expansion]`);
3776    expandRows?.forEach((row) => {
3777      if (row.rowId != pid) {
3778        row.expansion = false;
3779      }
3780    });
3781  }
3782
3783  moveRangeToCenter(startTime: number, dur: number) {
3784    let startNS = this.timerShaftEL?.getRange()?.startNS || 0;
3785    let endNS = this.timerShaftEL?.getRange()?.endNS || 0;
3786    let harfDur = Math.trunc((endNS - startNS) / 2 - dur / 2);
3787    let leftNs = startTime - harfDur;
3788    let rightNs = startTime + dur + harfDur;
3789    if (startTime - harfDur < 0) {
3790      leftNs = 0;
3791      rightNs += harfDur - startTime;
3792    }
3793    this.timerShaftEL?.setRangeNS(leftNs, rightNs);
3794    TraceRow.range!.refresh = true;
3795    this.refreshCanvas(true);
3796  }
3797
3798  showPreCpuStruct(currentIndex: number, cpuStructs: Array<CpuStruct>): number {
3799    if (cpuStructs.length == 0) {
3800      return 0;
3801    }
3802    let findIndex = -1;
3803    for (let i = cpuStructs.length - 1; i >= 0; i--) {
3804      let it = cpuStructs[i];
3805      if (
3806        i < currentIndex &&
3807        it.startTime! >= TraceRow.range!.startNS &&
3808        it.startTime! + it.dur! <= TraceRow.range!.endNS
3809      ) {
3810        findIndex = i;
3811        break;
3812      }
3813    }
3814    if (findIndex >= 0) {
3815      let findEntry = cpuStructs[findIndex];
3816      CpuStruct.selectCpuStruct = findEntry;
3817      this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => {
3818        item.highlight = item.rowId == `${findEntry.cpu}`;
3819        item.draw(true);
3820      });
3821      this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted');
3822    } else {
3823      for (let i = cpuStructs.length - 1; i >= 0; i--) {
3824        let it = cpuStructs[i];
3825        if (it.startTime! + it.dur! < TraceRow.range!.startNS) {
3826          findIndex = i;
3827          break;
3828        }
3829      }
3830      let findEntry: CpuStruct;
3831      if (findIndex == -1) {
3832        findIndex = cpuStructs.length - 1;
3833      }
3834      findEntry = cpuStructs[findIndex];
3835      CpuStruct.selectCpuStruct = findEntry;
3836      let startNS = this.timerShaftEL?.getRange()?.startNS || 0;
3837      let endNS = this.timerShaftEL?.getRange()?.endNS || 0;
3838      let harfDur = Math.trunc((endNS - startNS) / 2 - findEntry.dur! / 2);
3839      this.timerShaftEL?.setRangeNS(findEntry.startTime! - harfDur, findEntry.startTime! + findEntry.dur! + harfDur);
3840      this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => {
3841        item.highlight = item.rowId == `${findEntry.cpu}`;
3842        item.draw(true);
3843      });
3844      this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted');
3845    }
3846    CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct;
3847    this.onClickHandler(TraceRow.ROW_TYPE_CPU);
3848    return findIndex;
3849  }
3850
3851  showNextCpuStruct(currentIndex: number, cpuStructs: Array<CpuStruct>): number {
3852    if (cpuStructs.length == 0) {
3853      return 0;
3854    }
3855    let findIndex = cpuStructs.findIndex((it, idx) => {
3856      return (
3857        idx > currentIndex &&
3858        it.startTime! >= TraceRow.range!.startNS &&
3859        it.startTime! + it.dur! <= TraceRow.range!.endNS
3860      );
3861    });
3862    if (findIndex >= 0) {
3863      let findEntry = cpuStructs[findIndex];
3864      CpuStruct.selectCpuStruct = findEntry;
3865      this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => {
3866        item.highlight = item.rowId == `${findEntry.cpu}`;
3867        item.draw(true);
3868      });
3869      this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted');
3870    } else {
3871      findIndex = cpuStructs.findIndex((it) => it.startTime! > TraceRow.range!.endNS);
3872      let findEntry: CpuStruct;
3873      if (findIndex == -1) {
3874        findIndex = 0;
3875      }
3876      findEntry = cpuStructs[findIndex];
3877      CpuStruct.selectCpuStruct = findEntry;
3878      let startNS = this.timerShaftEL?.getRange()?.startNS || 0;
3879      let endNS = this.timerShaftEL?.getRange()?.endNS || 0;
3880      let harfDur = Math.trunc((endNS - startNS) / 2 - findEntry.dur! / 2);
3881      this.timerShaftEL?.setRangeNS(findEntry.startTime! - harfDur, findEntry.startTime! + findEntry.dur! + harfDur);
3882      this.rowsEL!.querySelectorAll<TraceRow<any>>(`trace-row[row-type='cpu-data']`).forEach((item) => {
3883        item.highlight = item.rowId == `${findEntry.cpu}`;
3884        item.draw(true);
3885      });
3886      this.timerShaftEL?.drawTriangle(findEntry.startTime || 0, 'inverted');
3887    }
3888    CpuStruct.hoverCpuStruct = CpuStruct.selectCpuStruct;
3889    this.onClickHandler(TraceRow.ROW_TYPE_CPU);
3890    return findIndex;
3891  }
3892
3893  reset(progress: Function | undefined | null) {
3894    this.visibleRows.length = 0;
3895    this.tipEL!.style.display = 'none';
3896    this.canvasPanelCtx?.clearRect(0, 0, this.canvasPanel!.clientWidth, this.canvasPanel!.offsetHeight);
3897    this.canvasFavoritePanelCtx?.clearRect(
3898      0,
3899      0,
3900      this.canvasFavoritePanel!.clientWidth,
3901      this.canvasFavoritePanel!.clientHeight
3902    );
3903    this.favoriteRowsEL!.style.height = '0';
3904    this.canvasFavoritePanel!.style.height = '0';
3905    this.loadTraceCompleted = false;
3906    this.collectRows = [];
3907    this.visibleRows = [];
3908    TraceRowConfig.allTraceRowList.forEach((it) => {
3909      it.clearMemory();
3910    });
3911    TraceRowConfig.allTraceRowList = [];
3912    if (this.favoriteRowsEL) {
3913      this.favoriteRowsEL.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((row) => {
3914        row.clearMemory();
3915        this.favoriteRowsEL!.removeChild(row);
3916      });
3917    }
3918    if (this.rowsEL) {
3919      this.rowsEL.querySelectorAll<TraceRow<any>>(`trace-row`).forEach((row) => {
3920        row.clearMemory();
3921        this.rowsEL!.removeChild(row);
3922      });
3923      this.rowsEL.innerHTML = '';
3924    }
3925    this.traceSheetEL?.clearMemory();
3926    this.spacerEL!.style.height = '0px';
3927    this.rangeSelect.rangeTraceRow = [];
3928    SpSystemTrace.SDK_CONFIG_MAP = undefined;
3929    SpSystemTrace.sliceRangeMark = undefined;
3930    this.timerShaftEL?.displayCollect(false);
3931    this.timerShaftEL!.collecBtn!.removeAttribute('close');
3932    CpuStruct.wakeupBean = undefined;
3933    this.selectStructNull();
3934    this.hoverStructNull();
3935    this.wakeupListNull();
3936    this.traceSheetEL?.setAttribute('mode', 'hidden');
3937    progress && progress('rest timershaft', 8);
3938    this.timerShaftEL?.reset();
3939    progress && progress('clear cache', 10);
3940    HeapDataInterface.getInstance().clearData();
3941    procedurePool.clearCache();
3942    Utils.clearData();
3943    procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: any) => {});
3944    procedurePool.submitWithName('logic1', 'clear', {}, undefined, (res: any) => {});
3945  }
3946
3947  init = async (param: { buf?: ArrayBuffer; url?: string }, wasmConfigUri: string, progress: Function) => {
3948    progress('Load database', 6);
3949    this.rowsPaneEL!.scroll({
3950      top: 0,
3951      left: 0,
3952    });
3953    if (param.buf) {
3954      let configJson = '';
3955      try {
3956        configJson = await fetch(wasmConfigUri).then((res) => res.text());
3957      } catch (e) {
3958        error('getWasmConfigFailed', e);
3959      }
3960      let parseConfig = FlagsConfig.getSpTraceStreamParseConfig();
3961      let { status, msg, sdkConfigMap } = await threadPool.initSqlite(param.buf, parseConfig, configJson, progress);
3962      if (!status) {
3963        return { status: false, msg: msg };
3964      }
3965      SpSystemTrace.SDK_CONFIG_MAP = sdkConfigMap == undefined ? undefined : sdkConfigMap;
3966    }
3967    if (param.url) {
3968      let { status, msg } = await threadPool.initServer(param.url, progress);
3969      if (!status) {
3970        return { status: false, msg: msg };
3971      }
3972    }
3973    await this.chartManager?.init(progress);
3974    let rowId: string = '';
3975    this.rowsEL?.querySelectorAll<TraceRow<any>>('trace-row').forEach((it: any) => {
3976      if (it.name.includes('Ark Ts')) {
3977        rowId = it.rowId;
3978      }
3979      it.addEventListener('expansion-change', this.extracted(it));
3980    });
3981    progress('completed', 100);
3982    info('All TraceRow Data initialized');
3983    this.loadTraceCompleted = true;
3984    this.rowsEL!.querySelectorAll<TraceRow<any>>('trace-row').forEach((it) => {
3985      if (rowId !== '' && (it.rowId?.includes(rowId) || it.name.includes(rowId))) {
3986        it.addTemplateTypes('Ark Ts');
3987        for (let child of it.childrenList) {
3988          child.addTemplateTypes('Ark Ts');
3989        }
3990      }
3991      if (it.folder) {
3992        let offsetYTimeOut: any = undefined;
3993        it.addEventListener('expansion-change', (event: any) => {
3994          JankStruct.delJankLineFlag = false;
3995          if (offsetYTimeOut) {
3996            clearTimeout(offsetYTimeOut);
3997          }
3998          if (event.detail.expansion) {
3999            offsetYTimeOut = setTimeout(() => {
4000              this.linkNodes.forEach((linkNode) => {
4001                JankStruct.selectJankStructList?.forEach((selectStruct: any) => {
4002                  if (event.detail.rowId == selectStruct.pid) {
4003                    JankStruct.selectJankStruct = selectStruct;
4004                    JankStruct.hoverJankStruct = selectStruct;
4005                  }
4006                });
4007                if (linkNode[0].rowEL.collect) {
4008                  linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - 195;
4009                } else {
4010                  linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
4011                }
4012                linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY;
4013                if (linkNode[1].rowEL.collect) {
4014                  linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - 195;
4015                } else {
4016                  linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
4017                }
4018                linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY;
4019              });
4020            }, 300);
4021          } else {
4022            if (JankStruct!.selectJankStruct) {
4023              JankStruct.selectJankStructList?.push(<JankStruct>JankStruct!.selectJankStruct);
4024            }
4025            offsetYTimeOut = setTimeout(() => {
4026              this.linkNodes?.forEach((linkNode) => {
4027                if (linkNode[0].rowEL.collect) {
4028                  linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - 195;
4029                } else {
4030                  linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
4031                }
4032                linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY;
4033                if (linkNode[1].rowEL.collect) {
4034                  linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - 195;
4035                } else {
4036                  linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
4037                }
4038                linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY;
4039              });
4040            }, 300);
4041          }
4042          let refreshTimeOut = setTimeout(() => {
4043            this.refreshCanvas(true);
4044            clearTimeout(refreshTimeOut);
4045          }, 360);
4046        });
4047      }
4048      this.intersectionObserver?.observe(it);
4049    });
4050    return { status: true, msg: 'success' };
4051  };
4052
4053  private extracted(it: any) {
4054    return () => {
4055      if (it.hasAttribute('expansion')) {
4056        this.shadowRoot?.querySelectorAll<any>(`[row-parent-id='${it.rowId}']`).forEach((child) => {
4057          if (child.folder) {
4058            child.addEventListener('expansion-change', this.extracted(child));
4059          }
4060          this.intersectionObserver?.observe(child);
4061        });
4062      } else {
4063        this.shadowRoot?.querySelectorAll<any>(`[row-parent-id='${it.rowId}']`).forEach((child) => {
4064          this.intersectionObserver?.unobserve(child);
4065        });
4066      }
4067      this.refreshCanvas(false);
4068    };
4069  }
4070
4071  displayTip(row: TraceRow<any>, struct: any, html: string) {
4072    let x = row.hoverX + 248;
4073    let y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0);
4074    if ((struct === undefined || struct === null) && this.tipEL) {
4075      this.tipEL.style.display = 'none';
4076      return;
4077    }
4078    if (this.tipEL) {
4079      this.tipEL.innerHTML = html;
4080      if (row.rowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER) {
4081        this.tipEL.style.maxWidth = row.clientWidth / 3 + 'px';
4082        this.tipEL.style.wordBreak = ' break-all';
4083        this.tipEL.style.height = 'unset';
4084        this.tipEL.style.display = 'block';
4085        y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0) + struct.depth * 20;
4086      } else {
4087        this.tipEL.style.display = 'flex';
4088        this.tipEL.style.height = row.style.height;
4089        y = row.getBoundingClientRect().top - 195 + (this.rowsPaneEL?.scrollTop ?? 0);
4090      }
4091      if (x + this.tipEL.clientWidth > (this.canvasPanel!.clientWidth ?? 0)) {
4092        this.tipEL.style.transform = `translateX(${x - this.tipEL.clientWidth - 1}px) translateY(${y}px)`;
4093      } else {
4094        this.tipEL.style.transform = `translateX(${x}px) translateY(${y}px)`;
4095      }
4096    }
4097  }
4098
4099  queryCPUWakeUpList(data: WakeupBean) {
4100    TabPaneCurrentSelection.queryCPUWakeUpListFromBean(data).then((a: any) => {
4101      if (a === null) {
4102        return null;
4103      }
4104      SpSystemTrace.wakeupList.push(a);
4105      this.queryCPUWakeUpList(a);
4106    });
4107  }
4108
4109  wakeupListNull() {
4110    SpSystemTrace.wakeupList = [];
4111  }
4112
4113  initPointToEvent() {
4114    this.eventMap = {
4115      'cpu-data': 'Cpu',
4116      'cpu-state': 'Cpu State',
4117      'cpu-freq': 'Cpu Frequency',
4118      'cpu-limit-freq': 'Cpu Freq Limit',
4119      process: 'Process',
4120      'native-memory': 'Native Memory',
4121      thread: 'Thread',
4122      func: 'Func',
4123      mem: 'Memory',
4124      'virtual-memory-cell': 'Virtual Memory',
4125      'virtual-memory-group': 'Virtual Memory',
4126      fps: 'FPS',
4127      'ability-monitor': 'Ability Monitor',
4128      'cpu-ability': 'Cpu Ability',
4129      'memory-ability': 'Memory Ability',
4130      'disk-ability': 'DiskIO Ability',
4131      'network-ability': 'Network Ability',
4132      sdk: 'Sdk',
4133      'sdk-counter': 'SDK Counter',
4134      'sdk-slice': 'Sdk Slice',
4135      energy: 'Energy',
4136      'power-energy': 'Power Event',
4137      'system-energy': 'System Event',
4138      'anomaly-energy': 'Anomaly Event',
4139      'clock-group': 'Clocks',
4140      clock: 'clock',
4141      'irq-group': 'Irqs',
4142      irq: 'irq',
4143      hiperf: 'HiPerf (All)',
4144      'hiperf-event': 'HiPerf Event',
4145      'hiperf-report': 'HiPerf Report',
4146      'hiperf-process': 'HiPerf Process',
4147      'hiperf-thread': 'HiPerf Thread',
4148      'js-memory': 'Js Memory',
4149    };
4150  }
4151
4152  initHtml(): string {
4153    return `
4154        <style>
4155        :host{
4156            display: block;
4157            width: 100%;
4158            height: 100%;
4159        }
4160        .timer-shaft{
4161            width: 100%;
4162            z-index: 2;
4163        }
4164        .rows-pane{
4165            overflow: overlay;
4166            overflow-anchor: none;
4167            /*height: 100%;*/
4168            max-height: calc(100vh - 147px - 48px);
4169        }
4170        .rows{
4171            color: #fff;
4172            display: flex;
4173            box-sizing: border-box;
4174            flex-direction: column;
4175            overflow-y: auto;
4176            flex: 1;
4177            width: 100%;
4178            background: var(--dark-background4,#ffffff);
4179            /*scroll-behavior: smooth;*/
4180        }
4181        .favorite-rows{
4182            width: 100%;
4183            position:fixed;
4184            overflow-y: auto;
4185            overflow-x: hidden;
4186            z-index:1001;
4187            background: var(--dark-background5,#ffffff);
4188            box-shadow: 0 10px 10px #00000044;
4189        }
4190        :host([disable]) .container{
4191            pointer-events: none;
4192        }
4193        .container{
4194            width: 100%;
4195            box-sizing: border-box;
4196            height: 100%;
4197            display: grid;
4198            grid-template-columns: 1fr;
4199            grid-template-rows: min-content 1fr min-content;
4200            /*grid-template-areas:    'head'*/
4201                                    /*'body'*/
4202                                    /*'sheet';*/
4203            position:relative;
4204        }
4205        .panel-canvas{
4206            position: absolute;
4207            top: 0;
4208            right: 0px;
4209            bottom: 0px;
4210            width: 100%;
4211            /*height: calc(100vh - 195px);*/
4212            height: 100%;
4213            box-sizing: border-box;
4214            /*background: #f0f0f0;*/
4215            /*border: 1px solid #000000;*/
4216            z-index: 0;
4217        }
4218        .panel-canvas-favorite{
4219            width: 100% ;
4220            display: block;
4221            position: absolute;
4222            height: 0;
4223            top: 0;
4224            right: 0;
4225            box-sizing: border-box;
4226            z-index: 100;
4227        }
4228        .trace-sheet{
4229            cursor: default;
4230        }
4231        .tip{
4232            z-index: 1001;
4233            position: absolute;
4234            top: 0;
4235            left: 0;
4236            /*height: 100%;*/
4237            background-color: white;
4238            border: 1px solid #f9f9f9;
4239            width: auto;
4240            font-size: 8px;
4241            color: #50809e;
4242            flex-direction: column;
4243            justify-content: center;
4244            align-items: flex-start;
4245            padding: 2px 10px;
4246            box-sizing: border-box;
4247            display: none;
4248            user-select: none;
4249        }
4250
4251        </style>
4252        <div class="container">
4253            <timer-shaft-element class="timer-shaft" style="position: relative;top: 0"></timer-shaft-element>
4254            <div class="rows-pane" style="position: relative;flex-direction: column;overflow-x: hidden;">
4255                <div class="favorite-rows">
4256                    <canvas id="canvas-panel-favorite" class="panel-canvas-favorite" ondragstart="return false"></canvas>
4257                </div>
4258                <canvas id="canvas-panel" class="panel-canvas" ondragstart="return false"></canvas>
4259                <div class="spacer" ondragstart="return false"></div>
4260                <div class="rows" ondragstart="return false"></div>
4261                <div id="tip" class="tip"></div>
4262            </div>
4263            <trace-sheet class="trace-sheet" mode="hidden" ondragstart="return false"></trace-sheet>
4264        </div>
4265        `;
4266  }
4267}
4268