• 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 { SelectionParam } from '../../../../bean/BoxSelection';
18import { LitIcon } from '../../../../../base-ui/icon/LitIcon';
19import { HiSysEventStruct } from '../../../../database/ui-worker/ProcedureWorkerHiSysEvent';
20import { LitTable } from '../../../../../base-ui/table/lit-table';
21import { ColorUtils } from '../../base/ColorUtils';
22import { TabPaneHiSysEventSummaryHtml } from './TabPaneHiSysEventSummary.html';
23import { NUM_30, NUM_40 } from '../../../../bean/NumBean';
24
25@element('tab-hi-sysevent-summary')
26export class TabPaneHiSysEventSummary extends BaseElement {
27  private summarySource: Array<HiSysEventStruct> = [];
28  private eventSummaryTable: HTMLDivElement | undefined | null;
29  private summaryTable: LitTable | undefined | null;
30  private eventTreeNodes: HiSysEventTreeNode[] = [];
31  private expansionDiv: HTMLDivElement | undefined | null;
32  private expansionUpIcon: LitIcon | undefined | null;
33  private expansionDownIcon: LitIcon | undefined | null;
34  private expandedNodeList: Set<number> = new Set();
35  private selectTreeDepth: number = 0;
36  private currentSelection: SelectionParam | undefined;
37
38  set data(systemEventParam: SelectionParam) {
39    if (systemEventParam === this.currentSelection) {
40      return;
41    }
42    this.summarySource = [];
43    this.expandedNodeList.clear();
44    this.expansionUpIcon!.name = 'up';
45    this.expansionDownIcon!.name = 'down';
46    this.eventSummaryTable!.innerHTML = '';
47    this.summaryTable!.recycleDataSource = [];
48    this.summarySource = systemEventParam.sysAllEventsData;
49    if (this.summarySource?.length !== 0 && systemEventParam) {
50      this.refreshRowNodeTable();
51    }
52  }
53
54  initElements(): void {
55    this.eventSummaryTable = this.shadowRoot?.querySelector<HTMLDivElement>('#tab-summary');
56    this.summaryTable = this.shadowRoot?.querySelector<LitTable>('#tb-event-summary');
57    this.expansionDiv = this.shadowRoot?.querySelector<HTMLDivElement>('.expansion-div');
58    this.expansionUpIcon = this.shadowRoot?.querySelector<LitIcon>('.expansion-up-icon');
59    this.expansionDownIcon = this.shadowRoot?.querySelector<LitIcon>('.expansion-down-icon');
60    let summaryTreeLevel: string[] = ['Level', '/Domain', '/EventName'];
61    this.shadowRoot?.querySelectorAll<HTMLLabelElement>('.head-label').forEach((summaryTreeHead) => {
62      summaryTreeHead.addEventListener('click', () => {
63        this.selectTreeDepth = summaryTreeLevel.indexOf(summaryTreeHead.textContent!);
64        this.expandedNodeList.clear();
65        this.refreshSelectDepth(this.eventTreeNodes);
66        this.refreshRowNodeTable(true);
67      });
68    });
69    this.eventSummaryTable?.addEventListener('scroll', () => {
70      let treeTableEl = this.shadowRoot?.querySelector<HTMLDivElement>('.event-tree-table');
71      if (treeTableEl) {
72        treeTableEl.scrollTop = this.eventSummaryTable?.scrollTop || 0;
73      }
74    });
75  }
76
77  initHtml(): string {
78    return TabPaneHiSysEventSummaryHtml;
79  }
80
81  connectedCallback(): void {
82    super.connectedCallback();
83    new ResizeObserver(() => {
84      this.parentElement!.style.overflow = 'hidden';
85      this.refreshRowNodeTable();
86    }).observe(this.parentElement!);
87    this.expansionDiv?.addEventListener('click', this.expansionClickEvent);
88  }
89
90  expansionClickEvent = (): void => {
91    this.expandedNodeList.clear();
92    if (this.expansionUpIcon?.name === 'down') {
93      this.selectTreeDepth = 0;
94      this.expansionUpIcon!.name = 'up';
95      this.expansionDownIcon!.name = 'down';
96    } else {
97      this.selectTreeDepth = 2;
98      this.expansionUpIcon!.name = 'down';
99      this.expansionDownIcon!.name = 'up';
100    }
101    this.refreshSelectDepth(this.eventTreeNodes);
102    this.refreshRowNodeTable(true);
103  };
104
105  disconnectedCallback(): void {
106    super.disconnectedCallback();
107    this.expansionDiv?.removeEventListener('click', this.expansionClickEvent);
108  }
109
110  private refreshSelectDepth(eventTreeNodes: HiSysEventTreeNode[]): void {
111    eventTreeNodes.forEach((item) => {
112      if (item.depth < this.selectTreeDepth) {
113        this.expandedNodeList.add(item.id);
114        if (item.children.length > 0) {
115          this.refreshSelectDepth(item.children);
116        }
117      }
118    });
119  }
120
121  private createRowNodeTableEL(
122    rowNodeList: HiSysEventTreeNode[],
123    tableTreeEl: HTMLDivElement,
124    tableCountEl: HTMLDivElement,
125    rowColor: string = ''
126  ): void {
127    let unitPadding: number = 20;
128    let leftPadding: number = 5;
129    rowNodeList.forEach((rowNode) => {
130      let tableRowEl: HTMLElement = document.createElement('tr');
131      tableRowEl.className = 'tree-row-tr';
132      tableRowEl.title = rowNode.summaryName!;
133      let tdEl: HTMLElement = document.createElement('td');
134      tdEl.style.paddingLeft = `${rowNode.depth * unitPadding + leftPadding}px`;
135      tableRowEl.appendChild(tdEl);
136      this.addToggleIconEl(rowNode, tableRowEl);
137      let rowNodeTextEL: HTMLElement = document.createElement('td');
138      rowNodeTextEL.textContent = rowNode.summaryName!;
139      rowNodeTextEL.className = 'row-name-td';
140      tableRowEl.appendChild(rowNodeTextEL);
141      tableTreeEl.appendChild(tableRowEl);
142      let tableCountRowEl: HTMLElement = document.createElement('tr');
143      let countEle: HTMLElement = document.createElement('td');
144      countEle.textContent = rowNode.count.toString();
145      countEle.className = 'count-column-td';
146      if (rowNode.depth === 0) {
147        rowNodeTextEL.style.color = ColorUtils.getHisysEventColor(rowNode.summaryName!);
148        countEle.style.color = ColorUtils.getHisysEventColor(rowNode.summaryName!);
149      } else {
150        rowNodeTextEL.style.color = rowColor;
151        countEle.style.color = rowColor;
152      }
153      tableCountRowEl.appendChild(countEle);
154      tableCountEl.appendChild(tableCountRowEl);
155      if (rowNode.children && this.expandedNodeList.has(rowNode.id)) {
156        this.createRowNodeTableEL(rowNode.children, tableTreeEl, tableCountEl, countEle.style.color);
157      }
158    });
159  }
160
161  private addToggleIconEl(rowNode: HiSysEventTreeNode, tableRowEl: HTMLElement): void {
162    let toggleIconEl: HTMLElement = document.createElement('td');
163    let expandIcon = document.createElement('lit-icon');
164    expandIcon.classList.add('tree-icon');
165    if (rowNode.children && rowNode.children.length > 0) {
166      toggleIconEl.appendChild(expandIcon);
167      // @ts-ignore
168      expandIcon.name = this.expandedNodeList.has(rowNode.id) ? 'minus-square' : 'plus-square';
169      toggleIconEl.classList.add('expand-icon');
170      toggleIconEl.addEventListener('click', () => {
171        let scrollTop = this.eventSummaryTable?.scrollTop ?? 0;
172        this.changeNode(rowNode.id);
173        this.eventSummaryTable!.scrollTop = scrollTop;
174      });
175    }
176    tableRowEl.appendChild(toggleIconEl);
177  }
178
179  private refreshRowNodeTable(useCacheRefresh: boolean = false): void {
180    this.eventSummaryTable!.innerHTML = '';
181    if (this.eventSummaryTable && this.parentElement) {
182      this.eventSummaryTable.style.height = `${this.parentElement.clientHeight - NUM_30}px`;
183    }
184    if (!useCacheRefresh) {
185      this.eventTreeNodes = this.buildTreeTblNodes(this.summarySource);
186      if (this.eventTreeNodes.length > 0) {
187        this.summaryTable!.recycleDataSource = this.eventTreeNodes;
188      } else {
189        this.summaryTable!.recycleDataSource = [];
190      }
191    }
192    let tableFragmentEl: DocumentFragment = document.createDocumentFragment();
193    let tableTreeEl: HTMLDivElement = document.createElement('div');
194    tableTreeEl.className = 'event-tree-table';
195    let tableCountEl: HTMLDivElement = document.createElement('div');
196    if (this.parentElement) {
197      tableTreeEl.style.height = `${this.parentElement!.clientHeight - NUM_40}px`;
198    }
199    this.createRowNodeTableEL(this.eventTreeNodes, tableTreeEl, tableCountEl, '');
200    const emptyTr = document.createElement('tr');
201    emptyTr.className = 'tree-row-tr';
202    tableTreeEl?.appendChild(emptyTr);
203    const emptyCountTr = document.createElement('tr');
204    emptyCountTr.className = 'tree-row-tr';
205    tableCountEl?.appendChild(emptyCountTr);
206    tableFragmentEl.appendChild(tableTreeEl);
207    tableFragmentEl.appendChild(tableCountEl);
208    this.eventSummaryTable!.appendChild(tableFragmentEl);
209  }
210
211  private changeNode(currentNode: number): void {
212    if (this.expandedNodeList.has(currentNode)) {
213      this.expandedNodeList['delete'](currentNode);
214    } else {
215      this.expandedNodeList.add(currentNode);
216    }
217    this.refreshRowNodeTable();
218  }
219
220  private buildTreeTblNodes(eventTreeNodes: HiSysEventStruct[]): HiSysEventTreeNode[] {
221    let id = 0;
222    let root: HiSysEventTreeNode = {id: id, depth: 0, children: [], summaryName: '', count: 0};
223    eventTreeNodes.forEach((item) => {
224      id++;
225      let levelNode = root.children.find((node) => node.summaryName === item.level);
226      if (levelNode) {
227        levelNode.count++;
228      } else {
229        id++;
230        levelNode = {id: id, depth: 0, children: [], summaryName: item.level, count: 1};
231        root.children.push(levelNode);
232      }
233      let domainNode = levelNode.children.find((node) => node.summaryName === item.domain);
234      if (domainNode) {
235        domainNode.count++;
236      } else {
237        id++;
238        domainNode = {id: id, depth: 1, children: [], summaryName: item.domain, count: 1};
239        levelNode.children.push(domainNode);
240      }
241      let eventNameNode = domainNode.children.find((node) => node.summaryName === item.eventName);
242      if (eventNameNode) {
243        eventNameNode.count++;
244      } else {
245        id++;
246        eventNameNode = {id: id, depth: 2, children: [], summaryName: item.eventName, count: 1};
247        domainNode.children.push(eventNameNode);
248      }
249      root.count++;
250    });
251    return root.children.sort((leftData, rightData) => {
252      return leftData.summaryName!.length - rightData.summaryName!.length;
253    });
254  }
255}
256
257export interface HiSysEventTreeNode {
258  id: number;
259  depth: number;
260  children: HiSysEventTreeNode[];
261  summaryName: string | undefined;
262  count: number;
263}
264