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 { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; 19import { resizeObserver } from '../SheetUtils'; 20import { TraceRow } from '../../base/TraceRow'; 21import { SpSystemTrace } from '../../../SpSystemTrace'; 22import { XpowerAppDetailStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerAppDetail'; 23import { Utils } from '../../base/Utils'; 24import { SpChartList } from '../../SpChartList'; 25 26@element('tabpane-xpower-display') 27export class TabPaneXpowerDisplay extends BaseElement { 28 private xpowerCounterTbl: LitTable | null | undefined; 29 private xpowerCounterRange: HTMLLabelElement | null | undefined; 30 private xpowerCounterSource: Array<SelectionData> = []; 31 private systemTrace: SpSystemTrace | undefined | null; 32 private spChartList: SpChartList | undefined | null; 33 private traceRow: TraceRow<XpowerAppDetailStruct> | undefined | null; 34 private tabTitle: HTMLDivElement | undefined | null; 35 private checked: boolean[] = []; 36 private checkedValue: string[] = []; 37 38 set data(xpowerCounterValue: SelectionParam) { 39 this.init(); 40 this.xpowerCounterTbl!.shadowRoot!.querySelector<HTMLElement>('.table')!.style.height = `${ 41 this.parentElement!.clientHeight - 45 42 }px`; 43 this.xpowerCounterRange!.textContent = `Selected range: ${parseFloat( 44 ((xpowerCounterValue.rightNs - xpowerCounterValue.leftNs) / 1000000.0).toFixed(5) 45 )} ms`; 46 this.traceRow = this.systemTrace!.shadowRoot?.querySelector<TraceRow<XpowerAppDetailStruct>>( 47 "trace-row[row-id='AppDetailDisplay']" 48 ); 49 if (!this.traceRow) { 50 this.spChartList = this.systemTrace!.shadowRoot?.querySelector('div > sp-chart-list'); 51 this.traceRow = this.spChartList?.shadowRoot!.querySelector(".root > div > trace-row[row-id='AppDetailDisplay']"); 52 } 53 this.checked = this.traceRow!.rowSettingCheckedBoxList!; 54 this.checkedValue = this.traceRow!.rowSettingCheckBoxList!; 55 this.getCounterData(xpowerCounterValue).then(); 56 } 57 58 async getCounterData(xpowerCounterValue: SelectionParam): Promise<void> { 59 let dataSource: Array<SelectionData> = []; 60 let collect = xpowerCounterValue.xpowerDisplayMapData; 61 this.xpowerCounterTbl!.loading = true; 62 for (let key of collect.keys()) { 63 let counters = collect.get(key); 64 let res = await counters?.({ 65 startNS: xpowerCounterValue.leftNs, 66 endNS: xpowerCounterValue.rightNs, 67 queryAll: true, 68 }); 69 let xpowerDisplayMap = new Map<string, number[]>(); 70 this.checkedValue.forEach((key) => { 71 res!.forEach((item) => { 72 // @ts-ignore 73 let value = item['c' + key]; 74 if (xpowerDisplayMap.has(key) && value !== 0) { 75 let data = xpowerDisplayMap.get(key); 76 data!.push(value); 77 xpowerDisplayMap.set(key, data!); 78 } else if (value !== 0) { 79 xpowerDisplayMap.set(key, []); 80 let data = xpowerDisplayMap.get(key); 81 data!.push(value); 82 xpowerDisplayMap.set(key, data!); 83 } 84 }); 85 }); 86 xpowerDisplayMap.forEach((value, key) => { 87 !this.checked[this.checkedValue.indexOf(key)] && xpowerDisplayMap.has(key) && xpowerDisplayMap.delete(key); 88 }); 89 xpowerDisplayMap.forEach((value, key) => { 90 let sd = this.createSelectCounterData(value, key); 91 dataSource.push(sd); 92 }); 93 } 94 this.xpowerCounterTbl!.loading = false; 95 this.xpowerCounterSource = dataSource; 96 this.xpowerCounterTbl!.recycleDataSource = dataSource; 97 } 98 99 initElements(): void { 100 this.systemTrace = document 101 .querySelector('body > sp-application') 102 ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace'); 103 this.xpowerCounterTbl = this.shadowRoot?.querySelector<LitTable>('#tb-counter'); 104 this.tabTitle = this.xpowerCounterTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement; 105 this.xpowerCounterRange = this.shadowRoot?.querySelector('#time-range'); 106 this.xpowerCounterTbl!.addEventListener('column-click', (evt): void => { 107 // @ts-ignore 108 this.sortByColumn(evt.detail); 109 }); 110 } 111 112 connectedCallback(): void { 113 super.connectedCallback(); 114 resizeObserver(this.parentElement!, this.xpowerCounterTbl!); 115 } 116 117 initHtml(): string { 118 return ` 119 <style> 120 .xpower-counter-label{ 121 margin-bottom: 5px; 122 } 123 :host{ 124 padding: 10px 10px; 125 display: flex; 126 flex-direction: column; 127 } 128 </style> 129 <label id="time-range" class="xpower-counter-label" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label> 130 <lit-table id="tb-counter" style="height: auto"> 131 <lit-table-column order title="Name" data-index="name" key="name" align="flex-start" width="20%"> 132 </lit-table-column> 133 <lit-table-column data-index="count" order title="Count" key="count" align="flex-start" width="1fr"> 134 </lit-table-column> 135 <lit-table-column title="Max(ms)" order data-index="max" key="max" align="flex-start" width="1fr"> 136 </lit-table-column> 137 <lit-table-column data-index="min" title="Min(ms)" order key="min" align="flex-start" width="1fr"> 138 </lit-table-column> 139 <lit-table-column title="Avg(ms)" key="average" order data-index="average" align="flex-start" width="1fr"> 140 </lit-table-column> 141 </lit-table> 142 `; 143 } 144 145 createSelectCounterData(list: number[], key: string): SelectionData { 146 let selectCounterData = new SelectionData(); 147 if (list.length > 0) { 148 selectCounterData.name = key; 149 selectCounterData.count = list.length.toString(); 150 let max = list[0]; 151 let min = list[0]; 152 let total = 0; 153 list.forEach((item) => { 154 max < item && (max = item); 155 min > item && (min = item); 156 total += item; 157 }); 158 selectCounterData.max = max.toString(); 159 selectCounterData.min = min.toString(); 160 selectCounterData.average = (total / list.length).toFixed(2); 161 } 162 return selectCounterData; 163 } 164 165 sortByColumn(detail: { key: string; sort: number }): void { 166 // @ts-ignore 167 function compare(property, sort, type) { 168 return function (xpowerCounterLeftData: SelectionData, xpowerCounterRightData: SelectionData): number { 169 if (xpowerCounterLeftData.process === ' ' || xpowerCounterRightData.process === ' ') { 170 return 0; 171 } 172 if (type === 'number') { 173 return sort === 2 // @ts-ignore 174 ? parseFloat(xpowerCounterRightData[property]) - parseFloat(xpowerCounterLeftData[property]) // @ts-ignore 175 : parseFloat(xpowerCounterLeftData[property]) - parseFloat(xpowerCounterRightData[property]); 176 } else { 177 // @ts-ignore 178 if (xpowerCounterRightData[property] > xpowerCounterLeftData[property]) { 179 return sort === 2 ? 1 : -1; 180 } else { 181 // @ts-ignore 182 if (xpowerCounterRightData[property] === xpowerCounterLeftData[property]) { 183 return 0; 184 } else { 185 return sort === 2 ? -1 : 1; 186 } 187 } 188 } 189 }; 190 } 191 if (detail.key === 'name') { 192 this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number')); 193 } else { 194 this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number')); 195 } 196 this.xpowerCounterTbl!.recycleDataSource = this.xpowerCounterSource; 197 } 198 199 private init(): void { 200 const thTable = this.tabTitle!.querySelector('.th'); 201 const list = thTable!.querySelectorAll('div'); 202 if (this.tabTitle!.hasAttribute('sort')) { 203 this.tabTitle!.removeAttribute('sort'); 204 list.forEach((item) => { 205 item.querySelectorAll('svg').forEach((svg) => { 206 svg.style.display = 'none'; 207 }); 208 }); 209 } 210 } 211} 212