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