• 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';
17import { LitTable } from '../../../../../base-ui/table/lit-table';
18import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection';
19import { resizeObserver } from '../SheetUtils';
20import { TraceRow } from '../../base/TraceRow';
21import { SpSystemTrace } from '../../../SpSystemTrace';
22import { XpowerAppDetailStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerAppDetail';
23import { Utils } from '../../base/Utils';
24import { SpChartList } from '../../SpChartList';
25
26@element('tabpane-xpower-display')
27export class TabPaneXpowerDisplay extends BaseElement {
28  private xpowerCounterTbl: LitTable | null | undefined;
29  private xpowerCounterRange: HTMLLabelElement | null | undefined;
30  private xpowerCounterSource: Array<SelectionData> = [];
31  private systemTrace: SpSystemTrace | undefined | null;
32  private spChartList: SpChartList | undefined | null;
33  private traceRow: TraceRow<XpowerAppDetailStruct> | undefined | null;
34  private tabTitle: HTMLDivElement | undefined | null;
35  private checked: boolean[] = [];
36  private checkedValue: string[] = [];
37
38  set data(xpowerCounterValue: SelectionParam) {
39    this.init();
40    this.xpowerCounterTbl!.shadowRoot!.querySelector<HTMLElement>('.table')!.style.height = `${
41      this.parentElement!.clientHeight - 45
42    }px`;
43    this.xpowerCounterRange!.textContent = `Selected range: ${parseFloat(
44      ((xpowerCounterValue.rightNs - xpowerCounterValue.leftNs) / 1000000.0).toFixed(5)
45    )} ms`;
46    this.traceRow = this.systemTrace!.shadowRoot?.querySelector<TraceRow<XpowerAppDetailStruct>>(
47      "trace-row[row-id='AppDetailDisplay']"
48    );
49    if (!this.traceRow) {
50      this.spChartList = this.systemTrace!.shadowRoot?.querySelector('div > sp-chart-list');
51      this.traceRow = this.spChartList?.shadowRoot!.querySelector(".root > div > trace-row[row-id='AppDetailDisplay']");
52    }
53    this.checked = this.traceRow!.rowSettingCheckedBoxList!;
54    this.checkedValue = this.traceRow!.rowSettingCheckBoxList!;
55    this.getCounterData(xpowerCounterValue).then();
56  }
57
58  async getCounterData(xpowerCounterValue: SelectionParam): Promise<void> {
59    let dataSource: Array<SelectionData> = [];
60    let collect = xpowerCounterValue.xpowerDisplayMapData;
61    this.xpowerCounterTbl!.loading = true;
62    for (let key of collect.keys()) {
63      let counters = collect.get(key);
64      let res = await counters?.({
65        startNS: xpowerCounterValue.leftNs,
66        endNS: xpowerCounterValue.rightNs,
67        queryAll: true,
68      });
69      let xpowerDisplayMap = new Map<string, number[]>();
70      this.checkedValue.forEach((key) => {
71        res!.forEach((item) => {
72          // @ts-ignore
73          let value = item['c' + key];
74          if (xpowerDisplayMap.has(key) && value !== 0) {
75            let data = xpowerDisplayMap.get(key);
76            data!.push(value);
77            xpowerDisplayMap.set(key, data!);
78          } else if (value !== 0) {
79            xpowerDisplayMap.set(key, []);
80            let data = xpowerDisplayMap.get(key);
81            data!.push(value);
82            xpowerDisplayMap.set(key, data!);
83          }
84        });
85      });
86      xpowerDisplayMap.forEach((value, key) => {
87        !this.checked[this.checkedValue.indexOf(key)] && xpowerDisplayMap.has(key) && xpowerDisplayMap.delete(key);
88      });
89      xpowerDisplayMap.forEach((value, key) => {
90        let sd = this.createSelectCounterData(value, key);
91        dataSource.push(sd);
92      });
93    }
94    this.xpowerCounterTbl!.loading = false;
95    this.xpowerCounterSource = dataSource;
96    this.xpowerCounterTbl!.recycleDataSource = dataSource;
97  }
98
99  initElements(): void {
100    this.systemTrace = document
101      .querySelector('body > sp-application')
102      ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace');
103    this.xpowerCounterTbl = this.shadowRoot?.querySelector<LitTable>('#tb-counter');
104    this.tabTitle = this.xpowerCounterTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
105    this.xpowerCounterRange = this.shadowRoot?.querySelector('#time-range');
106    this.xpowerCounterTbl!.addEventListener('column-click', (evt): void => {
107      // @ts-ignore
108      this.sortByColumn(evt.detail);
109    });
110  }
111
112  connectedCallback(): void {
113    super.connectedCallback();
114    resizeObserver(this.parentElement!, this.xpowerCounterTbl!);
115  }
116
117  initHtml(): string {
118    return `
119        <style>
120        .xpower-counter-label{
121            margin-bottom: 5px;
122        }
123        :host{
124            padding: 10px 10px;
125            display: flex;
126            flex-direction: column;
127        }
128        </style>
129        <label id="time-range" class="xpower-counter-label" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label>
130        <lit-table id="tb-counter" style="height: auto">
131            <lit-table-column order title="Name" data-index="name" key="name"  align="flex-start" width="20%">
132            </lit-table-column>
133            <lit-table-column data-index="count" order title="Count"  key="count"  align="flex-start" width="1fr">
134            </lit-table-column>
135            <lit-table-column title="Max(ms)" order data-index="max" key="max"  align="flex-start" width="1fr">
136            </lit-table-column>
137            <lit-table-column data-index="min" title="Min(ms)" order key="min"  align="flex-start" width="1fr">
138            </lit-table-column>
139            <lit-table-column title="Avg(ms)" key="average" order data-index="average" align="flex-start" width="1fr">
140            </lit-table-column>
141        </lit-table>
142        `;
143  }
144
145  createSelectCounterData(list: number[], key: string): SelectionData {
146    let selectCounterData = new SelectionData();
147    if (list.length > 0) {
148      selectCounterData.name = key;
149      selectCounterData.count = list.length.toString();
150      let max = list[0];
151      let min = list[0];
152      let total = 0;
153      list.forEach((item) => {
154        max < item && (max = item);
155        min > item && (min = item);
156        total += item;
157      });
158      selectCounterData.max = max.toString();
159      selectCounterData.min = min.toString();
160      selectCounterData.average = (total / list.length).toFixed(2);
161    }
162    return selectCounterData;
163  }
164
165  sortByColumn(detail: { key: string; sort: number }): void {
166    // @ts-ignore
167    function compare(property, sort, type) {
168      return function (xpowerCounterLeftData: SelectionData, xpowerCounterRightData: SelectionData): number {
169        if (xpowerCounterLeftData.process === ' ' || xpowerCounterRightData.process === ' ') {
170          return 0;
171        }
172        if (type === 'number') {
173          return sort === 2 // @ts-ignore
174            ? parseFloat(xpowerCounterRightData[property]) - parseFloat(xpowerCounterLeftData[property]) // @ts-ignore
175            : parseFloat(xpowerCounterLeftData[property]) - parseFloat(xpowerCounterRightData[property]);
176        } else {
177          // @ts-ignore
178          if (xpowerCounterRightData[property] > xpowerCounterLeftData[property]) {
179            return sort === 2 ? 1 : -1;
180          } else {
181            // @ts-ignore
182            if (xpowerCounterRightData[property] === xpowerCounterLeftData[property]) {
183              return 0;
184            } else {
185              return sort === 2 ? -1 : 1;
186            }
187          }
188        }
189      };
190    }
191    if (detail.key === 'name') {
192      this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number'));
193    } else {
194      this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number'));
195    }
196    this.xpowerCounterTbl!.recycleDataSource = this.xpowerCounterSource;
197  }
198
199  private init(): void {
200    const thTable = this.tabTitle!.querySelector('.th');
201    const list = thTable!.querySelectorAll('div');
202    if (this.tabTitle!.hasAttribute('sort')) {
203      this.tabTitle!.removeAttribute('sort');
204      list.forEach((item) => {
205        item.querySelectorAll('svg').forEach((svg) => {
206          svg.style.display = 'none';
207        });
208      });
209    }
210  }
211}
212