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 { XpowerStatisticStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerStatistic'; 23import { SpChartList } from '../../SpChartList'; 24 25@element('tabpane-xpower-statistic') 26export class TabPaneXpowerStatistic extends BaseElement { 27 private xpowerCounterTbl: LitTable | null | undefined; 28 private xpowerCounterRange: HTMLLabelElement | null | undefined; 29 private xpowerCounterSource: Array<SelectionData> = []; 30 private systemTrace: SpSystemTrace | undefined | null; 31 private spChartList: SpChartList | undefined | null; 32 private traceRow: TraceRow<XpowerStatisticStruct> | undefined | null; 33 private tabTitle: HTMLDivElement | undefined | null; 34 private checked: boolean[] = []; 35 private checkedValue: string[] = []; 36 37 set data(xpowerCounterValue: SelectionParam) { 38 this.init(); 39 //@ts-ignore 40 this.xpowerCounterTbl?.shadowRoot?.querySelector('.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<XpowerStatisticStruct>>( 47 "trace-row[row-id='Statistic']" 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='Statistic']"); 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.xpowerStatisticMapData; 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 res!.forEach((item) => { 70 // @ts-ignore 71 item.typeStr = SpSystemTrace.DATA_DICT.get(item.type)!; 72 }); 73 let xpowerStasticMap = new Map< 74 string, 75 { startTime: number; dur: number; energy: number; type: number; typeStr: string }[] 76 >(); 77 // @ts-ignore 78 res.forEach((item: { startTime: number; dur: number; energy: number; type: number; typeStr: string }) => { 79 if (xpowerStasticMap.has(item.typeStr)) { 80 let data = xpowerStasticMap.get(item.typeStr); 81 data!.push(item); 82 xpowerStasticMap.set(item.typeStr, data!); 83 } else { 84 xpowerStasticMap.set(item.typeStr, []); 85 let data = xpowerStasticMap.get(item.typeStr); 86 data!.push(item); 87 xpowerStasticMap.set(item.typeStr, data!); 88 } 89 }); 90 xpowerStasticMap.forEach((value, key) => { 91 !this.checked[this.checkedValue.indexOf(key)] && xpowerStasticMap.delete(key); 92 }); 93 xpowerStasticMap.forEach((value) => { 94 let sd = this.createSelectCounterData(value); 95 dataSource.push(sd); 96 }); 97 } 98 this.xpowerCounterTbl!.loading = false; 99 this.xpowerCounterSource = dataSource; 100 this.xpowerCounterTbl!.recycleDataSource = dataSource; 101 } 102 103 initElements(): void { 104 this.systemTrace = document 105 .querySelector('body > sp-application') 106 ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace'); 107 this.xpowerCounterTbl = this.shadowRoot?.querySelector<LitTable>('#tb-counter'); 108 this.tabTitle = this.xpowerCounterTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement; 109 this.xpowerCounterRange = this.shadowRoot?.querySelector('#time-range'); 110 this.xpowerCounterTbl!.addEventListener('column-click', (evt): void => { 111 // @ts-ignore 112 this.sortByColumn(evt.detail); 113 }); 114 } 115 116 connectedCallback(): void { 117 super.connectedCallback(); 118 resizeObserver(this.parentElement!, this.xpowerCounterTbl!); 119 } 120 121 initHtml(): string { 122 return ` 123 <style> 124 .xpower-counter-label{ 125 margin-bottom: 5px; 126 } 127 :host{ 128 padding: 10px 10px; 129 display: flex; 130 flex-direction: column; 131 } 132 </style> 133 <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> 134 <lit-table id="tb-counter" style="height: auto"> 135 <lit-table-column order title="Name" data-index="name" key="name" align="flex-start" width="20%"> 136 </lit-table-column> 137 <lit-table-column data-index="count" order title="Count" key="count" align="flex-start" width="1fr"> 138 </lit-table-column> 139 <lit-table-column title="Avg_Energy(mAh)" key="average" order data-index="average" align="flex-start" width="1fr"> 140 </lit-table-column> 141 <lit-table-column title="Max_Energy(mAh)" order data-index="max" key="max" align="flex-start" width="1fr"> 142 </lit-table-column> 143 <lit-table-column data-index="min" title="Min_Energy(mAh)" order key="min" align="flex-start" width="1fr"> 144 </lit-table-column> 145 </lit-table> 146 `; 147 } 148 149 createSelectCounterData( 150 list: { startTime: number; dur: number; energy: number; type: number; typeStr: string }[] 151 ): SelectionData { 152 let selectCounterData = new SelectionData(); 153 if (list.length > 0) { 154 selectCounterData.name = list[0].typeStr; 155 selectCounterData.count = list.length.toString(); 156 let max = list[0].energy; 157 let min = list[0].energy; 158 let total = 0; 159 list.forEach((item) => { 160 max < item.energy && (max = item.energy); 161 min > item.energy && (min = item.energy); 162 total += item.energy; 163 }); 164 selectCounterData.max = max.toString(); 165 selectCounterData.min = min.toString(); 166 selectCounterData.average = (total / list.length).toFixed(2); 167 } 168 return selectCounterData; 169 } 170 171 sortByColumn(detail: { key: string; sort: number }): void { 172 // @ts-ignore 173 function compare(property, sort, type) { 174 return function (xpowerCounterLeftData: SelectionData, xpowerCounterRightData: SelectionData): number { 175 if (xpowerCounterLeftData.process === ' ' || xpowerCounterRightData.process === ' ') { 176 return 0; 177 } 178 if (type === 'number') { 179 return sort === 2 // @ts-ignore 180 ? parseFloat(xpowerCounterRightData[property]) - parseFloat(xpowerCounterLeftData[property]) // @ts-ignore 181 : parseFloat(xpowerCounterLeftData[property]) - parseFloat(xpowerCounterRightData[property]); 182 } else { 183 // @ts-ignore 184 if (xpowerCounterRightData[property] > xpowerCounterLeftData[property]) { 185 return sort === 2 ? 1 : -1; 186 } else { 187 // @ts-ignore 188 if (xpowerCounterRightData[property] === xpowerCounterLeftData[property]) { 189 return 0; 190 } else { 191 return sort === 2 ? -1 : 1; 192 } 193 } 194 } 195 }; 196 } 197 if (detail.key === 'name') { 198 this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'string')); 199 } else { 200 this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number')); 201 } 202 this.xpowerCounterTbl!.recycleDataSource = this.xpowerCounterSource; 203 } 204 205 private init(): void { 206 const thTable = this.tabTitle!.querySelector('.th'); 207 const list = thTable!.querySelectorAll('div'); 208 if (this.tabTitle!.hasAttribute('sort')) { 209 this.tabTitle!.removeAttribute('sort'); 210 list.forEach((item) => { 211 item.querySelectorAll('svg').forEach((svg) => { 212 svg.style.display = 'none'; 213 }); 214 }); 215 } 216 } 217} 218