1/*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import { BaseElement, element } from '../../base-ui/BaseElement';
17import './trace/TimerShaftElement';
18import './trace/base/TraceRow';
19import { threadPool, threadPool2 } from '../database/SqlLite';
20import { TraceRow } from './trace/base/TraceRow';
21import { TimerShaftElement } from './trace/TimerShaftElement';
22import './trace/base/TraceSheet';
23import { TraceSheet } from './trace/base/TraceSheet';
24import { RangeSelect } from './trace/base/RangeSelect';
25import { SelectionParam } from '../bean/BoxSelection';
26import { procedurePool } from '../database/Procedure';
27import { SpApplication } from '../SpApplication';
28import { Flag } from './trace/timer-shaft/Flag';
29import { SlicesTime, SportRuler } from './trace/timer-shaft/SportRuler';
30import { SpHiPerf } from './chart/SpHiPerf';
31import { SearchSdkBean } from '../bean/SearchFuncBean';
32import { info } from '../../log/Log';
33import {
34  drawFlagLineSegment,
35  drawLines,
36  drawLinkLines,
37  drawLogsLineSegment,
38  drawWakeUp,
39  drawWakeUpList,
40  LineType,
41  ns2x,
42  ns2xByTimeShaft,
43  PairPoint,
44  Rect,
45  prioClickHandlerFun,
46  drawThreadCurve,
47} from '../database/ui-worker/ProcedureWorkerCommon';
48import { SpChartManager } from './chart/SpChartManager';
49import { CpuStruct, WakeupBean } from '../database/ui-worker/cpu/ProcedureWorkerCPU';
50import { ProcessStruct } from '../database/ui-worker/ProcedureWorkerProcess';
51import { CpuFreqStruct } from '../database/ui-worker/ProcedureWorkerFreq';
52import { CpuFreqLimitsStruct } from '../database/ui-worker/cpu/ProcedureWorkerCpuFreqLimits';
53import { ThreadStruct } from '../database/ui-worker/ProcedureWorkerThread';
54import { FuncStruct } from '../database/ui-worker/ProcedureWorkerFunc';
55import { CpuStateStruct } from '../database/ui-worker/cpu/ProcedureWorkerCpuState';
56import { HiPerfCpuStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfCPU2';
57import { HiPerfProcessStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfProcess2';
58import { HiPerfThreadStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfThread2';
59import { HiPerfEventStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfEvent';
60import { HiPerfReportStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfReport';
61import { FpsStruct } from '../database/ui-worker/ProcedureWorkerFPS';
62import { CpuAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerCpuAbility';
63import { DiskAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerDiskIoAbility';
64import { MemoryAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerMemoryAbility';
65import { NetworkAbilityMonitorStruct } from '../database/ui-worker/ProcedureWorkerNetworkAbility';
66import { ClockStruct } from '../database/ui-worker/ProcedureWorkerClock';
67import { DmaFenceStruct } from '../database/ui-worker/ProcedureWorkerDmaFence';
68import { Utils } from './trace/base/Utils';
69import { IrqStruct } from '../database/ui-worker/ProcedureWorkerIrq';
70import { JankStruct } from '../database/ui-worker/ProcedureWorkerJank';
71import { TabPaneCurrent } from './trace/sheet/TabPaneCurrent';
72import { HeapStruct } from '../database/ui-worker/ProcedureWorkerHeap';
73import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil';
74import { HeapSnapshotStruct } from '../database/ui-worker/ProcedureWorkerHeapSnapshot';
75import { HeapDataInterface } from '../../js-heap/HeapDataInterface';
76import { LitTabs } from '../../base-ui/tabs/lit-tabs';
77import { TraceRowConfig } from './trace/base/TraceRowConfig';
78import { TabPaneCurrentSelection } from './trace/sheet/TabPaneCurrentSelection';
79import { SpChartList } from './trace/SpChartList';
80import './trace/SpChartList';
81import { AppStartupStruct } from '../database/ui-worker/ProcedureWorkerAppStartup';
82import { AllAppStartupStruct } from '../database/ui-worker/ProcedureWorkerAllAppStartup';
83import { SoStruct } from '../database/ui-worker/ProcedureWorkerSoInit';
84import { FrameDynamicStruct } from '../database/ui-worker/ProcedureWorkerFrameDynamic';
85import { FrameAnimationStruct } from '../database/ui-worker/ProcedureWorkerFrameAnimation';
86import { FrameSpacingStruct } from '../database/ui-worker/ProcedureWorkerFrameSpacing';
87import { JsCpuProfilerStruct } from '../database/ui-worker/ProcedureWorkerCpuProfiler';
88import { FileInfo } from '../../js-heap/model/UiStruct';
89import { SnapshotStruct } from '../database/ui-worker/ProcedureWorkerSnapshot';
90import { TabPaneFrequencySample } from './trace/sheet/cpu/TabPaneFrequencySample';
91import { TabPaneCounterSample } from './trace/sheet/cpu/TabPaneCounterSample';
92import { TabPaneFlag } from './trace/timer-shaft/TabPaneFlag';
93import { LitTabpane } from '../../base-ui/tabs/lit-tabpane';
94import { HiPerfCallChartStruct } from '../database/ui-worker/hiperf/ProcedureWorkerHiPerfCallChart';
95import { InitAnalysis } from '../database/logic-worker/ProcedureLogicWorkerCommon';
96import { searchCpuDataSender } from '../database/data-trafic/CpuDataSender';
97import { resetVSync } from './chart/VSync';
98import { QueryEnum } from '../database/data-trafic/utils/QueryEnum';
99import { SpSystemTraceHtml } from './SpSystemTrace.html';
100import { querySceneSearchFunc, querySearchFunc } from '../database/sql/Func.sql';
101import { queryCpuKeyPathData } from '../database/sql/Cpu.sql';
102import { LtpoStruct } from '../database/ui-worker/ProcedureWorkerLTPO';
103import { HitchTimeStruct } from '../database/ui-worker/ProcedureWorkerHitchTime';
104import { ProcessMemStruct } from '../database/ui-worker/ProcedureWorkerMem';
105import {
106  spSystemTraceInit,
107  spSystemTraceInitElement,
108  spSystemTraceInitPointToEvent,
109  spSystemTraceParentRowSticky,
110  spSystemTraceShowStruct,
111} from './SpSystemTrace.init';
112import {
113  spSystemTraceDrawDistributedLine,
114  spSystemTraceDrawFuncLine,
115  spSystemTraceDrawJankLine,
116  spSystemTraceDrawTaskPollLine,
117  spSystemTraceDrawThreadLine,
118} from './SpSystemTrace.line';
119import spSystemTraceOnClickHandler, {
120  spSystemTraceDocumentOnClick,
121  spSystemTraceDocumentOnKeyDown,
122  spSystemTraceDocumentOnKeyPress,
123  spSystemTraceDocumentOnKeyUp,
124  spSystemTraceDocumentOnMouseDown,
125  spSystemTraceDocumentOnMouseMove,
126  spSystemTraceDocumentOnMouseOut,
127  spSystemTraceDocumentOnMouseUp,
128  spSystemTraceDocumentOnMouseMoveMouseDown,
129} from './SpSystemTrace.event';
130import { SampleStruct } from '../database/ui-worker/ProcedureWorkerBpftrace';
131import { readTraceFileBuffer } from '../SpApplicationPublicFunc';
132import { PerfToolStruct } from '../database/ui-worker/ProcedureWorkerPerfTool';
133import { BaseStruct } from '../bean/BaseStruct';
134import { GpuCounterStruct } from '../database/ui-worker/ProcedureWorkerGpuCounter';
135import { SpProcessChart } from './chart/SpProcessChart';
136import { LitSearch } from './trace/search/Search';
137import { LitTable } from '../../base-ui/table/lit-table';
138import { HangStruct } from '../database/ui-worker/ProcedureWorkerHang';
139import { SpAiAnalysisPage } from './SpAiAnalysisPage';
140
141function dpr(): number {
142  return window.devicePixelRatio || 1;
143}
144
145export class CurrentSlicesTime {
146  startTime: number | undefined;
147  endTime: number | undefined;
148}
149
150type HTMLDivElementAlias = HTMLDivElement | undefined | null;
151type FlagAlias = Flag | undefined | null;
152type SlicesTimeAlias = SlicesTime | undefined | null;
153
154@element('sp-system-trace')
155export class SpSystemTrace extends BaseElement {
156  mouseCurrentPosition = 0;
157  static isKeyUp: boolean = true;
158  offsetMouse = 0;
159  static isMouseLeftDown = false;
160  static scrollViewWidth = 0;
161  static isCanvasOffScreen = true;
162  static DATA_DICT: Map<number, string> = new Map<number, string>();
163  static DATA_TASK_POOL_CALLSTACK: Map<number, { id: number; ts: number; dur: number; name: string }> = new Map<
164    number,
165    { id: number; ts: number; dur: number; name: string }
166  >();
167  static SDK_CONFIG_MAP: unknown;
168  static sliceRangeMark: unknown;
169  static wakeupList: Array<WakeupBean> = [];
170  static keyPathList: Array<CpuStruct> = [];
171  static keyboardFlar: Boolean = true;
172  static jsProfilerMap: Map<number, unknown> = new Map<number, unknown>();
173  times: Set<number> = new Set<number>();
174  currentSlicesTime: CurrentSlicesTime = new CurrentSlicesTime();
175  intersectionObserver: IntersectionObserver | undefined;
176  tipEL: HTMLDivElementAlias;
177  rowsEL: HTMLDivElementAlias;
178  rowsPaneEL: HTMLDivElementAlias;
179  stateRowsId: Array<object> = [];
180  spacerEL: HTMLDivElementAlias; // @ts-ignore
181  visibleRows: Array<TraceRow<unknown>> = []; // @ts-ignore
182  invisibleRows: Array<TraceRow<unknown>> = []; // @ts-ignore
183  collectRows: Array<TraceRow<unknown>> = []; // @ts-ignore
184  currentRow: TraceRow<unknown> | undefined | null;
185  keyboardEnable = true;
186  mouseEventEnable = true;
187  currentRowType = ''; /*保存当前鼠标所在行的类型*/
188  observerScrollHeightEnable: boolean = false;
189  observerScrollHeightCallback: Function | undefined;
190  favoriteChartListEL: SpChartList | undefined | null;
191  // @ts-ignore
192  observer = new ResizeObserver((entries) => {
193    if (this.observerScrollHeightEnable && this.observerScrollHeightCallback) {
194      this.observerScrollHeightCallback();
195    }
196  });
197  static btnTimer: unknown = null;
198  isMousePointInSheet = false;
199  hoverFlag: FlagAlias;
200  selectFlag: FlagAlias;
201  slicestime: SlicesTimeAlias;
202  public timerShaftEL: TimerShaftElement | null | undefined;
203  public traceSheetEL: TraceSheet | undefined | null;
204  public rangeSelect!: RangeSelect;
205  chartManager: SpChartManager | undefined | null;
206  loadTraceCompleted: boolean = false; // @ts-ignore
207  rangeTraceRow: Array<TraceRow<unknown>> | undefined = [];
208  canvasFavoritePanelCtx: CanvasRenderingContext2D | null | undefined;
209  canvasPanel: HTMLCanvasElement | null | undefined; //绘制取消收藏后泳道图
210  canvasPanelCtx: CanvasRenderingContext2D | undefined | null;
211  linkNodes: PairPoint[][] = [];
212  public currentClickRow: HTMLDivElement | undefined | null;
213  private litTabs: LitTabs | undefined | null;
214  eventMap: unknown = {};
215  isSelectClick: boolean = false;
216  selectionParam: SelectionParam | undefined;
217  snapshotFiles: FileInfo | null | undefined;
218  tabCpuFreq: TabPaneFrequencySample | undefined | null;
219  tabCpuState: TabPaneCounterSample | undefined | null;
220  collapseAll: boolean = false;
221  currentCollectGroup: string = '1';
222  private _list: Array<SlicesTime> = [];
223  static isHiddenMenu: boolean = false; // @ts-ignore
224  expandRowList: Array<TraceRow<unknown>> = [];
225  _slicesList: Array<SlicesTime> = [];
226  _flagList: Array<unknown> = [];
227  static currentStartTime: number = 0;
228  static retargetIndex: number = 0;
229  prevScrollY: number = 0;
230  wakeupListTbl: LitTable | undefined | null;
231  _checkclick: boolean = false; //判断点击getWakeupList按钮
232  docomList: Array<number> = [];
233  repaintList: Array<number> = [];
234  presentList: Array<number> = [];
235  static isAiAsk: boolean = false;
236
237  set snapshotFile(data: FileInfo) {
238    this.snapshotFiles = data;
239  }
240
241  set slicesList(list: Array<SlicesTime>) {
242    this._slicesList = list;
243  }
244
245  set flagList(list: Array<unknown>) {
246    this._flagList = list;
247  }
248
249  get checkclick(): boolean {
250    return this._checkclick;
251  }
252
253  set checkclick(value: boolean) {
254    if (value) {
255      this._checkclick = true;
256    } else {
257      this._checkclick = false;
258    }
259  }
260
261  //节流处理
262  throttle(fn: Function, t: number, ev?: unknown): Function {
263    let timerId: unknown = null;
264    return (): void => {
265      if (!timerId) {
266        timerId = setTimeout(function (): void {
267          if (ev) {
268            fn(ev);
269          } else {
270            fn();
271          }
272          timerId = null;
273        }, t); // @ts-ignore
274        this.times.add(timerId);
275      }
276    };
277  }
278
279  // 防抖处理
280  debounce(fn: Function, ms: number, ev?: unknown): Function {
281    let timerId: undefined | number;
282    return (): void => {
283      if (timerId) {
284        window.clearTimeout(timerId);
285      } else {
286        timerId = window.setTimeout((): void => {
287          if (ev) {
288            fn(ev);
289          } else {
290            fn();
291          }
292          timerId = undefined;
293        }, ms);
294        this.times.add(timerId);
295      }
296    };
297  }
298
299  addPointPair(startPoint: PairPoint, endPoint: PairPoint, lineType?: string): void {
300    if (startPoint !== null && startPoint.rowEL !== null && endPoint !== null && endPoint.rowEL !== null) {
301      if (startPoint.rowEL.collect) {
302        if (this.timerShaftEL?._checkExpand) {
303          startPoint.rowEL.translateY =
304            startPoint.rowEL.getBoundingClientRect().top - 195 + this.timerShaftEL._usageFoldHeight!;
305        } else {
306          startPoint.rowEL.translateY = startPoint.rowEL.getBoundingClientRect().top - 195;
307        }
308      } else {
309        startPoint.rowEL.translateY = startPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
310      }
311      if (endPoint.rowEL.collect) {
312        endPoint.rowEL.translateY = endPoint.rowEL.getBoundingClientRect().top - 195;
313      } else {
314        endPoint.rowEL.translateY = endPoint.rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
315      }
316      startPoint.y = startPoint.rowEL!.translateY! + startPoint.offsetY;
317      endPoint.y = endPoint.rowEL!.translateY! + endPoint.offsetY;
318      startPoint.backrowEL = startPoint.rowEL;
319      endPoint.backrowEL = endPoint.rowEL;
320      //判断是否是分布式连线,分布式连线需有rangeTime
321      if (!lineType) {
322        this.linkNodes.push([startPoint, endPoint]);
323      } else {
324        if (startPoint.rangeTime) {
325          this.linkNodes.push([startPoint, endPoint]);
326        }
327      }
328      this.refreshCanvas(true);
329    }
330  }
331
332  clearPointPair(): void {
333    this.linkNodes.length = 0;
334  }
335
336  removeLinkLinesByBusinessType(...businessTypes: string[]): void {
337    this.linkNodes = this.linkNodes.filter((pointPair) => {
338      if (businessTypes.indexOf('distributed') >= 0) {
339        FuncStruct.selectLineFuncStruct = [];
340      }
341      return businessTypes.indexOf(pointPair[0].business) <= -1;
342    });
343  }
344
345  hiddenLinkLinesByBusinessType(...businessTypes: string[]): void {
346    this.linkNodes.map((value) => {
347      if (businessTypes.indexOf(value[0].business) !== -1) {
348        value[0].hidden = true;
349        value[1].hidden = true;
350      }
351    });
352  }
353
354  showLinkLinesByBusinessType(...businessTypes: string[]): void {
355    this.linkNodes.map((value) => {
356      if (businessTypes.indexOf(value[0].business) !== -1) {
357        value[0].hidden = false;
358        value[1].hidden = false;
359      }
360    });
361  }
362
363  initElements(): void {
364    spSystemTraceInitElement(this);
365  }
366
367  // 清除上一次点击调用栈产生的三角旗子
368  clearTriangle(flagList: Array<Flag>): void {
369    this.timerShaftEL!.sportRuler!.times = [];
370    for (let i = 0; i < flagList.length; i++) {
371      if (flagList[i].type === 'triangle') {
372        flagList.splice(i, 1);
373        this.timerShaftELFlagChange(this.hoverFlag, null);
374        i--;
375      }
376    }
377  }
378
379  pushPidToSelection(selection: SelectionParam, id: string, originalId?: string | Array<string>): void {
380    let add = (it: string): void => {
381      let pid = parseInt(it ? it : id);
382      if (!isNaN(pid!)) {
383        if (!selection.processIds.includes(pid!)) {
384          selection.processIds.push(pid!);
385        }
386      }
387    };
388    if (Array.isArray(originalId)) {
389      originalId.forEach(item => {
390        add(item);
391      });
392    } else {
393      add(originalId!);
394    }
395  }
396  // @ts-ignore
397  getCollectRows(condition: (row: TraceRow<unknown>) => boolean): Array<TraceRow<unknown>> {
398    return this.favoriteChartListEL!.getCollectRows(condition);
399  }
400  // @ts-ignore
401  createPointEvent(it: TraceRow<unknown>): unknown {
402    // @ts-ignore
403    let event = this.eventMap[`${it.rowType}`];
404    if (event) {
405      return event;
406    } else {
407      if (it.rowType === TraceRow.ROW_TYPE_HEAP) {
408        event = it.name;
409      } else if (it.rowType === TraceRow.ROW_TYPE_HIPERF_CPU) {
410        event = 'HiPerf Cpu';
411        if (it.rowId === 'HiPerf-cpu-merge') {
412          event = 'HiPerf';
413        }
414      } else if (it.rowType === TraceRow.ROW_TYPE_FILE_SYSTEM) {
415        event = this.handleFileSystemType(it, event);
416      } else if (it.rowType === TraceRow.ROW_TYPE_STATE_ENERGY) {
417        event = it.name;
418      } else if (it.rowType === TraceRow.ROW_TYPE_VM_TRACKER) {
419        if (it.rowParentId === '') {
420          event = 'VM Tracker';
421        } else {
422          event = it.name;
423        }
424      } else if (it.rowType === TraceRow.ROW_TYPE_JANK) {
425        if (it.rowId === 'frameTime' || it.rowParentId === 'frameTime') {
426          event = 'FrameTimeLine';
427        } else if (it.hasAttribute('frame_type')) {
428          event = `${it.getAttribute('frame_type')}`;
429        }
430      } else if (it.rowType === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) {
431        event = 'DeliverInputEvent';
432        if (it.rowParentId === TraceRow.ROW_TYPE_DELIVER_INPUT_EVENT) {
433          event = 'DeliverInputEvent Func';
434        }
435      } else if (it.rowType === TraceRow.ROW_TYPE_TOUCH_EVENT_DISPATCH) {
436        event = 'TouchEventDispatch';
437        if (it.rowParentId === TraceRow.ROW_TYPE_TOUCH_EVENT_DISPATCH) {
438          event = 'TouchEventDispatch Func';
439        }
440      } else {
441        event = it.name;
442      }
443      return event;
444    }
445  }
446  // @ts-ignore
447  private handleFileSystemType(it: TraceRow<unknown>, event: unknown): void {
448    if (it.rowId === 'FileSystemLogicalWrite') {
449      event = 'FileSystem Logical Write';
450    } else if (it.rowId === 'FileSystemLogicalRead') {
451      event = 'FileSystem Logical Read';
452    } else if (it.rowId === 'FileSystemVirtualMemory') {
453      event = 'Page Fault Trace';
454    } else if (it.rowId!.startsWith('FileSystemDiskIOLatency')) {
455      event = 'Disk I/O Latency';
456      if (it.rowId!.startsWith('FileSystemDiskIOLatency-')) {
457        event = 'Bio Process';
458      }
459    } // @ts-ignore
460    return event;
461  }
462
463  refreshFavoriteCanvas(): void {
464    this.favoriteChartListEL!.refreshFavoriteCanvas();
465  }
466  // @ts-ignore
467  expansionAllParentRow(currentRow: TraceRow<unknown>): void {
468    // @ts-ignore
469    let parentRow = this.rowsEL!.querySelector<TraceRow<unknown>>(
470      `trace-row[row-id='${currentRow.rowParentId}'][folder][scene]`
471    );
472    if (parentRow) {
473      parentRow.expansion = true; // @ts-ignore
474      if (this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${parentRow.rowParentId}'][folder]`)) {
475        this.expansionAllParentRow(parentRow);
476      }
477    }
478  }
479
480  canvasPanelConfig(): void {
481    this.canvasPanel!.style.left = `${this.timerShaftEL!.canvas!.offsetLeft!}px`;
482    this.canvasPanel!.width = this.canvasPanel!.offsetWidth * dpr();
483    this.canvasPanel!.height = this.canvasPanel!.offsetHeight * dpr();
484    this.canvasPanelCtx!.scale(dpr(), dpr());
485  }
486
487  getScrollWidth(): number {
488    let overflowDiv = document.createElement('div');
489    overflowDiv.style.cssText = 'position:absolute; top:-2000px;width:200px; height:200px; overflow:hidden;';
490    let totalScrollDiv = document.body.appendChild(overflowDiv).clientWidth;
491    overflowDiv.style.overflowY = 'scroll';
492    let scrollDiv = overflowDiv.clientWidth;
493    document.body.removeChild(overflowDiv);
494    return totalScrollDiv - scrollDiv;
495  }
496
497  getShowTab(): Array<string> {
498    let tabpane = this.traceSheetEL!.shadowRoot!.querySelectorAll('lit-tabpane') as NodeListOf<LitTabpane>;
499    let showTab: Array<string> = [];
500    for (let pane of tabpane) {
501      if (pane.getAttribute('hidden') === 'false') {
502        showTab.push(pane.getAttribute('id') || '');
503      }
504    }
505    return showTab;
506  }
507
508  timerShaftELFlagClickHandler = (flag: FlagAlias): void => {
509    if (flag) {
510      setTimeout(() => {
511        if (TraceRow.rangeSelectObject) {
512          let showTab = this.getShowTab();
513          this.traceSheetEL?.displayTab<TabPaneFlag>('box-flag', ...showTab).setCurrentFlag(flag);
514        } else {
515          this.traceSheetEL?.displayTab<TabPaneFlag>('box-flag').setCurrentFlag(flag);
516        }
517      }, 100);
518    }
519  };
520
521  timerShaftELFlagChange = (hoverFlag: FlagAlias, selectFlag: FlagAlias): void => {
522    this.hoverFlag = hoverFlag;
523    this.selectFlag = selectFlag;
524    this.refreshCanvas(true, 'flagChange');
525  };
526
527  timerShaftELRangeClick = (sliceTime: SlicesTimeAlias): void => {
528    if (sliceTime) {
529      setTimeout(() => {
530        if (TraceRow.rangeSelectObject) {
531          let showTab = this.getShowTab();
532          this.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current', ...showTab).setCurrentSlicesTime(sliceTime);
533        } else {
534          this.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current').setCurrentSlicesTime(sliceTime);
535        }
536      }, 0);
537    }
538  };
539
540  timerShaftELRangeChange = (e: unknown): void => {
541    // @ts-ignore
542    TraceRow.range = e;
543    if (TraceRow.rangeSelectObject) {
544      TraceRow.rangeSelectObject!.startX = Math.floor(
545        ns2x(
546          TraceRow.rangeSelectObject!.startNS!,
547          TraceRow.range?.startNS!,
548          TraceRow.range?.endNS!,
549          TraceRow.range?.totalNS!,
550          this.timerShaftEL!.sportRuler!.frame
551        )
552      );
553      TraceRow.rangeSelectObject!.endX = Math.floor(
554        ns2x(
555          TraceRow.rangeSelectObject!.endNS!,
556          TraceRow.range?.startNS!,
557          TraceRow.range?.endNS!,
558          TraceRow.range?.totalNS!,
559          this.timerShaftEL!.sportRuler!.frame
560        )
561      );
562    }
563    if (!TraceRow.rangeSelectObject && !this.isSlectStruct()) {
564      SpAiAnalysisPage.selectChangeListener(TraceRow.range?.startNS!, TraceRow.range?.endNS!)
565    }
566    //在rowsEL显示范围内的 trace-row组件将收到时间区间变化通知
567    this.linkNodes.forEach((it) => {
568      it[0].x = ns2xByTimeShaft(it[0].ns, this.timerShaftEL!);
569      it[1].x = ns2xByTimeShaft(it[1].ns, this.timerShaftEL!);
570    });
571    this.invisibleRows.forEach((it) => (it.needRefresh = true));
572    this.visibleRows.forEach((it) => (it.needRefresh = true));
573    this.refreshCanvas(false, 'rangeChange');
574  };
575  isSlectStruct() {
576    return CpuStruct.selectCpuStruct ||
577      CpuStruct.wakeupBean ||
578      CpuFreqStruct.selectCpuFreqStruct ||
579      ThreadStruct.selectThreadStruct ||
580      ThreadStruct.isClickPrio ||
581      FuncStruct.selectFuncStruct ||
582      SpHiPerf.selectCpuStruct ||
583      CpuStateStruct.selectStateStruct ||
584      CpuFreqLimitsStruct.selectCpuFreqLimitsStruct ||
585      ClockStruct.selectClockStruct ||
586      IrqStruct.selectIrqStruct ||
587      JankStruct.selectJankStruct ||
588      HeapStruct.selectHeapStruct ||
589      AppStartupStruct.selectStartupStruct ||
590      SoStruct.selectSoStruct ||
591      HeapSnapshotStruct.selectSnapshotStruct ||
592      FrameSpacingStruct.selectFrameSpacingStruct ||
593      FrameAnimationStruct.selectFrameAnimationStruct ||
594      FrameDynamicStruct.selectFrameDynamicStruct ||
595      JsCpuProfilerStruct.selectJsCpuProfilerStruct ||
596      SnapshotStruct.selectSnapshotStruct ||
597      HiPerfCallChartStruct.selectStruct ||
598      AllAppStartupStruct.selectStartupStruct ||
599      LtpoStruct.selectLtpoStruct ||
600      HitchTimeStruct.selectHitchTimeStruct ||
601      SampleStruct.selectSampleStruct ||
602      PerfToolStruct.selectPerfToolStruct ||
603      GpuCounterStruct.selectGpuCounterStruct ||
604      DmaFenceStruct.selectDmaFenceStruct;
605  }
606  top: number = 0;
607  handler: number = -1;
608  rowsElOnScroll = (e: unknown): void => {
609    // @ts-ignore
610    const currentScrollY = e.target.scrollTop;
611    const deltaY = currentScrollY - this.prevScrollY;
612    this.linkNodes.forEach((itln) => {
613      if (itln[0].rowEL.collect) {
614        if (this.timerShaftEL?._checkExpand) {
615          itln[0].rowEL.translateY =
616            itln[0].rowEL.getBoundingClientRect().top - 195 + this.timerShaftEL._usageFoldHeight!;
617        } else {
618          itln[0].rowEL.translateY = itln[0].rowEL.getBoundingClientRect().top - 195;
619        }
620      } else {
621        itln[0].rowEL.translateY = itln[0].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
622      }
623      if (itln[1].rowEL.collect) {
624        if (this.timerShaftEL?._checkExpand) {
625          itln[1].rowEL.translateY =
626            itln[1].rowEL.getBoundingClientRect().top - 195 + this.timerShaftEL._usageFoldHeight!;
627        } else {
628          itln[1].rowEL.translateY = itln[1].rowEL.getBoundingClientRect().top - 195;
629        }
630      } else {
631        itln[1].rowEL.translateY = itln[1].rowEL.offsetTop - this.rowsPaneEL!.scrollTop;
632      }
633      itln[0].y = itln[0].rowEL.translateY + itln[0].offsetY;
634      itln[1].y = itln[1].rowEL.translateY + itln[1].offsetY;
635    });
636    this.hoverStructNull();
637    if (this.scrollTimer) {
638      // @ts-ignore
639      clearTimeout(this.scrollTimer);
640    }
641    this.scrollTimer = setTimeout(() => {
642      TraceRow.range!.refresh = true;
643      requestAnimationFrame(() => this.refreshCanvas(false));
644    }, 200);
645    spSystemTraceParentRowSticky(this, deltaY);
646    this.prevScrollY = currentScrollY;
647  };
648
649  private scrollTimer: unknown;
650
651  favoriteRowsElOnScroll = (e: unknown): void => {
652    this.rowsElOnScroll(e);
653  };
654
655  offset = 147;
656
657  getRowsContentHeight(): number {
658    // @ts-ignore
659    return [...this.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row:not([sleeping])')]
660      .map((it) => it.clientHeight)
661      .reduce((acr, cur) => acr + cur, 0);
662  }
663
664  // refresh main canvas and favorite canvas
665  refreshCanvas(cache: boolean, from?: string): void {
666    if (this.visibleRows.length === 0) {
667      return;
668    }
669    //clear main canvas
670    this.canvasPanelCtx!.clearRect(0, 0, this.canvasPanel!.offsetWidth, this.canvasPanel!.offsetHeight);
671    this.favoriteChartListEL!.clearRect();
672    //draw lines for main canvas
673    let rowsContentHeight = this.getRowsContentHeight();
674    let canvasHeight =
675      rowsContentHeight > this.canvasPanel!.clientHeight ? this.canvasPanel!.clientHeight : rowsContentHeight;
676    drawLines(this.canvasPanelCtx!, TraceRow.range?.xs || [], canvasHeight, this.timerShaftEL!.lineColor());
677    //draw lines for favorite canvas
678    this.favoriteChartListEL?.drawLines(TraceRow.range?.xs, this.timerShaftEL!.lineColor()); // chart list
679
680    //canvas translate
681    this.canvasPanel!.style.transform = `translateY(${this.rowsPaneEL!.scrollTop}px)`;
682    //draw trace row
683    this.visibleRows.forEach((v, i) => {
684      if (v.collect) {
685        v.translateY =
686          v.getBoundingClientRect().top -
687          this.timerShaftEL?.clientHeight! -
688          this.parentElement!.previousElementSibling!.clientHeight -
689          1;
690      } else {
691        v.translateY = v.offsetTop - this.rowsPaneEL!.scrollTop;
692      }
693      v.draw(cache);
694    });
695    this.drawAllLines();
696  }
697
698  drawWakeUpLine(): void {
699    //draw wakeup for main canvas
700    drawWakeUp(
701      this.canvasPanelCtx,
702      CpuStruct.wakeupBean,
703      TraceRow.range!.startNS,
704      TraceRow.range!.endNS,
705      TraceRow.range!.totalNS,
706      {
707        x: 0,
708        y: 0,
709        width: TraceRow.FRAME_WIDTH,
710        height: this.canvasPanel!.clientHeight!,
711      } as Rect
712    );
713    this.favoriteChartListEL?.drawWakeUp();
714    // draw wakeuplist for main canvas
715    for (let i = 0; i < SpSystemTrace.wakeupList.length; i++) {
716      if (i + 1 === SpSystemTrace.wakeupList.length) {
717        return;
718      }
719      drawWakeUpList(
720        this.canvasPanelCtx,
721        SpSystemTrace.wakeupList[i + 1],
722        TraceRow.range!.startNS,
723        TraceRow.range!.endNS,
724        TraceRow.range!.totalNS,
725        {
726          x: 0,
727          y: 0,
728          width: this.timerShaftEL!.canvas!.clientWidth,
729          height: this.canvasPanel!.clientHeight!,
730        } as Rect
731      );
732      this.favoriteChartListEL?.drawWakeUpList(SpSystemTrace.wakeupList[i + 1]);
733    }
734  }
735
736  drawAllLines(): void {
737    // draw flag line segment for canvas
738    drawFlagLineSegment(
739      this.canvasPanelCtx,
740      this.hoverFlag,
741      this.selectFlag,
742      {
743        x: 0,
744        y: 0,
745        width: this.timerShaftEL?.canvas?.clientWidth,
746        height: this.canvasPanel?.clientHeight,
747      } as Rect,
748      this.timerShaftEL!
749    );
750    this.favoriteChartListEL?.drawFlagLineSegment(this.hoverFlag, this.selectFlag, this.timerShaftEL!);
751    this.drawWakeUpLine();
752    //draw system logs line segment for canvas
753    drawLogsLineSegment(
754      this.canvasPanelCtx,
755      this.traceSheetEL?.systemLogFlag,
756      {
757        x: 0,
758        y: 0,
759        width: this.timerShaftEL?.canvas?.clientWidth,
760        height: this.canvasPanel?.clientHeight,
761      },
762      this.timerShaftEL!
763    );
764    this.favoriteChartListEL?.drawLogsLineSegment(this.traceSheetEL!.systemLogFlag, this.timerShaftEL!);
765
766    // Draw the connection curve
767    if (this.linkNodes && this.linkNodes.length > 0) {
768      drawLinkLines(
769        this.canvasPanelCtx!,
770        this.linkNodes,
771        this.timerShaftEL!,
772        false,
773        this.favoriteChartListEL!.clientHeight
774      );
775      this.favoriteChartListEL?.drawLinkLines(
776        this.linkNodes,
777        this.timerShaftEL!,
778        true,
779        this.favoriteChartListEL!.clientHeight
780      );
781    }
782    // draw prio curve
783    if (
784      ThreadStruct.isClickPrio &&
785      this.currentRow!.parentRowEl!.expansion &&
786      ThreadStruct.selectThreadStruct &&
787      ThreadStruct.contrast(ThreadStruct.selectThreadStruct, this.currentRow!.rowParentId, this.currentRow!.rowId)
788    ) {
789      let context: CanvasRenderingContext2D;
790      if (this.currentRow!.currentContext) {
791        context = this.currentRow!.currentContext;
792      } else {
793        context = this.currentRow!.collect ? this.canvasFavoritePanelCtx! : this.canvasPanelCtx!;
794      }
795      this.drawPrioCurve(context, this.currentRow!);
796    }
797  }
798
799  // draw prio curve
800  // @ts-ignore
801  drawPrioCurve(context: unknown, row: TraceRow<unknown>): void {
802    let curveDrawList: unknown = [];
803    let oldVal: number = -1;
804    // @ts-ignore
805    let threadFilter = row.dataListCache.filter((it: unknown) => it.state === 'Running'); //筛选状态是Running的数据
806    //计算每个点的坐标
807    // @ts-ignore
808    prioClickHandlerFun(ThreadStruct.prioCount, row, threadFilter, curveDrawList, oldVal);
809    //绘制曲线透明度设置1,根据计算的曲线坐标开始画图
810    // @ts-ignore
811    context.globalAlpha = 1;
812    // @ts-ignore
813    context.beginPath();
814    let x0;
815    let y0;
816    // @ts-ignore
817    if (curveDrawList[0] && curveDrawList[0].frame) {
818      // @ts-ignore
819      x0 = curveDrawList[0].frame.x;
820      // @ts-ignore
821      y0 = curveDrawList[0].curveFloatY;
822    }
823    // @ts-ignore
824    context!.moveTo(x0!, y0!);
825    // @ts-ignore
826    if (SpSystemTrace.isKeyUp || curveDrawList.length < 90) {
827      // @ts-ignore
828      for (let i = 0; i < curveDrawList.length - 1; i++) {
829        // @ts-ignore
830        let re = curveDrawList[i];
831        // @ts-ignore
832        let nextRe = curveDrawList[i + 1];
833        // @ts-ignore
834        drawThreadCurve(context, re, nextRe);
835      }
836      // @ts-ignore
837      context.closePath();
838      // @ts-ignore
839    } else if (!SpSystemTrace.isKeyUp && curveDrawList.length >= 90) {
840      let x;
841      let y;
842      // @ts-ignore
843      if (curveDrawList[curveDrawList.length - 1] && curveDrawList[curveDrawList.length - 1].frame) {
844        // @ts-ignore
845        x = curveDrawList[curveDrawList.length - 1].frame.x;
846        // @ts-ignore
847        y = curveDrawList[curveDrawList.length - 1].curveFloatY;
848      }
849      // @ts-ignore
850      context.lineWidth = 1;
851      // @ts-ignore
852      context.strokeStyle = '#ffc90e';
853      // @ts-ignore
854      context.lineCap = 'round';
855      // @ts-ignore
856      context.lineTo(x, y);
857      // @ts-ignore
858      context.stroke();
859    }
860  }
861
862  documentOnMouseDown = (ev: MouseEvent): void => spSystemTraceDocumentOnMouseDown(this, ev);
863
864  onContextMenuHandler = (e: Event): void => {
865    setTimeout(() => {
866      for (let key of this.keyPressMap.keys()) {
867        if (this.keyPressMap.get(key)) {
868          this.timerShaftEL?.stopWASD({ key: key });
869          this.keyPressMap.set(key, false);
870        }
871      }
872    }, 100);
873  };
874
875  documentOnMouseUp = (ev: MouseEvent): void => spSystemTraceDocumentOnMouseUp(this, ev);
876
877  cancelDrag(): void {
878    this.rangeSelect.drag = false;
879    this.rangeSelect.isMouseDown = false;
880    TraceRow.rangeSelectObject = {
881      startX: 0,
882      endX: 0,
883      startNS: 0,
884      endNS: 0,
885    };
886  }
887
888  documentOnMouseOut = (ev: MouseEvent): void => spSystemTraceDocumentOnMouseOut(this, ev);
889
890  keyPressMap: Map<string, boolean> = new Map([
891    ['w', false],
892    ['s', false],
893    ['a', false],
894    ['d', false],
895    ['f', false],
896  ]);
897
898  documentOnKeyDown = (ev: KeyboardEvent): void => spSystemTraceDocumentOnKeyDown(this, ev);
899
900  documentOnKeyPress = (ev: KeyboardEvent): void => spSystemTraceDocumentOnKeyPress(this, ev);
901
902  verticalScrollToRow(): void {
903    if (this.currentRow) {
904      //@ts-ignore
905      this.currentRow.scrollIntoViewIfNeeded();
906    }
907  }
908
909  setCurrentSlicesTime(): void {
910    if (CpuStruct.selectCpuStruct) {
911      this.currentSlicesTime.startTime = CpuStruct.selectCpuStruct.startTime;
912      this.currentSlicesTime.endTime = CpuStruct.selectCpuStruct.startTime! + CpuStruct.selectCpuStruct.dur!;
913    } else if (ThreadStruct.selectThreadStruct) {
914      this.currentSlicesTime.startTime = ThreadStruct.selectThreadStruct.startTime;
915      this.currentSlicesTime.endTime =
916        ThreadStruct.selectThreadStruct.startTime! + ThreadStruct.selectThreadStruct.dur!;
917    } else if (FuncStruct.selectFuncStruct) {
918      this.currentSlicesTime.startTime = FuncStruct.selectFuncStruct.startTs;
919      this.currentSlicesTime.endTime = FuncStruct.selectFuncStruct.startTs! + FuncStruct.selectFuncStruct.dur!;
920    } else if (IrqStruct.selectIrqStruct) {
921      this.currentSlicesTime.startTime = IrqStruct.selectIrqStruct.startNS;
922      this.currentSlicesTime.endTime = IrqStruct.selectIrqStruct.startNS! + IrqStruct.selectIrqStruct.dur!;
923    } else if (TraceRow.rangeSelectObject) {
924      this.currentRow = undefined;
925      if (TraceRow.rangeSelectObject.startNS && TraceRow.rangeSelectObject.endNS) {
926        this.currentSlicesTime.startTime = TraceRow.rangeSelectObject.startNS;
927        this.currentSlicesTime.endTime = TraceRow.rangeSelectObject.endNS;
928      }
929    } else if (JankStruct.selectJankStruct) {
930      this.currentSlicesTime.startTime = JankStruct.selectJankStruct.ts;
931      this.currentSlicesTime.endTime = JankStruct.selectJankStruct.ts! + JankStruct.selectJankStruct.dur!;
932    } else if (SampleStruct.selectSampleStruct) {
933      if (SampleStruct.selectSampleStruct.begin && SampleStruct.selectSampleStruct.end) {
934        this.currentSlicesTime.startTime =
935          SampleStruct.selectSampleStruct.begin - SampleStruct.selectSampleStruct.startTs!;
936        this.currentSlicesTime.endTime = SampleStruct.selectSampleStruct.end - SampleStruct.selectSampleStruct.startTs!;
937      }
938    } else if (GpuCounterStruct.selectGpuCounterStruct) {
939      this.currentSlicesTime.startTime =
940        GpuCounterStruct.selectGpuCounterStruct.startNS! - GpuCounterStruct.selectGpuCounterStruct.startTime!;
941      this.currentSlicesTime.endTime =
942        GpuCounterStruct.selectGpuCounterStruct.startNS! +
943        GpuCounterStruct.selectGpuCounterStruct.dur! -
944        GpuCounterStruct.selectGpuCounterStruct.startTime!;
945    } else if (AppStartupStruct.selectStartupStruct) {
946      this.currentSlicesTime.startTime = AppStartupStruct.selectStartupStruct.startTs;
947      this.currentSlicesTime.endTime = AppStartupStruct.selectStartupStruct.startTs! + AppStartupStruct.selectStartupStruct.dur!;
948    } else if (AllAppStartupStruct.selectStartupStruct) {
949      this.currentSlicesTime.startTime = AllAppStartupStruct.selectStartupStruct.startTs;
950      this.currentSlicesTime.endTime = AllAppStartupStruct.selectStartupStruct.startTs! + AllAppStartupStruct.selectStartupStruct.dur!;
951    } else if (PerfToolStruct.selectPerfToolStruct) {
952      this.currentSlicesTime.startTime = PerfToolStruct.selectPerfToolStruct.startTs;
953      this.currentSlicesTime.endTime = PerfToolStruct.selectPerfToolStruct.startTs! + PerfToolStruct.selectPerfToolStruct.dur!;
954    } else if (DmaFenceStruct.selectDmaFenceStruct) {
955      if (DmaFenceStruct.selectDmaFenceStruct.startTime && DmaFenceStruct.selectDmaFenceStruct.dur) {
956        this.currentSlicesTime.startTime = DmaFenceStruct.selectDmaFenceStruct.startTime;
957        this.currentSlicesTime.endTime = DmaFenceStruct.selectDmaFenceStruct.startTime + DmaFenceStruct.selectDmaFenceStruct.dur;
958      }
959    } else {
960      this.currentSlicesTime.startTime = 0;
961      this.currentSlicesTime.endTime = 0;
962    }
963  }
964
965  public setSLiceMark = (shiftKey: boolean): SlicesTime | null | undefined => {
966    const selectedStruct: unknown =
967      CpuStruct.selectCpuStruct ||
968      ThreadStruct.selectThreadStruct ||
969      TraceRow.rangeSelectObject ||
970      FuncStruct.selectFuncStruct ||
971      IrqStruct.selectIrqStruct ||
972      JankStruct.selectJankStruct ||
973      AppStartupStruct.selectStartupStruct ||
974      SoStruct.selectSoStruct ||
975      SampleStruct.selectSampleStruct ||
976      GpuCounterStruct.selectGpuCounterStruct ||
977      AllAppStartupStruct.selectStartupStruct ||
978      FrameAnimationStruct.selectFrameAnimationStruct ||
979      JsCpuProfilerStruct.selectJsCpuProfilerStruct ||
980      PerfToolStruct.selectPerfToolStruct ||
981      DmaFenceStruct.selectDmaFenceStruct;
982    this.calculateSlicesTime(selectedStruct, shiftKey);
983
984    return this.slicestime;
985  };
986
987  private calculateSlicesTime(selected: unknown, shiftKey: boolean): void {
988    if (selected) {
989      let startTs = 0;
990      // @ts-ignore
991      if (selected.begin && selected.end) {
992        // @ts-ignore
993        startTs = selected.begin - selected.startTs;
994        // @ts-ignore
995        let end = selected.end - selected.startTs;
996        this.slicestime = this.timerShaftEL?.setSlicesMark(startTs, end, shiftKey);
997        // @ts-ignore
998      } else if (selected.startNS && selected.dur) {
999        // @ts-ignore
1000        startTs = selected.startNS - selected.startTime;
1001        // @ts-ignore
1002        let end = selected.startNS + selected.dur - selected.startTime;
1003        this.slicestime = this.timerShaftEL?.setSlicesMark(startTs, end, shiftKey);
1004      } else {
1005        // @ts-ignore
1006        startTs = selected.startTs || selected.startTime || selected.startNS || selected.ts || 0;
1007        // @ts-ignore
1008        let dur = selected.dur || selected.totalTime || selected.endNS - selected.startNS || 0;
1009        this.slicestime = this.timerShaftEL?.setSlicesMark(startTs, startTs + dur, shiftKey);
1010      }
1011    } else {
1012      this.slicestime = this.timerShaftEL?.setSlicesMark();
1013    }
1014  }
1015
1016  stopWASD = (): void => {
1017    setTimeout((): void => {
1018      for (let key of this.keyPressMap.keys()) {
1019        if (this.keyPressMap.get(key)) {
1020          this.timerShaftEL?.stopWASD({ key: key });
1021          this.keyPressMap.set(key, false);
1022        }
1023      }
1024    }, 100);
1025  };
1026
1027  // 一直按着回车键的时候执行搜索功能
1028  continueSearch = (ev: KeyboardEvent): void => {
1029    if (ev.key === 'Enter') {
1030      if (ev.shiftKey) {
1031        this.dispatchEvent(
1032          new CustomEvent('trace-previous-data', {
1033            detail: { down: true },
1034            composed: false,
1035          })
1036        );
1037      } else {
1038        this.dispatchEvent(
1039          new CustomEvent('trace-next-data', {
1040            detail: { down: true },
1041            composed: false,
1042          })
1043        );
1044      }
1045    }
1046  };
1047
1048  documentOnKeyUp = (ev: KeyboardEvent): void => spSystemTraceDocumentOnKeyUp(this, ev);
1049
1050  /**
1051   * 根据传入的参数实现卡尺和旗子的快捷跳转
1052   * @param list 要跳转的数组
1053   * @param type 标记类型(卡尺和旗子)
1054   * @param direction 跳转方向(前一个/后一个)
1055   */
1056  MarkJump(list: Array<unknown>, type: string, direction: string, ev: KeyboardEvent): void {
1057    this.traceSheetEL = this.shadowRoot?.querySelector('.trace-sheet'); // @ts-ignore
1058    let find = list.find((it) => it.selected);
1059    if (!find) {
1060      // 如果当前没有选中的,就选中第一个
1061      // @ts-ignore
1062      list.forEach((it) => (it.selected = false));
1063      this.ifSliceInView(list[0], type, ev); // @ts-ignore
1064      list[0].selected = true;
1065    } else {
1066      for (let i = 0; i < list.length; i++) {
1067        // 将当前数组中选中的那条数据改为未选中
1068        // @ts-ignore
1069        if (list[i].selected) {
1070          // @ts-ignore
1071          list[i].selected = false;
1072          if (direction === 'previous') {
1073            if (i === 0) {
1074              // 如果当前选中的是第一个,就循环到最后一个上
1075              this.ifSliceInView(list[list.length - 1], type, ev); // @ts-ignore
1076              list[list.length - 1].selected = true;
1077              break;
1078            } else {
1079              // 选中当前的上一个
1080              this.ifSliceInView(list[i - 1], type, ev); // @ts-ignore
1081              list[i - 1].selected = true;
1082              break;
1083            }
1084          } else if (direction === 'next') {
1085            if (i === list.length - 1) {
1086              // 如果当前选中的是最后一个,就循环到第一个上
1087              this.ifSliceInView(list[0], type, ev); // @ts-ignore
1088              list[0].selected = true;
1089              break;
1090            } else {
1091              // 选中当前的下一个
1092              this.ifSliceInView(list[i + 1], type, ev); // @ts-ignore
1093              list[i + 1].selected = true;
1094              break;
1095            }
1096          }
1097        }
1098      }
1099    }
1100
1101    if (type === 'flag') {
1102      let currentPane = this.traceSheetEL?.displayTab<TabPaneFlag>('box-flag');
1103      list.forEach((flag, index) => {
1104        // @ts-ignore
1105        this.timerShaftEL!.sportRuler!.drawTriangle(flag.time, flag.type); // @ts-ignore
1106        if (flag.selected) {
1107          // 修改当前选中的旗子对应的表格中某行的背景
1108          currentPane!.setTableSelection(index + 1);
1109        }
1110      });
1111    } else if (type === 'slice') {
1112      this.refreshCanvas(true);
1113      let currentPane = this.traceSheetEL?.displayTab<TabPaneCurrent>('tabpane-current');
1114      list.forEach((slice, index) => {
1115        // @ts-ignore
1116        if (slice.selected) {
1117          // 修改当前选中的卡尺对应的表格中某行的背景
1118          currentPane!.setTableSelection(index + 1);
1119        }
1120      });
1121    }
1122  }
1123
1124  ifSliceInView(data: unknown, type: string, ev: KeyboardEvent): void {
1125    let timeRangeEndNS = this.timerShaftEL?.getRangeRuler()?.range.endNS;
1126    let timeRangeStartNS = this.timerShaftEL?.getRangeRuler()?.range.startNS;
1127    if (type === 'flag') {
1128      // @ts-ignore
1129      data.startTime = data.time; // @ts-ignore
1130      data.endTime = data.time;
1131    } // @ts-ignore
1132    let endTime = data.endTime; // @ts-ignore
1133    let startTime = data.startTime;
1134    if (endTime > timeRangeEndNS! || startTime < timeRangeStartNS!) {
1135      // @ts-ignore
1136      this.timerShaftEL!.documentOnKeyPress(ev, data);
1137      setTimeout(() => {
1138        this.timerShaftEL!.documentOnKeyUp(ev);
1139      }, 1000);
1140    }
1141  }
1142
1143  isMouseInSheet = (ev: MouseEvent): boolean => {
1144    this.isMousePointInSheet =
1145      this.traceSheetEL?.getAttribute('mode') !== 'hidden' &&
1146      ev.offsetX > this.traceSheetEL!.offsetLeft &&
1147      ev.offsetY > this.traceSheetEL!.offsetTop;
1148    return this.isMousePointInSheet;
1149  };
1150  // @ts-ignore
1151  favoriteChangeHandler = (row: TraceRow<unknown>): void => {
1152    info('favoriteChangeHandler', row.frame, row.offsetTop, row.offsetHeight);
1153  };
1154
1155  /**
1156   * 根据选择的traceRow 处理foler
1157   * @param currentRow 当前点击checkbox的row
1158   */
1159  // @ts-ignore
1160  setParentCheckStatus(currentRow: TraceRow<unknown>): void {
1161    if (currentRow.parentRowEl?.folder && currentRow.parentRowEl?.childrenList) {
1162      const parent = currentRow.parentRowEl;
1163      const childrenList = parent.childrenList;
1164      const selectList = [];
1165      const unSelectList = [];
1166      for (const child of childrenList) {
1167        if (child.checkType === '2') {
1168          selectList.push(child);
1169        } else {
1170          unSelectList.push(child);
1171        }
1172      }
1173      if (unSelectList.length === 0) {
1174        parent.setAttribute('check-type', '2');
1175        parent.rangeSelect = true;
1176        parent.checkBoxEL!.checked = true;
1177        parent.checkBoxEL!.indeterminate = false;
1178      } else if (selectList.length === 0) {
1179        parent.setAttribute('check-type', '0');
1180        parent.rangeSelect = false;
1181        parent.checkBoxEL!.checked = false;
1182        parent.checkBoxEL!.indeterminate = false;
1183      } else {
1184        parent.setAttribute('check-type', '1');
1185        parent.rangeSelect = false;
1186        parent.checkBoxEL!.checked = false;
1187        parent.checkBoxEL!.indeterminate = true;
1188      }
1189    }
1190  }
1191
1192  /**
1193   * 处理点击checkbox的逻辑
1194   * @param row 当前点击checkbox的row
1195   */
1196  // @ts-ignore
1197  selectChangeHandler = (row: TraceRow<unknown>): void => {
1198    this.setParentCheckStatus(row);
1199    // @ts-ignore
1200    const foldSelectParentRowList: Array<TraceRow<unknown>> = this.shadowRoot!.querySelectorAll<TraceRow<unknown>>("trace-row[check-type='1']");
1201    // @ts-ignore
1202    const foldSelectRowList: Array<TraceRow<unknown>> = [];
1203    // @ts-ignore
1204    foldSelectParentRowList.length && foldSelectParentRowList.forEach((item) => item.childrenList.filter((child: { checkType: string }) => child!.checkType === '2' && foldSelectRowList.push(child)));
1205    const rows = [
1206      ...foldSelectRowList,
1207      // @ts-ignore
1208      ...this.shadowRoot!.querySelectorAll<TraceRow<unknown>>("trace-row[check-type='2']"),
1209      ...this.favoriteChartListEL!.getAllSelectCollectRows(),
1210    ];
1211    this.isSelectClick = true;
1212    this.rangeSelect.rangeTraceRow = rows;
1213    this.rangeSelect.checkRowsName(this.rangeSelect.rangeTraceRow);
1214    // @ts-ignore
1215    let changeTraceRows: Array<TraceRow<unknown>> = [];
1216    if (this.rangeTraceRow!.length < rows.length) {
1217      // @ts-ignore
1218      rows!.forEach((currentTraceRow: TraceRow<unknown>) => {
1219        let changeFilter = this.rangeTraceRow!.filter(
1220          // @ts-ignore
1221          (prevTraceRow: TraceRow<unknown>) => prevTraceRow === currentTraceRow
1222        );
1223        if (changeFilter.length < 1) {
1224          changeTraceRows.push(currentTraceRow);
1225        }
1226      });
1227      if (changeTraceRows.length > 0) {
1228        // @ts-ignore
1229        changeTraceRows!.forEach((changeTraceRow: TraceRow<unknown>) => {
1230          let pointEvent = this.createPointEvent(changeTraceRow);
1231          SpStatisticsHttpUtil.addOrdinaryVisitAction({
1232            action: 'trace_row', // @ts-ignore
1233            event: pointEvent,
1234          });
1235        });
1236      }
1237    }
1238    this.rangeTraceRow = rows;
1239    let search = document.querySelector('body > sp-application')!.shadowRoot!.querySelector<LitSearch>('#lit-search');
1240    if (search?.isClearValue) {
1241      spSystemTraceDocumentOnMouseMoveMouseDown(this, search!);
1242    }
1243    this.rangeSelect.selectHandler?.(this.rangeSelect.rangeTraceRow, false);
1244  };
1245  inFavoriteArea: boolean | undefined;
1246  documentOnMouseMove = (ev: MouseEvent): void => spSystemTraceDocumentOnMouseMove(this, ev);
1247
1248  hoverStructNull(): SpSystemTrace {
1249    CpuStruct.hoverCpuStruct = undefined;
1250    CpuFreqStruct.hoverCpuFreqStruct = undefined;
1251    ThreadStruct.hoverThreadStruct = undefined;
1252    FuncStruct.hoverFuncStruct = undefined;
1253    ProcessMemStruct.hoverProcessMemStruct = undefined;
1254    HiPerfCpuStruct.hoverStruct = undefined;
1255    HiPerfProcessStruct.hoverStruct = undefined;
1256    HiPerfThreadStruct.hoverStruct = undefined;
1257    HiPerfEventStruct.hoverStruct = undefined;
1258    HiPerfReportStruct.hoverStruct = undefined;
1259    CpuStateStruct.hoverStateStruct = undefined;
1260    CpuAbilityMonitorStruct.hoverCpuAbilityStruct = undefined;
1261    DiskAbilityMonitorStruct.hoverDiskAbilityStruct = undefined;
1262    MemoryAbilityMonitorStruct.hoverMemoryAbilityStruct = undefined;
1263    NetworkAbilityMonitorStruct.hoverNetworkAbilityStruct = undefined;
1264    CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct = undefined;
1265    FpsStruct.hoverFpsStruct = undefined;
1266    ClockStruct.hoverClockStruct = undefined;
1267    IrqStruct.hoverIrqStruct = undefined;
1268    HeapStruct.hoverHeapStruct = undefined;
1269    JankStruct.hoverJankStruct = undefined;
1270    AppStartupStruct.hoverStartupStruct = undefined;
1271    SoStruct.hoverSoStruct = undefined;
1272    HeapSnapshotStruct.hoverSnapshotStruct = undefined;
1273    FrameAnimationStruct.hoverFrameAnimationStruct = undefined;
1274    FrameDynamicStruct.hoverFrameDynamicStruct = undefined;
1275    FrameSpacingStruct.hoverFrameSpacingStruct = undefined;
1276    JsCpuProfilerStruct.hoverJsCpuProfilerStruct = undefined;
1277    SnapshotStruct.hoverSnapshotStruct = undefined;
1278    HiPerfCallChartStruct.hoverPerfCallCutStruct = undefined;
1279    SampleStruct.hoverSampleStruct = undefined;
1280    PerfToolStruct.hoverPerfToolStruct = undefined;
1281    GpuCounterStruct.hoverGpuCounterStruct = undefined;
1282    DmaFenceStruct.hoverDmaFenceStruct = undefined;//清空hover slice
1283    this.tipEL!.style.display = 'none';
1284    return this;
1285  }
1286
1287  selectStructNull(): SpSystemTrace {
1288    CpuStruct.selectCpuStruct = undefined;
1289    CpuStruct.wakeupBean = null;
1290    CpuFreqStruct.selectCpuFreqStruct = undefined;
1291    ThreadStruct.selectThreadStruct = undefined;
1292    ThreadStruct.isClickPrio = false;
1293    FuncStruct.selectFuncStruct = undefined;
1294    SpHiPerf.selectCpuStruct = undefined;
1295    CpuStateStruct.selectStateStruct = undefined;
1296    CpuFreqLimitsStruct.selectCpuFreqLimitsStruct = undefined;
1297    ClockStruct.selectClockStruct = undefined;
1298    HangStruct.selectHangStruct = undefined;
1299    IrqStruct.selectIrqStruct = undefined;
1300    JankStruct.selectJankStruct = undefined;
1301    HeapStruct.selectHeapStruct = undefined;
1302    AppStartupStruct.selectStartupStruct = undefined;
1303    SoStruct.selectSoStruct = undefined;
1304    HeapSnapshotStruct.selectSnapshotStruct = undefined;
1305    FrameSpacingStruct.selectFrameSpacingStruct = undefined;
1306    FrameAnimationStruct.selectFrameAnimationStruct = undefined;
1307    FrameDynamicStruct.selectFrameDynamicStruct = undefined;
1308    JsCpuProfilerStruct.selectJsCpuProfilerStruct = undefined;
1309    SnapshotStruct.selectSnapshotStruct = undefined;
1310    HiPerfCallChartStruct.selectStruct = undefined;
1311    AllAppStartupStruct.selectStartupStruct = undefined;
1312    LtpoStruct.selectLtpoStruct = undefined;
1313    HitchTimeStruct.selectHitchTimeStruct = undefined;
1314    SampleStruct.selectSampleStruct = undefined;
1315    PerfToolStruct.selectPerfToolStruct = undefined;
1316    GpuCounterStruct.selectGpuCounterStruct = undefined;
1317    DmaFenceStruct.selectDmaFenceStruct = undefined;//清空选中slice
1318    return this;
1319  }
1320
1321  isWASDKeyPress(): boolean | undefined {
1322    return (
1323      this.keyPressMap.get('w') || this.keyPressMap.get('a') || this.keyPressMap.get('d') || this.keyPressMap.get('s')
1324    );
1325  }
1326
1327  documentOnClick = (ev: MouseEvent): void => spSystemTraceDocumentOnClick(this, ev);
1328
1329  clickEmptyArea(): void {
1330    this.queryAllTraceRow().forEach((it) => {
1331      it.checkType = '-1';
1332      it.rangeSelect = false;
1333    });
1334    this.rangeSelect.rangeTraceRow = [];
1335    TraceRow.rangeSelectObject = undefined;
1336    SpAiAnalysisPage.selectChangeListener(TraceRow.range?.startNS!, TraceRow.range?.endNS!);
1337    this.selectStructNull();
1338    this.wakeupListNull();
1339    this.observerScrollHeightEnable = false;
1340    this.selectFlag = null;
1341    this.timerShaftEL?.removeTriangle('inverted');
1342    //   如果鼠标在SportRuler区域不隐藏tab页
1343    if (!SportRuler.isMouseInSportRuler) {
1344      this.traceSheetEL?.setMode('hidden');
1345    }
1346    this.removeLinkLinesByBusinessType('task', 'thread', 'func');
1347    this.removeLinkLinesByBusinessType('task', 'thread', 'distributed');
1348    this.refreshCanvas(true, 'click empty');
1349    JankStruct.delJankLineFlag = true;
1350  }
1351
1352  //泳道图点击判定条件
1353  traceRowClickJudgmentConditions: Map<string, () => boolean> = new Map<string, () => boolean>([
1354    [TraceRow.ROW_TYPE_CPU, (): boolean => CpuStruct.hoverCpuStruct !== null && CpuStruct.hoverCpuStruct !== undefined],
1355    [
1356      TraceRow.ROW_TYPE_THREAD,
1357      (): boolean => ThreadStruct.hoverThreadStruct !== null && ThreadStruct.hoverThreadStruct !== undefined,
1358    ],
1359    [
1360      TraceRow.ROW_TYPE_FUNC,
1361      (): boolean => FuncStruct.hoverFuncStruct !== null && FuncStruct.hoverFuncStruct !== undefined,
1362    ],
1363    [
1364      TraceRow.ROW_TYPE_SAMPLE,
1365      (): boolean => SampleStruct.hoverSampleStruct !== null && SampleStruct.hoverSampleStruct !== undefined,
1366    ],
1367    [
1368      TraceRow.ROW_TYPE_GPU_COUNTER,
1369      (): boolean =>
1370        GpuCounterStruct.hoverGpuCounterStruct !== null && GpuCounterStruct.hoverGpuCounterStruct !== undefined,
1371    ],
1372    [
1373      TraceRow.ROW_TYPE_CPU_FREQ,
1374      (): boolean => CpuFreqStruct.hoverCpuFreqStruct !== null && CpuFreqStruct.hoverCpuFreqStruct !== undefined,
1375    ],
1376    [
1377      TraceRow.ROW_TYPE_CPU_STATE,
1378      (): boolean => CpuStateStruct.hoverStateStruct !== null && CpuStateStruct.hoverStateStruct !== undefined,
1379    ],
1380    [
1381      TraceRow.ROW_TYPE_CPU_FREQ_LIMIT,
1382      (): boolean =>
1383        CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct !== null &&
1384        CpuFreqLimitsStruct.hoverCpuFreqLimitsStruct !== undefined,
1385    ],
1386    [
1387      TraceRow.ROW_TYPE_CLOCK,
1388      (): boolean => ClockStruct.hoverClockStruct !== null && ClockStruct.hoverClockStruct !== undefined,
1389    ],
1390    [TraceRow.ROW_TYPE_IRQ, (): boolean => IrqStruct.hoverIrqStruct !== null && IrqStruct.hoverIrqStruct !== undefined],
1391    [
1392      TraceRow.ROW_TYPE_APP_STARTUP,
1393      (): boolean => AppStartupStruct.hoverStartupStruct !== null && AppStartupStruct.hoverStartupStruct !== undefined,
1394    ],
1395    [
1396      TraceRow.ROW_TYPE_ALL_APPSTARTUPS,
1397      (): boolean =>
1398        AllAppStartupStruct.hoverStartupStruct !== null && AllAppStartupStruct.hoverStartupStruct !== undefined,
1399    ],
1400    [
1401      TraceRow.ROW_TYPE_STATIC_INIT,
1402      (): boolean => SoStruct.hoverSoStruct !== null && SoStruct.hoverSoStruct !== undefined,
1403    ],
1404    [
1405      TraceRow.ROW_TYPE_JANK,
1406      (): boolean => JankStruct.hoverJankStruct !== null && JankStruct.hoverJankStruct !== undefined,
1407    ],
1408    [
1409      TraceRow.ROW_TYPE_HEAP,
1410      (): boolean => HeapStruct.hoverHeapStruct !== null && HeapStruct.hoverHeapStruct !== undefined,
1411    ],
1412    [
1413      TraceRow.ROW_TYPE_SYS_MEMORY_GPU_TOTAL,
1414      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1415    ],
1416    [
1417      TraceRow.ROW_TYPE_SYS_MEMORY_GPU_WINDOW,
1418      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1419    ],
1420    [
1421      TraceRow.ROW_TYPE_HEAP_SNAPSHOT,
1422      (): boolean =>
1423        HeapSnapshotStruct.hoverSnapshotStruct !== null && HeapSnapshotStruct.hoverSnapshotStruct !== undefined,
1424    ],
1425    [
1426      TraceRow.ROW_TYPE_FRAME_ANIMATION,
1427      (): boolean =>
1428        FrameAnimationStruct.hoverFrameAnimationStruct !== null &&
1429        FrameAnimationStruct.hoverFrameAnimationStruct !== undefined,
1430    ],
1431    [
1432      TraceRow.ROW_TYPE_FRAME_DYNAMIC,
1433      (): boolean =>
1434        FrameDynamicStruct.hoverFrameDynamicStruct !== null && FrameDynamicStruct.hoverFrameDynamicStruct !== undefined,
1435    ],
1436    [
1437      TraceRow.ROW_TYPE_FRAME_SPACING,
1438      (): boolean =>
1439        FrameSpacingStruct.hoverFrameSpacingStruct !== null && FrameSpacingStruct.hoverFrameSpacingStruct !== undefined,
1440    ],
1441    [
1442      TraceRow.ROW_TYPE_JS_CPU_PROFILER,
1443      (): boolean =>
1444        JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== null &&
1445        JsCpuProfilerStruct.hoverJsCpuProfilerStruct !== undefined,
1446    ],
1447    [
1448      TraceRow.ROW_TYPE_PURGEABLE_TOTAL_ABILITY,
1449      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1450    ],
1451    [
1452      TraceRow.ROW_TYPE_PURGEABLE_PIN_ABILITY,
1453      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1454    ],
1455    [
1456      TraceRow.ROW_TYPE_PURGEABLE_TOTAL_VM,
1457      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1458    ],
1459    [
1460      TraceRow.ROW_TYPE_PURGEABLE_PIN_VM,
1461      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1462    ],
1463    [
1464      TraceRow.ROW_TYPE_DMA_ABILITY,
1465      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1466    ],
1467    [
1468      TraceRow.ROW_TYPE_DMA_VMTRACKER,
1469      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1470    ],
1471    [
1472      TraceRow.ROW_TYPE_GPU_MEMORY_ABILITY,
1473      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1474    ],
1475    [
1476      TraceRow.ROW_TYPE_GPU_MEMORY_VMTRACKER,
1477      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1478    ],
1479    [
1480      TraceRow.ROW_TYPE_GPU_RESOURCE_VMTRACKER,
1481      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1482    ],
1483    [
1484      TraceRow.ROW_TYPE_VMTRACKER_SHM,
1485      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1486    ],
1487    [
1488      TraceRow.ROW_TYPE_VM_TRACKER_SMAPS,
1489      (): boolean => SnapshotStruct.hoverSnapshotStruct !== null && SnapshotStruct.hoverSnapshotStruct !== undefined,
1490    ],
1491    [
1492      TraceRow.ROW_TYPE_HANG,
1493      (): boolean => HangStruct.hoverHangStruct !== null && HangStruct.hoverHangStruct !== undefined,
1494    ],
1495  ]);
1496
1497  // @ts-ignore
1498  onClickHandler(clickRowType: string, row?: TraceRow<unknown>, entry?: unknown): void {
1499    spSystemTraceOnClickHandler(this, clickRowType, row as TraceRow<BaseStruct>, entry);
1500  }
1501
1502  makePoint(
1503    ts: number,
1504    dur: number,
1505    translateY: number,
1506    rowStruct: unknown,
1507    offsetY: number,
1508    business: string,
1509    lineType: LineType,
1510    isRight: boolean
1511  ): PairPoint {
1512    return {
1513      x: ns2xByTimeShaft(ts + dur, this.timerShaftEL!),
1514      y: translateY!,
1515      offsetY: offsetY,
1516      ns: ts + dur, // @ts-ignore
1517      rowEL: rowStruct!,
1518      isRight: isRight,
1519      business: business,
1520      lineType: lineType,
1521    };
1522  }
1523  // @ts-ignore
1524  drawTaskPollLine(row?: TraceRow<unknown>): void {
1525    spSystemTraceDrawTaskPollLine(this, row);
1526  }
1527  drawJankLine(
1528    endParentRow: unknown,
1529    selectJankStruct: JankStruct,
1530    data: unknown,
1531    isBinderClick: boolean = false
1532  ): void {
1533    spSystemTraceDrawJankLine(this, endParentRow, selectJankStruct, data, isBinderClick);
1534  }
1535
1536  drawDistributedLine(
1537    sourceData: FuncStruct,
1538    targetData: FuncStruct,
1539    selectFuncStruct: FuncStruct,
1540  ): void {
1541    spSystemTraceDrawDistributedLine(this, sourceData, targetData, selectFuncStruct);
1542  }
1543
1544  drawThreadLine(endParentRow: unknown, selectThreadStruct: ThreadStruct | undefined, data: unknown): void {
1545    spSystemTraceDrawThreadLine(this, endParentRow, selectThreadStruct, data);
1546  }
1547
1548  drawFuncLine(endParentRow: unknown, selectFuncStruct: FuncStruct | undefined, data: unknown, binderTid: Number): void {
1549    spSystemTraceDrawFuncLine(this, endParentRow, selectFuncStruct, data, binderTid);
1550  }
1551
1552  getStartRow(selectRowId: number | undefined, collectList: unknown[]): unknown {
1553    let startRow = this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(
1554      `trace-row[row-id='${selectRowId}'][row-type='thread']`
1555    );
1556    if (!startRow) {
1557      for (let collectChart of collectList) {
1558        // @ts-ignore
1559        if (collectChart.rowId === selectRowId?.toString() && collectChart.rowType === 'thread') {
1560          // @ts-ignore
1561          startRow = collectChart;
1562          break;
1563        }
1564      }
1565    }
1566    return startRow;
1567  }
1568
1569  calculateStartY(startRow: unknown, pid: number | undefined, selectFuncStruct?: FuncStruct): [number, unknown, number] {
1570    // @ts-ignore
1571    let startY = startRow ? startRow!.translateY! : 0;
1572    let startRowEl = startRow;
1573    let startOffSetY = selectFuncStruct ? 20 * (0.5 + Number(selectFuncStruct.depth)) : 20 * 0.5;
1574    // @ts-ignore
1575    const startParentRow = startRow ? this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(`trace-row[row-id='${startRow.rowParentId}'][folder]`) : this.shadowRoot?.querySelector<TraceRow<ThreadStruct>>(
1576      `trace-row[row-id='${pid}'][folder]`
1577    );
1578    const expansionFlag = this.collectionHasThread(startRow);
1579    if (startParentRow && !startParentRow.expansion && expansionFlag) {
1580      startY = startParentRow.translateY!;
1581      startRowEl = startParentRow;
1582      startOffSetY = selectFuncStruct ? 10 * (0.5 + Number(selectFuncStruct.depth)) : 10 * 0.5;
1583    }
1584    return [startY, startRowEl, startOffSetY];
1585  }
1586
1587  calculateEndY(endParentRow: unknown, endRowStruct: unknown, data?: unknown): [number, unknown, number] {
1588    // @ts-ignore
1589    let endY = endRowStruct.translateY!;
1590    let endRowEl = endRowStruct;
1591    // @ts-ignore
1592    let endOffSetY = data ? 20 * (0.5 + Number(data.depth)) : 20 * 0.5;
1593    const expansionFlag = this.collectionHasThread(endRowStruct);
1594    // @ts-ignore
1595    if (!endParentRow.expansion && expansionFlag) {
1596      // @ts-ignore
1597      endY = endParentRow.translateY!;
1598      endRowEl = endParentRow;
1599      // @ts-ignore
1600      endOffSetY = data ? 10 * (0.5 + Number(data.depth)) : 10 * 0.5;
1601    }
1602    return [endY, endRowEl, endOffSetY];
1603  }
1604
1605  collectionHasThread(threadRow: unknown): boolean {
1606    const collectList = this.favoriteChartListEL!.getCollectRows();
1607    for (let item of collectList!) {
1608      // @ts-ignore
1609      if (threadRow && item.rowId === threadRow.rowId && item.rowType === threadRow.rowType) {
1610        return false;
1611      }
1612    }
1613    return true;
1614  }
1615
1616  translateByMouseMove(ev: MouseEvent): void {
1617    ev.preventDefault();
1618    let offset = 0;
1619    if (this.offsetMouse === 0) {
1620      this.offsetMouse = ev.clientX;
1621      offset = ev.clientX - this.mouseCurrentPosition;
1622    } else {
1623      offset = ev.clientX - this.offsetMouse;
1624    }
1625    this.offsetMouse = ev.clientX;
1626    const rangeRuler = this.timerShaftEL?.getRangeRuler()!;
1627    rangeRuler.translate(offset);
1628  }
1629
1630  private eventListener(): void {
1631    /**
1632     * 监听时间轴区间变化
1633     */
1634    this.timerShaftEL!.rangeChangeHandler = this.timerShaftELRangeChange;
1635    this.timerShaftEL!.rangeClickHandler = this.timerShaftELRangeClick;
1636    this.timerShaftEL!.flagChangeHandler = this.timerShaftELFlagChange;
1637    this.timerShaftEL!.flagClickHandler = this.timerShaftELFlagClickHandler;
1638    /**
1639     * 监听rowsEL的滚动时间,刷新可见区域的trace-row组件的时间区间(将触发trace-row组件重绘)
1640     */
1641    this.rowsPaneEL?.addEventListener('scroll', this.rowsElOnScroll, {
1642      passive: true,
1643    });
1644    this.favoriteChartListEL?.addEventListener('scroll', this.favoriteRowsElOnScroll, {
1645      passive: true,
1646    });
1647    /**
1648     * 监听document的mousemove事件 坐标通过换算后找到当前鼠标所在的trace-row组件,将坐标传入
1649     */
1650    this.addEventListener('mousemove', this.documentOnMouseMove);
1651    this.addEventListener('click', this.documentOnClick);
1652    this.addEventListener('mousedown', this.documentOnMouseDown);
1653    this.addEventListener('mouseup', this.documentOnMouseUp);
1654    this.addEventListener('mouseout', this.documentOnMouseOut);
1655    document.addEventListener('keydown', this.documentOnKeyDown);
1656    document.addEventListener('keypress', this.documentOnKeyPress);
1657    document.addEventListener('keyup', this.documentOnKeyUp);
1658    document.addEventListener('contextmenu', this.onContextMenuHandler);
1659    this.wheelListener();
1660  }
1661
1662  private subRecordExportListener(): void {
1663    window.subscribe(window.SmartEvent.UI.ExportRecord, (params) => {
1664      let range = this.timerShaftEL?.rangeRuler?.range;
1665      if (range) {
1666        let expandRows =
1667          Array.from(this.rowsEL!.querySelectorAll<TraceRow<BaseStruct>>('trace-row[folder][expansion]')) || [];
1668        let data = JSON.stringify({
1669          leftNS: range.startNS,
1670          rightNS: range.endNS,
1671          G1: this.favoriteChartListEL!.getCollectRowsInfo('1'),
1672          G2: this.favoriteChartListEL!.getCollectRowsInfo('2'),
1673          expand: expandRows.map((row) => {
1674            return {
1675              type: row.rowType,
1676              name: row.name,
1677              id: row.rowId,
1678            };
1679          }),
1680          scrollTop: this.rowsEL!.scrollTop,
1681          favoriteScrollTop: this.favoriteChartListEL!.scrollTop,
1682          //下载时存旗帜的信息
1683          drawFlag: this.timerShaftEL!.sportRuler!.flagList,
1684          //下载时存M和shiftM的信息
1685          markFlag: this.timerShaftEL!.sportRuler!.slicesTimeList,
1686        });
1687        this.downloadRecordFile(data).then(() => { });
1688      }
1689    });
1690  }
1691
1692  private async downloadRecordFile(jsonStr: string): Promise<void> {
1693    let a = document.createElement('a');
1694    let buffer = await readTraceFileBuffer();
1695    if (buffer) {
1696      let str = `MarkPositionJSON->${jsonStr}\n`;
1697      let mark = new Blob([str]);
1698      let markBuf = await mark.arrayBuffer();
1699      a.href = URL.createObjectURL(new Blob([`${markBuf.byteLength}`, mark, buffer])); // @ts-ignore
1700      a.download = (window as unknown).traceFileName || `${new Date().getTime()}`;
1701      a.click();
1702    }
1703    window.publish(window.SmartEvent.UI.Loading, { loading: false, text: 'Downloading trace file with mark' });
1704  }
1705
1706  private subRecordImportListener(): void {
1707    //@ts-ignore
1708    window.subscribe(window.SmartEvent.UI.ImportRecord, (data: string) => {
1709      let record = JSON.parse(data);
1710      if (record.leftNS !== undefined && record.rightNS !== undefined) {
1711        this.favoriteChartListEL?.removeAllCollectRow();
1712        let currentGroup = this.currentCollectGroup;
1713        if (record.G1) {
1714          this.currentCollectGroup = '1';
1715          this.restoreRecordCollectRows(record.G1);
1716        }
1717        if (record.G2) {
1718          this.currentCollectGroup = '2';
1719          this.restoreRecordCollectRows(record.G2);
1720        }
1721        this.restoreRecordExpandAndTimeRange(record);
1722        this.currentCollectGroup = currentGroup;
1723        if (record.drawFlag !== undefined) {
1724          this.timerShaftEL!.sportRuler!.flagList = record.drawFlag;//获取下载时存的旗帜信息
1725          this.selectFlag = this.timerShaftEL!.sportRuler!.flagList.find((it) => it.selected);//绘制被选中旗帜对应的线
1726        }
1727        if (record.markFlag !== undefined) {
1728          this.timerShaftEL!.sportRuler!.slicesTimeList = record.markFlag;//获取下载时存的M键信息
1729        }
1730        TraceRow.range!.refresh = true;
1731        this.refreshCanvas(true);
1732        this.restoreRecordScrollTop(record.scrollTop, record.favoriteScrollTop);
1733      }
1734    });
1735  }
1736
1737  private restoreRecordExpandAndTimeRange(record: unknown): void {
1738    // @ts-ignore
1739    if (record.expand) {
1740      let expandRows = // @ts-ignore
1741        Array.from(this.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row[folder][expansion]')) || [];
1742      // @ts-ignore
1743      let expands: Array<unknown> = record.expand;
1744      //关闭不在记录中的父泳道
1745      for (let expandRow of expandRows) {
1746        if (
1747          !expands.includes(
1748            (it: unknown) =>
1749              // @ts-ignore
1750              it.id === expandRow.rowId && it.name === expandRow.name && it.type === expandRow.rowType
1751          )
1752        ) {
1753          expandRow.expansion = false;
1754        }
1755      }
1756      //展开记录的泳道
1757      // @ts-ignore
1758      for (let it of record.expand) {
1759        // @ts-ignore
1760        let traceRow = this.rowsEL!.querySelector<TraceRow<unknown>>(
1761          `trace-row[folder][row-id='${it.id}'][row-type='${it.type}']`
1762        );
1763        if (traceRow && !traceRow.expansion) {
1764          traceRow.expansion = true;
1765        }
1766      }
1767    }
1768    // @ts-ignore
1769    this.timerShaftEL?.setRangeNS(record.leftNS, record.rightNS);
1770  }
1771
1772  private restoreRecordScrollTop(mainScrollTop: number, favoriteScrollTop: number): void {
1773    if (mainScrollTop && mainScrollTop > 0) {
1774      this.rowsPaneEL!.scroll({
1775        top: mainScrollTop,
1776        left: 0,
1777        behavior: 'smooth',
1778      });
1779    }
1780    if (favoriteScrollTop && favoriteScrollTop > 0) {
1781      this.favoriteChartListEL?.scroll({
1782        top: favoriteScrollTop,
1783        left: 0,
1784        behavior: 'smooth',
1785      });
1786    }
1787  }
1788
1789  private restoreRecordCollectRows(group: Array<unknown>): void {
1790    group.forEach((it: unknown) => {
1791      // @ts-ignore
1792      let traceRow: TraceRow<unknown> | undefined | null = this.rowsEL!.querySelector<TraceRow<unknown>>( // @ts-ignore
1793        `trace-row[row-id='${it.id}'][row-type='${it.type}']`
1794      );
1795      if (traceRow === null || traceRow === undefined) {
1796        // @ts-ignore
1797        if (it.parents.length > 0) {
1798          // @ts-ignore
1799          let rootFolder = it.parents[0]; // @ts-ignore
1800          let folderRow: TraceRow<unknown> | undefined | null = this.rowsEL!.querySelector<TraceRow<unknown>>(
1801            `trace-row[row-id='${rootFolder.id}'][row-type='${rootFolder.type}']`
1802          );
1803          if (folderRow) {
1804            if (!folderRow!.expansion) {
1805              folderRow!.expansion = true;
1806            } // @ts-ignore
1807            for (let i = 1; i < it.parents.length; i++) {
1808              folderRow = folderRow!.childrenList.find(
1809                // @ts-ignore
1810                (child) => child.rowId === it.parents[i].id && child.rowType === it.parents[i].type
1811              );
1812              if (!folderRow!.expansion) {
1813                folderRow!.expansion = true;
1814              }
1815            }
1816          }
1817          if (folderRow) {
1818            // @ts-ignore
1819            traceRow = folderRow.childrenList.find((child) => child.rowId === it.id && child.rowType === it.type);
1820          }
1821        }
1822      }
1823      if (traceRow) {
1824        traceRow.collectEL?.click();
1825      }
1826    });
1827  }
1828
1829  private wheelListener(): void {
1830    document.addEventListener(
1831      'wheel',
1832      (e): void => {
1833        if (e.ctrlKey) {
1834          if (e.deltaY > 0) {
1835            e.preventDefault();
1836            e.stopPropagation();
1837            let eventS = new KeyboardEvent('keypress', {
1838              key: 's',
1839              code: '83',
1840              keyCode: 83,
1841            });
1842            this.timerShaftEL!.documentOnKeyPress(eventS);
1843            setTimeout(() => this.timerShaftEL!.documentOnKeyUp(eventS), 200);
1844          }
1845          if (e.deltaY < 0) {
1846            e.preventDefault();
1847            e.stopPropagation();
1848            let eventW = new KeyboardEvent('keypress', {
1849              key: 'w',
1850              code: '87',
1851              keyCode: 87,
1852            });
1853            this.timerShaftEL!.documentOnKeyPress(eventW);
1854            setTimeout(() => this.timerShaftEL!.documentOnKeyUp(eventW), 200);
1855          }
1856        }
1857      },
1858      { passive: false }
1859    );
1860  }
1861
1862  connectedCallback(): void {
1863    this.initPointToEvent();
1864    this.eventListener();
1865    this.subRecordExportListener();
1866    this.subRecordImportListener();
1867    /**
1868     * 泳道图中添加ctrl+鼠标滚轮事件,对泳道图进行放大缩小。
1869     * 鼠标滚轮事件转化为键盘事件,keyPress和keyUp两个事件需要配合使用,
1870     * 否则泳道图会一直放大或一直缩小。
1871     * setTimeout()函数中的时间参数可以控制鼠标滚轮的频率。
1872     */
1873    SpApplication.skinChange2 = (val: boolean): void => {
1874      this.timerShaftEL?.render();
1875    };
1876    window.subscribe(window.SmartEvent.UI.UploadSOFile, (data): void => {
1877      this.chartManager?.importSoFileUpdate().then(() => {
1878        window.publish(window.SmartEvent.UI.Loading, { loading: false, text: 'Import So File' });
1879        let updateCanvas = this.traceSheetEL?.updateRangeSelect();
1880        if (updateCanvas) {
1881          this.refreshCanvas(true);
1882        }
1883      });
1884    });
1885    window.subscribe(window.SmartEvent.UI.KeyPath, (data): void => {
1886      this.invisibleRows.forEach((it) => (it.needRefresh = true));
1887      this.visibleRows.forEach((it) => (it.needRefresh = true)); //@ts-ignore
1888      if (data.length === 0) {
1889        // clear
1890        SpSystemTrace.keyPathList = [];
1891        this.refreshCanvas(false);
1892      } else {
1893        // draw
1894        //@ts-ignore
1895        queryCpuKeyPathData(data).then((res): void => {
1896          SpSystemTrace.keyPathList = res;
1897          this.refreshCanvas(false);
1898        });
1899      }
1900    });
1901    window.subscribe(window.SmartEvent.UI.CheckALL, (data): void => {
1902      //@ts-ignore
1903      this.getCollectRows((row) => row.rowParentId === data.rowId).forEach((it) => {
1904        //@ts-ignore
1905        it.checkType = data.isCheck ? '2' : '0';
1906      });
1907    });
1908    window.subscribe(window.SmartEvent.UI.HoverNull, () => this.hoverStructNull());
1909    this.subscribeBottomTabVisibleEvent();
1910  }
1911
1912  public scrollH: number = 0;
1913
1914  subscribeBottomTabVisibleEvent(): void {
1915    //@ts-ignore
1916    window.subscribe(window.SmartEvent.UI.ShowBottomTab, (data: { show: number; delta: number }): void => {
1917      if (data.show === 1) {
1918        //显示底部tab
1919        this.scrollH = this.rowsEL!.scrollHeight;
1920      } else {
1921        // 底部 tab 为 最小化 或者隐藏 时候
1922        if (this.rowsEL!.scrollHeight > this.scrollH) {
1923          this.rowsEL!.scrollTop = this.rowsEL!.scrollTop - data.delta;
1924        }
1925      }
1926    });
1927  }
1928  // @ts-ignore
1929  favoriteAreaSearchHandler(row: TraceRow<unknown>): void {
1930    if (this.timerShaftEL!.collecBtn!.hasAttribute('close')) {
1931      this.timerShaftEL!.collecBtn!.removeAttribute('close');
1932      this.favoriteChartListEL!.showCollectArea();
1933    }
1934    this.favoriteChartListEL?.expandSearchRowGroup(row);
1935  }
1936
1937  scrollToProcess(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true): void {
1938    let id = Utils.getDistributedRowId(rowId);
1939    let parentId = Utils.getDistributedRowId(rowParentId);
1940    let traceRow = // @ts-ignore
1941      this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${id}'][row-type='${rowType}']`) ||
1942      this.favoriteChartListEL!.getCollectRow((row) => row.rowId === id && row.rowType === rowType);
1943    if (traceRow?.collect) {
1944      this.favoriteChartListEL!.scroll({
1945        top:
1946          (traceRow?.offsetTop || 0) -
1947          this.favoriteChartListEL!.getCanvas()!.offsetHeight +
1948          (traceRow?.offsetHeight || 0),
1949        left: 0,
1950        behavior: smooth ? 'smooth' : undefined,
1951      });
1952    } else {
1953      // @ts-ignore
1954      let row = this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${parentId}'][folder]`);
1955      if (row && !row.expansion) {
1956        row.expansion = true;
1957      }
1958      if (traceRow && traceRow.offsetTop >= 0 && traceRow.offsetHeight >= 0) {
1959        this.rowsPaneEL!.scroll({
1960          top: (traceRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + (traceRow?.offsetHeight || 0),
1961          left: 0,
1962          behavior: smooth ? 'smooth' : undefined,
1963        });
1964      }
1965    }
1966  }
1967
1968  scrollToDepth(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true, depth: number): void {
1969    let rootRow = // @ts-ignore
1970      this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${rowId}'][row-type='${rowType}']`) ||
1971      this.favoriteChartListEL!.getCollectRow((row) => row.rowId === rowId && row.rowType === rowType);
1972    if (rootRow && rootRow!.collect) {
1973      this.favoriteAreaSearchHandler(rootRow);
1974      rootRow.expandFunc(rootRow, this);
1975      if (!this.isInViewport(rootRow)) {
1976        setTimeout(() => {
1977          rootRow!.scrollIntoView({ behavior: 'smooth' });
1978        }, 500);
1979      }
1980    } else {
1981      // @ts-ignore
1982      let row = this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${rowParentId}'][folder]`);
1983      if (row && !row.expansion) {
1984        row.expansion = true;
1985      }
1986      if (rootRow) {
1987        rootRow.expandFunc(rootRow, this);
1988      }
1989      setTimeout(() => {
1990        rootRow!.scrollIntoView({ behavior: 'smooth', block: 'center' });
1991      }, 500);
1992    }
1993  }
1994
1995  isInViewport(e: unknown): boolean {
1996    // @ts-ignore
1997    const rect = e.getBoundingClientRect();
1998    return (
1999      rect.top >= 0 &&
2000      rect.left >= 0 &&
2001      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
2002      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
2003    );
2004  }
2005
2006  scrollToFunction(rowId: string, rowParentId: string, rowType: string, smooth: boolean = true): void {
2007    let id = Utils.getDistributedRowId(rowId);
2008    let parentId = Utils.getDistributedRowId(rowParentId);
2009    let condition = `trace-row[row-id='${id}'][row-type='${rowType}'][row-parent-id='${parentId}']`;
2010    let rootRow = // @ts-ignore
2011      this.rowsEL!.querySelector<TraceRow<unknown>>(condition) ||
2012      this.favoriteChartListEL!.getCollectRow((row) => {
2013        return row.rowId === id && row.rowType === rowType && row.rowParentId === parentId;
2014      });
2015    if (rootRow?.collect) {
2016      this.favoriteAreaSearchHandler(rootRow);
2017      this.favoriteChartListEL!.scroll({
2018        top:
2019          (rootRow?.offsetTop || 0) -
2020          this.favoriteChartListEL!.getCanvas()!.offsetHeight +
2021          (rootRow?.offsetHeight || 0),
2022        left: 0,
2023        behavior: smooth ? 'smooth' : undefined,
2024      });
2025    } else {
2026      // @ts-ignore
2027      let row = this.rowsEL!.querySelector<TraceRow<unknown>>(`trace-row[row-id='${rowParentId}'][folder]`);
2028      if (row && !row.expansion) {
2029        row.expansion = true;
2030      }
2031      if (rootRow && rootRow.offsetTop >= 0 && rootRow.offsetHeight >= 0) {
2032        this.rowsPaneEL!.scroll({
2033          top: (rootRow?.offsetTop || 0) - this.canvasPanel!.offsetHeight + 20,
2034          left: 0,
2035          behavior: smooth ? 'smooth' : undefined,
2036        });
2037      }
2038    }
2039  }
2040
2041  disconnectedCallback(): void {
2042    this.timerShaftEL?.removeEventListener('range-change', this.timerShaftELRangeChange);
2043    this.rowsPaneEL?.removeEventListener('scroll', this.rowsElOnScroll);
2044    this.favoriteChartListEL?.removeEventListener('scroll', this.favoriteRowsElOnScroll);
2045    this.removeEventListener('mousemove', this.documentOnMouseMove);
2046    this.removeEventListener('click', this.documentOnClick);
2047    this.removeEventListener('mousedown', this.documentOnMouseDown);
2048    this.removeEventListener('mouseup', this.documentOnMouseUp);
2049    this.removeEventListener('mouseout', this.documentOnMouseOut);
2050    document.removeEventListener('keypress', this.documentOnKeyPress);
2051    document.removeEventListener('keydown', this.documentOnKeyDown);
2052    document.removeEventListener('keyup', this.documentOnKeyUp);
2053    document.removeEventListener('contextmenu', this.onContextMenuHandler);
2054    window.unsubscribe(window.SmartEvent.UI.SliceMark, this.sliceMarkEventHandler.bind(this));
2055  }
2056
2057  sliceMarkEventHandler(ev: unknown): void {
2058    SpSystemTrace.sliceRangeMark = ev; // @ts-ignore
2059    let startNS = ev.timestamp - (window as unknown).recordStartNS; // @ts-ignore
2060    let endNS = ev.maxDuration + startNS;
2061    TraceRow.rangeSelectObject = {
2062      startX: 0,
2063      startNS: startNS,
2064      endNS: endNS,
2065      endX: 0,
2066    };
2067    window.publish(window.SmartEvent.UI.MenuTrace, {});
2068    window.publish(window.SmartEvent.UI.TimeRange, {
2069      // @ts-ignore
2070      startNS: startNS - ev.maxDuration, // @ts-ignore
2071      endNS: endNS + ev.maxDuration,
2072    });
2073    this.queryAllTraceRow().forEach((it) => (it.checkType = '-1'));
2074    this.rangeSelect.rangeTraceRow = [];
2075    this.selectStructNull();
2076    this.wakeupListNull();
2077    this.traceSheetEL?.setMode('hidden');
2078    this.removeLinkLinesByBusinessType('janks');
2079    this.removeLinkLinesByBusinessType('distributed');
2080    TraceRow.range!.refresh = true;
2081    this.refreshCanvas(false, 'slice mark event');
2082  }
2083
2084  loadDatabaseUrl(
2085    url: string,
2086    progress: Function,
2087    complete?: ((res: { status: boolean; msg: string }) => void) | undefined
2088  ): void {
2089    this.observerScrollHeightEnable = false;
2090    this.init({ url: url }, '', progress, false).then((res) => {
2091      if (complete) {
2092        // @ts-ignore
2093        complete(res);
2094        window.publish(window.SmartEvent.UI.MouseEventEnable, {
2095          mouseEnable: true,
2096        });
2097      }
2098    });
2099  }
2100
2101  loadDatabaseArrayBuffer(
2102    buf: ArrayBuffer,
2103    thirdPartyWasmConfigUrl: string,
2104    progress: (name: string, percent: number) => void,
2105    isDistributed: boolean,
2106    complete?: ((res: { status: boolean; msg: string }) => void) | undefined,
2107    buf2?: ArrayBuffer,
2108    fileName1?: string,
2109    fileName2?: string
2110  ): void {
2111    this.observerScrollHeightEnable = false;
2112    if (isDistributed) {
2113      this.timerShaftEL?.setAttribute('distributed', '');
2114    } else {
2115      this.timerShaftEL?.removeAttribute('distributed');
2116    }
2117    this.init({ buf, buf2, fileName1, fileName2 }, thirdPartyWasmConfigUrl, progress, isDistributed).then((res) => {
2118      // @ts-ignore
2119      this.rowsEL?.querySelectorAll('trace-row').forEach((it: unknown) => this.observer.observe(it));
2120      if (complete) {
2121        // @ts-ignore
2122        complete(res);
2123        window.publish(window.SmartEvent.UI.MouseEventEnable, {
2124          mouseEnable: true,
2125        });
2126      }
2127    });
2128  }
2129
2130  loadSample = async (ev: File): Promise<void> => {
2131    this.observerScrollHeightEnable = false;
2132    await this.initSample(ev); // @ts-ignore
2133    this.rowsEL?.querySelectorAll('trace-row').forEach((it: unknown) => this.observer.observe(it));
2134    window.publish(window.SmartEvent.UI.MouseEventEnable, {
2135      mouseEnable: true,
2136    });
2137  };
2138
2139  initSample = async (ev: File): Promise<void> => {
2140    this.rowsPaneEL!.scroll({
2141      top: 0,
2142      left: 0,
2143    });
2144    this.chartManager?.initSample(ev).then((): void => {
2145      this.loadTraceCompleted = true; // @ts-ignore
2146      this.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((it): void => {
2147        this.intersectionObserver?.observe(it);
2148      });
2149    });
2150  };
2151
2152  loadGpuCounter = async (ev: File): Promise<void> => {
2153    this.observerScrollHeightEnable = false;
2154    await this.initGpuCounter(ev);
2155    // @ts-ignore
2156    this.rowsEL?.querySelectorAll('trace-row').forEach((it: unknown) => this.observer.observe(it));
2157    window.publish(window.SmartEvent.UI.MouseEventEnable, {
2158      mouseEnable: true,
2159    });
2160  };
2161
2162  initGpuCounter = async (ev: File): Promise<void> => {
2163    this.rowsPaneEL!.scroll({
2164      top: 0,
2165      left: 0,
2166    });
2167    this.chartManager?.initGpuCounter(ev).then(() => {
2168      this.loadTraceCompleted = true;
2169      // @ts-ignore
2170      this.rowsEL!.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((it) => {
2171        this.intersectionObserver?.observe(it);
2172      });
2173    });
2174  };
2175
2176  // @ts-ignore
2177  queryAllTraceRow<T>(selectors?: string, filter?: (row: TraceRow<unknown>) => boolean): TraceRow<unknown>[] {
2178    return [
2179      // @ts-ignore
2180      ...this.rowsEL!.querySelectorAll<TraceRow<unknown>>(selectors ?? 'trace-row'),
2181      ...this.favoriteChartListEL!.getCollectRows(filter),
2182    ];
2183  }
2184
2185  search(query: string): void {
2186    this.queryAllTraceRow().forEach((item): void => {
2187      if (query === null || query === undefined || query === '') {
2188        if (
2189          item.rowType === TraceRow.ROW_TYPE_CPU ||
2190          item.rowType === TraceRow.ROW_TYPE_CPU_FREQ ||
2191          item.rowType === TraceRow.ROW_TYPE_NATIVE_MEMORY ||
2192          item.rowType === TraceRow.ROW_TYPE_FPS ||
2193          item.rowType === TraceRow.ROW_TYPE_PROCESS ||
2194          item.rowType === TraceRow.ROW_TYPE_CPU_ABILITY ||
2195          item.rowType === TraceRow.ROW_TYPE_MEMORY_ABILITY ||
2196          item.rowType === TraceRow.ROW_TYPE_DISK_ABILITY ||
2197          item.rowType === TraceRow.ROW_TYPE_NETWORK_ABILITY
2198        ) {
2199          item.expansion = false;
2200          item.rowHidden = false;
2201        } else {
2202          item.rowHidden = true;
2203        }
2204      } else {
2205        item.rowHidden = item.name.toLowerCase().indexOf(query.toLowerCase()) < 0;
2206      }
2207    });
2208    this.visibleRows.forEach((it) => (it.rowHidden = false && it.draw(true)));
2209  }
2210
2211  async searchCPU(query: string): Promise<Array<unknown>> {
2212    let pidArr: Array<number> = [];
2213    let tidArr: Array<number> = [];
2214    let processMap = Utils.getInstance().getProcessMap(Utils.currentSelectTrace);
2215    let threadMap = Utils.getInstance().getThreadMap(Utils.currentSelectTrace);
2216    for (let key of processMap.keys()) {
2217      if (`${key}`.includes(query) || (processMap.get(key) || '').includes(query)) {
2218        pidArr.push(key);
2219      }
2220    }
2221    for (let key of threadMap.keys()) {
2222      if (`${key}`.includes(query) || (threadMap.get(key) || '').includes(query)) {
2223        tidArr.push(key);
2224      }
2225    }
2226    return await searchCpuDataSender(pidArr, tidArr, Utils.currentSelectTrace);
2227  }
2228  //根据seach的内容匹配异步缓存数据中那些符合条件
2229  seachAsyncFunc(query: string): unknown[] {
2230    let asyncFuncArr: Array<unknown> = [];
2231    let strNew = (str: unknown): string => {
2232      const specialChars = {
2233        '': '\\^',
2234        '$': '\\$',
2235        '.': '\\.',
2236        '*': '\\*',
2237        '+': '\\+',
2238        '?': '\\?',
2239        '-': '\\-',
2240        '|': '\\|',
2241        '(': '\\(',
2242        ')': '\\)',
2243        '[': '\\[',
2244        ']': '\\]',
2245        '{': '\\{',
2246        '}': '\\}',
2247      };
2248      // @ts-ignore
2249      return str.replace(/[$\^.*+?|()\[\]{}-]/g, (match: string) => specialChars[match as keyof typeof specialChars]); // 类型断言
2250    };
2251    let regex = new RegExp(strNew(query), 'i');
2252    SpProcessChart.asyncFuncCache.forEach((item: unknown) => {
2253      // @ts-ignore
2254      if (regex.test(item.funName)) {
2255        asyncFuncArr.push(item);
2256      }
2257    });
2258    return asyncFuncArr;
2259  }
2260
2261  async searchFunction(cpuList: Array<unknown>, asynList: Array<unknown>, query: string): Promise<Array<unknown>> {
2262    let processList: Array<string> = [];
2263    let traceRow = // @ts-ignore
2264      this.shadowRoot!.querySelector<TraceRow<unknown>>('trace-row[scene]') ||
2265      this.favoriteChartListEL!.getCollectRow((row) => row.hasAttribute('scene'));
2266    if (traceRow) {
2267      // @ts-ignore
2268      this.shadowRoot!.querySelectorAll<TraceRow<unknown>>("trace-row[row-type='process'][scene]").forEach(
2269        (row): void => {
2270          let rowId = row.rowId;
2271          if (rowId && rowId.includes('-')) {
2272            rowId = rowId.split('-')[0];
2273          }
2274          processList.push(rowId as string);
2275        }
2276      );
2277      if (query.includes('_')) {
2278        query = query.replace(/_/g, '\\_');
2279      }
2280      if (query.includes('%')) {
2281        query = query.replace(/%/g, '\\%');
2282      }
2283      let list = await querySceneSearchFunc(query, processList);
2284      cpuList = cpuList.concat(asynList);
2285      cpuList = cpuList.concat(list); // @ts-ignore
2286      cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
2287      return cpuList;
2288    } else {
2289      let list = await querySearchFunc(query);
2290      cpuList = cpuList.concat(asynList);
2291      cpuList = cpuList.concat(list); // @ts-ignore
2292      cpuList.sort((a, b) => (a.startTime || 0) - (b.startTime || 0));
2293      return cpuList;
2294    }
2295  }
2296
2297  searchTargetTraceHandler(): void {
2298    if (Utils.currentSelectTrace) {
2299      // @ts-ignore
2300      let traceFolder1 = this.shadowRoot!.querySelector<TraceRow<unknown>>(`trace-row[row-id='trace-1']`);
2301      // @ts-ignore
2302      let traceFolder2 = this.shadowRoot!.querySelector<TraceRow<unknown>>(`trace-row[row-id='trace-2']`);
2303      if (Utils.currentSelectTrace === '1') {
2304        if (traceFolder2?.expansion) {
2305          traceFolder2!.expansion = false;
2306        }
2307        traceFolder1!.expansion = true;
2308      } else {
2309        if (traceFolder1?.expansion) {
2310          traceFolder1!.expansion = false;
2311        }
2312        traceFolder2!.expansion = true;
2313      }
2314    }
2315  }
2316
2317  searchSdk(dataList: Array<unknown>, query: string): Array<unknown> {
2318    let traceRow = // @ts-ignore
2319      this.shadowRoot!.querySelector<TraceRow<unknown>>('trace-row[scene]') ||
2320      this.favoriteChartListEL!.getCollectRow((row) => row.hasAttribute('scene'));
2321    let dataAll = "trace-row[row-type^='sdk']";
2322    if (traceRow) {
2323      dataAll = "trace-row[row-type^='sdk'][scene]";
2324    }
2325    let allTraceRow: unknown = []; // @ts-ignore
2326    let parentRows = this.shadowRoot!.querySelectorAll<TraceRow<unknown>>(`${dataAll}`); // @ts-ignore
2327    parentRows.forEach((parentRow: TraceRow<unknown>): void => {
2328      // @ts-ignore
2329      allTraceRow.push(parentRow);
2330      if (parentRow.childrenList && parentRow.childrenList.length > 0) {
2331        // @ts-ignore
2332        allTraceRow.push(...parentRow.childrenList);
2333      }
2334    }); // @ts-ignore
2335    allTraceRow.forEach((row: unknown): void => {
2336      // @ts-ignore
2337      if (row!.name.indexOf(query) >= 0) {
2338        let searchSdkBean = new SearchSdkBean();
2339        searchSdkBean.startTime = TraceRow.range!.startNS;
2340        searchSdkBean.dur = TraceRow.range!.totalNS; // @ts-ignore
2341        searchSdkBean.name = row.name; // @ts-ignore
2342        searchSdkBean.rowId = row.rowId;
2343        searchSdkBean.type = 'sdk'; // @ts-ignore
2344        searchSdkBean.rowType = row.rowType; // @ts-ignore
2345        searchSdkBean.rowParentId = row.rowParentId;
2346        dataList.push(searchSdkBean);
2347      }
2348    });
2349    return dataList;
2350  }
2351
2352  showStruct(previous: boolean, currentIndex: number, structs: Array<unknown>, retargetIndex?: number): number {
2353    let tagIndex = spSystemTraceShowStruct(this, previous, currentIndex, structs, retargetIndex);
2354    return tagIndex === -1 ? currentIndex : tagIndex;
2355  }
2356
2357  private toTargetDepth = (entry: unknown, funcRowID: string, funcStract: unknown): void => {
2358    if (entry) {
2359      this.hoverStructNull();
2360      this.selectStructNull();
2361      this.wakeupListNull();
2362      // @ts-ignore
2363      FuncStruct.hoverFuncStruct = entry; // @ts-ignore
2364      FuncStruct.selectFuncStruct = entry;
2365      this.scrollToDepth(
2366        `${funcRowID}`, // @ts-ignore
2367        `${Utils.getDistributedRowId(funcStract.pid)}`,
2368        'func',
2369        true, // @ts-ignore
2370        entry.depth || 0
2371      );
2372      // 鼠标左键点击不需要触发点击事件
2373      if (FuncStruct.funcSelect) {
2374        this.onClickHandler(TraceRow.ROW_TYPE_FUNC, undefined, entry);
2375      } // @ts-ignore
2376      FuncStruct.funcSelect = true;
2377    }
2378  };
2379
2380  scrollToActFunc(funcStract: unknown, highlight: boolean): void {
2381    if (!Utils.isBinder(funcStract)) {
2382      // @ts-ignore
2383      if (funcStract.dur === -1 || funcStract.dur === null || funcStract.dur === undefined) {
2384        // @ts-ignore
2385        funcStract.dur = (TraceRow.range?.totalNS || 0) - (funcStract.startTs || 0); // @ts-ignore
2386        funcStract.flag = 'Did not end';
2387      }
2388    }
2389    //@ts-ignore
2390    let funId = funcStract.row_id === null ? `${funcStract.funName}-${funcStract.pid}` : funcStract.row_id;
2391    //@ts-ignore
2392    let funcRowID = (funcStract.cookie === null || funcStract.cookie === undefined) ? `${Utils.getDistributedRowId(funcStract.tid)}` : funId;
2393    let targetRow = this.favoriteChartListEL?.getCollectRow((row) => {
2394      return row.rowId === funcRowID && row.rowType === 'func';
2395    });
2396    if (targetRow) {
2397      targetRow.fixedList[0] = funcStract;
2398      targetRow.highlight = highlight;
2399      //如果目标泳道图在收藏上面,则跳转至收藏
2400      this.toTargetDepth(funcStract, funcRowID, funcStract);
2401      return;
2402    }
2403    let parentRow = this.rowsEL!.querySelector<TraceRow<BaseStruct>>(
2404      // @ts-ignore
2405      `trace-row[row-id='${Utils.getDistributedRowId(funcStract.pid)}'][folder]`
2406    );
2407    if (!parentRow) {
2408      return;
2409    }
2410    let filterRow = parentRow.childrenList.filter((child) => child.rowId === funcRowID && child.rowType === 'func')[0];
2411    if (!filterRow) {
2412      // @ts-ignore
2413      let funcRow = this.rowsEL?.querySelector<TraceRow<unknown>>(`trace-row[row-id='${funcRowID}'][row-type='func']`);
2414      if (funcRow) {
2415        filterRow = funcRow;
2416      } else {
2417        return;
2418      }
2419    }
2420    filterRow.fixedList = [funcStract];
2421    filterRow!.highlight = highlight;
2422    let row = this.rowsEL!.querySelector<TraceRow<BaseStruct>>( // @ts-ignore
2423      `trace-row[row-id='${Utils.getDistributedRowId(funcStract.pid)}'][folder]`
2424    );
2425    this.currentRow = row;
2426    if (row && !row.expansion) {
2427      row.expansion = true;
2428    }
2429    const completeEntry = (): void => {
2430      this.toTargetDepth(filterRow.fixedList[0], funcRowID, funcStract);
2431    };
2432    if (filterRow!.isComplete) {
2433      completeEntry();
2434    } else {
2435      // @ts-ignore
2436      this.scrollToProcess(`${funcStract.tid}`, `${funcStract.pid}`, 'thread', false); // @ts-ignore
2437      this.scrollToFunction(`${funcStract.tid}`, `${funcStract.pid}`, 'func', true);
2438      // filterRow!.onComplete = completeEntry;
2439      completeEntry();
2440    }
2441  }
2442
2443  closeAllExpandRows(pid: string): void {
2444    let expandRows = this.rowsEL?.querySelectorAll<TraceRow<ProcessStruct>>("trace-row[row-type='process'][expansion]");
2445    expandRows?.forEach((row): void => {
2446      if (row.rowId !== pid) {
2447        row.expansion = false;
2448      }
2449    });
2450  }
2451
2452  moveRangeToLeft(startTime: number, dur: number): void {
2453    let startNS = this.timerShaftEL?.getRange()?.startNS || 0;
2454    let endNS = this.timerShaftEL?.getRange()?.endNS || 0;
2455    let harfDur = Math.trunc(endNS - startNS - dur / 2);
2456    let leftNs = startTime;
2457    let rightNs = startTime + dur + harfDur;
2458    if (startTime - harfDur < 0) {
2459      leftNs = 0;
2460      rightNs += harfDur - startTime;
2461    }
2462    this.timerShaftEL?.setRangeNS(leftNs, rightNs);
2463    TraceRow.range!.refresh = true;
2464    this.refreshCanvas(true, 'move range to left');
2465  }
2466
2467  moveRangeToCenter(startTime: number, dur: number): void {
2468    let startNS = this.timerShaftEL?.getRange()?.startNS || 0;
2469    let endNS = this.timerShaftEL?.getRange()?.endNS || 0;
2470    let harfDur = Math.trunc((endNS - startNS) / 2 - dur / 2);
2471    let leftNs = startTime - harfDur;
2472    let rightNs = startTime + dur + harfDur;
2473    if (startTime - harfDur < 0) {
2474      leftNs = 0;
2475      rightNs += harfDur - startTime;
2476    }
2477    this.timerShaftEL?.setRangeNS(leftNs, rightNs);
2478    TraceRow.range!.refresh = true;
2479    this.refreshCanvas(true, 'move range to center');
2480  }
2481
2482  rechargeCpuData(it: CpuStruct, next: CpuStruct | undefined): void {
2483    let p = Utils.getInstance().getProcessMap().get(it.processId!);
2484    let t = Utils.getInstance().getThreadMap().get(it.tid!);
2485    let slice = Utils.getInstance().getSchedSliceMap().get(`${it.id}-${it.startTime}`);
2486    if (slice) {
2487      it.end_state = slice.endState;
2488      it.priority = slice.priority;
2489    }
2490    it.processName = p;
2491    it.processCmdLine = p;
2492    it.name = t;
2493    if (next) {
2494      if (it.startTime! + it.dur! > next!.startTime! || it.dur === -1 || it.dur === null || it.dur === undefined) {
2495        it.dur = next!.startTime! - it.startTime!;
2496        it.nofinish = true;
2497      }
2498    } else {
2499      if (it.dur === -1 || it.dur === null || it.dur === undefined) {
2500        it.dur = TraceRow.range!.endNS - it.startTime!;
2501        it.nofinish = true;
2502      }
2503    }
2504  }
2505
2506  reset(progress: Function | undefined | null): void {
2507    this.visibleRows.length = 0;
2508    this.tipEL!.style.display = 'none';
2509    this.canvasPanelCtx?.clearRect(0, 0, this.canvasPanel!.clientWidth, this.canvasPanel!.offsetHeight);
2510    this.loadTraceCompleted = false;
2511    this.collectRows = [];
2512    this.visibleRows = [];
2513    TraceRowConfig.allTraceRowList.forEach((it) => {
2514      it.clearMemory();
2515    });
2516    TraceRowConfig.allTraceRowList = [];
2517    this.favoriteChartListEL!.reset();
2518    if (this.rowsEL) {
2519      // @ts-ignore
2520      this.rowsEL.querySelectorAll<TraceRow<unknown>>('trace-row').forEach((row) => {
2521        row.clearMemory();
2522        this.rowsEL!.removeChild(row);
2523      });
2524    }
2525    this.traceSheetEL?.clearMemory();
2526    this.spacerEL!.style.height = '0px';
2527    this.rangeSelect.rangeTraceRow = [];
2528    SpSystemTrace.SDK_CONFIG_MAP = undefined;
2529    SpSystemTrace.sliceRangeMark = undefined;
2530    this.timerShaftEL?.displayCollect(false);
2531    this.timerShaftEL!.collecBtn!.removeAttribute('close');
2532    CpuStruct.wakeupBean = undefined;
2533    this.selectStructNull();
2534    this.hoverStructNull();
2535    this.wakeupListNull();
2536    this.traceSheetEL?.setMode('hidden');
2537    progress?.('rest timershaft', 8);
2538    this.timerShaftEL?.reset();
2539    progress?.('clear cache', 10);
2540    HeapDataInterface.getInstance().clearData();
2541    procedurePool.clearCache();
2542    Utils.clearData();
2543    InitAnalysis.getInstance().isInitAnalysis = true;
2544    procedurePool.submitWithName('logic0', 'clear', {}, undefined, (res: unknown) => { });
2545    if (threadPool) {
2546      threadPool.submitProto(QueryEnum.ClearMemoryCache, {}, (res: unknown, len: number): void => { });
2547    }
2548    if (threadPool2) {
2549      threadPool2.submitProto(QueryEnum.ClearMemoryCache, {}, (res: unknown, len: number): void => { });
2550    }
2551    this.times.clear();
2552    resetVSync();
2553    SpSystemTrace.keyPathList = [];
2554    Utils.isTransformed = false;
2555  }
2556
2557  init = async (
2558    param: { buf?: ArrayBuffer; url?: string; buf2?: ArrayBuffer; fileName1?: string; fileName2?: string },
2559    wasmConfigUri: string,
2560    progress: Function,
2561    isDistributed: boolean
2562  ): Promise<unknown> => {
2563    return spSystemTraceInit(this, param, wasmConfigUri, progress, isDistributed);
2564  };
2565  // @ts-ignore
2566  extracted(it: TraceRow<unknown>) {
2567    return (): void => {
2568      if (it.hasAttribute('expansion')) {
2569        it.childrenList.forEach((child): void => {
2570          if (child.hasAttribute('scene') && !child.collect) {
2571            child.rowHidden = false;
2572          }
2573          if (child.folder) {
2574            child.addEventListener('expansion-change', this.extracted(child));
2575          }
2576          this.intersectionObserver?.observe(child);
2577        });
2578      } else {
2579        //@ts-ignore
2580        let parentElTopHeight = it.hasParentRowEl ? //@ts-ignore
2581          (it.parentRowEl.getBoundingClientRect().top + it.parentRowEl.clientHeight) : this.rowsPaneEL!.getBoundingClientRect().top;
2582        it.childrenList.forEach((child): void => {
2583          if (child.hasAttribute('scene') && !child.collect) {
2584            child.rowHidden = true;
2585            this.intersectionObserver?.unobserve(child);
2586          }
2587          if (child.folder) {
2588            child.removeEventListener('expansion-change', this.extracted(child));
2589          }
2590        });
2591        if (it.getBoundingClientRect().top < 0) {
2592          this.rowsPaneEL!.scrollTop =
2593            this.rowsPaneEL!.scrollTop -
2594            (it.getBoundingClientRect().top * -1 + parentElTopHeight);
2595        } else if (it.getBoundingClientRect().top > 0) {
2596          this.rowsPaneEL!.scrollTop =
2597            parentElTopHeight <
2598              it.getBoundingClientRect().top ?
2599              this.rowsPaneEL!.scrollTop :
2600              this.rowsPaneEL!.scrollTop -
2601              (parentElTopHeight - it.getBoundingClientRect().top);
2602        } else {
2603          this.rowsPaneEL!.scrollTop =
2604            this.rowsPaneEL!.scrollTop -
2605            parentElTopHeight;
2606        }
2607        this.linkNodes.map((value): void => {
2608          if ('task' === value[0].business && value[0].rowEL.parentRowEl?.rowId === it.rowId) {
2609            value[0].hidden = true;
2610            value[1].hidden = true;
2611            this.clickEmptyArea();
2612          }
2613        });
2614      }
2615      this.resetDistributedLine();
2616      if (!this.collapseAll) {
2617        this.refreshCanvas(false, 'extracted');
2618      }
2619    };
2620  }
2621
2622  resetDistributedLine(): void {
2623    if (FuncStruct.selectFuncStruct) {
2624      let dataList = FuncStruct.selectLineFuncStruct;
2625      this.removeLinkLinesByBusinessType('distributed');
2626      FuncStruct.selectLineFuncStruct = dataList;
2627      for (let index = 0; index < FuncStruct.selectLineFuncStruct.length; index++) {
2628        let sourceData = FuncStruct.selectLineFuncStruct[index];
2629        if (index !== FuncStruct.selectLineFuncStruct.length - 1) {
2630          let targetData = FuncStruct.selectLineFuncStruct[index + 1];
2631          this.drawDistributedLine(sourceData, targetData, FuncStruct.selectFuncStruct!);
2632        }
2633      }
2634      this.refreshCanvas(true);
2635    }
2636  }
2637
2638  // @ts-ignore
2639  displayTip(row: TraceRow<unknown>, struct: unknown, html: string): void {
2640    let x = row.hoverX + 248;
2641    let y = row.getBoundingClientRect().top - this.getBoundingClientRect().top;
2642    if ((struct === undefined || struct === null) && this.tipEL) {
2643      this.tipEL.style.display = 'none';
2644      return;
2645    }
2646    if (this.tipEL) {
2647      this.tipEL.innerHTML = html;
2648      if (
2649        row.rowType === TraceRow.ROW_TYPE_JS_CPU_PROFILER ||
2650        row.rowType === TraceRow.ROW_TYPE_PERF_CALLCHART ||
2651        row.rowType === TraceRow.ROW_TYPE_BINDER_COUNT
2652      ) {
2653        this.tipEL.style.maxWidth = `${row.clientWidth / 3} px`;
2654        this.tipEL.style.wordBreak = ' break-all';
2655        this.tipEL.style.height = 'unset';
2656        this.tipEL.style.display = 'block'; // @ts-ignore
2657        y = y + struct.depth * 20;
2658        if (row.rowType === TraceRow.ROW_TYPE_BINDER_COUNT) {
2659          this.tipEL.style.height = 'auto';
2660          y = row.hoverY + row.getBoundingClientRect().top - this.getBoundingClientRect().top;
2661        }
2662      } else {
2663        this.tipEL.style.display = 'flex';
2664        this.tipEL.style.height = row.style.height;
2665      }
2666      if (x + this.tipEL.clientWidth > (this.canvasPanel!.clientWidth ?? 0)) {
2667        this.tipEL.style.transform = `translateX(${x - this.tipEL.clientWidth - 1}px) translateY(${y}px)`;
2668      } else {
2669        this.tipEL.style.transform = `translateX(${x}px) translateY(${y}px)`;
2670      }
2671    }
2672  }
2673
2674  queryCPUWakeUpList(data: WakeupBean): void {
2675    if (this._checkclick) {
2676      this.wakeupListTbl!.loading = true;
2677    }
2678    TabPaneCurrentSelection.queryCPUWakeUpListFromBean(data).then((a: unknown) => {
2679      if (a === null) {
2680        window.publish(window.SmartEvent.UI.WakeupList, SpSystemTrace.wakeupList);
2681        this.wakeupListTbl!.loading = false;
2682        this._checkclick = false;
2683        this.refreshCanvas(true);
2684        return null;
2685      } // @ts-ignore
2686      SpSystemTrace.wakeupList.push(a); // @ts-ignore
2687      this.queryCPUWakeUpList(a);
2688    });
2689  }
2690
2691  wakeupListNull(): SpSystemTrace {
2692    SpSystemTrace.wakeupList = [];
2693    return this;
2694  }
2695
2696  initPointToEvent(): void {
2697    spSystemTraceInitPointToEvent(this);
2698  }
2699
2700  initHtml(): string {
2701    return SpSystemTraceHtml;
2702  }
2703}
2704