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.js"; 17import {LitTable} from "../../../../../base-ui/table/lit-table.js"; 18import {SelectionData, SelectionParam} from "../../../../bean/BoxSelection.js"; 19import {getTabSdkSliceData, queryStartTime} from "../../../../database/SqlLite.js"; 20import "../../../SpFilter.js"; 21import {LitTableColumn} from "../../../../../base-ui/table/lit-table-column.js"; 22import {Utils} from "../../base/Utils.js"; 23import {SpSystemTrace} from "../../../SpSystemTrace.js"; 24 25@element('tabpane-sdk-slice') 26export class TabPaneSdkSlice extends BaseElement { 27 private tbl: LitTable | null | undefined; 28 private range: HTMLLabelElement | null | undefined; 29 private keyList: Array<string> | undefined; 30 private statDataArray: any = [] 31 private columnMap: any = {} 32 33 set data(val: SelectionParam | any) { 34 this.range!.textContent = "Selected range: " + ((val.rightNs - val.leftNs) / 1000000.0).toFixed(5) + " ms" 35 this.queryDataByDB(val) 36 } 37 38 initElements(): void { 39 this.tbl = this.shadowRoot?.querySelector<LitTable>('#tb-sdk-slice'); 40 this.range = this.shadowRoot?.querySelector('#time-range'); 41 this.tbl!.addEventListener('column-click', (evt) => { 42 // @ts-ignore 43 this.sortByColumn(evt.detail) 44 }); 45 } 46 47 connectedCallback() { 48 super.connectedCallback(); 49 new ResizeObserver((entries) => { 50 if (this.parentElement?.clientHeight != 0) { 51 // @ts-ignore 52 this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 45) + "px" 53 this.tbl?.reMeauseHeight() 54 } 55 }).observe(this.parentElement!); 56 } 57 58 queryDataByDB(val: SelectionParam | any) { 59 queryStartTime().then(res => { 60 let startTime = res[0].start_ts; 61 let componentId: number = 0 62 let slices: Array<string> = []; 63 for (let index = 0; index < val.sdkSliceIds.length; index++) { 64 let values = val.sdkSliceIds[index].split("-") 65 let value = values[0]; 66 componentId = values[1]; 67 slices.push(value) 68 } 69 getTabSdkSliceData(this.parseJson(SpSystemTrace.SDK_CONFIG_MAP), startTime, val.leftNs, val.rightNs, slices, componentId).then(item => { 70 this.keyList = []; 71 this.tbl!.innerHTML = '' 72 this.statDataArray = [] 73 if (item.length != null && item.length > 0) { 74 for (let index = 0; index < item.length; index++) { 75 const dataResult = item[index]; 76 let keys = Object.keys(dataResult); 77 let values = Object.values(dataResult); 78 let jsonText = '{'; 79 for (let keyIndex = 0; keyIndex < keys.length; keyIndex++) { 80 let key = keys[keyIndex]; 81 if (this.keyList.indexOf(key) <= -1) { 82 this.keyList.push(key) 83 } 84 let value = values[keyIndex]; 85 if (this.columnMap[key] == 'TimeStamp') { 86 value = Utils.getTimeString(Number(value)) 87 } else if (this.columnMap[key] == 'ClockTime') { 88 value = Utils.getTimeStampHMS(Number(value)) 89 } else if (this.columnMap[key] == 'RangTime') { 90 value = Utils.getDurString(Number(value)) 91 } else if (this.columnMap[key] == 'PercentType') { 92 value = value + "%" 93 } else if (this.columnMap[key] == 'CurrencyType') { 94 // @ts-ignore 95 value = value.toString().replace(/\B(?=(\d{3})+$)/g, ",") 96 } 97 if (typeof value == "string") { 98 value = value.replace(/</gi, "<").replace(/>/gi, ">") 99 } 100 jsonText += '"' + key + '"' + ': ' + '"' + value + '"'; 101 if (keyIndex != keys.length - 1) { 102 jsonText += ',' 103 } else { 104 jsonText += '}'; 105 } 106 } 107 this.statDataArray.push(JSON.parse(jsonText)) 108 } 109 this.tbl!.recycleDataSource = this.statDataArray; 110 } else { 111 this.tbl!.recycleDataSource = []; 112 } 113 this.initDataElement() 114 115 setTimeout(() => { 116 this.tbl!.recycleDataSource = this.statDataArray; 117 new ResizeObserver(() => { 118 if (this.parentElement?.clientHeight != 0) { 119 this.tbl!.style.height = '100%' 120 this.tbl!.reMeauseHeight() 121 } 122 }).observe(this.parentElement!) 123 }, 200) 124 }) 125 }) 126 127 } 128 129 parseJson(map: Map<number, string>): string { 130 let keys = map.keys(); 131 for (let key of keys) { 132 let configStr = map.get(key); 133 if (configStr != undefined) { 134 let json = JSON.parse(configStr); 135 let tableConfig = json.tableConfig 136 if (tableConfig != null) { 137 let showTypes = tableConfig.showType; 138 for (let i = 0; i < showTypes.length; i++) { 139 let showType = showTypes[i]; 140 let type = this.getTableType(showType); 141 if (type == "slice") { 142 let selectSql = "select "; 143 for (let j = 0; j < showType.columns.length; j++) { 144 this.columnMap[showType.columns[j].column] = showType.columns[j].displayName 145 if (showType.columns[j].showType.indexOf(3) > -1) { 146 selectSql += showType.columns[j].column + "," 147 } 148 } 149 return selectSql.substring(0, selectSql.length - 1) + " from " + showType.tableName + 150 " where slice_id in ($slices)" + 151 " and ((start_ts - $startTime) >= $leftNs and (end_ts - $startTime) <= $rightNs " + 152 "or (start_ts - $startTime) <= $leftNs and $leftNs <= (end_ts - $startTime) " + 153 "or (start_ts - $startTime) <= $rightNs and $rightNs <= (end_ts - $startTime))" 154 } 155 } 156 } 157 } 158 } 159 return "" 160 } 161 162 initDataElement() { 163 if (this.keyList) { 164 this.keyList.forEach((item) => { 165 let htmlElement = document.createElement('lit-table-column') as LitTableColumn; 166 htmlElement.setAttribute('title', item); 167 htmlElement.setAttribute('data-index', item); 168 htmlElement.setAttribute('key', item); 169 htmlElement.setAttribute('align', 'flex-start'); 170 htmlElement.setAttribute("width", "1fr"); 171 htmlElement.setAttribute("order", ""); 172 this.tbl!.appendChild(htmlElement); 173 }) 174 } 175 } 176 177 initHtml(): string { 178 return ` 179<style> 180:host{ 181 display: flex; 182 flex-direction: column; 183 padding: 10px 10px; 184} 185</style> 186<div style="display: flex;height: 20px;align-items: center;flex-direction: row;margin-bottom: 5px"> 187 <stack-bar id="stack-bar" style="flex: 1"></stack-bar> 188 <label id="time-range" style="width: auto;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label> 189 </div> 190<lit-table id="tb-sdk-slice" style="height: auto"> 191</lit-table> 192 `; 193 } 194 195 sortByColumn(detail: any) { 196 // @ts-ignore 197 function compare(property, sort) { 198 return function (a: SelectionData, b: SelectionData) { 199 if (a.process == " " || b.process == " ") { 200 return 0; 201 } 202 // @ts-ignore 203 if (b[property] > a[property]) { 204 return sort === 2 ? 1 : -1; 205 } else { // @ts-ignore 206 if (b[property] == a[property]) { 207 return 0; 208 } else { 209 return sort === 2 ? -1 : 1; 210 } 211 } 212 } 213 } 214 215 // @ts-ignore 216 this.statDataArray.sort(compare(detail.key, detail.sort)) 217 this.tbl!.recycleDataSource = this.statDataArray; 218 } 219 220 private getTableType(showType: any) { 221 let columns = showType.columns; 222 for (let i = 0; i < columns.length; i++) { 223 let column = columns[i]; 224 let showType = column.showType 225 if (showType != null) { 226 if (showType.indexOf(1) != -1) { 227 return "counter" 228 } 229 if (showType.indexOf(2) != -1) { 230 return "slice" 231 } 232 } 233 } 234 return "" 235 } 236}