• 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;width: 100%;" 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.00
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.00
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}