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