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 { LitTable } from '../../../base-ui/table/lit-table'; 20import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; 21import '../../../base-ui/progress-bar/LitProgressBar'; 22import { getDataNo } from './utils/Utils'; 23import './TableNoData'; 24import { TableNoData } from './TableNoData'; 25import { TabCpuDetailsThreadsHtml } from './TabCpuDetailsThreads.html'; 26 27@element('tab-cpu-details-threads') 28export class TabCpuDetailsThreads extends BaseElement { 29 private tableNoData: TableNoData | null | undefined; 30 private cpuDetailsThreadUsageTbl: LitTable | null | undefined; 31 private progress: LitProgressBar | null | undefined; 32 private cpuDetailsThreadPie: LitChartPie | null | undefined; 33 private data: Array<unknown> = []; 34 private cpuDetailsThreadSortColumn: string = ''; 35 private sortType: number = 0; 36 37 initElements(): void { 38 this.tableNoData = this.shadowRoot!.querySelector<TableNoData>('#table-no-data'); 39 this.progress = this.shadowRoot!.querySelector<LitProgressBar>('#loading'); 40 this.cpuDetailsThreadPie = this.shadowRoot!.querySelector<LitChartPie>('#cpu-thread-chart-pie'); 41 this.cpuDetailsThreadUsageTbl = this.shadowRoot!.querySelector<LitTable>('#tb-cpu-usage'); 42 43 this.shadowRoot!.querySelector<HTMLDivElement>('.cpu-thread-go-back')!.onclick = (e): void => { 44 if (!this.progress!.loading) { 45 this.parentNode!.querySelector<HTMLDivElement>('.d-box')!.style.display = 'flex'; 46 this.setShow = false; 47 } 48 }; 49 50 this.cpuDetailsThreadUsageTbl!.addEventListener('row-click', (evt: unknown): void => { 51 // @ts-ignore 52 let data = evt.detail.data; 53 data.isSelected = true; 54 // @ts-ignore 55 if ((evt.detail as unknown).callBack) { 56 // @ts-ignore 57 (evt.detail as unknown).callBack(true); 58 } 59 }); 60 61 this.cpuDetailsThreadUsageTbl!.addEventListener('column-click', (evt: unknown): void => { 62 //@ts-ignore 63 this.cpuDetailsThreadSortColumn = evt.detail.key; //@ts-ignore 64 this.sortType = evt.detail.sort; 65 // @ts-ignore 66 this.sortByColumn(evt.detail); 67 }); 68 this.cpuDetailsThreadUsageTbl!.addEventListener('row-hover', (evt: unknown): void => { 69 //@ts-ignore 70 if (evt.detail.data) { 71 //@ts-ignore 72 let data = evt.detail.data; 73 data.isHover = true; //@ts-ignore 74 if ((evt.detail as unknown).callBack) { 75 //@ts-ignore 76 (evt.detail as unknown).callBack(true); 77 } 78 } 79 this.cpuDetailsThreadPie?.showHover(); 80 }); 81 } 82 83 init(cpu: number, it: unknown): void { 84 this.shadowRoot!.querySelector<HTMLDivElement>('.cpu-thread-subheading')!.textContent = 85 //@ts-ignore 86 `Threads in Freq ${it.value}`; 87 this.progress!.loading = true; 88 procedurePool.submitWithName( 89 'logic0', 90 'scheduling-CPU Frequency Thread', //@ts-ignore 91 { cpu: cpu, freq: (it as unknown).value }, 92 undefined, 93 (res: unknown): void => { 94 this.progress!.loading = false; 95 this.queryPieChartDataByType(res); 96 } 97 ); 98 } 99 100 set setShow(v: boolean) { 101 if (v) { 102 this.style.display = 'flex'; 103 } else { 104 this.clearData(); 105 this.style.display = 'none'; 106 } 107 } 108 109 queryPieChartDataByType(res: unknown): void { 110 //@ts-ignore 111 this.data = res || []; 112 this.data = getDataNo(this.data); 113 this.tableNoData!.noData = this.data.length === 0; 114 this.noData(this.data.length === 0); 115 this.cpuDetailsThreadPie!.config = { 116 appendPadding: 0, 117 data: this.data, 118 angleField: 'dur', 119 colorField: 'tName', 120 radius: 1, 121 label: { 122 type: 'outer', 123 }, 124 tip: (obj): string => { 125 return `<div> 126 <div>t_name:${ 127 // @ts-ignore 128 obj.obj.tName 129 }</div> 130 <div>tid:${ 131 // @ts-ignore 132 obj.obj.tid 133 }</div> 134 <div>p_name:${ 135 // @ts-ignore 136 obj.obj.pName 137 }</div> 138 <div>p_pid:${ 139 // @ts-ignore 140 obj.obj.pid 141 }</div> 142 <div>duration:${ 143 // @ts-ignore 144 obj.obj.durStr 145 }</div> 146 <div>ratio:${ 147 // @ts-ignore 148 obj.obj.ratio 149 }%</div> 150 </div> 151 `; 152 }, 153 hoverHandler: (data): void => { 154 if (data) { 155 this.cpuDetailsThreadUsageTbl!.setCurrentHover(data); 156 } else { 157 this.cpuDetailsThreadUsageTbl!.mouseOut(); 158 } 159 }, 160 interactions: [ 161 { 162 type: 'element-active', 163 }, 164 ], 165 }; 166 if (this.cpuDetailsThreadSortColumn !== '') { 167 this.sortByColumn({ key: this.cpuDetailsThreadSortColumn, sort: this.sortType }); 168 } else { 169 this.cpuDetailsThreadUsageTbl!.recycleDataSource = this.data; 170 } 171 this.cpuDetailsThreadUsageTbl?.reMeauseHeight(); 172 } 173 174 noData(value: boolean): void { 175 this.shadowRoot!.querySelector<HTMLDivElement>('.cpu-thread-chart-box')!.style.display = value ? 'none' : 'block'; 176 this.shadowRoot!.querySelector<HTMLDivElement>('.cpu-thread-table-box')!.style.width = value ? '100%' : '60%'; 177 } 178 179 clearData(): void { 180 this.cpuDetailsThreadPie!.dataSource = []; 181 this.cpuDetailsThreadUsageTbl!.recycleDataSource = []; 182 this.noData(false); 183 } 184 185 sortByColumn(detail: unknown): void { 186 // @ts-ignore 187 function compare(cpuDetailsThreadProperty, sort, type) { 188 return function (a: unknown, b: unknown) { 189 if (type === 'number') { 190 // @ts-ignore 191 return sort === 2 192 // @ts-ignore 193 ? parseFloat(b[cpuDetailsThreadProperty]) - parseFloat(a[cpuDetailsThreadProperty]) 194 // @ts-ignore 195 : parseFloat(a[cpuDetailsThreadProperty]) - parseFloat(b[cpuDetailsThreadProperty]); 196 } else { 197 if (sort === 2) { 198 // @ts-ignore 199 return b[cpuDetailsThreadProperty].toString().localeCompare(a[cpuDetailsThreadProperty].toString()); 200 } else { 201 // @ts-ignore 202 return a[cpuDetailsThreadProperty].toString().localeCompare(b[cpuDetailsThreadProperty].toString()); 203 } 204 } 205 }; 206 } 207 208 // @ts-ignore 209 if (detail.key === 'durStr') { 210 // @ts-ignore 211 detail.key = 'dur'; 212 // @ts-ignore 213 this.data.sort(compare(detail.key, detail.sort, 'number')); 214 } else if ( 215 // @ts-ignore 216 detail.key === 'value' || 217 // @ts-ignore 218 detail.key === 'ratio' || 219 // @ts-ignore 220 detail.key === 'index' || 221 // @ts-ignore 222 detail.key === 'tid' || 223 // @ts-ignore 224 detail.key === 'pid' 225 ) { 226 // @ts-ignore 227 this.data.sort(compare(detail.key, detail.sort, 'number')); 228 } else { 229 // @ts-ignore 230 this.data.sort(compare(detail.key, detail.sort, 'string')); 231 } 232 this.cpuDetailsThreadUsageTbl!.recycleDataSource = this.data; 233 } 234 235 initHtml(): string { 236 return TabCpuDetailsThreadsHtml; 237 } 238} 239