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 { CpuStruct } from '../../../database/ui-worker/cpu/ProcedureWorkerCPU'; 17import { HangType } from '../../chart/SpHangChart'; 18 19export class ColorUtils { 20 public static GREY_COLOR: string = '#f0f0f0'; 21 22 public static FUNC_COLOR_A: Array<string> = [ 23 '#A37775', 24 '#B1CDF1', 25 '#76D1C0', 26 '#0CBDD4', 27 '#36BAA4', 28 '#69D3E5', 29 '#E3AA7D', 30 '#7DA6F4', 31 '#E68C43', 32 '#99C47C', 33 '#A56DF5', 34 '#E86B6A', 35 '#DC8077', 36 '#ADB7DB', 37 '#A1CD94', 38 '#66C7BA', 39 '#998FE6', 40 '#E7B75D', 41 '#8770D3', 42 '#93D090', 43 ]; 44 public static FUNC_COLOR_B: Array<string> = [ 45 '#23b0e7', 46 '#aa4fba', 47 '#4ca694', 48 '#8d9171', 49 '#ebc247', 50 '#8a8a8b', 51 '#78aec2', 52 '#FF0066', 53 '#a16a40', 54 '#e05b52', 55 '#7a9160', 56 '#9fafc4', 57 '#9bb87a', 58 '#8091D0', 59 '#c2cc66', 60 '#a94eb9', 61 '#8983B5', 62 '#B9A683', 63 '#40b3e7', 64 '#789876', 65 ]; 66 67 public static ANIMATION_COLOR: Array<string> = [ 68 '#ECECEC', 69 '#FE3000', 70 '#61CFBE', 71 '#000', 72 '#FFFFFF', 73 '#C6D9F2', 74 '#BFEBE5', 75 '#0A59F7', 76 '#25ACF5', 77 '#FFFFFF', 78 ]; 79 80 public static JANK_COLOR: Array<string> = [ 81 '#42A14D', 82 '#C0CE85', 83 '#FF651D', 84 '#E8BE44', 85 '#009DFA', 86 '#E97978', 87 '#A8D1F4', 88 ]; 89 public static MD_PALETTE: Array<string> = ColorUtils.FUNC_COLOR_B; 90 public static FUNC_COLOR: Array<string> = ColorUtils.FUNC_COLOR_B; 91 public static getHilogColor(loglevel: string | number): string { 92 let logColor: string = '#00000'; 93 switch (loglevel) { 94 case 0: 95 case 'D': 96 case 'Debug': 97 logColor = '#00BFBF'; 98 break; 99 case 1: 100 case 'I': 101 case 'Info': 102 logColor = '#00BF00'; 103 break; 104 case 2: 105 case 'W': 106 case 'Warn': 107 logColor = '#BFBF00'; 108 break; 109 case 3: 110 case 'E': 111 case 'Error': 112 logColor = '#FF4040'; 113 break; 114 case 4: 115 case 'F': 116 case 'Fatal': 117 logColor = '#BF00A4'; 118 break; 119 default: 120 break; 121 } 122 return logColor; 123 } 124 125 public static getHangColor(hangType: HangType): string { 126 return ({ 127 'Instant': '#559CFF', 128 'Circumstantial': '#E8BE44', 129 'Micro': '#FEB354', 130 'Severe': '#FC7470', 131 '': '#000000', 132 })[hangType]; 133 } 134 135 public static getHisysEventColor(level: string | number): string { 136 let eventColor: string = '#00000'; 137 switch (level) { 138 case 0: 139 case 'MINOR': 140 eventColor = '#000000'; 141 break; 142 case 1: 143 case 'CRITICAL': 144 eventColor = '#FF4040'; 145 break; 146 default: 147 break; 148 } 149 return eventColor; 150 } 151 152 public static hash(str: string, max: number): number { 153 let colorA: number = 0x811c9dc5; 154 let colorB: number = 0xfffffff; 155 let colorC: number = 16777619; 156 let colorD: number = 0xffffffff; 157 let hash: number = colorA & colorB; 158 159 for (let index: number = 0; index < str.length; index++) { 160 hash ^= str.charCodeAt(index); 161 hash = (hash * colorC) & colorD; 162 } 163 return Math.abs(hash) % max; 164 } 165 166 public static colorForThread(thread: CpuStruct): string { 167 if (thread === null) { 168 return ColorUtils.GREY_COLOR; 169 } 170 let tid: number | undefined | null = (thread.processId || -1) >= 0 ? thread.processId : thread.tid; 171 return ColorUtils.colorForTid(tid || 0); 172 } 173 174 public static colorForTid(tid: number): string { 175 let colorIdx: number = ColorUtils.hash(`${tid}`, ColorUtils.MD_PALETTE.length); 176 return ColorUtils.MD_PALETTE[colorIdx]; 177 } 178 179 public static colorForName(name: string): string { 180 let colorIdx: number = ColorUtils.hash(name, ColorUtils.MD_PALETTE.length); 181 return ColorUtils.MD_PALETTE[colorIdx]; 182 } 183 184 public static formatNumberComma(str: number): string { 185 if (str === undefined || str === null) { 186 return ''; 187 } 188 let unit = str >= 0 ? '' : '-'; 189 let l = Math.abs(str).toString().split('').reverse(); 190 let t: string = ''; 191 for (let i = 0; i < l.length; i++) { 192 t += l[i] + ((i + 1) % 3 === 0 && i + 1 !== l.length ? ',' : ''); 193 } 194 return unit + t.split('').reverse().join(''); 195 } 196 197 public static hashFunc(str: string, depth: number, max: number): number { 198 let colorA: number = 0x811c9dc5; 199 let colorB: number = 0xfffffff; 200 let colorC: number = 16777619; 201 let colorD: number = 0xffffffff; 202 let hash: number = colorA & colorB; 203 let st = str.replace(/[0-9]+/g, ''); 204 for (let index: number = 0; index < st.length; index++) { 205 hash ^= st.charCodeAt(index); 206 hash = (hash * colorC) & colorD; 207 } 208 return (Math.abs(hash) + depth) % max; 209 } 210 211 public static funcTextColor(val: string): string { 212 let reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; 213 // 把颜色值变成小写 214 let color = val.toLowerCase(); 215 let result = ''; 216 if (reg.test(color)) { 217 if (color.length === 4) { 218 let colorNew = '#'; 219 for (let i = 1; i < 4; i += 1) { 220 colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1)); 221 } 222 color = colorNew; 223 } 224 let colorChange = []; 225 for (let i = 1; i < 7; i += 2) { 226 colorChange.push(parseInt(`0x${color.slice(i, i + 2)}`)); 227 } 228 let grayLevel = colorChange[0] * 0.299 + colorChange[1] * 0.587 + colorChange[2] * 0.114; 229 if (grayLevel >= 100) { 230 //浅色模式 231 return '#000'; 232 } else { 233 return '#fff'; 234 } 235 } else { 236 result = '无效'; 237 return result; 238 } 239 } 240} 241export function interpolateColorBrightness(colorHex: string, percentage: number): number[] { 242 const color = hexToRgb(colorHex); 243 if (color.length === 0) { 244 return []; 245 } 246 const [h, s, l] = rgbToHsl(color[0] / 255, color[1] / 255, color[2] / 255); 247 248 // 根据百分比计算亮度插值 249 const interpolatedL = 1 - percentage * 0.75; // 百分比越高,亮度越低 250 251 // 将插值后的亮度值与原始的色相和饱和度值组合 252 const interpolatedColor = hslToRgb(h, s, interpolatedL); 253 return interpolatedColor.map((val) => Math.round(val * 255)); 254} 255 256function rgbToHsl(r: number, g: number, b: number): number[] { 257 const max = Math.max(r, g, b); 258 const min = Math.min(r, g, b); 259 let h = 0; 260 let s = 0; 261 let l = (max + min) / 2; 262 263 if (max === min) { 264 h = s = 0; // achromatic 265 } else { 266 const d = max - min; 267 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 268 switch (max) { 269 case r: 270 h = (g - b) / d + (g < b ? 6 : 0); 271 break; 272 case g: 273 h = (b - r) / d + 2; 274 break; 275 case b: 276 h = (r - g) / d + 4; 277 break; 278 } 279 h /= 6; 280 } 281 282 return [h, s, l]; 283} 284 285function hexToRgb(colorHex: string): number[] { 286 // 16进制颜色值 287 const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; 288 let color = colorHex.toLowerCase(); 289 if (reg.test(color)) { 290 // 如果只有三位的值,需变成六位,如:#fff => #ffffff 291 if (color.length === 4) { 292 let colorNew = '#'; 293 for (let i = 1; i < 4; i += 1) { 294 colorNew += color.slice(i, i + 1).concat(color.slice(i, i + 1)); 295 } 296 color = colorNew; 297 } 298 // 处理六位的颜色值,转为RGB 299 let rgb = []; 300 for (let i = 1; i < 7; i += 2) { 301 rgb.push(parseInt(`0x${color.slice(i, i + 2)}`)); 302 } 303 return rgb; 304 } 305 return []; 306} 307 308function hslToRgb(h: number, s: number, l: number): number[] { 309 let r = 0; 310 let g = 0; 311 let b = 0; 312 313 if (s === 0) { 314 r = g = b = l; // achromatic 315 } else { 316 const hue2rgb = (p: number, q: number, t: number): number => { 317 if (t < 0) { 318 t += 1; 319 } 320 if (t > 1) { 321 t -= 1; 322 } 323 if (t < 1 / 6) { 324 return p + (q - p) * 6 * t; 325 } 326 if (t < 1 / 2) { 327 return q; 328 } 329 if (t < 2 / 3) { 330 return p + (q - p) * (2 / 3 - t) * 6; 331 } 332 return p; 333 }; 334 335 const q = l < 0.5 ? l * (1 + s) : l + s - l * s; 336 const p = 2 * l - q; 337 338 r = hue2rgb(p, q, h + 1 / 3); 339 g = hue2rgb(p, q, h); 340 b = hue2rgb(p, q, h - 1 / 3); 341 } 342 343 return [r, g, b]; 344} 345