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