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