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 { BaseStruct, isFrameContainPoint, ns2x, Rect, Render } from './ProcedureWorkerCommon'; 17import { TraceRow } from '../../component/trace/base/TraceRow'; 18 19export class SdkCounterRender extends Render { 20 renderMainThread( 21 req: { 22 context: CanvasRenderingContext2D; 23 useCache: boolean; 24 type: string; 25 maxName: string; 26 maxValue: number; 27 }, 28 row: TraceRow<CounterStruct> 29 ): void { 30 let counterList = row.dataList; 31 let counterFilter = row.dataListCache; 32 let maxCounter = req.maxValue; 33 let maxCounterName = req.maxName; 34 this.counter( 35 counterList, 36 counterFilter, 37 TraceRow.range?.startNS ?? 0, 38 TraceRow.range?.endNS ?? 0, 39 TraceRow.range?.totalNS ?? 0, 40 row.frame, 41 req.useCache || (TraceRow.range?.refresh ?? false) 42 ); 43 req.context.beginPath(); 44 let sdkCounterFind = false; 45 for (let re of counterFilter) { 46 if (row.isHover && re.frame && isFrameContainPoint(re.frame, row.hoverX, row.hoverY)) { 47 CounterStruct.hoverCounterStruct = re; 48 sdkCounterFind = true; 49 } 50 CounterStruct.draw(req.context, re, maxCounter); 51 } 52 if (!sdkCounterFind && row.isHover) { 53 CounterStruct.hoverCounterStruct = undefined; 54 } 55 req.context.closePath(); 56 let textMetrics = req.context.measureText(maxCounterName); 57 req.context.globalAlpha = 0.8; 58 req.context.fillStyle = '#f0f0f0'; 59 req.context.fillRect(0, 5, textMetrics.width + 8, 18); 60 req.context.globalAlpha = 1; 61 req.context.fillStyle = '#333'; 62 req.context.textBaseline = 'middle'; 63 req.context.fillText(maxCounterName, 4, 5 + 9); 64 } 65 66 counter( 67 sdkCounterList: Array<unknown>, 68 sdkCounterFilters: Array<unknown>, 69 startNS: number, 70 endNS: number, 71 totalNS: number, 72 frame: Rect, 73 use: boolean 74 ): void { 75 if (use && sdkCounterFilters.length > 0) { 76 for (let index = 0; index < sdkCounterFilters.length; index++) { 77 let item = sdkCounterFilters[index]; 78 //@ts-ignore 79 if ((item.ts || 0) + (item.dur || 0) > startNS && (item.ts || 0) < endNS) { 80 CounterStruct.setCounterFrame(sdkCounterFilters[index], 5, startNS, endNS, totalNS, frame); 81 } else { 82 //@ts-ignore 83 sdkCounterFilters[index].frame = null; 84 } 85 } 86 return; 87 } 88 sdkCounterFilters.length = 0; 89 setSdkCounterFilter(sdkCounterList, sdkCounterFilters, startNS, endNS, totalNS, frame); 90 } 91} 92function setSdkCounterFilter( 93 list: Array<unknown>, 94 sdkCounterFilters: Array<unknown>, 95 startNS: number, 96 endNS: number, 97 totalNS: number, 98 frame: Rect 99): void { 100 if (list) { 101 for (let index = 0; index < list.length; index++) { 102 let item = list[index]; 103 //@ts-ignore 104 item.dur = index === list.length - 1 ? endNS - (item.ts || 0) : (list[index + 1].ts || 0) - (item.ts || 0); 105 //@ts-ignore 106 if ((item.ts || 0) + (item.dur || 0) > startNS && (item.ts || 0) < endNS) { 107 CounterStruct.setCounterFrame(list[index], 5, startNS, endNS, totalNS, frame); 108 if ( 109 !( 110 index > 0 && 111 //@ts-ignore 112 (list[index - 1].frame?.x || 0) === (list[index].frame?.x || 0) && 113 //@ts-ignore 114 (list[index - 1].frame?.width || 0) === (list[index].frame?.width || 0) 115 ) 116 ) { 117 sdkCounterFilters.push(item); 118 } 119 } 120 } 121 } 122} 123 124export class CounterStruct extends BaseStruct { 125 static maxCounter: number = 0; 126 static maxCounterName: string = ''; 127 static hoverCounterStruct: CounterStruct | undefined; 128 static selectCounterStruct: CounterStruct | undefined; 129 130 value: number | undefined; 131 ts: number | undefined; 132 counter_id: number | undefined; 133 134 static draw(sdkCounterContext: CanvasRenderingContext2D, data: CounterStruct, maxCounter: number): void { 135 if (data.frame) { 136 let width = data.frame.width || 0; 137 sdkCounterContext.fillStyle = '#67B0FC'; 138 sdkCounterContext.strokeStyle = '#67B0FC'; 139 if (data.ts === CounterStruct.hoverCounterStruct?.ts) { 140 sdkCounterContext.lineWidth = 1; 141 let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0) * 1.0) / maxCounter); 142 sdkCounterContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight + 4, width, drawHeight); 143 sdkCounterContext.beginPath(); 144 sdkCounterContext.arc(data.frame.x, data.frame.y + data.frame.height - drawHeight + 4, 3, 0, 2 * Math.PI, true); 145 sdkCounterContext.fill(); 146 sdkCounterContext.globalAlpha = 1.0; 147 sdkCounterContext.stroke(); 148 sdkCounterContext.beginPath(); 149 sdkCounterContext.moveTo(data.frame.x + 3, data.frame.y + data.frame.height - drawHeight + 4); 150 sdkCounterContext.lineWidth = 3; 151 sdkCounterContext.lineTo(data.frame.x + width, data.frame.y + data.frame.height - drawHeight + 4); 152 sdkCounterContext.stroke(); 153 } else { 154 sdkCounterContext.lineWidth = 1; 155 let drawHeight: number = Math.floor(((data.value || 0) * (data.frame.height || 0)) / maxCounter); 156 sdkCounterContext.fillRect(data.frame.x, data.frame.y + data.frame.height - drawHeight + 4, width, drawHeight); 157 } 158 } 159 sdkCounterContext.globalAlpha = 1.0; 160 sdkCounterContext.lineWidth = 1; 161 } 162 163 static setCounterFrame( 164 counterNode: unknown, 165 padding: number, 166 startNS: number, 167 endNS: number, 168 totalNS: number, 169 frame: Rect 170 ): void { 171 let sdkCounterStartPointX: number; 172 let sdkCountEndPointX: number; 173 //@ts-ignore 174 if ((counterNode.ts || 0) < startNS) { 175 sdkCounterStartPointX = 0; 176 } else { 177 //@ts-ignore 178 sdkCounterStartPointX = ns2x(counterNode.ts || 0, startNS, endNS, totalNS, frame); 179 } 180 //@ts-ignore 181 if ((counterNode.ts || 0) + (counterNode.dur || 0) > endNS) { 182 sdkCountEndPointX = frame.width; 183 } else { 184 //@ts-ignore 185 sdkCountEndPointX = ns2x((counterNode.ts || 0) + (counterNode.dur || 0), startNS, endNS, totalNS, frame); 186 } 187 let frameWidth: number = 188 sdkCountEndPointX - sdkCounterStartPointX <= 1 ? 1 : sdkCountEndPointX - sdkCounterStartPointX; 189 //@ts-ignore 190 if (!counterNode.frame) { 191 //@ts-ignore 192 counterNode.frame = {}; 193 } 194 //@ts-ignore 195 counterNode.frame.x = Math.floor(sdkCounterStartPointX); 196 //@ts-ignore 197 counterNode.frame.y = frame.y + padding; 198 //@ts-ignore 199 counterNode.frame.width = Math.ceil(frameWidth); 200 //@ts-ignore 201 counterNode.frame.height = Math.floor(frame.height - padding * 2); 202 } 203} 204