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 { LitTableColumn } from '../../../../../base-ui/table/lit-table-column'; 20import { Utils } from '../../base/Utils'; 21import { SpSystemTrace } from '../../../SpSystemTrace'; 22import { TabUtil } from './TabUtil'; 23import { resizeObserver } from '../SheetUtils'; 24import { getTabSdkCounterData, getTabSdkCounterLeftData } from '../../../../database/sql/Sdk.sql'; 25import { queryStartTime } from '../../../../database/sql/SqlLite.sql'; 26 27@element('tabpane-sdk-counter') 28export class TabPaneSdkCounter extends BaseElement { 29 private tblSdkCounter: LitTable | null | undefined; 30 private sdkRange: HTMLLabelElement | null | undefined; 31 private keyList: Array<string> | undefined; 32 private statDataArray: unknown = []; 33 private columnMap: unknown = {}; 34 private sqlMap: Map<number, unknown> = new Map<number, unknown>(); 35 36 set data(valSdkCounter: SelectionParam | unknown) { 37 this.sdkRange!.textContent = 38 // @ts-ignore 39 'Selected range: ' + ((valSdkCounter.rightNs - valSdkCounter.leftNs) / 1000000.0).toFixed(5) + ' ms'; 40 this.queryDataByDB(valSdkCounter); 41 } 42 43 initElements(): void { 44 this.tblSdkCounter = this.shadowRoot?.querySelector<LitTable>('#tb-counter'); 45 this.sdkRange = this.shadowRoot?.querySelector('#sdk-counter-time-range'); 46 this.tblSdkCounter!.addEventListener('column-click', (evt) => { 47 // @ts-ignore 48 this.sortByColumn(evt.detail); 49 }); 50 } 51 52 connectedCallback(): void { 53 super.connectedCallback(); 54 resizeObserver(this.parentElement!, this.tblSdkCounter!); 55 } 56 57 getStatDataArray(counterItem: unknown): void { 58 this.keyList = []; 59 this.tblSdkCounter!.innerHTML = ''; 60 this.statDataArray = []; 61 // @ts-ignore 62 if (counterItem.length !== null && counterItem.length > 0) { 63 // @ts-ignore 64 for (let counterItemIndex = 0; counterItemIndex < counterItem.length; counterItemIndex++) { 65 // @ts-ignore 66 const dataResult = counterItem[counterItemIndex]; 67 let keys = Object.keys(dataResult); 68 // @ts-ignore 69 let values = Object.values(dataResult); 70 let counterJsonText = '{'; 71 for (let counterKeyIndex = 0; counterKeyIndex < keys.length; counterKeyIndex++) { 72 let counterKey = keys[counterKeyIndex]; 73 if (this.keyList.indexOf(counterKey) <= -1) { 74 this.keyList.push(counterKey); 75 } 76 let counterValue = values[counterKeyIndex]; 77 // @ts-ignore 78 if (this.columnMap[counterKey] === 'TimeStamp') { 79 counterValue = Utils.getTimeString(Number(counterValue)); 80 // @ts-ignore 81 } else if (this.columnMap[counterKey] === 'ClockTime') { 82 counterValue = Utils.getTimeStampHMS(Number(counterValue)); 83 // @ts-ignore 84 } else if (this.columnMap[counterKey] === 'RangTime') { 85 // @ts-ignore 86 counterValue = Utils.getDurString(Number(counterValue)); 87 // @ts-ignore 88 } else if (this.columnMap[counterKey] === 'PercentType') { 89 counterValue = counterValue + '%'; 90 // @ts-ignore 91 } else if (this.columnMap[counterKey] === 'CurrencyType') { 92 // @ts-ignore 93 counterValue = counterValue.toString().replace(/\B(?=(\d{3})+$)/g, ','); 94 } 95 if (typeof counterValue === 'string') { 96 counterValue = counterValue.replace(/</gi, '<').replace(/>/gi, '>'); 97 } 98 counterJsonText += '"' + counterKey + '"' + ': ' + '"' + counterValue + '"'; 99 if (counterKeyIndex !== keys.length - 1) { 100 counterJsonText += ','; 101 } else { 102 counterJsonText += '}'; 103 } 104 } 105 // @ts-ignore 106 this.statDataArray.push(JSON.parse(counterJsonText)); 107 } 108 // @ts-ignore 109 this.tblSdkCounter!.recycleDataSource = this.statDataArray; 110 } else { 111 this.tblSdkCounter!.recycleDataSource = []; 112 } 113 } 114 115 queryDataByDB(sdkVal: SelectionParam | unknown): void { 116 queryStartTime().then((res) => { 117 //@ts-ignore 118 let startTime = res[0].start_ts; 119 // @ts-ignore 120 this.parseJson(SpSystemTrace.SDK_CONFIG_MAP); 121 let counters: Array<string> = []; 122 let componentId: number = -1; 123 // @ts-ignore 124 for (let index = 0; index < sdkVal.sdkCounterIds.length; index++) { 125 // @ts-ignore 126 let values = sdkVal.sdkCounterIds[index].split('-'); 127 let value = values[0]; 128 componentId = Number(values[1]); 129 counters.push(value); 130 } 131 let sqlObj = this.sqlMap.get(componentId); 132 // @ts-ignore 133 let sql = sqlObj.TabCounterLeftData; 134 // @ts-ignore 135 getTabSdkCounterLeftData(sql, sdkVal.leftNs + startTime, counters, componentId).then((res) => { 136 //@ts-ignore 137 let leftTime = res[res.length - 1].max_value - startTime; 138 // @ts-ignore 139 let sql = sqlObj.TabCounterData; 140 // @ts-ignore 141 getTabSdkCounterData(sql, startTime, leftTime, sdkVal.rightNs, counters, componentId).then((counterItem) => { 142 this.getStatDataArray(counterItem); 143 this.initDataElement(); 144 setTimeout(() => { 145 // @ts-ignore 146 this.tblSdkCounter!.recycleDataSource = this.statDataArray; 147 new ResizeObserver(() => { 148 if (this.parentElement?.clientHeight !== 0) { 149 this.tblSdkCounter!.style.height = '100%'; 150 this.tblSdkCounter!.reMeauseHeight(); 151 } 152 }).observe(this.parentElement!); 153 }, 200); 154 }); 155 }); 156 }); 157 } 158 159 parseJson(configMap: Map<number, string>): string { 160 let keys = configMap.keys(); 161 for (let key of keys) { 162 let counterConfigObject: unknown = configMap.get(key); 163 if (counterConfigObject !== undefined) { 164 // @ts-ignore 165 let configStr = counterConfigObject.jsonConfig; 166 let configJson = JSON.parse(configStr); 167 let counterTableConfig = configJson.tableConfig; 168 if (counterTableConfig !== null) { 169 let showTypes = counterTableConfig.showType; 170 for (let counterTypesIndex = 0; counterTypesIndex < showTypes.length; counterTypesIndex++) { 171 let showType = showTypes[counterTypesIndex]; 172 let type = TabUtil.getTableType(showType); 173 if (type === 'counter') { 174 let selectSql = 'select '; 175 for (let counterColumnsIndex = 0; counterColumnsIndex < showType.columns.length; counterColumnsIndex++) { 176 // @ts-ignore 177 this.columnMap[showType.columns[counterColumnsIndex].column] = 178 showType.columns[counterColumnsIndex].displayName; 179 if (showType.columns[counterColumnsIndex].showType.indexOf(3) > -1) { 180 selectSql += showType.columns[counterColumnsIndex].column + ','; 181 } 182 } 183 let counterLeftSql = 184 'select max(ts) as max_value,counter_id from ' + 185 showType.tableName + 186 ' where ts <= $leftNs and counter_id in' + 187 ' ($counters) group by counter_id order by max_value desc'; 188 let tabCounterDataSql = 189 selectSql.substring(0, selectSql.length - 1) + 190 ' from ' + 191 showType.tableName + 192 ' where counter_id in ($counters) and (ts - $startTime) between $leftNs and $rightNs'; 193 this.sqlMap.set(key, { 194 TabCounterData: tabCounterDataSql, 195 TabCounterLeftData: counterLeftSql, 196 }); 197 } 198 } 199 } 200 } 201 } 202 return ''; 203 } 204 205 initDataElement(): void { 206 if (this.keyList) { 207 this.keyList.forEach((sdkCounterItemKey) => { 208 let sdkCounterEl = document.createElement('lit-table-column') as LitTableColumn; 209 sdkCounterEl.setAttribute('title', sdkCounterItemKey); 210 sdkCounterEl.setAttribute('data-index', sdkCounterItemKey); 211 sdkCounterEl.setAttribute('key', sdkCounterItemKey); 212 sdkCounterEl.setAttribute('align', 'flex-start'); 213 sdkCounterEl.setAttribute('width', '1fr'); 214 sdkCounterEl.setAttribute('order', ''); 215 this.tblSdkCounter!.appendChild(sdkCounterEl); 216 }); 217 } 218 } 219 220 initHtml(): string { 221 return ` 222<style> 223.sdk-counter-table{ 224 display: flex; 225 margin-bottom: 5px; 226} 227:host{ 228 padding: 10px 10px; 229 display: flex; 230 flex-direction: column; 231} 232</style> 233<div class="sdk-counter-table" style="height: 20px;align-items: center;flex-direction: row;"> 234 <stack-bar id="sdk-counter-stack-bar" style="flex: 1"></stack-bar> 235 <label id="sdk-counter-time-range" style="width: auto;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label> 236 </div> 237<lit-table id="tb-counter" class="sdk-counter-tbl" style="height: auto"> 238</lit-table> 239 `; 240 } 241 242 sortByColumn(counterDetail: unknown): void { 243 // @ts-ignore 244 function compare(property, countreSort, type) { 245 return function (aSdkCounter: SelectionData, bSdkCounter: SelectionData): number { 246 if (aSdkCounter.process === ' ' || bSdkCounter.process === ' ') { 247 return 0; 248 } 249 if (type === 'number') { 250 return countreSort === 2 251 ? // @ts-ignore 252 parseFloat(bSdkCounter[property]) - parseFloat(aSdkCounter[property]) 253 : // @ts-ignore 254 parseFloat(aSdkCounter[property]) - parseFloat(bSdkCounter[property]); 255 } 256 // @ts-ignore 257 if (bSdkCounter[property] > aSdkCounter[property]) { 258 return countreSort === 2 ? 1 : -1; 259 } else { 260 // @ts-ignore 261 if (bSdkCounter[property] === aSdkCounter[property]) { 262 return 0; 263 } else { 264 return countreSort === 2 ? -1 : 1; 265 } 266 } 267 }; 268 } 269 270 // @ts-ignore 271 if (counterDetail.key.indexOf('name') !== -1) { 272 // @ts-ignore 273 this.statDataArray.sort(compare(counterDetail.key, counterDetail.sort, 'string')); 274 } else { 275 // @ts-ignore 276 this.statDataArray.sort(compare(counterDetail.key, counterDetail.sort, 'number')); 277 } 278 // @ts-ignore 279 this.tblSdkCounter!.recycleDataSource = this.statDataArray; 280 } 281} 282