• 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 { BaseElement, element } from '../../base-ui/BaseElement.js';
17import { SelectionData } from '../bean/BoxSelection.js';
18import { Utils } from './trace/base/Utils.js';
19
20@element('stack-bar')
21export class StackBar extends BaseElement {
22  private container: HTMLDivElement | undefined | null;
23
24  static get observedAttributes() {
25    return ['mode']; // max min hidden show 三种状态
26  }
27
28  set data(val: Array<SelectionData>) {
29    let map = new Map<string, StackValue>();
30    for (let v of val) {
31      if (map.has(v.state)) {
32        let sv = map.get(v.state);
33        sv!.value = sv!.value + v.wallDuration;
34        sv!.state = v.state + ' : ' + sv!.value.toFixed(7) + 'ms';
35      } else {
36        let sv = new StackValue();
37        sv.value = v.wallDuration;
38        sv.state = v.state + ' : ' + sv.value.toFixed(7) + 'ms';
39        sv.color = Utils.getStateColor(v.stateJX);
40        map.set(v.state, sv);
41      }
42    }
43    let totalDuration = 0;
44    let arr: Array<StackValue> = [];
45    for (let key of map.keys()) {
46      if (key == ' ') {
47        totalDuration = map.get(key)!.value;
48      } else {
49        arr.push(map.get(key)!);
50      }
51    }
52    arr.sort((a, b) => a.value - b.value);
53    this.container!.innerHTML = '';
54    for (let stackValue of arr) {
55      this.container!.appendChild(this.createBarElement(stackValue, totalDuration));
56    }
57  }
58
59  initElements(): void {
60    this.container = this.shadowRoot?.querySelector('#container');
61  }
62
63  initHtml(): string {
64    return `
65        <style>
66            :host([mode='hidden']){
67                display: none;
68            }
69            :host{
70                display: block;
71                /*background-color: rebeccapurple;*/
72            }
73            .state-text{
74                width: 10%;display: inline-block;overflow: hidden;white-space: nowrap;padding: 5px; margin-right: 2px;font-size: 9pt;
75            }
76            </style>
77            <div style="display: flex;flex-direction: row;" id="container">
78            </div>
79        `;
80  }
81
82  getStateWidth(state: string): number {
83    let canvas = document.createElement('canvas');
84    let context = canvas.getContext('2d');
85    context!.font = '9pt';
86    let metrics = context!.measureText(state);
87    return metrics.width;
88  }
89
90  createBarElement(sv: StackValue, total: number): HTMLDivElement {
91    let bar = document.createElement('div');
92    bar.setAttribute('class', 'state-text');
93    bar.setAttribute('need-width', this.getStateWidth(sv.state) + '');
94    bar.style.backgroundColor = sv.color;
95    bar.textContent = sv.state;
96    if (sv.state.startsWith('Sleeping')) {
97      bar.style.color = '#555555';
98    } else {
99      bar.style.color = '#ffffff';
100    }
101    let weight = ((sv.value * 1.0) / total) * 100.0;
102    if (weight < 1) {
103      weight = 1;
104    }
105    bar.style.width = weight + '%';
106    bar.addEventListener('mouseover', (event) => {
107      let needWidth = parseFloat(bar.getAttribute('need-width')!);
108      let trueWidth = parseFloat(window.getComputedStyle(bar).width);
109      if (trueWidth < needWidth) {
110        bar.style.width = needWidth + 100 + 'px';
111      }
112    });
113    bar.addEventListener('mouseleave', (event) => {
114      let weight = ((sv.value * 1.0) / total) * 100.0;
115      if (weight < 1) {
116        weight = 1;
117      }
118      bar.style.width = weight + '%';
119    });
120    return bar;
121  }
122}
123
124export class StackValue {
125  state: string = '';
126  color: string = '';
127  value: number = 0;
128}
129