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 { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie';
18import { procedurePool } from '../../database/Procedure';
19import { SpSchedulingAnalysis } from './SpSchedulingAnalysis';
20import { info } from '../../../log/Log';
21import { LitTable } from '../../../base-ui/table/lit-table';
22import '../../../base-ui/progress-bar/LitProgressBar';
23import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar';
24import { getDataNo } from './utils/Utils';
25import './TableNoData';
26import { TableNoData } from './TableNoData';
27import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData';
28import { TabCpuDetailsIdleHtml } from './TabCpuDetailsIdle.html';
29
30@element('tab-cpu-details-idle')
31export class TabCpuDetailsIdle extends BaseElement {
32  private tableNoData: TableNoData | null | undefined;
33  private cpuDetailsLdlUsageTbl: LitTable | null | undefined;
34  private cpuDetailsLdlProgress: LitProgressBar | null | undefined;
35  traceChange: boolean = false;
36  private cpuDetailsLdlPie: LitChartPie | null | undefined;
37  private cpuDetailsLdlData: Array<unknown> = [];
38  private cpuDetailsLdlSortColumn: string = '';
39  private sortType: number = 0;
40
41  initElements(): void {
42    this.tableNoData = this.shadowRoot!.querySelector<TableNoData>('#table-no-data');
43    this.cpuDetailsLdlProgress = this.shadowRoot!.querySelector<LitProgressBar>('#loading');
44    this.cpuDetailsLdlPie = this.shadowRoot!.querySelector<LitChartPie>('#cpu_idle_chart-pie');
45    this.cpuDetailsLdlUsageTbl = this.shadowRoot!.querySelector<LitTable>('#idle-tb-cpu-usage');
46
47    this.cpuDetailsLdlUsageTbl!.addEventListener('row-click', (evt: unknown): void => {
48      // @ts-ignore
49      let data = evt.detail.data;
50      data.isSelected = true;
51      // @ts-ignore
52      if ((evt.detail as unknown).callBack) {
53        // @ts-ignore
54        (evt.detail as unknown).callBack(true);
55      }
56    });
57
58    this.cpuDetailsLdlUsageTbl!.addEventListener('column-click', (evt: unknown): void => {
59      //@ts-ignore
60      this.cpuDetailsLdlSortColumn = evt.detail.key; //@ts-ignore
61      this.sortType = evt.detail.sort;
62      // @ts-ignore
63      this.sortByColumn(evt.detail);
64    });
65    this.cpuDetailsLdlUsageTbl!.addEventListener('row-hover', (evt: unknown): void => {
66      //@ts-ignore
67      if (evt.detail.data) {
68        //@ts-ignore
69        let data = evt.detail.data;
70        data.isHover = true; //@ts-ignore
71        if ((evt.detail as unknown).callBack) {
72          //@ts-ignore
73          (evt.detail as unknown).callBack(true);
74        }
75      }
76      this.cpuDetailsLdlPie?.showHover();
77    });
78  }
79
80  init(cpu: number): void {
81    this.queryPieChartDataByType('CPU Idle', cpu);
82  }
83
84  queryPieChartDataByType(type: string, cpu: number): void {
85    if (this.traceChange) {
86      return;
87    }
88    this.cpuDetailsLdlProgress!.loading = true;
89    this.queryLoginWorker(`scheduling-${type}`, 'query Cpu Frequency Analysis Time:', (res): void => {
90      this.traceChange = true;
91      this.cpuDetailsLdlProgress!.loading = false; //@ts-ignore
92      this.cpuDetailsLdlData = res.get(cpu) || [];
93      this.cpuDetailsLdlData = getDataNo(this.cpuDetailsLdlData);
94      this.tableNoData!.noData = this.cpuDetailsLdlData.length === 0;
95      this.noData(this.cpuDetailsLdlData.length === 0);
96      this.setLdlPieConfig(type);
97      if (this.cpuDetailsLdlSortColumn !== '') {
98        this.sortByColumn({
99          key: this.cpuDetailsLdlSortColumn,
100          sort: this.sortType,
101        });
102      } else {
103        this.cpuDetailsLdlUsageTbl!.recycleDataSource = this.cpuDetailsLdlData;
104      }
105      this.cpuDetailsLdlUsageTbl?.reMeauseHeight();
106    });
107  }
108
109  private setLdlPieConfig(type: string): void {
110    this.cpuDetailsLdlPie!.config = {
111      appendPadding: 0,
112      data: this.cpuDetailsLdlData,
113      angleField: 'sum',
114      colorField: 'value',
115      radius: 1,
116      label: {
117        type: 'outer',
118        color:
119          type !== 'CPU Idle'
120            ? undefined
121            : (it): string => {
122                //@ts-ignore
123                return pieChartColors[(it as unknown).value];
124              },
125      },
126      hoverHandler: (data): void => {
127        if (data) {
128          this.cpuDetailsLdlUsageTbl!.setCurrentHover(data);
129        } else {
130          this.cpuDetailsLdlUsageTbl!.mouseOut();
131        }
132      },
133      tip: (idleObj): string => {
134        return `<div>
135                                <div>idle:${
136                                  // @ts-ignore
137                                  idleObj.obj.value
138                                }</div> 
139                                <div>min:${
140                                  // @ts-ignore
141                                  idleObj.obj.min
142                                }</div>
143                                <div>max:${
144                                  // @ts-ignore
145                                  idleObj.obj.max
146                                }</div>
147                                <div>average:${
148                                  // @ts-ignore
149                                  idleObj.obj.avg
150                                }</div>
151                                <div>duration:${
152                                  // @ts-ignore
153                                  idleObj.obj.sumTimeStr
154                                }</div>
155                                <div>ratio:${
156                                  // @ts-ignore
157                                  idleObj.obj.ratio
158                                }%</div>
159                            </div>
160                                `;
161      },
162      interactions: [
163        {
164          type: 'element-active',
165        },
166      ],
167    };
168  }
169
170  noData(value: boolean): void {
171    this.shadowRoot!.querySelector<HTMLDivElement>('.idle-chart-box')!.style.display = value ? 'none' : 'block';
172    this.shadowRoot!.querySelector<HTMLDivElement>('.cpu_idle_table-box')!.style.width = value ? '100%' : '60%';
173  }
174
175  clearData(): void {
176    this.traceChange = false;
177    this.cpuDetailsLdlPie!.dataSource = [];
178    this.cpuDetailsLdlUsageTbl!.recycleDataSource = [];
179    this.noData(false);
180  }
181
182  queryLoginWorker(idleType: string, log: string, handler: (res: unknown) => void): void {
183    let cpuDetailsldleTime = new Date().getTime();
184    procedurePool.submitWithName(
185      'logic0',
186      idleType,
187      {
188        endTs: SpSchedulingAnalysis.endTs,
189        total: SpSchedulingAnalysis.totalDur,
190      },
191      undefined,
192      handler
193    );
194    let durTime = new Date().getTime() - cpuDetailsldleTime;
195    info(log, durTime);
196  }
197
198  sortByColumn(detail: unknown): void {
199    // @ts-ignore
200    function compare(cpuDetailsLdlProperty, sort, type) {
201      return function (a: unknown, b: unknown) {
202        if (type === 'number') {
203          return sort === 2
204            ? // @ts-ignore
205              parseFloat(b[cpuDetailsLdlProperty]) - parseFloat(a[cpuDetailsLdlProperty])
206            : //@ts-ignore
207              parseFloat(a[cpuDetailsLdlProperty]) - parseFloat(b[cpuDetailsLdlProperty]);
208        } else {
209          if (sort === 2) {
210            //@ts-ignore
211            return b[cpuDetailsLdlProperty].toString().localeCompare(a[cpuDetailsLdlProperty].toString());
212          } else {
213            //@ts-ignore
214            return a[cpuDetailsLdlProperty].toString().localeCompare(b[cpuDetailsLdlProperty].toString());
215          }
216        }
217      };
218    }
219
220    //@ts-ignore
221    if (detail.key === 'min') {
222      //@ts-ignore
223      detail.key = 'minValue'; //@ts-ignore
224      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'number')); //@ts-ignore
225    } else if (detail.key === 'max') {
226      //@ts-ignore
227      detail.key = 'maxValue'; //@ts-ignore
228      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'number')); //@ts-ignore
229    } else if (detail.key === 'avg') {
230      //@ts-ignore
231      detail.key = 'avgValue'; //@ts-ignore
232      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'number')); //@ts-ignore
233    } else if (detail.key === 'sumTimeStr') {
234      //@ts-ignore
235      detail.key = 'sum'; //@ts-ignore
236      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'number')); //@ts-ignore
237    } else if (detail.key === 'value' || detail.key === 'ratio' || detail.key === 'index') {
238      //@ts-ignore
239      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'number'));
240    } else {
241      //@ts-ignore
242      this.cpuDetailsLdlData.sort(compare(detail.key, detail.sort, 'string'));
243    }
244    this.cpuDetailsLdlUsageTbl!.recycleDataSource = this.cpuDetailsLdlData;
245  }
246
247  initHtml(): string {
248    return TabCpuDetailsIdleHtml;
249  }
250}
251