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 {getTabSlices, getTabSlicesAsyncFunc} from "../../../../database/SqlLite.js"; 20 21@element('tabpane-slices') 22export class TabPaneSlices extends BaseElement { 23 private tbl: LitTable | null | undefined; 24 private range: HTMLLabelElement | null | undefined; 25 private source: Array<SelectionData> = [] 26 27 set data(val: SelectionParam | any) { 28 this.range!.textContent = "Selected range: " + parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) + " ms" 29 let asyncNames: Array<string> = []; 30 let asyncPid: Array<number> = []; 31 val.funAsync.forEach((it: any) => { 32 asyncNames.push(it.name) 33 asyncPid.push(it.pid) 34 }) 35 getTabSlicesAsyncFunc(asyncNames, asyncPid, val.leftNs, val.rightNs).then(res => { 36 getTabSlices(val.funTids, val.leftNs, val.rightNs).then((res2) => { 37 let result = (res || []).concat(res2 || []); 38 if (result != null && result.length > 0) { 39 let sumWall = 0.0; 40 let sumOcc = 0; 41 for (let e of result) { 42 e.name = e.name == null ? "" : e.name 43 sumWall += e.wallDuration 44 sumOcc += e.occurrences 45 e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5)); 46 e.avgDuration = parseFloat((e.avgDuration / 1000000.0).toFixed(5)); 47 } 48 let count = new SelectionData() 49 count.process = " "; 50 count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(5)); 51 count.occurrences = sumOcc; 52 result.splice(0, 0, count) 53 this.source = result 54 this.tbl!.recycleDataSource = result 55 } else { 56 this.source = []; 57 this.tbl!.recycleDataSource = this.source; 58 } 59 }); 60 }); 61 } 62 63 initElements(): void { 64 this.tbl = this.shadowRoot?.querySelector<LitTable>('#tb-slices'); 65 this.range = this.shadowRoot?.querySelector('#time-range'); 66 this.tbl!.addEventListener('column-click', (evt) => { 67 // @ts-ignore 68 this.sortByColumn(evt.detail) 69 }); 70 } 71 72 connectedCallback() { 73 super.connectedCallback(); 74 new ResizeObserver((entries) => { 75 if (this.parentElement?.clientHeight != 0) { 76 // @ts-ignore 77 this.tbl?.shadowRoot.querySelector(".table").style.height = (this.parentElement.clientHeight - 45) + "px" 78 this.tbl?.reMeauseHeight() 79 } 80 }).observe(this.parentElement!) 81 } 82 83 initHtml(): string { 84 return ` 85 <style> 86 :host{ 87 display: flex; 88 flex-direction: column; 89 padding: 10px 10px; 90 } 91 </style> 92 <label id="time-range" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;margin-bottom: 5px">Selected range:0.0 ms</label> 93 <lit-table id="tb-slices" style="height: auto"> 94 <lit-table-column title="Name" width="500px" data-index="name" key="name" align="flex-start" order> 95 </lit-table-column> 96 <lit-table-column title="Wall duration(ms)" width="1fr" data-index="wallDuration" key="wallDuration" align="flex-start" order > 97 </lit-table-column> 98 <lit-table-column title="Avg Wall duration(ms)" width="1fr" data-index="avgDuration" key="avgDuration" align="flex-start" order > 99 </lit-table-column> 100 <lit-table-column title="Occurrences" width="1fr" data-index="occurrences" key="occurrences" align="flex-start" order > 101 </lit-table-column> 102 </lit-table> 103 `; 104 } 105 106 sortByColumn(detail: any) { 107 // @ts-ignore 108 function compare(property, sort, type) { 109 return function (a: SelectionData, b: SelectionData) { 110 if (a.process == " " || b.process == " ") { 111 return 0; 112 } 113 if (type === 'number') { 114 // @ts-ignore 115 return sort === 2 ? parseFloat(b[property]) - parseFloat(a[property]) : parseFloat(a[property]) - parseFloat(b[property]); 116 } else { 117 // @ts-ignore 118 if (b[property] > a[property]) { 119 return sort === 2 ? 1 : -1; 120 } else { // @ts-ignore 121 if (b[property] == a[property]) { 122 return 0; 123 } else { 124 return sort === 2 ? -1 : 1; 125 } 126 } 127 } 128 } 129 } 130 131 if (detail.key === "name") { 132 this.source.sort(compare(detail.key, detail.sort, 'string')) 133 } else { 134 this.source.sort(compare(detail.key, detail.sort, 'number')) 135 } 136 this.tbl!.recycleDataSource = this.source; 137 } 138 139}