• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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