• 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 */
15import { BaseElement, element } from '../../../../../base-ui/BaseElement';
16import { RedrawTreeForm, type LitTable } from '../../../../../base-ui/table/lit-table';
17import { resizeObserver } from '../SheetUtils';
18import { VmTrackerChart } from '../../../chart/SpVmTrackerChart';
19import { log } from '../../../../../log/Log';
20import { SpSystemTrace } from '../../../SpSystemTrace';
21import { Utils } from '../../base/Utils';
22import { queryGpuDataByTs } from '../../../../database/sql/Gpu.sql';
23interface GpuTreeItem {
24  name: string;
25  id: number;
26  size: number;
27  sizeStr: string;
28  children?: GpuTreeItem[] | undefined;
29}
30
31@element('tabpane-gpu-click-select')
32export class TabPaneGpuClickSelect extends BaseElement {
33  private gpuTbl: LitTable | null | undefined;
34  private gpuSource: Array<GpuTreeItem> = [];
35  gpuClickData(gpu: { type: string; startTs: number }): void {
36    let td = this.gpuTbl!.shadowRoot!.querySelector('.thead')?.firstChild?.firstChild as HTMLDivElement;
37    let title = gpu.type === 'total' ? 'Module / Category' : 'Window / Module / Category';
38    let titleArr = title.split('/');
39    if (td) {
40      let labelEls = td.querySelectorAll('label');
41      if (labelEls) {
42        for (let el of labelEls) {
43          td.removeChild(el);
44        }
45      }
46      for (let i = 0; i < titleArr.length; i++) {
47        let label = document.createElement('label');
48        label.style.cursor = 'pointer';
49        i === 0 ? (label.innerHTML = titleArr[i]) : (label.innerHTML = '/' + titleArr[i]);
50        td.appendChild(label);
51      }
52    }
53    //@ts-ignore
54    this.gpuTbl?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 45 + 'px';
55    this.gpuTbl!.loading = true;
56    let window = gpu.type === 'total' ? 0 : VmTrackerChart.gpuWindow;
57    let module = gpu.type === 'total' ? VmTrackerChart.gpuTotalModule : VmTrackerChart.gpuWindowModule;
58    queryGpuDataByTs(gpu.startTs, window || 0, module).then((result) => {
59      this.gpuTbl!.loading = false;
60      if (result !== null && result.length > 0) {
61        log('queryGpuDataByTs result size : ' + result.length);
62        let items = this.createTreeData(result);
63        // @ts-ignore
64        this.gpuSource = (gpu.type === 'total' ? items[0].children : items) || [];
65        this.gpuTbl!.recycleDataSource = this.gpuSource;
66        this.theadClick(this.gpuTbl!, this.gpuSource);
67      } else {
68        this.gpuSource = [];
69        this.gpuTbl!.recycleDataSource = [];
70      }
71    });
72  }
73  protected createTreeData(result: unknown): Array<unknown> {
74    // @ts-ignore
75    let gpuDataObj = result.reduce(
76      (
77        group: unknown,
78        item: { categoryId: number; size: number; windowNameId: number; moduleId: number; windowId: unknown }
79      ) => {
80        let categoryItem: GpuTreeItem = this.setGpuTreeItem(item);
81        // @ts-ignore
82        if (group[`${item.windowNameId}(${item.windowId})`]) {
83          // @ts-ignore
84          let windowGroup = group[`${item.windowNameId}(${item.windowId})`] as GpuTreeItem;
85          windowGroup.size += item.size;
86          windowGroup.sizeStr = Utils.getBinaryByteWithUnit(windowGroup.size);
87          let moduleGroup = windowGroup.children!.find((it) => it.id === item.moduleId);
88          if (moduleGroup) {
89            moduleGroup.size += item.size;
90            moduleGroup.sizeStr = Utils.getBinaryByteWithUnit(moduleGroup.size);
91            moduleGroup.children?.push(categoryItem);
92          } else {
93            windowGroup.children?.push({
94              name: SpSystemTrace.DATA_DICT.get(item.moduleId) || 'null',
95              id: item.moduleId,
96              size: item.size,
97              sizeStr: Utils.getBinaryByteWithUnit(item.size),
98              children: [categoryItem],
99            });
100          }
101        } else {
102          // @ts-ignore
103          group[`${item.windowNameId}(${item.windowId})`] = {
104            name: SpSystemTrace.DATA_DICT.get(item.windowNameId) + `(${item.windowId})`,
105            id: item.windowNameId,
106            size: item.size,
107            sizeStr: Utils.getBinaryByteWithUnit(item.size),
108            children: [
109              {
110                name: SpSystemTrace.DATA_DICT.get(item.moduleId),
111                id: item.moduleId,
112                size: item.size,
113                sizeStr: Utils.getBinaryByteWithUnit(item.size),
114                children: [categoryItem],
115              },
116            ],
117          };
118        }
119        return group;
120      },
121      {}
122    );
123    return Object.values(gpuDataObj) as GpuTreeItem[];
124  }
125
126  private setGpuTreeItem(item: unknown): GpuTreeItem {
127    return {
128      // @ts-ignore
129      name: SpSystemTrace.DATA_DICT.get(item.categoryId) || 'null',
130      // @ts-ignore
131      id: item.categoryId,
132      // @ts-ignore
133      size: item.size,
134      // @ts-ignore
135      sizeStr: Utils.getBinaryByteWithUnit(item.size),
136    };
137  }
138  initElements(): void {
139    this.gpuTbl = this.shadowRoot?.querySelector<LitTable>('#tb-gpu');
140    this.gpuTbl!.addEventListener('column-click', (evt: unknown) => {
141      // @ts-ignore
142      this.sortByColumn(evt.detail);
143    });
144  }
145  connectedCallback(): void {
146    super.connectedCallback();
147    this.parentElement!.style.overflow = 'hidden';
148    resizeObserver(this.parentElement!, this.gpuTbl!, 18);
149  }
150  public theadClick(table: LitTable, data: Array<unknown>): void {
151    let labels = table?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label');
152    if (labels) {
153      for (let i = 0; i < labels.length; i++) {
154        let label = labels[i].innerHTML;
155        labels[i].addEventListener('click', (e) => {
156          if ((label.includes('Window') && i === 0) || (label.includes('Module') && i === 0)) {
157            table!.setStatus(data, false);
158            table!.recycleDs = table!.meauseTreeRowElement(data, RedrawTreeForm.Retract);
159          } else if (label.includes('Module') && i === 1) {
160            table!.setStatus(data, false, 0, 1);
161            table!.recycleDs = table!.meauseTreeRowElement(data, RedrawTreeForm.Retract);
162          } else if ((label.includes('Category') && i === 2) || (label.includes('Category') && i === 1)) {
163            table!.setStatus(data, true);
164            table!.recycleDs = table!.meauseTreeRowElement(data, RedrawTreeForm.Expand);
165          }
166          e.stopPropagation();
167        });
168      }
169    }
170  }
171  initHtml(): string {
172    return `
173        <style>
174        :host{
175            display: flex;
176            flex-direction: column;
177            padding: 10px 10px;
178        }
179        </style>
180        <lit-table id="tb-gpu" style="height: auto" tree>
181                <lit-table-column width="50%" title="" data-index="name" key="name" align="flex-start" order retract>
182                </lit-table-column>
183                <lit-table-column width="1fr" title="Size" data-index="sizeStr" key="sizeStr"  align="flex-start" order>
184                </lit-table-column>
185        </lit-table>
186        `;
187  }
188  sortByColumn(gpuDetail: unknown): void {
189    let compare = (gpuA: GpuTreeItem, gpuB: GpuTreeItem): number => {
190      // @ts-ignore
191      if (gpuDetail.sort === 0) {
192        return gpuA.size - gpuB.size;
193        // @ts-ignore
194      } else if (gpuDetail.sort === 1) {
195        return gpuA.size - gpuB.size;
196      } else {
197        return gpuB.size - gpuA.size;
198      }
199    };
200    let deepCompare = (arr: GpuTreeItem[]): void => {
201      arr.forEach((it) => {
202        if (it.children) {
203          deepCompare(it.children);
204        }
205      });
206      arr.sort(compare);
207    };
208    deepCompare(this.gpuSource);
209    this.gpuTbl!.recycleDataSource = this.gpuSource;
210  }
211}
212