1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { BaseElement, element } from '../../base-ui/BaseElement'; 17fb726d48Sopenharmony_ciimport { SelectionData } from '../bean/BoxSelection'; 18fb726d48Sopenharmony_ciimport { Utils } from './trace/base/Utils'; 19fb726d48Sopenharmony_ci 20fb726d48Sopenharmony_ci@element('stack-bar') 21fb726d48Sopenharmony_ciexport class StackBar extends BaseElement { 22fb726d48Sopenharmony_ci private vessel: HTMLDivElement | undefined | null; 23fb726d48Sopenharmony_ci 24fb726d48Sopenharmony_ci static get observedAttributes(): string[] { 25fb726d48Sopenharmony_ci return ['mode']; // max min hidden show 三种状态 26fb726d48Sopenharmony_ci } 27fb726d48Sopenharmony_ci 28fb726d48Sopenharmony_ci set data(val: Array<SelectionData>) { 29fb726d48Sopenharmony_ci let map = new Map<string, StackValue>(); 30fb726d48Sopenharmony_ci for (let v of val) { 31fb726d48Sopenharmony_ci if (map.has(v.stateJX)) { 32fb726d48Sopenharmony_ci let sv = map.get(v.stateJX); 33fb726d48Sopenharmony_ci sv!.value = sv!.value + v.wallDuration; 34fb726d48Sopenharmony_ci sv!.state = `${v.stateJX} : ${sv!.value.toFixed(5)}ms`; 35fb726d48Sopenharmony_ci } else { 36fb726d48Sopenharmony_ci let sv = new StackValue(); 37fb726d48Sopenharmony_ci sv.value = v.wallDuration; 38fb726d48Sopenharmony_ci sv.state = `${v.stateJX} : ${sv.value.toFixed(5)}ms`; 39fb726d48Sopenharmony_ci sv.color = Utils.getStateColor(v.state); 40fb726d48Sopenharmony_ci map.set(v.stateJX, sv); 41fb726d48Sopenharmony_ci } 42fb726d48Sopenharmony_ci } 43fb726d48Sopenharmony_ci let totalDuration = 0; 44fb726d48Sopenharmony_ci let arr: Array<StackValue> = []; 45fb726d48Sopenharmony_ci for (let key of map.keys()) { 46fb726d48Sopenharmony_ci if (key === ' ') { 47fb726d48Sopenharmony_ci totalDuration = map.get(key)!.value; 48fb726d48Sopenharmony_ci } else { 49fb726d48Sopenharmony_ci arr.push(map.get(key)!); 50fb726d48Sopenharmony_ci } 51fb726d48Sopenharmony_ci } 52fb726d48Sopenharmony_ci arr.sort((a, b) => a.value - b.value); 53fb726d48Sopenharmony_ci this.vessel!.innerHTML = ''; 54fb726d48Sopenharmony_ci for (let stackValue of arr) { 55fb726d48Sopenharmony_ci this.vessel!.appendChild(this.createBarElement(stackValue, totalDuration)); 56fb726d48Sopenharmony_ci } 57fb726d48Sopenharmony_ci } 58fb726d48Sopenharmony_ci 59fb726d48Sopenharmony_ci initElements(): void { 60fb726d48Sopenharmony_ci this.vessel = this.shadowRoot?.querySelector('#vessel'); 61fb726d48Sopenharmony_ci } 62fb726d48Sopenharmony_ci 63fb726d48Sopenharmony_ci initHtml(): string { 64fb726d48Sopenharmony_ci return ` 65fb726d48Sopenharmony_ci <style> 66fb726d48Sopenharmony_ci :host([mode='hidden']){ 67fb726d48Sopenharmony_ci display: none; 68fb726d48Sopenharmony_ci } 69fb726d48Sopenharmony_ci :host{ 70fb726d48Sopenharmony_ci display: block; 71fb726d48Sopenharmony_ci /*background-color: rebeccapurple;*/ 72fb726d48Sopenharmony_ci } 73fb726d48Sopenharmony_ci .state-text{ 74fb726d48Sopenharmony_ci width: 10%;display: inline-block;overflow: hidden;white-space: nowrap;padding: 5px; margin-right: 2px;font-size: 9pt; 75fb726d48Sopenharmony_ci } 76fb726d48Sopenharmony_ci </style> 77fb726d48Sopenharmony_ci <div style="display: flex;flex-direction: row;" id="vessel"> 78fb726d48Sopenharmony_ci </div> 79fb726d48Sopenharmony_ci `; 80fb726d48Sopenharmony_ci } 81fb726d48Sopenharmony_ci 82fb726d48Sopenharmony_ci getStateWidth(state: string): number { 83fb726d48Sopenharmony_ci let canvas = document.createElement('canvas'); 84fb726d48Sopenharmony_ci let context = canvas.getContext('2d'); 85fb726d48Sopenharmony_ci context!.font = '9pt'; 86fb726d48Sopenharmony_ci let metrics = context!.measureText(state); 87fb726d48Sopenharmony_ci return metrics.width; 88fb726d48Sopenharmony_ci } 89fb726d48Sopenharmony_ci 90fb726d48Sopenharmony_ci createBarElement(sv: StackValue, total: number): HTMLDivElement { 91fb726d48Sopenharmony_ci let bar = document.createElement('div'); 92fb726d48Sopenharmony_ci bar.setAttribute('class', 'state-text'); 93fb726d48Sopenharmony_ci bar.setAttribute('need-width', `${this.getStateWidth(sv.state)}`); 94fb726d48Sopenharmony_ci bar.style.backgroundColor = sv.color; 95fb726d48Sopenharmony_ci bar.textContent = sv.state; 96fb726d48Sopenharmony_ci if (sv.state.startsWith('Sleeping')) { 97fb726d48Sopenharmony_ci bar.style.color = '#555555'; 98fb726d48Sopenharmony_ci } else { 99fb726d48Sopenharmony_ci bar.style.color = '#ffffff'; 100fb726d48Sopenharmony_ci } 101fb726d48Sopenharmony_ci let weight = ((sv.value * 1.0) / total) * 100.0; 102fb726d48Sopenharmony_ci if (weight < 1) { 103fb726d48Sopenharmony_ci weight = 1; 104fb726d48Sopenharmony_ci } 105fb726d48Sopenharmony_ci bar.style.width = `${weight}%`; 106fb726d48Sopenharmony_ci bar.addEventListener('mouseover', (): void => { 107fb726d48Sopenharmony_ci let needWidth = parseFloat(bar.getAttribute('need-width')!); 108fb726d48Sopenharmony_ci let trueWidth = parseFloat(window.getComputedStyle(bar).width); 109fb726d48Sopenharmony_ci if (trueWidth < needWidth) { 110fb726d48Sopenharmony_ci bar.style.width = `${needWidth + 100}px`; 111fb726d48Sopenharmony_ci } 112fb726d48Sopenharmony_ci }); 113fb726d48Sopenharmony_ci bar.addEventListener('mouseleave', (): void => { 114fb726d48Sopenharmony_ci let weight = ((sv.value * 1.0) / total) * 100.0; 115fb726d48Sopenharmony_ci if (weight < 1) { 116fb726d48Sopenharmony_ci weight = 1; 117fb726d48Sopenharmony_ci } 118fb726d48Sopenharmony_ci bar.style.width = `${weight}%`; 119fb726d48Sopenharmony_ci }); 120fb726d48Sopenharmony_ci return bar; 121fb726d48Sopenharmony_ci } 122fb726d48Sopenharmony_ci} 123fb726d48Sopenharmony_ci 124fb726d48Sopenharmony_ciexport class StackValue { 125fb726d48Sopenharmony_ci state: string = ''; 126fb726d48Sopenharmony_ci color: string = ''; 127fb726d48Sopenharmony_ci value: number = 0; 128fb726d48Sopenharmony_ci} 129