• 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 { XpowerStatisticStruct } from '../../../../database/ui-worker/ProcedureWorkerXpowerStatistic';
23import { SpChartList } from '../../SpChartList';
24
25@element('tabpane-xpower-statistic')
26export class TabPaneXpowerStatistic extends BaseElement {
27  private xpowerCounterTbl: LitTable | null | undefined;
28  private xpowerCounterRange: HTMLLabelElement | null | undefined;
29  private xpowerCounterSource: Array<SelectionData> = [];
30  private systemTrace: SpSystemTrace | undefined | null;
31  private spChartList: SpChartList | undefined | null;
32  private traceRow: TraceRow<XpowerStatisticStruct> | undefined | null;
33  private tabTitle: HTMLDivElement | undefined | null;
34  private checked: boolean[] = [];
35  private checkedValue: string[] = [];
36
37  set data(xpowerCounterValue: SelectionParam) {
38    this.init();
39    //@ts-ignore
40    this.xpowerCounterTbl?.shadowRoot?.querySelector('.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<XpowerStatisticStruct>>(
47      "trace-row[row-id='Statistic']"
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='Statistic']");
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.xpowerStatisticMapData;
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      res!.forEach((item) => {
70        // @ts-ignore
71        item.typeStr = SpSystemTrace.DATA_DICT.get(item.type)!;
72      });
73      let xpowerStasticMap = new Map<
74        string,
75        { startTime: number; dur: number; energy: number; type: number; typeStr: string }[]
76      >();
77      // @ts-ignore
78      res.forEach((item: { startTime: number; dur: number; energy: number; type: number; typeStr: string }) => {
79        if (xpowerStasticMap.has(item.typeStr)) {
80          let data = xpowerStasticMap.get(item.typeStr);
81          data!.push(item);
82          xpowerStasticMap.set(item.typeStr, data!);
83        } else {
84          xpowerStasticMap.set(item.typeStr, []);
85          let data = xpowerStasticMap.get(item.typeStr);
86          data!.push(item);
87          xpowerStasticMap.set(item.typeStr, data!);
88        }
89      });
90      xpowerStasticMap.forEach((value, key) => {
91        !this.checked[this.checkedValue.indexOf(key)] && xpowerStasticMap.delete(key);
92      });
93      xpowerStasticMap.forEach((value) => {
94        let sd = this.createSelectCounterData(value);
95        dataSource.push(sd);
96      });
97    }
98    this.xpowerCounterTbl!.loading = false;
99    this.xpowerCounterSource = dataSource;
100    this.xpowerCounterTbl!.recycleDataSource = dataSource;
101  }
102
103  initElements(): void {
104    this.systemTrace = document
105      .querySelector('body > sp-application')
106      ?.shadowRoot!.querySelector<SpSystemTrace>('#sp-system-trace');
107    this.xpowerCounterTbl = this.shadowRoot?.querySelector<LitTable>('#tb-counter');
108    this.tabTitle = this.xpowerCounterTbl!.shadowRoot?.querySelector('.thead') as HTMLDivElement;
109    this.xpowerCounterRange = this.shadowRoot?.querySelector('#time-range');
110    this.xpowerCounterTbl!.addEventListener('column-click', (evt): void => {
111      // @ts-ignore
112      this.sortByColumn(evt.detail);
113    });
114  }
115
116  connectedCallback(): void {
117    super.connectedCallback();
118    resizeObserver(this.parentElement!, this.xpowerCounterTbl!);
119  }
120
121  initHtml(): string {
122    return `
123        <style>
124        .xpower-counter-label{
125            margin-bottom: 5px;
126        }
127        :host{
128            padding: 10px 10px;
129            display: flex;
130            flex-direction: column;
131        }
132        </style>
133        <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>
134        <lit-table id="tb-counter" style="height: auto">
135            <lit-table-column order title="Name" data-index="name" key="name"  align="flex-start" width="20%">
136            </lit-table-column>
137            <lit-table-column data-index="count" order title="Count"  key="count"  align="flex-start" width="1fr">
138            </lit-table-column>
139            <lit-table-column title="Avg_Energy(mAh)" key="average" order data-index="average" align="flex-start" width="1fr">
140            </lit-table-column>
141            <lit-table-column title="Max_Energy(mAh)" order data-index="max" key="max"  align="flex-start" width="1fr">
142            </lit-table-column>
143            <lit-table-column data-index="min" title="Min_Energy(mAh)" order key="min"  align="flex-start" width="1fr">
144            </lit-table-column>
145        </lit-table>
146        `;
147  }
148
149  createSelectCounterData(
150    list: { startTime: number; dur: number; energy: number; type: number; typeStr: string }[]
151  ): SelectionData {
152    let selectCounterData = new SelectionData();
153    if (list.length > 0) {
154      selectCounterData.name = list[0].typeStr;
155      selectCounterData.count = list.length.toString();
156      let max = list[0].energy;
157      let min = list[0].energy;
158      let total = 0;
159      list.forEach((item) => {
160        max < item.energy && (max = item.energy);
161        min > item.energy && (min = item.energy);
162        total += item.energy;
163      });
164      selectCounterData.max = max.toString();
165      selectCounterData.min = min.toString();
166      selectCounterData.average = (total / list.length).toFixed(2);
167    }
168    return selectCounterData;
169  }
170
171  sortByColumn(detail: { key: string; sort: number }): void {
172    // @ts-ignore
173    function compare(property, sort, type) {
174      return function (xpowerCounterLeftData: SelectionData, xpowerCounterRightData: SelectionData): number {
175        if (xpowerCounterLeftData.process === ' ' || xpowerCounterRightData.process === ' ') {
176          return 0;
177        }
178        if (type === 'number') {
179          return sort === 2 // @ts-ignore
180            ? parseFloat(xpowerCounterRightData[property]) - parseFloat(xpowerCounterLeftData[property]) // @ts-ignore
181            : parseFloat(xpowerCounterLeftData[property]) - parseFloat(xpowerCounterRightData[property]);
182        } else {
183          // @ts-ignore
184          if (xpowerCounterRightData[property] > xpowerCounterLeftData[property]) {
185            return sort === 2 ? 1 : -1;
186          } else {
187            // @ts-ignore
188            if (xpowerCounterRightData[property] === xpowerCounterLeftData[property]) {
189              return 0;
190            } else {
191              return sort === 2 ? -1 : 1;
192            }
193          }
194        }
195      };
196    }
197    if (detail.key === 'name') {
198      this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'string'));
199    } else {
200      this.xpowerCounterSource.sort(compare(detail.key, detail.sort, 'number'));
201    }
202    this.xpowerCounterTbl!.recycleDataSource = this.xpowerCounterSource;
203  }
204
205  private init(): void {
206    const thTable = this.tabTitle!.querySelector('.th');
207    const list = thTable!.querySelectorAll('div');
208    if (this.tabTitle!.hasAttribute('sort')) {
209      this.tabTitle!.removeAttribute('sort');
210      list.forEach((item) => {
211        item.querySelectorAll('svg').forEach((svg) => {
212          svg.style.display = 'none';
213        });
214      });
215    }
216  }
217}
218