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 { LitTable } from '../../../base-ui/table/lit-table';
18import { procedurePool } from '../../database/Procedure';
19import { info } from '../../../log/Log';
20import '../../../base-ui/chart/pie/LitChartPie';
21import { LitChartPie } from '../../../base-ui/chart/pie/LitChartPie';
22import '../../../base-ui/progress-bar/LitProgressBar';
23import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar';
24import './TableNoData';
25import { TableNoData } from './TableNoData';
26
27@element('top20-process-thread-count')
28export class Top20ProcessThreadCount extends BaseElement {
29  traceChange: boolean = false;
30  private processThreadCountTbl: LitTable | null | undefined;
31  private processThreadCountPie: LitChartPie | null | undefined;
32  private processThreadCountProgress: LitProgressBar | null | undefined;
33  private nodata: TableNoData | null | undefined;
34  private processThreadCountData: Array<unknown> = [];
35
36  initElements(): void {
37    this.nodata = this.shadowRoot!.querySelector<TableNoData>('#nodata');
38    this.processThreadCountProgress = this.shadowRoot!.querySelector<LitProgressBar>('#loading');
39    this.processThreadCountTbl = this.shadowRoot!.querySelector<LitTable>('#tb-process-thread-count');
40    this.processThreadCountPie = this.shadowRoot!.querySelector<LitChartPie>('#pie');
41
42    this.processThreadCountTbl!.addEventListener('row-click', (evt: unknown): void => {
43      //@ts-ignore
44      let data = evt.detail.data;
45      data.isSelected = true;
46      // @ts-ignore
47      if ((evt.detail as unknown).callBack) {
48        // @ts-ignore
49        (evt.detail as unknown).callBack(true);
50      }
51    });
52
53    this.processThreadCountTbl!.addEventListener('column-click', (evt): void => {
54      // @ts-ignore
55      this.sortByColumn(evt.detail);
56    });
57    this.processThreadCountTbl!.addEventListener('row-hover', (evt: unknown): void => {
58      //@ts-ignore
59      if (evt.detail.data) {
60        //@ts-ignore
61        let data = evt.detail.data;
62        data.isHover = true;
63        //@ts-ignore
64        if ((evt.detail as unknown).callBack) {
65          //@ts-ignore
66          (evt.detail as unknown).callBack(true);
67        }
68      }
69      this.processThreadCountPie?.showHover();
70    });
71  }
72
73  init(): void {
74    if (!this.traceChange) {
75      if (this.processThreadCountTbl!.recycleDataSource.length > 0) {
76        this.processThreadCountTbl?.reMeauseHeight();
77      }
78      return;
79    }
80    this.traceChange = false;
81    this.processThreadCountProgress!.loading = true;
82    this.queryLogicWorker(
83      'scheduling-Process ThreadCount',
84      'query Process Thread Count Analysis Time:',
85      (res): void => {
86        //@ts-ignore
87        this.nodata!.noData = res === undefined || res.length === 0;
88        //@ts-ignore
89        this.processThreadCountTbl!.recycleDataSource = res;
90        this.processThreadCountTbl!.reMeauseHeight();
91        //@ts-ignore
92        this.processThreadCountData = res;
93        this.processThreadCountPie!.config = {
94          appendPadding: 10,
95          //@ts-ignore
96          data: res,
97          angleField: 'threadNumber',
98          colorField: 'pid',
99          radius: 0.8,
100          label: {
101            type: 'outer',
102          },
103          hoverHandler: (data): void => {
104            if (data) {
105              this.processThreadCountTbl!.setCurrentHover(data);
106            } else {
107              this.processThreadCountTbl!.mouseOut();
108            }
109          },
110          tip: (obj): string => {
111            return `<div>
112                             <div>pid:${
113                               // @ts-ignore
114                               obj.obj.pid
115                             }</div> 
116                             <div>p_name:${
117                               // @ts-ignore
118                               obj.obj.pName
119                             }</div> 
120                             <div>thread count:${
121                               // @ts-ignore
122                               obj.obj.threadNumber
123                             }</div> 
124                        </div>
125                `;
126          },
127          interactions: [
128            {
129              type: 'element-active',
130            },
131          ],
132        };
133        this.processThreadCountProgress!.loading = false;
134      }
135    );
136  }
137
138  clearData(): void {
139    this.traceChange = true;
140    this.processThreadCountPie!.dataSource = [];
141    this.processThreadCountTbl!.recycleDataSource = [];
142  }
143
144  queryLogicWorker(option: string, log: string, handler: (res: unknown) => void): void {
145    let processThreadCountTime = new Date().getTime();
146    procedurePool.submitWithName('logic0', option, {}, undefined, handler);
147    let durTime = new Date().getTime() - processThreadCountTime;
148    info(log, durTime);
149  }
150
151  sortByColumn(detail: unknown): void {
152    // @ts-ignore
153    function compare(property, sort, type) {
154      return function (a: unknown, b: unknown) {
155        if (type === 'number') {
156          // @ts-ignore
157          return sort === 2
158            ? //@ts-ignore
159              parseFloat(b[property]) - parseFloat(a[property])
160            : //@ts-ignore
161              parseFloat(a[property]) - parseFloat(b[property]);
162        } else {
163          if (sort === 2) {
164            //@ts-ignore
165            return b[property].toString().localeCompare(a[property].toString());
166          } else {
167            //@ts-ignore
168            return a[property].toString().localeCompare(b[property].toString());
169          }
170        }
171      };
172    }
173
174    //@ts-ignore
175    if (detail.key === 'NO' || detail.key === 'pid' || detail.key === 'threadNumber') {
176      //@ts-ignore
177      this.processThreadCountData.sort(compare(detail.key, detail.sort, 'number'));
178    } else {
179      //@ts-ignore
180      this.processThreadCountData.sort(compare(detail.key, detail.sort, 'string'));
181    }
182    this.processThreadCountTbl!.recycleDataSource = this.processThreadCountData;
183  }
184
185  initHtml(): string {
186    return `
187        <style>
188        :host {
189            width: 100%;
190            height: 100%;
191            background-color: var(--dark-background5,#F6F6F6);
192        }
193        .pie-chart{
194            display: flex;
195            box-sizing: border-box;
196            width: 500px;
197            height: 500px;
198        }
199        .tb_thread_count{
200            flex: 1;
201            overflow: auto ;
202            border-radius: 5px;
203            border: solid 1px var(--dark-border1,#e0e0e0);
204            margin: 15px;
205            padding: 5px 15px
206        }
207        .thread-root{
208            width: 100%;
209            height: 100%;
210            box-sizing: border-box;
211            display: flex;
212            flex-direction: row;
213        }
214        </style>
215        <lit-progress-bar id="loading" style="height: 1px;width: 100%" loading></lit-progress-bar>
216        <table-no-data id="nodata" contentHeight="500px">
217        <div class="thread-root">
218            <div style="display: flex;flex-direction: column;align-items: center">
219                <div>Statistics By Thread Count</div>
220                <lit-chart-pie id="pie" class="pie-chart"></lit-chart-pie>
221            </div>
222            <div class="tb_thread_count">
223                <lit-table id="tb-process-thread-count" hideDownload style="height: auto">
224                    <lit-table-column width="1fr" title="NO" data-index="NO" key="NO" align="flex-start" order></lit-table-column>
225                    <lit-table-column width="1fr" title="pid" data-index="pid" key="pid" align="flex-start" order></lit-table-column>
226                    <lit-table-column width="1fr" title="p_name" data-index="pName" key="pName" align="flex-start" order></lit-table-column>
227                    <lit-table-column width="1fr" title="thread count" data-index="threadNumber" key="threadNumber" align="flex-start" order></lit-table-column>        
228                </lit-table>
229            </div>
230        </div>
231        </table-no-data>
232        `;
233  }
234}
235