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 */ 15import { BaseElement, element } from '../../../../../base-ui/BaseElement.js'; 16import { LitTable } from '../../../../../base-ui/table/lit-table.js'; 17import { resizeObserver } from '../SheetUtils.js'; 18import { queryGpuDataByTs } from '../../../../database/SqlLite.js'; 19import { VmTrackerChart } from '../../../chart/SpVmTrackerChart.js'; 20import { log } from '../../../../../log/Log.js'; 21import { SpSystemTrace } from '../../../SpSystemTrace.js'; 22import { Utils } from '../../base/Utils.js'; 23interface GpuTreeItem { 24 name: string; 25 id: number; 26 size: number; 27 sizeStr: string; 28 children?: GpuTreeItem[] | undefined; 29} 30@element('tabpane-gpu-click-select') 31export class TabPaneGpuClickSelect extends BaseElement { 32 private gpuTbl: LitTable | null | undefined; 33 private gpuSource: Array<GpuTreeItem> = []; 34 gpuClickData(gpu: { type: string; startTs: number }) { 35 let label = this.gpuTbl!.shadowRoot!.querySelector('.thead')?.firstChild?.firstChild?.firstChild; 36 if (label) { 37 (label as HTMLLabelElement).innerHTML = gpu.type === 'total' ? 'Module / Category' : 'Window / Module / Category'; 38 } 39 //@ts-ignore 40 this.gpuTbl?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 45 + 'px'; 41 this.gpuTbl!.loading = true; 42 let window = gpu.type === 'total' ? 0 : VmTrackerChart.gpuWindow; 43 let module = gpu.type === 'total' ? VmTrackerChart.gpuTotalModule : VmTrackerChart.gpuWindowModule; 44 queryGpuDataByTs(gpu.startTs, window || 0, module).then((result) => { 45 this.gpuTbl!.loading = false; 46 if (result != null && result.length > 0) { 47 log('queryGpuDataByTs result size : ' + result.length); 48 let items = this.createTreeData(result); 49 this.gpuSource = (gpu.type === 'total' ? items[0].children : items) || []; 50 this.gpuTbl!.recycleDataSource = this.gpuSource; 51 } else { 52 this.gpuSource = []; 53 this.gpuTbl!.recycleDataSource = []; 54 } 55 }); 56 } 57 protected createTreeData(result: any): Array<any> { 58 let gpuDataObj = result.reduce( 59 ( 60 group: any, 61 item: { categoryId: number; size: number; windowNameId: number; moduleId: number; windowId: any } 62 ) => { 63 let categoryItem: GpuTreeItem = { 64 name: SpSystemTrace.DATA_DICT.get(item.categoryId) || 'null', 65 id: item.categoryId, 66 size: item.size, 67 sizeStr: Utils.getBinaryByteWithUnit(item.size), 68 }; 69 if (group[`${item.windowNameId}(${item.windowId})`]) { 70 let windowGroup = group[`${item.windowNameId}(${item.windowId})`] as GpuTreeItem; 71 windowGroup.size += item.size; 72 windowGroup.sizeStr = Utils.getBinaryByteWithUnit(windowGroup.size); 73 let moduleGroup = windowGroup.children!.find((it) => it.id === item.moduleId); 74 if (moduleGroup) { 75 moduleGroup.size += item.size; 76 moduleGroup.sizeStr = Utils.getBinaryByteWithUnit(moduleGroup.size); 77 moduleGroup.children?.push(categoryItem); 78 } else { 79 windowGroup.children?.push({ 80 name: SpSystemTrace.DATA_DICT.get(item.moduleId) || 'null', 81 id: item.moduleId, 82 size: item.size, 83 sizeStr: Utils.getBinaryByteWithUnit(item.size), 84 children: [categoryItem], 85 }); 86 } 87 } else { 88 group[`${item.windowNameId}(${item.windowId})`] = { 89 name: SpSystemTrace.DATA_DICT.get(item.windowNameId) + `(${item.windowId})`, 90 id: item.windowNameId, 91 size: item.size, 92 sizeStr: Utils.getBinaryByteWithUnit(item.size), 93 children: [ 94 { 95 name: SpSystemTrace.DATA_DICT.get(item.moduleId), 96 id: item.moduleId, 97 size: item.size, 98 sizeStr: Utils.getBinaryByteWithUnit(item.size), 99 children: [categoryItem], 100 }, 101 ], 102 }; 103 } 104 return group; 105 }, 106 {} 107 ); 108 let items = Object.values(gpuDataObj) as GpuTreeItem[]; 109 return items; 110 } 111 initElements(): void { 112 this.gpuTbl = this.shadowRoot?.querySelector<LitTable>('#tb-gpu'); 113 this.gpuTbl!.addEventListener('column-click', (evt: any) => { 114 this.sortByColumn(evt.detail); 115 }); 116 } 117 connectedCallback(): void { 118 super.connectedCallback(); 119 this.parentElement!.style.overflow = 'hidden'; 120 resizeObserver(this.parentElement!, this.gpuTbl!, 18); 121 } 122 initHtml(): string { 123 return ` 124 <style> 125 :host{ 126 display: flex; 127 flex-direction: column; 128 padding: 10px 10px; 129 } 130 </style> 131 <lit-table id="tb-gpu" style="height: auto" tree> 132 <lit-table-column width="50%" title="Window / Module / Category" data-index="name" key="name" align="flex-start"> 133 </lit-table-column> 134 <lit-table-column width="1fr" title="Size" data-index="sizeStr" key="sizeStr" align="flex-start" order > 135 </lit-table-column> 136 </lit-table> 137 `; 138 } 139 sortByColumn(gpuDetail: any): void { 140 let compare = (gpuA: GpuTreeItem, gpuB: GpuTreeItem): number => { 141 if (gpuDetail.sort === 0) { 142 return gpuA.size - gpuB.size; 143 } else if (gpuDetail.sort === 1) { 144 return gpuA.size - gpuB.size; 145 } else { 146 return gpuB.size - gpuA.size; 147 } 148 }; 149 let deepCompare = (arr: GpuTreeItem[]) => { 150 arr.forEach((it) => { 151 if (it.children) { 152 deepCompare(it.children); 153 } 154 }); 155 arr.sort(compare); 156 }; 157 deepCompare(this.gpuSource); 158 this.gpuTbl!.recycleDataSource = this.gpuSource; 159 } 160} 161