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