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 { type LitTable } from '../../../../../base-ui/table/lit-table'; 18import { type SelectionParam } from '../../../../bean/BoxSelection'; 19import { MemoryConfig } from '../../../../bean/MemoryConfig'; 20import { Utils } from '../../base/Utils'; 21import { resizeObserver } from '../SheetUtils'; 22import { querySysPurgeableTab } from '../../../../database/sql/Ability.sql'; 23import { queryProcessPurgeableTab } from '../../../../database/sql/ProcessThread.sql'; 24 25@element('tabpane-purg-total') 26export class TabPanePurgTotal extends BaseElement { 27 private purgeableTotalTable: LitTable | null | undefined; 28 private purgeableTotalSource: Array<PurgeableTabStruct> = []; 29 private tabTitle: HTMLDivElement | undefined | null; 30 private purgTotalTimeRange: HTMLLabelElement | undefined | null; 31 private sortKey = 'avgSize'; 32 private sortType = 2; 33 34 set data(selection: SelectionParam) { 35 if (this.purgeableTotalTable) { 36 //@ts-ignore 37 this.purgeableTotalTable.shadowRoot.querySelector('.table').style.height = `${ 38 this.parentElement!.clientHeight - 45 39 }px`; 40 } 41 this.init(); 42 this.purgTotalTimeRange!.textContent = 43 'Selected range: ' + ((selection.rightNs - selection.leftNs) / 1000000.0).toFixed(5) + ' ms'; 44 this.purgeableTotalTable!.loading = true; 45 this.purgeableTotalTable!.recycleDataSource = []; 46 // 框选了 Purgeable Total 47 if (selection.purgeableTotalAbility.length > 0) { 48 this.purgeableTotalSource = []; 49 querySysPurgeableTab( 50 selection.leftNs, 51 selection.rightNs, 52 (MemoryConfig.getInstance().interval * 1000000) / 5 53 ).then((purgeTotalResults) => { 54 this.purgeableTotalTable!.loading = false; 55 this.getPurgeableTotalSource(purgeTotalResults); 56 }); 57 } else if (selection.purgeableTotalVM.length > 0) { 58 this.purgeableTotalSource = []; 59 queryProcessPurgeableTab( 60 selection.leftNs, 61 selection.rightNs, 62 (MemoryConfig.getInstance().interval * 1000000) / 5, 63 MemoryConfig.getInstance().iPid 64 ).then((results) => { 65 this.purgeableTotalTable!.loading = false; 66 this.getPurgeableTotalSource(results); 67 }); 68 } 69 } 70 71 getPurgeableTotalSource(results: any): void { 72 if (results.length > 0) { 73 for (let i = 0; i < results.length; i++) { 74 this.purgeableTotalSource.push( 75 this.toTabStruct(results[i].name, results[i].maxSize, results[i].minSize, results[i].avgSize) 76 ); 77 } 78 this.sortByColumn({key: this.sortKey, sort: this.sortType}); 79 let total = this.totalData(this.purgeableTotalSource); 80 this.purgeableTotalSource.unshift(total); 81 this.purgeableTotalTable!.recycleDataSource = this.purgeableTotalSource; 82 this.purgeableTotalSource.shift(); 83 } else { 84 this.purgeableTotalSource = []; 85 this.purgeableTotalTable!.recycleDataSource = []; 86 } 87 } 88 89 private init(): void { 90 const thTable = this.tabTitle!.querySelector('.th'); 91 const purgeTotalTblNode = thTable!.querySelectorAll('div'); 92 if (this.tabTitle!.hasAttribute('sort')) { 93 this.tabTitle!.removeAttribute('sort'); 94 purgeTotalTblNode.forEach((item) => { 95 item.querySelectorAll('svg').forEach((svg) => { 96 svg.style.display = 'none'; 97 }); 98 }); 99 } 100 this.sortKey = 'avgSize'; 101 this.sortType = 2; 102 } 103 104 private toTabStruct(type: string, maxSize: number, minSize: number, avgSize: number): PurgeableTabStruct { 105 const tabStruct = new PurgeableTabStruct( 106 type, 107 maxSize, 108 minSize, 109 avgSize, 110 Utils.getBinaryByteWithUnit(avgSize), 111 Utils.getBinaryByteWithUnit(maxSize), 112 Utils.getBinaryByteWithUnit(minSize) 113 ); 114 return tabStruct; 115 } 116 117 private totalData(source: Array<PurgeableTabStruct>): PurgeableTabStruct { 118 // 计算总的time作为表格的第一行显示 119 let totalAvg = 0; 120 let totalMax = 0; 121 let totalMin = 0; 122 for (let item of source) { 123 totalAvg += item.avgSize; 124 totalMax += item.maxSize; 125 totalMin += item.minSize; 126 } 127 let totalData = this.toTabStruct('Total', totalAvg, totalMax, totalMin); 128 return totalData; 129 } 130 131 private sortByColumn(detail: any): void { 132 // @ts-ignore 133 function compare(key, sort, type) { 134 return function (purgeTotalLeftData: any, purgeTotalRightData: any) { 135 // 不管哪一列的排序方式是0(默认排序),都按照avgSize列从大到小排序 136 if (sort === 0) { 137 sort = 2; 138 key = 'avgSize'; 139 type = 'number'; 140 } 141 if (type === 'number') { 142 // @ts-ignore 143 return sort === 2 144 ? parseFloat(purgeTotalRightData[key]) - parseFloat(purgeTotalLeftData[key]) 145 : parseFloat(purgeTotalLeftData[key]) - parseFloat(purgeTotalRightData[key]); 146 } else { 147 if (sort === 2) { 148 return purgeTotalRightData[key].toString().localeCompare(purgeTotalLeftData[key].toString()); 149 } else { 150 return purgeTotalLeftData[key].toString().localeCompare(purgeTotalRightData[key].toString()); 151 } 152 } 153 }; 154 } 155 156 if (detail.key === 'type') { 157 this.purgeableTotalSource.sort(compare(detail.key, detail.sort, 'string')); 158 } else { 159 this.purgeableTotalSource.sort(compare(detail.key, detail.sort, 'number')); 160 } 161 let total = this.totalData(this.purgeableTotalSource); 162 this.purgeableTotalSource.unshift(total); 163 this.purgeableTotalTable!.recycleDataSource = this.purgeableTotalSource; 164 this.purgeableTotalSource.shift(); 165 } 166 167 initElements(): void { 168 this.purgeableTotalTable = this.shadowRoot?.querySelector<LitTable>('#tb-purgeable-total'); 169 this.tabTitle = this.purgeableTotalTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement; 170 this.purgTotalTimeRange = this.shadowRoot?.querySelector('#purg-total-time-range') as HTMLLabelElement; 171 this.purgeableTotalTable!.addEventListener('column-click', (evt: any) => { 172 this.sortKey = evt.detail.key; 173 this.sortType = evt.detail.sort; 174 // @ts-ignore 175 this.sortByColumn(evt.detail); 176 }); 177 } 178 179 connectedCallback(): void { 180 super.connectedCallback(); 181 resizeObserver(this.parentElement!, this.purgeableTotalTable!); 182 } 183 184 initHtml(): string { 185 return ` 186 <style> 187 :host{ 188 display: flex; 189 flex-direction: column; 190 padding: 10px 10px; 191 } 192 .purg-total-label{ 193 display: flex; 194 height: 20px; 195 align-items: center; 196 flex-direction: row; 197 margin-bottom: 5px; 198 } 199 #purg-total-time-range{ 200 width: auto; 201 text-align: end; 202 font-size: 10pt; 203 } 204 </style> 205 <div class="purg-total-label"> 206 <div style="flex: 1"></div> 207 <label id="purg-total-time-range">Selected range:0.0 ms</label> 208 </div> 209 <lit-table id="tb-purgeable-total" style="height: auto"> 210 <lit-table-column width="1fr" title="Type" data-index="type" key="type" align="flex-start" order> 211 </lit-table-column> 212 <lit-table-column width="1fr" title="AvgSize" data-index="avgSizeStr" key="avgSize" align="flex-start" order> 213 </lit-table-column> 214 <lit-table-column width="1fr" title="MaxSize" data-index="maxSizeStr" key="maxSize" align="flex-start" order> 215 </lit-table-column> 216 <lit-table-column width="1fr" title="MinSize" data-index="minSizeStr" key="minSize" align="flex-start" order> 217 </lit-table-column> 218 </lit-table> 219 `; 220 } 221} 222 223export class PurgeableTabStruct { 224 type: string; 225 avgSize: number; 226 maxSize: number; 227 minSize: number; 228 avgSizeStr: string; 229 maxSizeStr: string; 230 minSizeStr: string; 231 232 constructor( 233 type: string, 234 avgSize: number, 235 maxSize: number, 236 minSize: number, 237 avgSizeStr: string, 238 maxSizeStr: string, 239 minSizeStr: string 240 ) { 241 this.type = type; 242 this.avgSize = avgSize; 243 this.maxSize = maxSize; 244 this.minSize = minSize; 245 this.avgSizeStr = avgSizeStr; 246 this.maxSizeStr = maxSizeStr; 247 this.minSizeStr = minSizeStr; 248 } 249} 250