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 { BaseElement, element } from '../../../base-ui/BaseElement';
17fb726d48Sopenharmony_ciimport { SpSchedulingAnalysis } from './SpSchedulingAnalysis';
18fb726d48Sopenharmony_ciimport { DrawerCpuTabs } from './DrawerCpuTabs';
19fb726d48Sopenharmony_ciimport { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie';
20fb726d48Sopenharmony_ciimport { LitDrawer } from '../../../base-ui/drawer/LitDrawer';
21fb726d48Sopenharmony_ciimport '../../../base-ui/drawer/LitDrawer';
22fb726d48Sopenharmony_ciimport './DrawerCpuTabs';
23fb726d48Sopenharmony_ciimport { procedurePool } from '../../database/Procedure';
24fb726d48Sopenharmony_ciimport { info } from '../../../log/Log';
25fb726d48Sopenharmony_ciimport { LitSelect } from '../../../base-ui/select/LitSelect';
26fb726d48Sopenharmony_ciimport '../../../base-ui/progress-bar/LitProgressBar';
27fb726d48Sopenharmony_ciimport { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar';
28fb726d48Sopenharmony_ciimport { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData';
29fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil';
30fb726d48Sopenharmony_ciimport { TabCpuAnalysisHtml } from './TabCpuAnalysis.html';
31fb726d48Sopenharmony_ci
32fb726d48Sopenharmony_ci@element('tab-cpu-analysis')
33fb726d48Sopenharmony_ciexport class TabCpuAnalysis extends BaseElement {
34fb726d48Sopenharmony_ci  private cpuUsageGrid: HTMLDivElement | undefined;
35fb726d48Sopenharmony_ci  private cpuUsageChart: HTMLDivElement | undefined;
36fb726d48Sopenharmony_ci  private drawer: LitDrawer | undefined | null;
37fb726d48Sopenharmony_ci  private cpuPieMap: Map<number, LitChartPie> = new Map<number, LitChartPie>();
38fb726d48Sopenharmony_ci  private schedulingSelect: LitSelect | undefined | null;
39fb726d48Sopenharmony_ci  private drawerCpuTabs: DrawerCpuTabs | undefined | null;
40fb726d48Sopenharmony_ci  private progress: LitProgressBar | null | undefined;
41fb726d48Sopenharmony_ci  private loadingUsage: boolean = false;
42fb726d48Sopenharmony_ci  private loadingPieData: boolean = false;
43fb726d48Sopenharmony_ci
44fb726d48Sopenharmony_ci  initElements(): void {
45fb726d48Sopenharmony_ci    this.progress = this.shadowRoot!.querySelector<LitProgressBar>('#loading');
46fb726d48Sopenharmony_ci    this.cpuUsageGrid = this.shadowRoot?.querySelector('#cpu_usage_table') as HTMLDivElement;
47fb726d48Sopenharmony_ci    this.cpuUsageChart = this.shadowRoot?.querySelector('#cpu_usage_chart') as HTMLDivElement;
48fb726d48Sopenharmony_ci    this.schedulingSelect = this.shadowRoot?.querySelector<LitSelect>('#scheduling_select');
49fb726d48Sopenharmony_ci    this.drawer = this.shadowRoot!.querySelector<LitDrawer>('#drawer-right');
50fb726d48Sopenharmony_ci    this.drawerCpuTabs = this.shadowRoot?.querySelector<DrawerCpuTabs>('#drawer-cpu-tabs');
51fb726d48Sopenharmony_ci    this.schedulingSelect!.onchange = (e): void => {
52fb726d48Sopenharmony_ci      this.loadingPieData = true;
53fb726d48Sopenharmony_ci      this.progress!.loading = this.loadingUsage || this.loadingPieData; //@ts-ignore
54fb726d48Sopenharmony_ci      this.queryPieChartDataByType((e as unknown).detail.text);
55fb726d48Sopenharmony_ci    };
56fb726d48Sopenharmony_ci    this.drawer!.onClose = (): void => {
57fb726d48Sopenharmony_ci      this.drawerCpuTabs!.clearData();
58fb726d48Sopenharmony_ci    };
59fb726d48Sopenharmony_ci  }
60fb726d48Sopenharmony_ci
61fb726d48Sopenharmony_ci  init(): void {
62fb726d48Sopenharmony_ci    this.cpuPieMap.clear();
63fb726d48Sopenharmony_ci    this.cpuUsageGrid!.innerHTML = '';
64fb726d48Sopenharmony_ci    this.cpuUsageChart!.innerHTML = '';
65fb726d48Sopenharmony_ci    this.schedulingSelect!.value = '1';
66fb726d48Sopenharmony_ci    this.cpuUsageGrid!.append(this.createUsageItem('usage', '%'));
67fb726d48Sopenharmony_ci    for (let i = 0; i < SpSchedulingAnalysis.cpuCount; i++) {
68fb726d48Sopenharmony_ci      let cpuPie = new LitChartPie();
69fb726d48Sopenharmony_ci      cpuPie.className = 'pie-chart';
70fb726d48Sopenharmony_ci      this.cpuPieMap.set(i, cpuPie);
71fb726d48Sopenharmony_ci      this.cpuUsageGrid!.append(this.createUsageItem(`CPU: ${i}`, 0));
72fb726d48Sopenharmony_ci      this.cpuUsageChart!.append(this.createUsageChartItem(i, cpuPie));
73fb726d48Sopenharmony_ci    }
74fb726d48Sopenharmony_ci    this.loadingUsage = true;
75fb726d48Sopenharmony_ci    this.loadingPieData = true;
76fb726d48Sopenharmony_ci    this.progress!.loading = this.loadingUsage || this.loadingPieData;
77fb726d48Sopenharmony_ci    this.queryLogicWorker('scheduling-getCpuUsage', 'query Cpu Usage Time:', (res): void => {
78fb726d48Sopenharmony_ci      //@ts-ignore
79fb726d48Sopenharmony_ci      if (res && res.length > 0) {
80fb726d48Sopenharmony_ci        this.cpuUsageGrid!.innerHTML = '';
81fb726d48Sopenharmony_ci        this.cpuUsageGrid!.append(this.createUsageItem('usage', '%'));
82fb726d48Sopenharmony_ci        if (res instanceof Array) {
83fb726d48Sopenharmony_ci          for (let re of res) {
84fb726d48Sopenharmony_ci            this.cpuUsageGrid!.append(this.createUsageItem(`CPU: ${re.cpu}`, ((re.usage || 0) * 100).toFixed(2)));
85fb726d48Sopenharmony_ci          }
86fb726d48Sopenharmony_ci        }
87fb726d48Sopenharmony_ci      }
88fb726d48Sopenharmony_ci      this.loadingUsage = false;
89fb726d48Sopenharmony_ci      this.progress!.loading = this.loadingUsage || this.loadingPieData;
90fb726d48Sopenharmony_ci    });
91fb726d48Sopenharmony_ci    this.queryPieChartDataByType('CPU Idle');
92fb726d48Sopenharmony_ci    SpStatisticsHttpUtil.addOrdinaryVisitAction({
93fb726d48Sopenharmony_ci      event: 'CPU Data',
94fb726d48Sopenharmony_ci      action: 'trace_tab',
95fb726d48Sopenharmony_ci    });
96fb726d48Sopenharmony_ci  }
97fb726d48Sopenharmony_ci
98fb726d48Sopenharmony_ci  queryPieChartDataByType(type: string): void {
99fb726d48Sopenharmony_ci    SpStatisticsHttpUtil.addOrdinaryVisitAction({
100fb726d48Sopenharmony_ci      event: `Analysis ${type}`,
101fb726d48Sopenharmony_ci      action: 'scheduling_analysis',
102fb726d48Sopenharmony_ci    });
103fb726d48Sopenharmony_ci    let tip = '';
104fb726d48Sopenharmony_ci    if (type === 'CPU Frequency') {
105fb726d48Sopenharmony_ci      tip = 'freq:';
106fb726d48Sopenharmony_ci    } else if (type === 'CPU Idle') {
107fb726d48Sopenharmony_ci      tip = 'idle:';
108fb726d48Sopenharmony_ci    } else {
109fb726d48Sopenharmony_ci      tip = 'irq:';
110fb726d48Sopenharmony_ci    }
111fb726d48Sopenharmony_ci    this.queryLogicWorker(`scheduling-${type}`, `query ${type} Analysis Time:`, (res): void => {
112fb726d48Sopenharmony_ci      for (let key of this.cpuPieMap.keys()) {
113fb726d48Sopenharmony_ci        this.cpuPieMap.get(key)!.config = {
114fb726d48Sopenharmony_ci          appendPadding: 10, //@ts-ignore
115fb726d48Sopenharmony_ci          data: res.get(key) || [],
116fb726d48Sopenharmony_ci          angleField: 'sum',
117fb726d48Sopenharmony_ci          colorField: 'value',
118fb726d48Sopenharmony_ci          radius: 0.8,
119fb726d48Sopenharmony_ci          tip: (obj): string => {
120fb726d48Sopenharmony_ci            return `<div>
121fb726d48Sopenharmony_ci                                    <div>${tip}${
122fb726d48Sopenharmony_ci              // @ts-ignore
123fb726d48Sopenharmony_ci              obj.obj.value
124fb726d48Sopenharmony_ci            }</div> 
125fb726d48Sopenharmony_ci                                    <div>ratio:${
126fb726d48Sopenharmony_ci                                      // @ts-ignore
127fb726d48Sopenharmony_ci                                      obj.obj.ratio
128fb726d48Sopenharmony_ci                                    }%</div>
129fb726d48Sopenharmony_ci                                </div>
130fb726d48Sopenharmony_ci                                `;
131fb726d48Sopenharmony_ci          },
132fb726d48Sopenharmony_ci          label: {
133fb726d48Sopenharmony_ci            type: 'outer',
134fb726d48Sopenharmony_ci            color:
135fb726d48Sopenharmony_ci              type !== 'CPU Idle'
136fb726d48Sopenharmony_ci                ? undefined
137fb726d48Sopenharmony_ci                : (it): string => {
138fb726d48Sopenharmony_ci                    //@ts-ignore
139fb726d48Sopenharmony_ci                    return pieChartColors[(it as unknown).value];
140fb726d48Sopenharmony_ci                  },
141fb726d48Sopenharmony_ci          },
142fb726d48Sopenharmony_ci          interactions: [
143fb726d48Sopenharmony_ci            {
144fb726d48Sopenharmony_ci              type: 'element-active',
145fb726d48Sopenharmony_ci            },
146fb726d48Sopenharmony_ci          ],
147fb726d48Sopenharmony_ci        };
148fb726d48Sopenharmony_ci      }
149fb726d48Sopenharmony_ci      this.loadingPieData = false;
150fb726d48Sopenharmony_ci      this.progress!.loading = this.loadingUsage || this.loadingPieData;
151fb726d48Sopenharmony_ci    });
152fb726d48Sopenharmony_ci  }
153fb726d48Sopenharmony_ci
154fb726d48Sopenharmony_ci  queryLogicWorker(cpuAnalysisType: string, log: string, handler: (res: unknown) => void): void {
155fb726d48Sopenharmony_ci    let cpuAnalysisTime = new Date().getTime();
156fb726d48Sopenharmony_ci    procedurePool.submitWithName(
157fb726d48Sopenharmony_ci      'logic0',
158fb726d48Sopenharmony_ci      cpuAnalysisType,
159fb726d48Sopenharmony_ci      {
160fb726d48Sopenharmony_ci        endTs: SpSchedulingAnalysis.endTs,
161fb726d48Sopenharmony_ci        total: SpSchedulingAnalysis.totalDur,
162fb726d48Sopenharmony_ci      },
163fb726d48Sopenharmony_ci      undefined,
164fb726d48Sopenharmony_ci      handler
165fb726d48Sopenharmony_ci    );
166fb726d48Sopenharmony_ci    let durTime = new Date().getTime() - cpuAnalysisTime;
167fb726d48Sopenharmony_ci    info(log, durTime);
168fb726d48Sopenharmony_ci  }
169fb726d48Sopenharmony_ci
170fb726d48Sopenharmony_ci  createUsageItem(name: string, value: unknown): HTMLDivElement {
171fb726d48Sopenharmony_ci    let div = document.createElement('div');
172fb726d48Sopenharmony_ci    div.className = 'usage_item_box';
173fb726d48Sopenharmony_ci    div.innerHTML = `<div class="usage_item">${name}</div><div class="usage_item">${value}</div>`;
174fb726d48Sopenharmony_ci    return div;
175fb726d48Sopenharmony_ci  }
176fb726d48Sopenharmony_ci
177fb726d48Sopenharmony_ci  createUsageChartItem(cpu: number, pie: LitChartPie): HTMLDivElement {
178fb726d48Sopenharmony_ci    let div = document.createElement('div');
179fb726d48Sopenharmony_ci    div.className = 'usage_chart';
180fb726d48Sopenharmony_ci    div.style.cursor = 'pointer';
181fb726d48Sopenharmony_ci    div.innerHTML = `
182fb726d48Sopenharmony_ci            <div style="height: 40px;line-height: 40px;margin-left: 10px">CPU: ${cpu}</div>
183fb726d48Sopenharmony_ci        `;
184fb726d48Sopenharmony_ci    div.append(pie);
185fb726d48Sopenharmony_ci    div.addEventListener('click', (): void => {
186fb726d48Sopenharmony_ci      if (this.loadingUsage || this.loadingPieData) {
187fb726d48Sopenharmony_ci        return;
188fb726d48Sopenharmony_ci      }
189fb726d48Sopenharmony_ci      this.drawer!.drawerTitle = `CPU: ${cpu}`;
190fb726d48Sopenharmony_ci      this.drawer!.visible = true;
191fb726d48Sopenharmony_ci      this.drawerCpuTabs!.init(cpu, this.schedulingSelect!.value);
192fb726d48Sopenharmony_ci    });
193fb726d48Sopenharmony_ci    return div;
194fb726d48Sopenharmony_ci  }
195fb726d48Sopenharmony_ci
196fb726d48Sopenharmony_ci  initHtml(): string {
197fb726d48Sopenharmony_ci    return TabCpuAnalysisHtml;
198fb726d48Sopenharmony_ci  }
199fb726d48Sopenharmony_ci}
200