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 { 17 BaseStruct, 18 drawLoadingFrame, 19 isFrameContainPoint, 20 ns2x, 21 Render, 22 RequestMessage, 23} from './ProcedureWorkerCommon'; 24import { TraceRow } from '../../component/trace/base/TraceRow'; 25 26export class EnergySystemRender extends Render { 27 renderMainThread( 28 req: { 29 useCache: boolean; 30 context: CanvasRenderingContext2D; 31 type: string; 32 }, 33 row: TraceRow<EnergySystemStruct> 34 ) { 35 let systemList = row.dataList; 36 let systemFilter = row.dataListCache; 37 system( 38 systemList, 39 systemFilter, 40 TraceRow.range!.startNS || 0, 41 TraceRow.range!.endNS || 0, 42 TraceRow.range!.totalNS || 0, 43 row.frame, 44 req.useCache || !TraceRow.range!.refresh 45 ); 46 drawLoadingFrame(req.context, row.dataListCache, row); 47 drawProcedureWorkerEnergy(req, systemFilter, row); 48 } 49} 50 51function drawProcedureWorkerEnergy(req: any, systemFilter: Array<any>, row: TraceRow<EnergySystemStruct>) { 52 req.context.beginPath(); 53 let find = false; 54 let energySystemData: any = {}; 55 for (let i = 0; i < systemFilter.length; i++) { 56 let energySysStruct = systemFilter[i]; 57 EnergySystemStruct.draw(req.context, energySysStruct); 58 if (row.isHover && energySysStruct.frame && isFrameContainPoint(energySysStruct.frame, row.hoverX, row.hoverY)) { 59 EnergySystemStruct.hoverEnergySystemStruct = energySysStruct; 60 if (energySysStruct.type === 0) { 61 if (energySysStruct.count !== undefined) { 62 energySystemData.workScheduler = energySysStruct.count; 63 } else { 64 energySystemData.workScheduler = '0'; 65 } 66 } 67 if (energySysStruct.type === 1) { 68 if (energySysStruct.count !== undefined) { 69 energySystemData.power = energySysStruct.count + ''; 70 } else { 71 energySystemData.power = '0'; 72 } 73 } 74 if (energySysStruct.type === 2) { 75 if (energySysStruct.count !== undefined) { 76 energySystemData.location = energySysStruct.count + ''; 77 } else { 78 energySystemData.location = '0'; 79 } 80 } 81 find = true; 82 } 83 } 84 if (!find && row.isHover) EnergySystemStruct.hoverEnergySystemStruct = undefined; 85 if (EnergySystemStruct.hoverEnergySystemStruct) { 86 EnergySystemStruct.hoverEnergySystemStruct!.workScheduler = 87 energySystemData.workScheduler === undefined ? '0' : energySystemData.workScheduler; 88 EnergySystemStruct.hoverEnergySystemStruct!.power = 89 energySystemData.power === undefined ? '0' : energySystemData.power; 90 EnergySystemStruct.hoverEnergySystemStruct!.location = 91 energySystemData.location === undefined ? '0' : energySystemData.location; 92 } 93 let spApplication = document.getElementsByTagName('sp-application')[0]; 94 let isDark = spApplication.hasAttribute('dark'); 95 drawLegend(req, isDark); 96 req.context.closePath(); 97} 98 99export function drawLegend(req: RequestMessage | any, isDark?: boolean) { 100 let textList = ['WORKSCHEDULER', 'POWER_RUNNINGLOCK', 'LOCATION']; 101 for (let index = 0; index < textList.length; index++) { 102 let text = req.context.measureText(textList[index]); 103 req.context.fillStyle = EnergySystemStruct.getColor(index); 104 let canvasEndX = req.context.canvas.clientWidth - EnergySystemStruct.OFFSET_WIDTH; 105 let textColor = isDark ? '#FFFFFF' : '#333'; 106 if (textList[index] == 'WORKSCHEDULER') { 107 req.context.fillRect(canvasEndX - EnergySystemStruct.itemNumber * 120, 12, 8, 8); 108 req.context.globalAlpha = 1; 109 req.context.textBaseline = 'middle'; 110 req.context.fillStyle = textColor; 111 req.context.fillText(textList[index], canvasEndX - EnergySystemStruct.itemNumber * 120 + 10, 18); 112 EnergySystemStruct.currentTextWidth = canvasEndX - EnergySystemStruct.itemNumber * 120 + 40 + text.width; 113 } else { 114 req.context.fillRect(EnergySystemStruct.currentTextWidth, 12, 8, 8); 115 req.context.globalAlpha = 1; 116 req.context.fillStyle = textColor; 117 req.context.textBaseline = 'middle'; 118 req.context.fillText(textList[index], EnergySystemStruct.currentTextWidth + 12, 18); 119 EnergySystemStruct.currentTextWidth = EnergySystemStruct.currentTextWidth + 40 + text.width; 120 } 121 } 122 req.context.fillStyle = '#333'; 123} 124 125export function systemData(data: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any) { 126 for (let index = 0; index < data.length; index++) { 127 let systemItem = data[index]; 128 if (index === data.length - 1) { 129 systemItem.dur = (endNS || 0) - (systemItem.startNs || 0); 130 } else { 131 systemItem.dur = (data[index + 1].startNs! || 0) - (systemItem.startNs! || 0); 132 } 133 if (systemItem.count == 0) { 134 systemItem.dur = 0; 135 } 136 if ( 137 (systemItem.startNs || 0) + (systemItem.dur || 0) > (startNS || 0) && 138 (systemItem.startNs || 0) < (endNS || 0) 139 ) { 140 EnergySystemStruct.setSystemFrame(systemItem, 10, startNS || 0, endNS || 0, totalNS || 0, frame); 141 } 142 } 143} 144 145export function system( 146 systemList: Array<any>, 147 res: Array<any>, 148 startNS: number, 149 endNS: number, 150 totalNS: number, 151 frame: any, 152 use: boolean 153) { 154 if (use && res.length > 0) { 155 let lockData: any = []; 156 let locationData: any = []; 157 let workData: any = []; 158 res.forEach((item) => { 159 if (item.dataType === 1) { 160 lockData.push(item); 161 } else if (item.dataType === 2) { 162 locationData.push(item); 163 } else { 164 workData.push(item); 165 } 166 }); 167 if (lockData.length > 0) { 168 systemData(lockData, startNS, endNS, totalNS, frame); 169 } 170 if (locationData.length > 0) { 171 systemData(locationData, startNS, endNS, totalNS, frame); 172 } 173 if (workData.length > 0) { 174 systemData(workData, startNS, endNS, totalNS, frame); 175 } 176 return; 177 } 178 res.length = 0; 179 setEnergySystemFilter(systemList, res, startNS, endNS, totalNS, frame); 180} 181function setEnergySystemFilter( 182 systemList: Array<any>, 183 res: Array<any>, 184 startNS: number, 185 endNS: number, 186 totalNS: number, 187 frame: any 188) { 189 if (systemList) { 190 for (let i = 0; i < 3; i++) { 191 let arr = systemList[i]; 192 if (arr) { 193 for (let index = 0; index < arr.length; index++) { 194 let item = arr[index]; 195 if (index === arr.length - 1) { 196 item.dur = endNS - (item.startNs || 0); 197 } else { 198 item.dur = (arr[index + 1].startNs || 0) - (item.startNs || 0); 199 } 200 if (item.count == 0) { 201 item.dur = 0; 202 } 203 if ((item.startNs || 0) + (item.dur || 0) > startNS && (item.startNs || 0) < endNS) { 204 EnergySystemStruct.setSystemFrame(item, 10, startNS, endNS, totalNS, frame); 205 res.push(item); 206 } 207 } 208 } 209 } 210 } 211} 212 213export class EnergySystemStruct extends BaseStruct { 214 static hoverEnergySystemStruct: EnergySystemStruct | undefined; 215 static selectEnergySystemStruct: EnergySystemStruct | undefined; 216 static itemNumber: number = 3; 217 static currentTextWidth: number = 0; 218 static OFFSET_WIDTH: number = 266; 219 type: number | undefined; 220 startNs: number | undefined; 221 dur: number | undefined; 222 count: number | undefined; 223 token: number | undefined; 224 workScheduler: string | undefined; 225 power: string | undefined; 226 location: string | undefined; 227 id: number | undefined; 228 eventName: string | undefined; 229 eventValue: string | undefined; 230 appKey: string | undefined; 231 dataType: number | undefined; 232 233 static draw(energySystemContext: CanvasRenderingContext2D, data: EnergySystemStruct) { 234 if (data.frame) { 235 let width = data.frame.width || 0; 236 energySystemContext.globalAlpha = 1.0; 237 energySystemContext.lineWidth = 1; 238 energySystemContext.fillStyle = this.getColor(data.type!); 239 energySystemContext.strokeStyle = this.getColor(data.type!); 240 energySystemContext.fillRect(data.frame.x, data.frame.y + 4, width, data.frame.height); 241 } 242 energySystemContext.globalAlpha = 1.0; 243 energySystemContext.lineWidth = 1; 244 } 245 246 static setSystemFrame(systemNode: any, padding: number, startNS: number, endNS: number, totalNS: number, frame: any) { 247 let systemStartPointX: number; 248 let systemEndPointX: number; 249 if ((systemNode.startNs || 0) < startNS) { 250 systemStartPointX = 0; 251 } else { 252 systemStartPointX = ns2x(systemNode.startNs || 0, startNS, endNS, totalNS, frame); 253 } 254 if ((systemNode.startNs || 0) + (systemNode.dur || 0) > endNS) { 255 systemEndPointX = frame.width; 256 } else { 257 systemEndPointX = ns2x((systemNode.startNs || 0) + (systemNode.dur || 0), startNS, endNS, totalNS, frame); 258 } 259 let frameWidth: number = systemEndPointX - systemStartPointX <= 1 ? 1 : systemEndPointX - systemStartPointX; 260 if (!systemNode.frame) { 261 systemNode.frame = {}; 262 } 263 systemNode.frame.x = Math.floor(systemStartPointX); 264 if (systemNode.type === 0) { 265 systemNode.frame.y = frame.y + padding * 2.5; 266 } else if (systemNode.type === 1) { 267 systemNode.frame.y = frame.y + padding * 4.5; 268 } else if (systemNode.type === 2) { 269 systemNode.frame.y = frame.y + padding * 6.5; 270 } 271 systemNode.frame.width = Math.ceil(frameWidth); 272 systemNode.frame.height = Math.floor(padding); 273 } 274 275 static getColor(textItem: number): string { 276 switch (textItem) { 277 case 0: 278 return '#E64566'; 279 case 1: 280 return '#FFC880'; 281 default: 282 return '#564AF7'; 283 } 284 } 285} 286