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'; 20 21@element('tabpane-clock-counter') 22export class TabPaneClockCounter extends BaseElement { 23 private clockCounterTbl: LitTable | null | undefined; 24 private clockCounterRange: HTMLLabelElement | null | undefined; 25 private clockCounterSource: Array<SelectionData> = []; 26 27 set data(clockCounterValue: SelectionParam) { 28 //@ts-ignore 29 this.clockCounterTbl?.shadowRoot?.querySelector('.table')?.style?.height = `${ 30 this.parentElement!.clientHeight - 45 31 }px`; 32 this.clockCounterRange!.textContent = `Selected range: ${parseFloat( 33 ((clockCounterValue.rightNs - clockCounterValue.leftNs) / 1000000.0).toFixed(5) 34 )} ms`; 35 this.getCounterData(clockCounterValue).then(); 36 } 37 38 async getCounterData(clockCounterValue: SelectionParam): Promise<void> { 39 let dataSource: Array<SelectionData> = []; 40 let collect = clockCounterValue.clockMapData; 41 let sumCount = 0; 42 this.clockCounterTbl!.loading = true; 43 for (let key of collect.keys()) { 44 let counters = collect.get(key); 45 let res = await counters?.({ 46 startNS: clockCounterValue.leftNs, 47 endNS: clockCounterValue.rightNs, 48 queryAll: true, 49 }); 50 let sd = this.createSelectCounterData(key, res || [], clockCounterValue.leftNs, clockCounterValue.rightNs); 51 sumCount += Number.parseInt(sd.count || '0'); 52 dataSource.push(sd); 53 } 54 let sumData = new SelectionData(); 55 sumData.count = sumCount.toString(); 56 sumData.process = ' '; 57 dataSource.splice(0, 0, sumData); 58 this.clockCounterTbl!.loading = false; 59 this.clockCounterSource = dataSource; 60 this.clockCounterTbl!.recycleDataSource = dataSource; 61 } 62 63 initElements(): void { 64 this.clockCounterTbl = this.shadowRoot?.querySelector<LitTable>('#tb-counter'); 65 this.clockCounterRange = this.shadowRoot?.querySelector('#time-range'); 66 this.clockCounterTbl!.addEventListener('column-click', (evt): void => { 67 // @ts-ignore 68 this.sortByColumn(evt.detail); 69 }); 70 } 71 72 connectedCallback(): void { 73 super.connectedCallback(); 74 resizeObserver(this.parentElement!, this.clockCounterTbl!); 75 } 76 77 initHtml(): string { 78 return ` 79 <style> 80 .clock-counter-label{ 81 margin-bottom: 5px; 82 } 83 :host{ 84 padding: 10px 10px; 85 display: flex; 86 flex-direction: column; 87 } 88 </style> 89 <label id="time-range" class="clock-counter-label" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label> 90 <lit-table id="tb-counter" style="height: auto"> 91 <lit-table-column order title="Name" data-index="name" key="name" align="flex-start" width="25%"> 92 </lit-table-column> 93 <lit-table-column data-index="delta" order title="Delta value" key="delta" align="flex-start" width="1fr"> 94 </lit-table-column> 95 <lit-table-column title="Rate /s" key="rate" order data-index="rate" align="flex-start" width="1fr"> 96 </lit-table-column> 97 <lit-table-column title="Weighted avg value" order data-index="avgWeight" key="avgWeight" align="flex-start" width="1fr"> 98 </lit-table-column> 99 <lit-table-column data-index="count" title="Count" order key="count" align="flex-start" width="1fr"> 100 </lit-table-column> 101 <lit-table-column title="First value" data-index="first" order key="first" align="flex-start" width="1fr"> 102 </lit-table-column> 103 <lit-table-column title="Last value" align="flex-start" order data-index="last" key="last" width="1fr"> 104 </lit-table-column> 105 <lit-table-column title="Min value" key="min" data-index="min" order align="flex-start" width="1fr"> 106 </lit-table-column> 107 <lit-table-column data-index="max" title="Max value" key="max" order align="flex-start" width="1fr"> 108 </lit-table-column> 109 </lit-table> 110 `; 111 } 112 113 createSelectCounterData(name: string, list: Array<unknown>, leftNs: number, rightNs: number): SelectionData { 114 let selectCounterData = new SelectionData(); 115 if (list.length > 0) { 116 let range = rightNs - leftNs; 117 let first = list[0]; 118 // @ts-ignore 119 selectCounterData.trackId = first.filterId; 120 selectCounterData.name = name; 121 // @ts-ignore 122 selectCounterData.first = `${first.value}`; 123 selectCounterData.count = `${list.length}`; 124 // @ts-ignore 125 selectCounterData.last = `${list[list.length - 1].value}`; 126 selectCounterData.delta = `${parseInt(selectCounterData.last) - parseInt(selectCounterData.first)}`; 127 selectCounterData.rate = (parseInt(selectCounterData.delta) / ((range * 1.0) / 1000000000)).toFixed(4); 128 // @ts-ignore 129 selectCounterData.min = `${first.value}`; 130 selectCounterData.max = '0'; 131 let weightAvg = 0.0; 132 for (let i = 0; i < list.length; i++) { 133 let counter = list[i]; 134 // @ts-ignore 135 if (counter.value < parseInt(selectCounterData.min)) { 136 // @ts-ignore 137 selectCounterData.min = counter.value.toString(); 138 } 139 // @ts-ignore 140 if (counter.value > parseInt(selectCounterData.max)) { 141 // @ts-ignore 142 selectCounterData.max = counter.value.toString(); 143 } 144 // @ts-ignore 145 let start = i === 0 ? leftNs : counter.startNS; 146 // @ts-ignore 147 let end = i === list.length - 1 ? rightNs : list[i + 1].startNS; 148 // @ts-ignore 149 weightAvg += counter.value * (((end - start) * 1.0) / range); 150 } 151 selectCounterData.avgWeight = weightAvg.toFixed(2); 152 } 153 return selectCounterData; 154 } 155 156 sortByColumn(detail: unknown): void { 157 // @ts-ignore 158 function compare(property, sort, type) { 159 return function (clockCounterLeftData: SelectionData, clockCounterRightData: SelectionData): number { 160 if (clockCounterLeftData.process === ' ' || clockCounterRightData.process === ' ') { 161 return 0; 162 } 163 if (type === 'number') { 164 return sort === 2 // @ts-ignore 165 ? parseFloat(clockCounterRightData[property]) - parseFloat(clockCounterLeftData[property]) // @ts-ignore 166 : parseFloat(clockCounterLeftData[property]) - parseFloat(clockCounterRightData[property]); 167 } else { 168 // @ts-ignore 169 if (clockCounterRightData[property] > clockCounterLeftData[property]) { 170 return sort === 2 ? 1 : -1; 171 } else { 172 // @ts-ignore 173 if (clockCounterRightData[property] === clockCounterLeftData[property]) { 174 return 0; 175 } else { 176 return sort === 2 ? -1 : 1; 177 } 178 } 179 } 180 }; 181 } 182 // @ts-ignore 183 if (detail.key === 'name') { 184 // @ts-ignore 185 this.clockCounterSource.sort(compare(detail.key, detail.sort, 'string')); 186 } else { 187 // @ts-ignore 188 this.clockCounterSource.sort(compare(detail.key, detail.sort, 'number')); 189 } 190 this.clockCounterTbl!.recycleDataSource = this.clockCounterSource; 191 } 192} 193