1fb726d48Sopenharmony_ci/*
2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd.
3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License.
5fb726d48Sopenharmony_ci * You may obtain a copy of the License at
6fb726d48Sopenharmony_ci *
7fb726d48Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fb726d48Sopenharmony_ci *
9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and
13fb726d48Sopenharmony_ci * limitations under the License.
14fb726d48Sopenharmony_ci */
15fb726d48Sopenharmony_ci
16fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow';
17fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker';
18fb726d48Sopenharmony_ciimport { JankRender, JankStruct } from '../../database/ui-worker/ProcedureWorkerJank';
19fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace';
20fb726d48Sopenharmony_ciimport { JanksStruct } from '../../bean/JanksStruct';
21fb726d48Sopenharmony_ciimport { ns2xByTimeShaft, type PairPoint } from '../../database/ui-worker/ProcedureWorkerCommon';
22fb726d48Sopenharmony_ciimport { FrameDynamicRender, FrameDynamicStruct } from '../../database/ui-worker/ProcedureWorkerFrameDynamic';
23fb726d48Sopenharmony_ciimport { FrameAnimationRender, FrameAnimationStruct } from '../../database/ui-worker/ProcedureWorkerFrameAnimation';
24fb726d48Sopenharmony_ciimport { type BaseStruct } from '../../bean/BaseStruct';
25fb726d48Sopenharmony_ciimport { FrameSpacingRender, FrameSpacingStruct } from '../../database/ui-worker/ProcedureWorkerFrameSpacing';
26fb726d48Sopenharmony_ciimport { FlagsConfig, type Params } from '../SpFlags';
27fb726d48Sopenharmony_ciimport { type AnimationRanges, type DeviceStruct } from '../../bean/FrameComponentBean';
28fb726d48Sopenharmony_ciimport { type EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU';
29fb726d48Sopenharmony_ciimport { TreeItemData } from '../../../base-ui/tree/LitTree';
30fb726d48Sopenharmony_ciimport { QueryEnum } from '../../database/data-trafic/utils/QueryEnum';
31fb726d48Sopenharmony_ciimport {
32fb726d48Sopenharmony_ci  frameAnimationSender,
33fb726d48Sopenharmony_ci  frameDynamicSender,
34fb726d48Sopenharmony_ci  frameSpacingSender,
35fb726d48Sopenharmony_ci} from '../../database/data-trafic/FrameDynamicEffectSender';
36fb726d48Sopenharmony_ciimport { frameJanksSender } from '../../database/data-trafic/FrameJanksSender';
37fb726d48Sopenharmony_ciimport {
38fb726d48Sopenharmony_ci  queryAnimationIdAndNameData,
39fb726d48Sopenharmony_ci  queryAnimationTimeRangeData,
40fb726d48Sopenharmony_ci  queryDynamicIdAndNameData,
41fb726d48Sopenharmony_ci  queryFrameApp,
42fb726d48Sopenharmony_ci  queryFrameTimeData,
43fb726d48Sopenharmony_ci  queryPhysicalData,
44fb726d48Sopenharmony_ci  querySourceTypen,
45fb726d48Sopenharmony_ci} from '../../database/sql/SqlLite.sql';
46fb726d48Sopenharmony_ciimport { queryAllProcessNames } from '../../database/sql/ProcessThread.sql';
47fb726d48Sopenharmony_ci
48fb726d48Sopenharmony_ciexport class SpFrameTimeChart {
49fb726d48Sopenharmony_ci  private trace: SpSystemTrace;
50fb726d48Sopenharmony_ci  private flagConfig: Params | undefined;
51fb726d48Sopenharmony_ci  private pidToProcessNameMap: Map<number, string> = new Map();
52fb726d48Sopenharmony_ci  private idToProcessNameMap: Map<number, string> = new Map();
53fb726d48Sopenharmony_ci
54fb726d48Sopenharmony_ci  constructor(trace: SpSystemTrace) {
55fb726d48Sopenharmony_ci    this.trace = trace;
56fb726d48Sopenharmony_ci  }
57fb726d48Sopenharmony_ci
58fb726d48Sopenharmony_ci  async init(): Promise<void> {
59fb726d48Sopenharmony_ci    let frameTimeData = await queryFrameTimeData();
60fb726d48Sopenharmony_ci    this.pidToProcessNameMap.clear();
61fb726d48Sopenharmony_ci    this.idToProcessNameMap.clear();
62fb726d48Sopenharmony_ci    if (frameTimeData.length > 0) {
63fb726d48Sopenharmony_ci      let processNamesArray = await queryAllProcessNames();
64fb726d48Sopenharmony_ci      processNamesArray.forEach((it) => {
65fb726d48Sopenharmony_ci        //@ts-ignore
66fb726d48Sopenharmony_ci        this.pidToProcessNameMap.set(it.pid, it.name); //@ts-ignore
67fb726d48Sopenharmony_ci        this.idToProcessNameMap.set(it.id, it.name);
68fb726d48Sopenharmony_ci      });
69fb726d48Sopenharmony_ci      let frameTimeLineRow: TraceRow<JanksStruct> = await this.initFrameTimeLine();
70fb726d48Sopenharmony_ci      await this.initExpectedChart(frameTimeLineRow);
71fb726d48Sopenharmony_ci      await this.initActualChart(frameTimeLineRow);
72fb726d48Sopenharmony_ci    }
73fb726d48Sopenharmony_ci  }
74fb726d48Sopenharmony_ci
75fb726d48Sopenharmony_ci  async initFrameTimeLine(): Promise<TraceRow<JanksStruct>> {
76fb726d48Sopenharmony_ci    let frameTimeLineRow: TraceRow<JanksStruct> = TraceRow.skeleton<JanksStruct>();
77fb726d48Sopenharmony_ci    frameTimeLineRow.rowId = 'frameTime';
78fb726d48Sopenharmony_ci    frameTimeLineRow.rowType = TraceRow.ROW_TYPE_JANK;
79fb726d48Sopenharmony_ci    frameTimeLineRow.rowParentId = '';
80fb726d48Sopenharmony_ci    frameTimeLineRow.style.width = '100%';
81fb726d48Sopenharmony_ci    frameTimeLineRow.style.height = '40px';
82fb726d48Sopenharmony_ci    frameTimeLineRow.folder = true;
83fb726d48Sopenharmony_ci    frameTimeLineRow.name = 'FrameTimeline';
84fb726d48Sopenharmony_ci    frameTimeLineRow.setAttribute('children', '');
85fb726d48Sopenharmony_ci    frameTimeLineRow.supplier = (): Promise<JanksStruct[]> =>
86fb726d48Sopenharmony_ci      new Promise((resolve) => {
87fb726d48Sopenharmony_ci        resolve([]);
88fb726d48Sopenharmony_ci      });
89fb726d48Sopenharmony_ci    frameTimeLineRow.addTemplateTypes('AppStartup');
90fb726d48Sopenharmony_ci    frameTimeLineRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
91fb726d48Sopenharmony_ci    frameTimeLineRow.selectChangeHandler = this.trace.selectChangeHandler;
92fb726d48Sopenharmony_ci    frameTimeLineRow.onThreadHandler = (useCache: boolean): void => {
93fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
94fb726d48Sopenharmony_ci      if (frameTimeLineRow.currentContext) {
95fb726d48Sopenharmony_ci        context = frameTimeLineRow.currentContext;
96fb726d48Sopenharmony_ci      } else {
97fb726d48Sopenharmony_ci        context = frameTimeLineRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
98fb726d48Sopenharmony_ci      }
99fb726d48Sopenharmony_ci      frameTimeLineRow!.canvasSave(context);
100fb726d48Sopenharmony_ci      (renders.jank as JankRender).renderMainThread(
101fb726d48Sopenharmony_ci        {
102fb726d48Sopenharmony_ci          context: context,
103fb726d48Sopenharmony_ci          useCache: useCache,
104fb726d48Sopenharmony_ci          type: 'expected_frame_timeline_slice',
105fb726d48Sopenharmony_ci        },
106fb726d48Sopenharmony_ci        frameTimeLineRow!
107fb726d48Sopenharmony_ci      );
108fb726d48Sopenharmony_ci      frameTimeLineRow!.canvasRestore(context, this.trace);
109fb726d48Sopenharmony_ci    };
110fb726d48Sopenharmony_ci    this.trace.rowsEL?.appendChild(frameTimeLineRow);
111fb726d48Sopenharmony_ci    return frameTimeLineRow;
112fb726d48Sopenharmony_ci  }
113fb726d48Sopenharmony_ci
114fb726d48Sopenharmony_ci  private expectedChartSupplierFrame(expectedTimeLineRow: TraceRow<JanksStruct>): void {
115fb726d48Sopenharmony_ci    expectedTimeLineRow.supplierFrame = async (): Promise<JanksStruct[]> => {
116fb726d48Sopenharmony_ci      const res = await frameJanksSender(QueryEnum.FrameExpectedData, expectedTimeLineRow);
117fb726d48Sopenharmony_ci      let maxDepth: number = 1;
118fb726d48Sopenharmony_ci      let unitHeight: number = 20;
119fb726d48Sopenharmony_ci      res.forEach((item) => {
120fb726d48Sopenharmony_ci        if (item.depth! >= maxDepth) {
121fb726d48Sopenharmony_ci          maxDepth = item.depth! + 1;
122fb726d48Sopenharmony_ci        }
123fb726d48Sopenharmony_ci        item.frameType = 'frameTime';
124fb726d48Sopenharmony_ci        item.cmdline = this.pidToProcessNameMap.get(item.pid!);
125fb726d48Sopenharmony_ci        item.rs_name = this.idToProcessNameMap.get(Number(item.rs_name)!);
126fb726d48Sopenharmony_ci      });
127fb726d48Sopenharmony_ci      if (expectedTimeLineRow && !expectedTimeLineRow.isComplete && res.length > 0) {
128fb726d48Sopenharmony_ci        let maxHeight: number = maxDepth * unitHeight;
129fb726d48Sopenharmony_ci        expectedTimeLineRow.style.height = `${maxHeight}px`;
130fb726d48Sopenharmony_ci        expectedTimeLineRow.setAttribute('height', `${maxHeight}`);
131fb726d48Sopenharmony_ci      }
132fb726d48Sopenharmony_ci      return res;
133fb726d48Sopenharmony_ci    };
134fb726d48Sopenharmony_ci  }
135fb726d48Sopenharmony_ci
136fb726d48Sopenharmony_ci  async initExpectedChart(frameTimeLineRow: TraceRow<JanksStruct>): Promise<void> {
137fb726d48Sopenharmony_ci    let expectedTimeLineRow = TraceRow.skeleton<JanksStruct>();
138fb726d48Sopenharmony_ci    expectedTimeLineRow.rowId = 'expected frameTime';
139fb726d48Sopenharmony_ci    expectedTimeLineRow.rowType = TraceRow.ROW_TYPE_JANK;
140fb726d48Sopenharmony_ci    expectedTimeLineRow.rowHidden = !frameTimeLineRow.expansion;
141fb726d48Sopenharmony_ci    expectedTimeLineRow.rowParentId = 'frameTime';
142fb726d48Sopenharmony_ci    expectedTimeLineRow.style.width = '100%';
143fb726d48Sopenharmony_ci    expectedTimeLineRow.name = 'Expected Timeline';
144fb726d48Sopenharmony_ci    expectedTimeLineRow.addTemplateTypes('FrameTimeline');
145fb726d48Sopenharmony_ci    expectedTimeLineRow.setAttribute('children', '');
146fb726d48Sopenharmony_ci    this.expectedChartSupplierFrame(expectedTimeLineRow);
147fb726d48Sopenharmony_ci    expectedTimeLineRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
148fb726d48Sopenharmony_ci    expectedTimeLineRow.selectChangeHandler = this.trace.selectChangeHandler;
149fb726d48Sopenharmony_ci    expectedTimeLineRow.onThreadHandler = (useCache: boolean): void => {
150fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
151fb726d48Sopenharmony_ci      if (expectedTimeLineRow.currentContext) {
152fb726d48Sopenharmony_ci        context = expectedTimeLineRow.currentContext;
153fb726d48Sopenharmony_ci      } else {
154fb726d48Sopenharmony_ci        context = expectedTimeLineRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
155fb726d48Sopenharmony_ci      }
156fb726d48Sopenharmony_ci      expectedTimeLineRow!.canvasSave(context);
157fb726d48Sopenharmony_ci      (renders.jank as JankRender).renderMainThread(
158fb726d48Sopenharmony_ci        {
159fb726d48Sopenharmony_ci          context: context,
160fb726d48Sopenharmony_ci          useCache: useCache,
161fb726d48Sopenharmony_ci          type: 'expected_frame_timeline_slice',
162fb726d48Sopenharmony_ci        },
163fb726d48Sopenharmony_ci        expectedTimeLineRow!
164fb726d48Sopenharmony_ci      );
165fb726d48Sopenharmony_ci      expectedTimeLineRow!.canvasRestore(context, this.trace);
166fb726d48Sopenharmony_ci    };
167fb726d48Sopenharmony_ci    frameTimeLineRow.addChildTraceRow(expectedTimeLineRow);
168fb726d48Sopenharmony_ci  }
169fb726d48Sopenharmony_ci
170fb726d48Sopenharmony_ci  private actualChartSupplierFrame(row: TraceRow<JanksStruct>): void {
171fb726d48Sopenharmony_ci    row.supplierFrame = async (): Promise<JanksStruct[]> => {
172fb726d48Sopenharmony_ci      const res = await frameJanksSender(QueryEnum.FrameActualData, row);
173fb726d48Sopenharmony_ci      let maxDepth: number = 1;
174fb726d48Sopenharmony_ci      let unitHeight: number = 20;
175fb726d48Sopenharmony_ci      res.forEach((item) => {
176fb726d48Sopenharmony_ci        if (item.depth! >= maxDepth) {
177fb726d48Sopenharmony_ci          maxDepth = item.depth! + 1;
178fb726d48Sopenharmony_ci        }
179fb726d48Sopenharmony_ci        item.frameType = 'frameTime';
180fb726d48Sopenharmony_ci        item.cmdline = this.pidToProcessNameMap.get(item.pid!);
181fb726d48Sopenharmony_ci        item.rs_name = this.idToProcessNameMap.get(Number(item.rs_name)!);
182fb726d48Sopenharmony_ci        item.type = '0';
183fb726d48Sopenharmony_ci      });
184fb726d48Sopenharmony_ci      if (row && !row.isComplete && res.length > 0) {
185fb726d48Sopenharmony_ci        let maxHeight: number = maxDepth * unitHeight;
186fb726d48Sopenharmony_ci        row.style.height = `${maxHeight}px`;
187fb726d48Sopenharmony_ci        row.setAttribute('height', `${maxHeight}`);
188fb726d48Sopenharmony_ci      }
189fb726d48Sopenharmony_ci      return res;
190fb726d48Sopenharmony_ci    };
191fb726d48Sopenharmony_ci  }
192fb726d48Sopenharmony_ci
193fb726d48Sopenharmony_ci  async initActualChart(frameTimeLineRow: TraceRow<JanksStruct>): Promise<void> {
194fb726d48Sopenharmony_ci    let actualTimeLineRow = TraceRow.skeleton<JanksStruct>();
195fb726d48Sopenharmony_ci    actualTimeLineRow.rowId = 'actual frameTime';
196fb726d48Sopenharmony_ci    actualTimeLineRow.rowType = TraceRow.ROW_TYPE_JANK;
197fb726d48Sopenharmony_ci    actualTimeLineRow.rowHidden = !frameTimeLineRow.expansion;
198fb726d48Sopenharmony_ci    actualTimeLineRow.rowParentId = 'frameTime';
199fb726d48Sopenharmony_ci    actualTimeLineRow.style.width = '100%';
200fb726d48Sopenharmony_ci    actualTimeLineRow.name = 'Actual Timeline';
201fb726d48Sopenharmony_ci    actualTimeLineRow.addTemplateTypes('FrameTimeline');
202fb726d48Sopenharmony_ci    actualTimeLineRow.setAttribute('children', '');
203fb726d48Sopenharmony_ci    this.actualChartSupplierFrame(actualTimeLineRow);
204fb726d48Sopenharmony_ci    actualTimeLineRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
205fb726d48Sopenharmony_ci    actualTimeLineRow.selectChangeHandler = this.trace.selectChangeHandler;
206fb726d48Sopenharmony_ci    actualTimeLineRow.onThreadHandler = (useCache: boolean): void => {
207fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D;
208fb726d48Sopenharmony_ci      if (actualTimeLineRow.currentContext) {
209fb726d48Sopenharmony_ci        context = actualTimeLineRow.currentContext;
210fb726d48Sopenharmony_ci      } else {
211fb726d48Sopenharmony_ci        context = actualTimeLineRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
212fb726d48Sopenharmony_ci      }
213fb726d48Sopenharmony_ci      actualTimeLineRow!.canvasSave(context);
214fb726d48Sopenharmony_ci      (renders.jank as JankRender).renderMainThread(
215fb726d48Sopenharmony_ci        {
216fb726d48Sopenharmony_ci          context: context,
217fb726d48Sopenharmony_ci          useCache: useCache,
218fb726d48Sopenharmony_ci          type: 'expected_frame_timeline_slice',
219fb726d48Sopenharmony_ci        },
220fb726d48Sopenharmony_ci        actualTimeLineRow!
221fb726d48Sopenharmony_ci      );
222fb726d48Sopenharmony_ci      actualTimeLineRow!.canvasRestore(context, this.trace);
223fb726d48Sopenharmony_ci    };
224fb726d48Sopenharmony_ci    frameTimeLineRow.addChildTraceRow(actualTimeLineRow);
225fb726d48Sopenharmony_ci    let offsetYTimeOut: number = 0;
226fb726d48Sopenharmony_ci    frameTimeLineRow.addEventListener('expansion-change', (customEventInit: CustomEventInit) => {
227fb726d48Sopenharmony_ci      JankStruct.delJankLineFlag = false;
228fb726d48Sopenharmony_ci      if (offsetYTimeOut) {
229fb726d48Sopenharmony_ci        clearTimeout(offsetYTimeOut);
230fb726d48Sopenharmony_ci      }
231fb726d48Sopenharmony_ci      if (customEventInit.detail?.expansion) {
232fb726d48Sopenharmony_ci        offsetYTimeOut = this.frameExpandTimeOut(customEventInit, actualTimeLineRow);
233fb726d48Sopenharmony_ci      } else {
234fb726d48Sopenharmony_ci        offsetYTimeOut = this.frameNoExpandTimeOut(customEventInit, frameTimeLineRow);
235fb726d48Sopenharmony_ci      }
236fb726d48Sopenharmony_ci    });
237fb726d48Sopenharmony_ci  }
238fb726d48Sopenharmony_ci
239fb726d48Sopenharmony_ci  async initAnimatedScenesChart(
240fb726d48Sopenharmony_ci    processRow: TraceRow<BaseStruct>,
241fb726d48Sopenharmony_ci    process: { pid: number | null; processName: string | null },
242fb726d48Sopenharmony_ci    firstRow: TraceRow<BaseStruct>,
243fb726d48Sopenharmony_ci    secondRow: TraceRow<BaseStruct>
244fb726d48Sopenharmony_ci  ): Promise<void> {
245fb726d48Sopenharmony_ci    let sourceTypeName = await querySourceTypen();
246fb726d48Sopenharmony_ci    this.flagConfig = FlagsConfig.getFlagsConfig('AnimationAnalysis');
247fb726d48Sopenharmony_ci    let appNameMap: Map<number, string> = new Map();
248fb726d48Sopenharmony_ci    //@ts-ignore
249fb726d48Sopenharmony_ci    if (this.flagConfig?.AnimationAnalysis === 'Enabled' && sourceTypeName[0].value !== 'txt-based-trace') {
250fb726d48Sopenharmony_ci      if (process.processName?.startsWith('render_service')) {
251fb726d48Sopenharmony_ci        let targetRowList = processRow.childrenList.filter(
252fb726d48Sopenharmony_ci          (childRow) => childRow.rowType === 'thread' && childRow.name.startsWith('render_service')
253fb726d48Sopenharmony_ci        );
254fb726d48Sopenharmony_ci        let nameArr: { name: string }[] = await queryFrameApp();
255fb726d48Sopenharmony_ci        if (nameArr && nameArr.length > 0) {
256fb726d48Sopenharmony_ci          let currentName = nameArr[0].name;
257fb726d48Sopenharmony_ci          let frameChart = await this.initFrameChart(processRow, nameArr);
258fb726d48Sopenharmony_ci          if (firstRow !== null) {
259fb726d48Sopenharmony_ci            processRow.addChildTraceRowBefore(frameChart, firstRow);
260fb726d48Sopenharmony_ci          } else if (secondRow !== null) {
261fb726d48Sopenharmony_ci            processRow.addChildTraceRowBefore(frameChart, secondRow);
262fb726d48Sopenharmony_ci          } else {
263fb726d48Sopenharmony_ci            // @ts-ignore
264fb726d48Sopenharmony_ci            processRow.addChildTraceRowBefore(frameChart, targetRowList[0]);
265fb726d48Sopenharmony_ci          }
266fb726d48Sopenharmony_ci          let appNameList = await queryDynamicIdAndNameData();
267fb726d48Sopenharmony_ci          appNameList.forEach((item) => {
268fb726d48Sopenharmony_ci            appNameMap.set(item.id, item.appName);
269fb726d48Sopenharmony_ci          });
270fb726d48Sopenharmony_ci          let animationRanges = await this.initAnimationChart(processRow);
271fb726d48Sopenharmony_ci          await this.initDynamicCurveChart(appNameMap, frameChart, currentName, animationRanges);
272fb726d48Sopenharmony_ci          await this.initFrameSpacing(appNameMap, frameChart, currentName, animationRanges);
273fb726d48Sopenharmony_ci        }
274fb726d48Sopenharmony_ci      }
275fb726d48Sopenharmony_ci    }
276fb726d48Sopenharmony_ci  }
277fb726d48Sopenharmony_ci
278fb726d48Sopenharmony_ci  private async initFrameChart(
279fb726d48Sopenharmony_ci    processRow: TraceRow<BaseStruct>,
280fb726d48Sopenharmony_ci    nameArr: { name: string }[]
281fb726d48Sopenharmony_ci  ): Promise<TraceRow<BaseStruct>> {
282fb726d48Sopenharmony_ci    let frameChart: TraceRow<BaseStruct> = TraceRow.skeleton<BaseStruct>();
283fb726d48Sopenharmony_ci    let labelName = frameChart.shadowRoot?.querySelector('.name') as HTMLLabelElement;
284fb726d48Sopenharmony_ci    labelName.style.marginRight = '77px';
285fb726d48Sopenharmony_ci    this.addSystemConfigButton(frameChart, nameArr, 'model-name', true);
286fb726d48Sopenharmony_ci    frameChart.rowId = 'frame';
287fb726d48Sopenharmony_ci    frameChart.rowType = TraceRow.ROW_TYPE_FRAME;
288fb726d48Sopenharmony_ci    frameChart.rowHidden = !processRow.expansion;
289fb726d48Sopenharmony_ci    frameChart.rowParentId = processRow.rowId;
290fb726d48Sopenharmony_ci    frameChart.style.width = '100%';
291fb726d48Sopenharmony_ci    frameChart.style.height = '40px';
292fb726d48Sopenharmony_ci    frameChart.folder = true;
293fb726d48Sopenharmony_ci    frameChart.name = nameArr[0].name;
294fb726d48Sopenharmony_ci    frameChart.setAttribute('children', '');
295fb726d48Sopenharmony_ci    frameChart.supplier = (): Promise<BaseStruct[]> =>
296fb726d48Sopenharmony_ci      new Promise((resolve) => {
297fb726d48Sopenharmony_ci        resolve([]);
298fb726d48Sopenharmony_ci      });
299fb726d48Sopenharmony_ci    frameChart.favoriteChangeHandler = this.trace.favoriteChangeHandler;
300fb726d48Sopenharmony_ci    frameChart.selectChangeHandler = this.trace.selectChangeHandler;
301fb726d48Sopenharmony_ci    frameChart.onThreadHandler = (useCache: boolean): void => {
302fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D = frameChart!.collect
303fb726d48Sopenharmony_ci        ? this.trace.canvasFavoritePanelCtx!
304fb726d48Sopenharmony_ci        : this.trace.canvasPanelCtx!;
305fb726d48Sopenharmony_ci      frameChart!.canvasSave(context);
306fb726d48Sopenharmony_ci      (renders.empty as EmptyRender).renderMainThread(
307fb726d48Sopenharmony_ci        {
308fb726d48Sopenharmony_ci          context: context,
309fb726d48Sopenharmony_ci          useCache: useCache,
310fb726d48Sopenharmony_ci          type: 'frame',
311fb726d48Sopenharmony_ci        },
312fb726d48Sopenharmony_ci        frameChart!
313fb726d48Sopenharmony_ci      );
314fb726d48Sopenharmony_ci      frameChart!.canvasRestore(context, this.trace);
315fb726d48Sopenharmony_ci    };
316fb726d48Sopenharmony_ci    this.trace.rowsEL?.appendChild(frameChart);
317fb726d48Sopenharmony_ci    return frameChart;
318fb726d48Sopenharmony_ci  }
319fb726d48Sopenharmony_ci
320fb726d48Sopenharmony_ci  private animationChartSupplierFrame(
321fb726d48Sopenharmony_ci    row: TraceRow<FrameAnimationStruct>,
322fb726d48Sopenharmony_ci    animationIdNameMap: Map<number, string>,
323fb726d48Sopenharmony_ci    animationIdInfoMap: Map<number, string>
324fb726d48Sopenharmony_ci  ): void {
325fb726d48Sopenharmony_ci    const unitIndex: number = 1;
326fb726d48Sopenharmony_ci    const unitHeight: number = 20;
327fb726d48Sopenharmony_ci    row.supplierFrame = async (): Promise<FrameAnimationStruct[]> => {
328fb726d48Sopenharmony_ci      const result = await frameAnimationSender(row);
329fb726d48Sopenharmony_ci      let maxDepth = 0;
330fb726d48Sopenharmony_ci      result.forEach((item) => {
331fb726d48Sopenharmony_ci        if (`${item.status}` === '1') {
332fb726d48Sopenharmony_ci          item.status = 'Completion delay';
333fb726d48Sopenharmony_ci        } else if (`${item.status}` === '0') {
334fb726d48Sopenharmony_ci          item.status = 'Response delay';
335fb726d48Sopenharmony_ci        }
336fb726d48Sopenharmony_ci        if (item.depth > maxDepth) {
337fb726d48Sopenharmony_ci          maxDepth = item.depth;
338fb726d48Sopenharmony_ci        }
339fb726d48Sopenharmony_ci        if (animationIdNameMap.has(item.animationId!)) {
340fb726d48Sopenharmony_ci          item.name = animationIdNameMap.get(item.animationId!);
341fb726d48Sopenharmony_ci          item.frameInfo = item.status === 'Completion delay' ? animationIdInfoMap.get(item.animationId!) : '0';
342fb726d48Sopenharmony_ci        }
343fb726d48Sopenharmony_ci      });
344fb726d48Sopenharmony_ci      let maxHeight: number = (maxDepth + unitIndex) * unitHeight;
345fb726d48Sopenharmony_ci      row.style.height = `${maxHeight}px`;
346fb726d48Sopenharmony_ci      row.setAttribute('height', `${maxHeight}`);
347fb726d48Sopenharmony_ci      return result;
348fb726d48Sopenharmony_ci    };
349fb726d48Sopenharmony_ci  }
350fb726d48Sopenharmony_ci  private animationThreadHandler(row: TraceRow<FrameAnimationStruct>): void {
351fb726d48Sopenharmony_ci    row.onThreadHandler = (useCache): void => {
352fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D = row!.collect
353fb726d48Sopenharmony_ci        ? this.trace.canvasFavoritePanelCtx!
354fb726d48Sopenharmony_ci        : this.trace.canvasPanelCtx!;
355fb726d48Sopenharmony_ci      row!.canvasSave(context);
356fb726d48Sopenharmony_ci      (renders.frameAnimation as FrameAnimationRender).renderMainThread(
357fb726d48Sopenharmony_ci        {
358fb726d48Sopenharmony_ci          context: context,
359fb726d48Sopenharmony_ci          useCache: useCache,
360fb726d48Sopenharmony_ci          type: 'frameAnimation',
361fb726d48Sopenharmony_ci        },
362fb726d48Sopenharmony_ci        row!
363fb726d48Sopenharmony_ci      );
364fb726d48Sopenharmony_ci      row!.canvasRestore(context, this.trace);
365fb726d48Sopenharmony_ci    };
366fb726d48Sopenharmony_ci  }
367fb726d48Sopenharmony_ci
368fb726d48Sopenharmony_ci  async initAnimationChart(processRow: TraceRow<BaseStruct>): Promise<AnimationRanges[]> {
369fb726d48Sopenharmony_ci    let animationRanges: AnimationRanges[] = [];
370fb726d48Sopenharmony_ci    let frameAnimationRow = TraceRow.skeleton<FrameAnimationStruct>();
371fb726d48Sopenharmony_ci
372fb726d48Sopenharmony_ci    frameAnimationRow.rowId = 'Animation';
373fb726d48Sopenharmony_ci    frameAnimationRow.rowType = TraceRow.ROW_TYPE_FRAME_ANIMATION;
374fb726d48Sopenharmony_ci    frameAnimationRow.rowHidden = !processRow.expansion;
375fb726d48Sopenharmony_ci    frameAnimationRow.rowParentId = processRow.rowId;
376fb726d48Sopenharmony_ci    frameAnimationRow.style.width = '100%';
377fb726d48Sopenharmony_ci    frameAnimationRow.name = 'Animation';
378fb726d48Sopenharmony_ci    frameAnimationRow.addTemplateTypes('AnimationEffect');
379fb726d48Sopenharmony_ci    frameAnimationRow.setAttribute('children', '');
380fb726d48Sopenharmony_ci    let timeRangeData = await queryAnimationTimeRangeData();
381fb726d48Sopenharmony_ci    timeRangeData.forEach((rangeTime) => {
382fb726d48Sopenharmony_ci      if (rangeTime.status === 'Completion delay') {
383fb726d48Sopenharmony_ci        animationRanges.push({
384fb726d48Sopenharmony_ci          start: rangeTime.startTs,
385fb726d48Sopenharmony_ci          end: rangeTime.endTs,
386fb726d48Sopenharmony_ci        });
387fb726d48Sopenharmony_ci      }
388fb726d48Sopenharmony_ci    });
389fb726d48Sopenharmony_ci    let animationIdNameMap: Map<number, string> = new Map<number, string>();
390fb726d48Sopenharmony_ci    let animationIdInfoMap: Map<number, string> = new Map<number, string>();
391fb726d48Sopenharmony_ci    let animationNameData = await queryAnimationIdAndNameData();
392fb726d48Sopenharmony_ci    animationNameData.forEach((item) => {
393fb726d48Sopenharmony_ci      animationIdNameMap.set(item.id, item.name);
394fb726d48Sopenharmony_ci      animationIdInfoMap.set(item.id, item.info);
395fb726d48Sopenharmony_ci    });
396fb726d48Sopenharmony_ci    this.animationChartSupplierFrame(frameAnimationRow, animationIdNameMap, animationIdInfoMap);
397fb726d48Sopenharmony_ci    frameAnimationRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
398fb726d48Sopenharmony_ci    frameAnimationRow.selectChangeHandler = this.trace.selectChangeHandler;
399fb726d48Sopenharmony_ci    this.animationThreadHandler(frameAnimationRow);
400fb726d48Sopenharmony_ci    processRow.addChildTraceRowSpecifyLocation(frameAnimationRow, 0);
401fb726d48Sopenharmony_ci    return animationRanges;
402fb726d48Sopenharmony_ci  }
403fb726d48Sopenharmony_ci
404fb726d48Sopenharmony_ci  private dynamicCurveChartThreadHandler(
405fb726d48Sopenharmony_ci    dynamicCurveRow: TraceRow<FrameDynamicStruct>,
406fb726d48Sopenharmony_ci    animationRanges: AnimationRanges[]
407fb726d48Sopenharmony_ci  ): void {
408fb726d48Sopenharmony_ci    dynamicCurveRow.onThreadHandler = (useCache: boolean): void => {
409fb726d48Sopenharmony_ci      let context: CanvasRenderingContext2D = dynamicCurveRow!.collect
410fb726d48Sopenharmony_ci        ? this.trace.canvasFavoritePanelCtx!
411fb726d48Sopenharmony_ci        : this.trace.canvasPanelCtx!;
412fb726d48Sopenharmony_ci      dynamicCurveRow!.canvasSave(context);
413fb726d48Sopenharmony_ci      (renders.frameDynamicCurve as FrameDynamicRender).renderMainThread(
414fb726d48Sopenharmony_ci        {
415fb726d48Sopenharmony_ci          context: context,
416fb726d48Sopenharmony_ci          useCache: useCache,
417fb726d48Sopenharmony_ci          type: 'dynamicEffectCurve',
418fb726d48Sopenharmony_ci          animationRanges: animationRanges,
419fb726d48Sopenharmony_ci        },
420fb726d48Sopenharmony_ci        dynamicCurveRow!
421fb726d48Sopenharmony_ci      );
422fb726d48Sopenharmony_ci      dynamicCurveRow!.canvasRestore(context, this.trace);
423fb726d48Sopenharmony_ci    };
424fb726d48Sopenharmony_ci  }
425fb726d48Sopenharmony_ci
426fb726d48Sopenharmony_ci  async initDynamicCurveChart(
427fb726d48Sopenharmony_ci    appNameMap: Map<number, string>,
428fb726d48Sopenharmony_ci    frameChart: TraceRow<BaseStruct>,
429fb726d48Sopenharmony_ci    name: string,
430fb726d48Sopenharmony_ci    animationRanges: AnimationRanges[]
431fb726d48Sopenharmony_ci  ): Promise<void> {
432fb726d48Sopenharmony_ci    let systemConfigList: {
433fb726d48Sopenharmony_ci      name: string;
434fb726d48Sopenharmony_ci    }[] = [{ name: 'x' }, { name: 'y' }, { name: 'width' }, { name: 'height' }, { name: 'alpha' }];
435fb726d48Sopenharmony_ci    let dynamicCurveRow: TraceRow<FrameDynamicStruct> = TraceRow.skeleton<FrameDynamicStruct>();
436fb726d48Sopenharmony_ci    this.addSystemConfigButton(dynamicCurveRow, systemConfigList, 'model-type');
437fb726d48Sopenharmony_ci    dynamicCurveRow.setAttribute('model-type', systemConfigList[0].name);
438fb726d48Sopenharmony_ci    dynamicCurveRow.rowId = 'animation-Effect-Curve';
439fb726d48Sopenharmony_ci    dynamicCurveRow.rowType = TraceRow.ROW_TYPE_FRAME_DYNAMIC;
440fb726d48Sopenharmony_ci    dynamicCurveRow.rowHidden = !frameChart.expansion;
441fb726d48Sopenharmony_ci    dynamicCurveRow.rowParentId = frameChart.rowId;
442fb726d48Sopenharmony_ci    dynamicCurveRow.style.width = '100%';
443fb726d48Sopenharmony_ci    dynamicCurveRow.style.height = '40px';
444fb726d48Sopenharmony_ci    dynamicCurveRow.style.height = '100px';
445fb726d48Sopenharmony_ci    let labelName = dynamicCurveRow.shadowRoot?.querySelector('.name') as HTMLLabelElement;
446fb726d48Sopenharmony_ci    labelName.style.marginRight = '77px';
447fb726d48Sopenharmony_ci    dynamicCurveRow.name = 'Animation Effect Curve';
448fb726d48Sopenharmony_ci    dynamicCurveRow.addTemplateTypes('AnimationEffect');
449fb726d48Sopenharmony_ci    dynamicCurveRow.setAttribute('height', '100px');
450fb726d48Sopenharmony_ci    dynamicCurveRow.setAttribute('children', '');
451fb726d48Sopenharmony_ci    dynamicCurveRow.setAttribute('model-type', systemConfigList[0].name);
452fb726d48Sopenharmony_ci    dynamicCurveRow.setAttribute('model-name', name);
453fb726d48Sopenharmony_ci    dynamicCurveRow.supplierFrame = async (): Promise<FrameDynamicStruct[]> => {
454fb726d48Sopenharmony_ci      const result = await frameDynamicSender(dynamicCurveRow);
455fb726d48Sopenharmony_ci      result.forEach((dataItem) => {
456fb726d48Sopenharmony_ci        if (appNameMap.has(dataItem.id!)) {
457fb726d48Sopenharmony_ci          dataItem.appName = appNameMap.get(dataItem.id!);
458fb726d48Sopenharmony_ci        }
459fb726d48Sopenharmony_ci      });
460fb726d48Sopenharmony_ci      return result;
461fb726d48Sopenharmony_ci    };
462fb726d48Sopenharmony_ci    dynamicCurveRow.selectChangeHandler = this.trace.selectChangeHandler;
463fb726d48Sopenharmony_ci    this.dynamicCurveChartThreadHandler(dynamicCurveRow, animationRanges);
464fb726d48Sopenharmony_ci    frameChart.addChildTraceRow(dynamicCurveRow);
465fb726d48Sopenharmony_ci  }
466fb726d48Sopenharmony_ci
467fb726d48Sopenharmony_ci  private FrameSpacingThreadHandler(
468fb726d48Sopenharmony_ci    frameSpacingRow: TraceRow<FrameSpacingStruct>,
469fb726d48Sopenharmony_ci    animationRanges: AnimationRanges[],
470fb726d48Sopenharmony_ci    rate: number
471fb726d48Sopenharmony_ci  ): void {
472fb726d48Sopenharmony_ci    frameSpacingRow.onThreadHandler = (useCache: boolean): void => {
473fb726d48Sopenharmony_ci      let context = frameSpacingRow!.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!;
474fb726d48Sopenharmony_ci      frameSpacingRow!.canvasSave(context);
475fb726d48Sopenharmony_ci      (renders.frameSpacing as FrameSpacingRender).renderMainThread(
476fb726d48Sopenharmony_ci        {
477fb726d48Sopenharmony_ci          context: context,
478fb726d48Sopenharmony_ci          useCache: useCache,
479fb726d48Sopenharmony_ci          type: 'frame_spacing_slice',
480fb726d48Sopenharmony_ci          frameRate: rate,
481fb726d48Sopenharmony_ci          animationRanges: animationRanges,
482fb726d48Sopenharmony_ci        },
483fb726d48Sopenharmony_ci        frameSpacingRow!
484fb726d48Sopenharmony_ci      );
485fb726d48Sopenharmony_ci      frameSpacingRow!.canvasRestore(context, this.trace);
486fb726d48Sopenharmony_ci    };
487fb726d48Sopenharmony_ci  }
488fb726d48Sopenharmony_ci
489fb726d48Sopenharmony_ci  async initFrameSpacing(
490fb726d48Sopenharmony_ci    appNameMap: Map<number, string>,
491fb726d48Sopenharmony_ci    frameChart: TraceRow<BaseStruct>,
492fb726d48Sopenharmony_ci    name: string,
493fb726d48Sopenharmony_ci    animationRanges: AnimationRanges[]
494fb726d48Sopenharmony_ci  ): Promise<void> {
495fb726d48Sopenharmony_ci    let deviceStructArray = await queryPhysicalData();
496fb726d48Sopenharmony_ci    let deviceStruct: DeviceStruct = deviceStructArray[0];
497fb726d48Sopenharmony_ci    let frameSpacingRow = TraceRow.skeleton<FrameSpacingStruct>();
498fb726d48Sopenharmony_ci    frameSpacingRow.rowId = 'frame spacing';
499fb726d48Sopenharmony_ci    frameSpacingRow.rowType = TraceRow.ROW_TYPE_FRAME_SPACING;
500fb726d48Sopenharmony_ci    frameSpacingRow.rowHidden = !frameChart.expansion;
501fb726d48Sopenharmony_ci    frameSpacingRow.rowParentId = frameChart.rowId;
502fb726d48Sopenharmony_ci    frameSpacingRow.style.width = '100%';
503fb726d48Sopenharmony_ci    frameSpacingRow.style.height = '140px';
504fb726d48Sopenharmony_ci    frameSpacingRow.name = 'Frame spacing';
505fb726d48Sopenharmony_ci    frameSpacingRow.addTemplateTypes('AnimationEffect');
506fb726d48Sopenharmony_ci    frameSpacingRow.setAttribute('height', '140');
507fb726d48Sopenharmony_ci    frameSpacingRow.setAttribute('children', '');
508fb726d48Sopenharmony_ci    frameSpacingRow.setAttribute('model-name', name);
509fb726d48Sopenharmony_ci    let physicalConfigWidth = Number(this.flagConfig!.physicalWidth);
510fb726d48Sopenharmony_ci    let physicalConfigHeight = Number(this.flagConfig!.physicalHeight);
511fb726d48Sopenharmony_ci    let physicalWidth = physicalConfigWidth !== 0 ? physicalConfigWidth : deviceStruct.physicalWidth;
512fb726d48Sopenharmony_ci    let physicalHeight = physicalConfigHeight !== 0 ? physicalConfigHeight : deviceStruct.physicalHeight;
513fb726d48Sopenharmony_ci    frameSpacingRow.supplierFrame = async (): Promise<FrameSpacingStruct[]> => {
514fb726d48Sopenharmony_ci      const result = await frameSpacingSender(physicalWidth, physicalHeight, frameSpacingRow);
515fb726d48Sopenharmony_ci      result.forEach((dataItem) => {
516fb726d48Sopenharmony_ci        if (appNameMap.has(dataItem.id!)) {
517fb726d48Sopenharmony_ci          dataItem.nameId = appNameMap.get(dataItem.id!);
518fb726d48Sopenharmony_ci        }
519fb726d48Sopenharmony_ci        dataItem.physicalWidth = physicalWidth;
520fb726d48Sopenharmony_ci        dataItem.physicalHeight = physicalHeight;
521fb726d48Sopenharmony_ci      });
522fb726d48Sopenharmony_ci      return result;
523fb726d48Sopenharmony_ci    };
524fb726d48Sopenharmony_ci    frameSpacingRow.favoriteChangeHandler = this.trace.favoriteChangeHandler;
525fb726d48Sopenharmony_ci    frameSpacingRow.selectChangeHandler = this.trace.selectChangeHandler;
526fb726d48Sopenharmony_ci    this.FrameSpacingThreadHandler(frameSpacingRow, animationRanges, deviceStruct.physicalFrameRate);
527fb726d48Sopenharmony_ci    frameChart.addChildTraceRow(frameSpacingRow);
528fb726d48Sopenharmony_ci  }
529fb726d48Sopenharmony_ci
530fb726d48Sopenharmony_ci  addSystemConfigButton(
531fb726d48Sopenharmony_ci    systemTraceRow: TraceRow<BaseStruct>,
532fb726d48Sopenharmony_ci    systemConfigList: { name: string }[],
533fb726d48Sopenharmony_ci    attributeKey: string,
534fb726d48Sopenharmony_ci    allowChangeName: boolean = false
535fb726d48Sopenharmony_ci  ): void {
536fb726d48Sopenharmony_ci    let componentList: Array<TreeItemData> = [];
537fb726d48Sopenharmony_ci    for (let index = 0; index < systemConfigList.length; index++) {
538fb726d48Sopenharmony_ci      let componentName = systemConfigList[index].name;
539fb726d48Sopenharmony_ci      componentList.push({
540fb726d48Sopenharmony_ci        key: `${componentName}`,
541fb726d48Sopenharmony_ci        title: `${componentName}`,
542fb726d48Sopenharmony_ci        checked: index === 0,
543fb726d48Sopenharmony_ci      });
544fb726d48Sopenharmony_ci    }
545fb726d48Sopenharmony_ci    systemTraceRow.addRowSettingPop();
546fb726d48Sopenharmony_ci    systemTraceRow.rowSetting = 'enable';
547fb726d48Sopenharmony_ci    systemTraceRow.rowSettingPopoverDirection = 'bottomLeft';
548fb726d48Sopenharmony_ci    systemTraceRow.rowSettingList = componentList;
549fb726d48Sopenharmony_ci    systemTraceRow.onRowSettingChangeHandler = (value: string[]): void => {
550fb726d48Sopenharmony_ci      if (allowChangeName) {
551fb726d48Sopenharmony_ci        systemTraceRow.name = value[0];
552fb726d48Sopenharmony_ci      }
553fb726d48Sopenharmony_ci      systemTraceRow.setAttribute(attributeKey, `${value[0]}`);
554fb726d48Sopenharmony_ci      systemTraceRow.childrenList.forEach((row): void => {
555fb726d48Sopenharmony_ci        row.setAttribute(attributeKey, `${value[0]}`);
556fb726d48Sopenharmony_ci      });
557fb726d48Sopenharmony_ci      this.trace.refreshCanvas(false);
558fb726d48Sopenharmony_ci    };
559fb726d48Sopenharmony_ci  }
560fb726d48Sopenharmony_ci
561fb726d48Sopenharmony_ci  private frameNoExpandTimeOut(event: CustomEventInit<unknown>, frameTimeLineRow: TraceRow<JanksStruct>): number {
562fb726d48Sopenharmony_ci    if (JankStruct!.selectJankStruct) {
563fb726d48Sopenharmony_ci      JankStruct.selectJankStructList?.push(<JankStruct>JankStruct!.selectJankStruct);
564fb726d48Sopenharmony_ci    }
565fb726d48Sopenharmony_ci    let topPadding: number = 195;
566fb726d48Sopenharmony_ci    let halfNumber: number = 2;
567fb726d48Sopenharmony_ci    let offsetYTime: number = 300;
568fb726d48Sopenharmony_ci    let refreshTime: number = 360;
569fb726d48Sopenharmony_ci    let offsetYTimeOut: number = window.setTimeout(() => {
570fb726d48Sopenharmony_ci      this.trace.linkNodes.forEach((linkNode: PairPoint[]) => {
571fb726d48Sopenharmony_ci        if (linkNode[0].rowEL.collect) {
572fb726d48Sopenharmony_ci          linkNode[0].rowEL.translateY = linkNode[0].rowEL.getBoundingClientRect().top - topPadding;
573fb726d48Sopenharmony_ci        } else {
574fb726d48Sopenharmony_ci          linkNode[0].rowEL.translateY = linkNode[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop;
575fb726d48Sopenharmony_ci        }
576fb726d48Sopenharmony_ci        linkNode[0].y = linkNode[0].rowEL!.translateY! + linkNode[0].offsetY;
577fb726d48Sopenharmony_ci        if (linkNode[1].rowEL.collect) {
578fb726d48Sopenharmony_ci          linkNode[1].rowEL.translateY = linkNode[1].rowEL.getBoundingClientRect().top - topPadding;
579fb726d48Sopenharmony_ci        } else {
580fb726d48Sopenharmony_ci          linkNode[1].rowEL.translateY = linkNode[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop;
581fb726d48Sopenharmony_ci        }
582fb726d48Sopenharmony_ci        linkNode[1].y = linkNode[1].rowEL!.translateY! + linkNode[1].offsetY; //@ts-ignore
583fb726d48Sopenharmony_ci        if (linkNode[0].rowEL.rowParentId === event.detail?.rowId) {
584fb726d48Sopenharmony_ci          if (!linkNode[0].rowEL.collect) {
585fb726d48Sopenharmony_ci            linkNode[0].x = ns2xByTimeShaft(linkNode[0].ns, this.trace.timerShaftEL!);
586fb726d48Sopenharmony_ci            linkNode[0].y = frameTimeLineRow!.translateY! + linkNode[0].offsetY / halfNumber;
587fb726d48Sopenharmony_ci            linkNode[0].offsetY = linkNode[0].offsetY / halfNumber; //@ts-ignore
588fb726d48Sopenharmony_ci            linkNode[0].rowEL = frameTimeLineRow;
589fb726d48Sopenharmony_ci          } //@ts-ignore
590fb726d48Sopenharmony_ci        } else if (linkNode[1].rowEL.rowParentId === event.detail?.rowId) {
591fb726d48Sopenharmony_ci          if (!linkNode[1].rowEL.collect) {
592fb726d48Sopenharmony_ci            linkNode[1].x = ns2xByTimeShaft(linkNode[1].ns, this.trace.timerShaftEL!);
593fb726d48Sopenharmony_ci            linkNode[1].y = frameTimeLineRow!.translateY! + linkNode[1].offsetY / halfNumber;
594fb726d48Sopenharmony_ci            linkNode[1].offsetY = linkNode[1].offsetY / halfNumber; //@ts-ignore
595fb726d48Sopenharmony_ci            linkNode[1].rowEL = frameTimeLineRow!;
596fb726d48Sopenharmony_ci          }
597fb726d48Sopenharmony_ci        }
598fb726d48Sopenharmony_ci      });
599fb726d48Sopenharmony_ci    }, offsetYTime);
600fb726d48Sopenharmony_ci    let refreshTimeOut: number = window.setTimeout(() => {
601fb726d48Sopenharmony_ci      this.trace.refreshCanvas(true);
602fb726d48Sopenharmony_ci      clearTimeout(refreshTimeOut);
603fb726d48Sopenharmony_ci    }, refreshTime);
604fb726d48Sopenharmony_ci    return offsetYTimeOut;
605fb726d48Sopenharmony_ci  }
606fb726d48Sopenharmony_ci
607fb726d48Sopenharmony_ci  private frameExpandTimeOut(
608fb726d48Sopenharmony_ci    event: CustomEventInit<{ expansion: boolean; rowType: string; rowId: string; rowParentId: string }>,
609fb726d48Sopenharmony_ci    actualTimeLineRow: TraceRow<JanksStruct>
610fb726d48Sopenharmony_ci  ): number {
611fb726d48Sopenharmony_ci    let topPadding: number = 195;
612fb726d48Sopenharmony_ci    let halfNumber: number = 2;
613fb726d48Sopenharmony_ci    let offsetYTime: number = 300;
614fb726d48Sopenharmony_ci    let refreshTime: number = 360;
615fb726d48Sopenharmony_ci    let offsetYTimeOut: number = window.setTimeout(() => {
616fb726d48Sopenharmony_ci      this.trace.linkNodes.forEach((linkFrameNode: PairPoint[]) => {
617fb726d48Sopenharmony_ci        JankStruct.selectJankStructList?.forEach((dat: JankStruct) => {
618fb726d48Sopenharmony_ci          if (event.detail?.rowId === dat.pid) {
619fb726d48Sopenharmony_ci            JankStruct.selectJankStruct = dat;
620fb726d48Sopenharmony_ci            JankStruct.hoverJankStruct = dat;
621fb726d48Sopenharmony_ci          }
622fb726d48Sopenharmony_ci        });
623fb726d48Sopenharmony_ci        if (linkFrameNode[0].rowEL.collect) {
624fb726d48Sopenharmony_ci          linkFrameNode[0].rowEL.translateY = linkFrameNode[0].rowEL.getBoundingClientRect().top - topPadding;
625fb726d48Sopenharmony_ci        } else {
626fb726d48Sopenharmony_ci          linkFrameNode[0].rowEL.translateY = linkFrameNode[0].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop;
627fb726d48Sopenharmony_ci        }
628fb726d48Sopenharmony_ci        linkFrameNode[0].y = linkFrameNode[0].rowEL!.translateY! + linkFrameNode[0].offsetY;
629fb726d48Sopenharmony_ci        if (linkFrameNode[1].rowEL.collect) {
630fb726d48Sopenharmony_ci          linkFrameNode[1].rowEL.translateY = linkFrameNode[1].rowEL.getBoundingClientRect().top - topPadding;
631fb726d48Sopenharmony_ci        } else {
632fb726d48Sopenharmony_ci          linkFrameNode[1].rowEL.translateY = linkFrameNode[1].rowEL.offsetTop - this.trace.rowsPaneEL!.scrollTop;
633fb726d48Sopenharmony_ci        }
634fb726d48Sopenharmony_ci        linkFrameNode[1].y = linkFrameNode[1].rowEL!.translateY! + linkFrameNode[1].offsetY;
635fb726d48Sopenharmony_ci        if (linkFrameNode[0].rowEL.rowId === event.detail?.rowId) {
636fb726d48Sopenharmony_ci          linkFrameNode[0].x = ns2xByTimeShaft(linkFrameNode[0].ns, this.trace.timerShaftEL!);
637fb726d48Sopenharmony_ci          linkFrameNode[0].y = actualTimeLineRow!.translateY! + linkFrameNode[0].offsetY * halfNumber;
638fb726d48Sopenharmony_ci          linkFrameNode[0].offsetY = linkFrameNode[0].offsetY * halfNumber;
639fb726d48Sopenharmony_ci          //@ts-ignore
640fb726d48Sopenharmony_ci          linkFrameNode[0].rowEL = actualTimeLineRow;
641fb726d48Sopenharmony_ci        } else if (linkFrameNode[1].rowEL.rowId === event.detail?.rowId) {
642fb726d48Sopenharmony_ci          linkFrameNode[1].x = ns2xByTimeShaft(linkFrameNode[1].ns, this.trace.timerShaftEL!);
643fb726d48Sopenharmony_ci          linkFrameNode[1].y = actualTimeLineRow!.translateY! + linkFrameNode[1].offsetY * halfNumber;
644fb726d48Sopenharmony_ci          linkFrameNode[1].offsetY = linkFrameNode[1].offsetY * halfNumber;
645fb726d48Sopenharmony_ci          //@ts-ignore
646fb726d48Sopenharmony_ci          linkFrameNode[1].rowEL = actualTimeLineRow!;
647fb726d48Sopenharmony_ci        }
648fb726d48Sopenharmony_ci      });
649fb726d48Sopenharmony_ci    }, offsetYTime);
650fb726d48Sopenharmony_ci    let refreshTimeOut: number = window.setTimeout(() => {
651fb726d48Sopenharmony_ci      this.trace.refreshCanvas(true);
652fb726d48Sopenharmony_ci      clearTimeout(refreshTimeOut);
653fb726d48Sopenharmony_ci    }, refreshTime);
654fb726d48Sopenharmony_ci    return offsetYTimeOut;
655fb726d48Sopenharmony_ci  }
656fb726d48Sopenharmony_ci}
657