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 { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; 18import { LitTable } from '../../../../../base-ui/table/lit-table'; 19 20import { SelectionParam } from '../../../../bean/BoxSelection'; 21import { EnergyAnomalyStruct } from '../../../../database/ui-worker/ProcedureWorkerEnergyAnomaly'; 22import { resizeObserver } from '../SheetUtils'; 23import { queryAnomalyDetailedData } from '../../../../database/sql/ProcessThread.sql'; 24 25@element('tabpane-anomaly-details') 26export class TabPaneEnergyAnomaly extends BaseElement { 27 private tblAnomaly: LitTable | null | undefined; 28 private static KEY_INDEX: number = 2; 29 private static VALUE_INDEX: number = 3; 30 31 set data(selectionAnomaly: SelectionParam) { 32 let div: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#anomaly-details'); 33 let htmlText = ''; 34 if (selectionAnomaly) { 35 this.queryAnomalyTableData(selectionAnomaly.leftNs, selectionAnomaly.rightNs).then((bean) => { 36 let filterAppMap = this.setFilterAppMapByAnomalyData(bean); 37 let tempSet = new Set(); 38 for (let index = 0; index < bean.length; index++) { 39 // @ts-ignore 40 let values = Object.values(bean[index]); 41 let findAppNameIndex = -1; 42 if (filterAppMap.get(values[0] + values[1]) == -1) { 43 continue; 44 } else { 45 findAppNameIndex = filterAppMap.get(values[0] + values[1]); 46 } 47 if (!tempSet.has(values[0])) { 48 tempSet.add(values[0]); 49 htmlText += '<div><table' + 50 ' style=\'border:none;table-layout:fixed;word-break:break-all\' cellspacing="5"; cellpadding="5"><tbody>' + 51 '<tr><td colspan="5" style=\'font-weight: 700;font-size: 14px\'>' + 52 values[1] + '</td></tr>'; 53 } 54 // @ts-ignore 55 if (tempSet.has(Object.values(bean[index])[0])) { 56 let appValues = values[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); 57 htmlText += 58 '<tr><td style=\'font-weight: 400;font-size: 14px;opacity:0.9;width:150px;\'>' + 59 values[TabPaneEnergyAnomaly.KEY_INDEX] + 60 '</td><td style=\'font-weight: 400;font-size: 14px;opacity:0.6;width:250px;\'>' + 61 (findAppNameIndex >= 0 ? appValues.length > 1 ? appValues[findAppNameIndex] : 62 values[TabPaneEnergyAnomaly.VALUE_INDEX] : values[TabPaneEnergyAnomaly.VALUE_INDEX]) + 63 TabPaneEnergyAnomaly.getUnit(values[TabPaneEnergyAnomaly.KEY_INDEX]) + 64 '</td><td style=\'width:100px\'></td>'; 65 } 66 if (index + 1 < bean.length) { 67 // @ts-ignore 68 let nextValues = Object.values(bean[index + 1]); 69 htmlText = this.spliceHtmlText(findAppNameIndex, nextValues, htmlText, tempSet); 70 if (!tempSet.has(nextValues[0])) { 71 continue; 72 } 73 index++; 74 } 75 } 76 div!.innerHTML = htmlText; 77 }); 78 } 79 } 80 81 private spliceHtmlText(findAppNameIndex: number, nextValues: any[], htmlText: string, tempSet: Set<any>): string{ 82 let appValues = nextValues[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); 83 if (tempSet.has(nextValues[0])) { 84 htmlText += 85 '<td style=\'font-weight: 400;font-size: 14px;opacity:0.9;width:150px;\'>' + 86 nextValues[TabPaneEnergyAnomaly.KEY_INDEX] + 87 '</td><td style=\'font-weight: 400;font-size: 14px;opacity:0.6;width:250px;\'>' + 88 (findAppNameIndex >= 0 89 ? appValues.length > 1 90 ? appValues[findAppNameIndex] 91 : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX] 92 : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX]) + 93 TabPaneEnergyAnomaly.getUnit(nextValues[TabPaneEnergyAnomaly.KEY_INDEX]) + 94 '</td></tr>'; 95 } else { 96 htmlText += '</tr>'; 97 htmlText += '</tbody></table></div>'; 98 return htmlText 99 } 100 return htmlText 101 } 102 103 private setFilterAppMapByAnomalyData(bean: EnergyAnomalyStruct[]): Map<string, any> { 104 let filterAppMap = new Map(); 105 for (let index = 0; index < bean.length; index++) { 106 let findAppNameIndex = -1; 107 // @ts-ignore 108 let values = Object.values(bean[index]); 109 if (values[TabPaneEnergyAnomaly.VALUE_INDEX]) { 110 let apps = values[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); 111 for (let appIndex = 0; appIndex < apps.length; appIndex++) { 112 if (apps.indexOf(SpHiSysEnergyChart.app_name) !== -1) { 113 findAppNameIndex = apps.indexOf(SpHiSysEnergyChart.app_name); 114 filterAppMap.set(values[0] + values[1], findAppNameIndex); 115 break; 116 } 117 } 118 if (values[TabPaneEnergyAnomaly.KEY_INDEX] == 'APPNAME') { 119 //ts+eventName : appNameIndex 120 filterAppMap.set(values[0] + values[1], findAppNameIndex); 121 } 122 } 123 } 124 return filterAppMap; 125 } 126 127 static getUnit(value: any) { 128 if (value == 'DURATION') { 129 return ' ms'; 130 } else if (value == 'ENERGY' || value == 'BGENERGY' || value == 'BATTERY_GAS_GUAGE') { 131 return ' mAh'; 132 } else if (value == 'BGUSAGE') { 133 return ' s'; 134 } 135 return ''; 136 } 137 138 /** 139 * 查询出 异常详细信息 140 * @param data 141 */ 142 async queryAnomalyTableData(startTime: number, endTime: number): Promise<Array<EnergyAnomalyStruct>> { 143 let anomalyTableData = await queryAnomalyDetailedData(startTime, endTime); 144 return anomalyTableData; 145 } 146 147 initElements(): void { 148 this.tblAnomaly = this.shadowRoot?.querySelector<LitTable>('#anomalyselectionTbl'); 149 this.tblAnomaly?.addEventListener('column-click', (ev: any) => { 150 }); 151 } 152 153 connectedCallback() { 154 super.connectedCallback(); 155 resizeObserver(this.parentElement!, this.tblAnomaly!); 156 } 157 158 initHtml(): string { 159 return ` 160 <style> 161 .anomaly-title{ 162 display: flex; 163 width: 95%; 164 background: var(--dark-background,#ffffff); 165 top: 0; 166 position: sticky; 167 } 168 .anomaly-title h2{ 169 padding: 0 10px; 170 font-size: 16px; 171 font-weight: 400; 172 width: 50%; 173 visibility: visible; 174 } 175 .scroll-area{ 176 overflow-y: auto; 177 height: auto; 178 display: flex; 179 180 } 181 .left-table{ 182 padding: 0 10px; 183 width: 50%; 184 } 185 .anomaly-table{ 186 height: auto; 187 } 188 </style> 189 <div style="width: 100%;height: auto;position: relative"> 190 <div id="anomaly-details" class="anomaly-title" style="margin-left: 12px;display: block"> 191 <h2 id="leftTitle"></h2> 192 </div> 193 <div class="scroll-area"> 194 <div class="left-table"> 195 <lit-table id="anomalyselectionTbl" no-head class="anomaly-table"> 196 <lit-table-column key="name" align="flex-start" width="180px" title="name" data-index="name" > 197 </lit-table-column> 198 <lit-table-column key="value" align="flex-start" title="value" data-index="value"> 199 </lit-table-column> 200 </lit-table> 201 </div> 202 </div> 203 </div> 204 `; 205 } 206} 207