• 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 { XpowerThreadInfoStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerThreadInfo';
20import { SortDetail, resizeObserver } from '../SheetUtils';
21
22@element('tabpane-xpower-thread-energy')
23export class TabPaneXpowerThreadEnergy extends BaseElement {
24  private XpowerThreadEnergyTbl: LitTable | null | undefined;
25  private XpowerThreadEnergyRange: HTMLLabelElement | null | undefined;
26  private XpowerThreadEnergySource: Array<SelectionData> = [];
27  private sumCount: number = 0;
28  private tabTitle: HTMLDivElement | undefined | null;
29
30  set data(XpowerThreadEnergyValue: SelectionParam) {
31    this.init();
32    this.XpowerThreadEnergyTbl!.shadowRoot!.querySelector<HTMLDivElement>('.table')!.style!.height = `${
33      this.parentElement!.clientHeight - 45
34    }px`;
35    this.XpowerThreadEnergyRange!.textContent = `Selected range: ${parseFloat(
36      ((XpowerThreadEnergyValue.rightNs - XpowerThreadEnergyValue.leftNs) / 1000000.0).toFixed(5)
37    )} ms`;
38    this.getThreadEnergyData(XpowerThreadEnergyValue).then();
39  }
40
41  async getThreadEnergyData(XpowerThreadEnergyValue: SelectionParam): Promise<void> {
42    this.sumCount = 0;
43    let dataSource: SelectionData[] = [];
44    let collect = XpowerThreadEnergyValue.xpowerThreadEnergyMapData;
45    this.XpowerThreadEnergyTbl!.loading = true;
46    for (let key of collect.keys()) {
47      let threadEnergys = collect.get(key);
48      let res = (await threadEnergys?.({
49        startNS: XpowerThreadEnergyValue.leftNs,
50        endNS: XpowerThreadEnergyValue.rightNs,
51        queryAll: true,
52      })) as XpowerThreadInfoStruct[];
53      let sd = this.createSelectThreadEnergyData(res || []);
54      dataSource = dataSource.concat(sd);
55    }
56    this.XpowerThreadEnergyTbl!.loading = false;
57    this.XpowerThreadEnergySource = dataSource;
58    this.XpowerThreadEnergyTbl!.recycleDataSource = dataSource;
59  }
60
61  private init(): void {
62    const thTable = this.tabTitle!.querySelector('.th');
63    const list = thTable!.querySelectorAll('div');
64    if (this.tabTitle!.hasAttribute('sort')) {
65      this.tabTitle!.removeAttribute('sort');
66      list.forEach((item) => {
67        item.querySelectorAll('svg').forEach((svg) => {
68          svg.style.display = 'none';
69        });
70      });
71    }
72  }
73
74  initElements(): void {
75    this.XpowerThreadEnergyTbl = this.shadowRoot?.querySelector<LitTable>('#tb-threadEnergy');
76    this.tabTitle = this.XpowerThreadEnergyTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
77    this.XpowerThreadEnergyRange = this.shadowRoot?.querySelector('#time-range');
78    this.XpowerThreadEnergyTbl!.addEventListener('column-click', (evt): void => {
79      // @ts-ignore
80      this.sortByColumn(evt.detail);
81    });
82  }
83
84  connectedCallback(): void {
85    super.connectedCallback();
86    resizeObserver(this.parentElement!, this.XpowerThreadEnergyTbl!);
87  }
88
89  initHtml(): string {
90    return `
91        <style>
92        .xpower-thread-energy-label{
93            margin-bottom: 5px;
94        }
95        :host{
96            padding: 10px 10px;
97            display: flex;
98            flex-direction: column;
99        }
100        </style>
101        <label id="time-range" class="xpower-thread-energy-label" style="width: 100%;height: 20px;text-align: end;font-size: 10pt;">Selected range:0.0 ms</label>
102        <lit-table id="tb-threadEnergy" style="height: auto">
103            <lit-table-column order title="ThreadName" data-index="name" key="name"  align="flex-start" width="25%">
104            </lit-table-column>
105            <lit-table-column data-index="count" title="Count" order key="count"  align="flex-start" width="1fr">
106            </lit-table-column>
107            <lit-table-column title="Avg Energy(mAh)" data-index="avgNumber" order key="avgNumber" align="flex-start" width="1fr">
108            </lit-table-column>
109            <lit-table-column title="Max Energy(mAh)" align="flex-start" order data-index="maxNumber" key="maxNumber" width="1fr">
110            </lit-table-column>
111            <lit-table-column title="Min Energy(mAh)" key="minNumber" data-index="minNumber" order align="flex-start" width="1fr">
112            </lit-table-column>
113        </lit-table>
114        `;
115  }
116
117  private createSelectThreadEnergyData(list: Array<XpowerThreadInfoStruct>): SelectionData[] {
118    let SelectThreadEnergyArray: SelectionData[] = [];
119    if (list.length > 0) {
120      let threadEnergyMap = new Map();
121      list.forEach((item) => {
122        if (item.value > 0) {
123          if (threadEnergyMap.has(item.threadName)) {
124            const data = threadEnergyMap.get(item.threadName)!;
125            data.push(item);
126          } else {
127            const data: XpowerThreadInfoStruct[] = [];
128            data.push(item);
129            threadEnergyMap.set(item.threadName, data);
130          }
131        }
132      });
133      for (let itemArray of threadEnergyMap.values()) {
134        let SelectThreadEnergyData = new SelectionData();
135        let max = 0;
136        let min = 0;
137        let sum = 0;
138        SelectThreadEnergyData.name = itemArray[0].threadName;
139        SelectThreadEnergyData.count = itemArray.length;
140        if (itemArray.length > 1) {
141          max = itemArray.map((item: { value: unknown }) => item.value).reduce((a: number, b: number) => Math.max(a, b));
142          min = itemArray.map((item: { value: unknown }) => item.value).reduce((a: number, b: number) => Math.min(a, b));
143          // @ts-ignore
144          sum = itemArray.reduce((acc: unknown, obj: { value: unknown }) => acc + obj.value, 0);
145          SelectThreadEnergyData.avgNumber = parseFloat((sum / itemArray.length).toFixed(2));
146          SelectThreadEnergyData.maxNumber = max;
147          SelectThreadEnergyData.minNumber = min;
148        } else if (itemArray.length === 1) {
149          let value = itemArray[0].value;
150          SelectThreadEnergyData.avgNumber = value;
151          SelectThreadEnergyData.maxNumber = value;
152          SelectThreadEnergyData.minNumber = value;
153        }
154        this.sumCount += itemArray.length;
155        SelectThreadEnergyArray.push(SelectThreadEnergyData);
156      }
157    }
158    return SelectThreadEnergyArray;
159  }
160
161  private sortByColumn(detail: SortDetail): void {
162    function compare(property: string, sort: number, type: string) {
163      return function (xpowerThreadEnergyLeftData: SelectionData, xpowerThreadEnergyRightData: SelectionData): number {
164        if (xpowerThreadEnergyLeftData.process === ' ' || xpowerThreadEnergyRightData.process === ' ') {
165          return 0;
166        }
167        if (type === 'number') {
168          return sort === 2 // @ts-ignore
169            ? parseFloat(xpowerThreadEnergyRightData[property]) - parseFloat(xpowerThreadEnergyLeftData[property]) // @ts-ignore
170            : parseFloat(xpowerThreadEnergyLeftData[property]) - parseFloat(xpowerThreadEnergyRightData[property]);
171        } else {
172          // @ts-ignore
173          if (xpowerThreadEnergyRightData[property] > xpowerThreadEnergyLeftData[property]) {
174            return sort === 2 ? 1 : -1;
175          } else {
176            // @ts-ignore
177            if (xpowerThreadEnergyRightData[property] === xpowerThreadEnergyLeftData[property]) {
178              return 0;
179            } else {
180              return sort === 2 ? -1 : 1;
181            }
182          }
183        }
184      };
185    }
186    if (detail.key === 'name') {
187      this.XpowerThreadEnergySource.sort(compare(detail.key, detail.sort, 'string'));
188    } else {
189      this.XpowerThreadEnergySource.sort(compare(detail.key, detail.sort, 'number'));
190    }
191    this.XpowerThreadEnergyTbl!.recycleDataSource = this.XpowerThreadEnergySource;
192  }
193}
194