/* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { BaseElement, element } from '../../../base-ui/BaseElement'; import { LitTable } from '../../../base-ui/table/lit-table'; import { LitChartColumn } from '../../../base-ui/chart/column/LitChartColumn'; import '../../../base-ui/chart/column/LitChartColumn'; import './CheckCpuSetting'; import '../../../base-ui/icon/LitIcon'; import { CheckCpuSetting } from './CheckCpuSetting'; import { procedurePool } from '../../database/Procedure'; import { info } from '../../../log/Log'; import '../../../base-ui/progress-bar/LitProgressBar'; import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; import './TableNoData'; import { TableNoData } from './TableNoData'; import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon'; import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; import { Top20ThreadCpuUsageHtml } from './Top20ThreadCpuUsage.html'; @element('top20-thread-cpu-usage') export class Top20ThreadCpuUsage extends BaseElement { traceChange: boolean = false; private table: LitTable | null | undefined; private tableBig: LitTable | null | undefined; private tableMid: LitTable | null | undefined; private tableSmall: LitTable | null | undefined; private chartTotal: LitChartColumn | null | undefined; private chart2: LitChartColumn | null | undefined; private chart3: LitChartColumn | null | undefined; private chart4: LitChartColumn | null | undefined; private cpuSetting: CheckCpuSetting | undefined | null; private setting: HTMLDivElement | null | undefined; private progress: LitProgressBar | null | undefined; private nodata: TableNoData | null | undefined; private map: Map | undefined; private data: Array = []; private dataBig: Array = []; private dataMid: Array = []; private dataSmall: Array = []; private sort: unknown = { total: { key: '', sort: 0 }, small: { key: '', sort: 0 }, mid: { key: '', sort: 0 }, big: { key: '', sort: 0 }, }; private publicColumns = ` `; private bigColumn = ` `; private midColumn = ` `; private smallColumn = ` `; initElements(): void { this.nodata = this.shadowRoot!.querySelector('#nodata'); this.progress = this.shadowRoot!.querySelector('#loading'); this.table = this.shadowRoot!.querySelector('#tb-thread-usage'); this.tableBig = this.shadowRoot!.querySelector('#tb-thread-big'); this.tableMid = this.shadowRoot!.querySelector('#tb-thread-mid'); this.tableSmall = this.shadowRoot!.querySelector('#tb-thread-small'); this.chartTotal = this.shadowRoot!.querySelector('#chart_total'); this.chart2 = this.shadowRoot!.querySelector('#chart_2'); this.chart3 = this.shadowRoot!.querySelector('#chart_3'); this.chart4 = this.shadowRoot!.querySelector('#chart_4'); this.map = new Map(); this.map.set('total', { chart: this.chartTotal!, table: this.table! }); this.map.set('small', { chart: this.chart2!, table: this.tableSmall! }); this.map.set('mid', { chart: this.chart3!, table: this.tableMid! }); this.map.set('big', { chart: this.chart4!, table: this.tableBig! }); this.setting = this.shadowRoot!.querySelector('#setting'); this.cpuSetting = this.shadowRoot!.querySelector('#cpu_setting'); this.cpuSetting!.cpuSetListener = (): void => { this.cpuSetting!.style.display = 'none'; //@ts-ignore (this.shadowRoot!.querySelector('#total')! as unknown).style.display = 'grid'; //@ts-ignore (this.shadowRoot!.querySelector('#small')! as unknown).style.display = CheckCpuSetting.small_cores.length > 0 ? 'grid' : 'none'; //@ts-ignore (this.shadowRoot!.querySelector('#mid')! as unknown).style.display = CheckCpuSetting.mid_cores.length > 0 ? 'grid' : 'none'; //@ts-ignore (this.shadowRoot!.querySelector('#big')! as unknown).style.display = CheckCpuSetting.big_cores.length > 0 ? 'grid' : 'none'; this.queryData(); }; this.setting?.addEventListener('click', (): void => { for (let node of this.shadowRoot!.querySelectorAll('.content_grid')) { //@ts-ignore (node as unknown).style.display = 'none'; } this.cpuSetting!.style.display = 'inline'; this.cpuSetting?.init(); }); this.tabListener(); } private tabListener(): void { for (let key of this.map!.keys()) { let tab = this.map!.get(key)!.table; let chart = this.map!.get(key)!.chart; tab!.addEventListener('row-click', (evt: unknown): void => { //@ts-ignore let data = evt.detail.data; data.isSelected = true; // @ts-ignore if ((evt.detail as unknown).callBack) { // @ts-ignore (evt.detail as unknown).callBack(true); } }); tab!.addEventListener('column-click', (evt: unknown): void => { //@ts-ignore this.sort[key].key = evt.detail.key; //@ts-ignore this.sort[key].sort = evt.detail.sort; if (key === 'total') { //@ts-ignore this.sortByColumn(evt.detail, tab, this.data); } else if (key === 'small') { //@ts-ignore this.sortByColumn(evt.detail, tab, this.dataSmall); } else if (key === 'mid') { //@ts-ignore this.sortByColumn(evt.detail, tab, this.dataMid); } else if (key === 'big') { //@ts-ignore this.sortByColumn(evt.detail, tab, this.dataBig); } }); tab!.addEventListener('row-hover', (evt: unknown): void => { //@ts-ignore if (evt.detail.data) { //@ts-ignore let data = evt.detail.data; data.isHover = true; //@ts-ignore if ((evt.detail as unknown).callBack) { //@ts-ignore (evt.detail as unknown).callBack(true); } chart.showHoverColumn(data.no); } }); } } sortByColumn(detail: unknown, table: LitTable | null | undefined, data: Array): void { // @ts-ignore function compare(threadCpuUsageProperty, sort, type) { return function (a: unknown, b: unknown) { if (type === 'number') { return sort === 2 ? // @ts-ignore parseFloat(b[threadCpuUsageProperty]) - parseFloat(a[threadCpuUsageProperty]) : //@ts-ignore parseFloat(a[threadCpuUsageProperty]) - parseFloat(b[threadCpuUsageProperty]); } else { if (sort === 2) { //@ts-ignore return b[threadCpuUsageProperty].toString().localeCompare(a[threadCpuUsageProperty].toString()); } else { //@ts-ignore return a[threadCpuUsageProperty].toString().localeCompare(b[threadCpuUsageProperty].toString()); } } }; } let type = 'number'; //@ts-ignore let key = detail.key; if (key === 'bigTimeStr') { key = 'big'; } else if (key === 'midTimeStr') { key = 'mid'; } else if (key === 'smallTimeStr') { key = 'small'; } else if ( key === 'bigPercent' || key === 'ratio' || key === 'tid' || key === 'pid' || key === 'midPercent' || key.includes('cpu') ) { } else { type = 'string'; } //@ts-ignore data.sort(compare(key, detail.sort, type)); table!.recycleDataSource = data; } init(): void { if (!this.traceChange) { for (let key of this.map!.keys()) { this.map!.get(key)!.table.reMeauseHeight(); } return; } this.traceChange = false; for (let key of this.map!.keys()) { let table = this.map!.get(key)!.table; table.innerHTML = ''; let columns = this.getTableColumns(key); for (let i = 0; i < SpSchedulingAnalysis.cpuCount; i++) { columns = ` ${columns} `; } table.innerHTML = columns; } if (!CheckCpuSetting.init_setting) { for (let node of this.shadowRoot!.querySelectorAll('.content_grid')) { //@ts-ignore (node as unknown).style.display = 'none'; } this.cpuSetting!.style.display = 'inline'; this.cpuSetting?.init(); } else { this.queryData(); } } clearData(): void { this.traceChange = true; for (let key of this.map!.keys()) { this.map!.get(key)!.chart.dataSource = []; this.map!.get(key)!.table.recycleDataSource = []; } } queryData(): void { this.progress!.loading = true; this.queryLogicWorker('scheduling-Thread CpuUsage', 'query Thread Cpu Usage Analysis Time:', (res): void => { //@ts-ignore this.nodata!.noData = res.keys().length === 0; for (let key of this.map!.keys()) { let obj = this.map!.get(key)!; //@ts-ignore let source: unknown[] = res.get(key) || []; source = source.map((it: unknown, index: number) => { let data: unknown = { //@ts-ignore pid: it.pid, //@ts-ignore pName: it.pName, //@ts-ignore tid: it.tid, //@ts-ignore tName: it.tName, //@ts-ignore total: it.total, //@ts-ignore big: it.big, //@ts-ignore mid: it.mid, //@ts-ignore small: it.small, no: index + 1, visible: 1, //@ts-ignore bigPercent: it.bigPercent, //@ts-ignore midPercent: it.midPercent, //@ts-ignore smallPercent: it.smallPercent, //@ts-ignore bigTimeStr: it.bigTimeStr, //@ts-ignore midTimeStr: it.midTimeStr, //@ts-ignore smallTimeStr: it.smallTimeStr, hideHandler: (): void => { //@ts-ignore let arr = source.filter((o) => o.visible === 1); obj.chart.dataSource = this.getArrayDataBySize(key, arr); }, }; for (let i = 0; i < SpSchedulingAnalysis.cpuCount; i++) { //@ts-ignore data[`cpu${i}`] = (it[`cpu${i}`] || 0) / 1000; } return data; }); this.setChartConfig(obj, key, source); this.assignmentData(key, source, obj); } this.progress!.loading = false; }); } private assignmentData(key: string, source: unknown[], obj: { chart: LitChartColumn; table: LitTable }): void { if (key === 'total') { this.data = source; } else if (key === 'small') { this.dataSmall = source; } else if (key === 'mid') { this.dataMid = source; } else if (key === 'big') { this.dataBig = source; } //@ts-ignore if (this.sort[key].key !== '') { //@ts-ignore this.sortByColumn(this.sort[key], obj.table, source); } else { obj.table.recycleDataSource = source; } } private setChartConfig(obj: { chart: LitChartColumn; table: LitTable }, key: string, source: unknown[]): void { obj.chart.config = { data: this.getArrayDataBySize(key, source), appendPadding: 10, xField: 'tid', yField: 'total', seriesField: key === 'total' ? 'size' : '', color: (a): string => { //@ts-ignore if (a.size === 'big core') { return '#2f72f8'; //@ts-ignore } else if (a.size === 'middle core') { return '#ffab67'; //@ts-ignore } else if (a.size === 'small core') { return '#a285d2'; } else { return '#0a59f7'; } }, hoverHandler: (no): void => { this.setHover(source, no, obj); }, tip: (a): string => { //@ts-ignore if (a && a[0]) { let tip = ''; let total = 0; //@ts-ignore for (let obj of a) { total += obj.obj.total; tip = `${tip}
${obj.type || key}:${obj.obj.timeStr}
`; } tip = `
tid:${ //@ts-ignore a[0].obj.tid }
${tip} ${ //@ts-ignore a.length > 1 ? `
total:${getProbablyTime(total)}
` : '' }
`; return tip; } else { return ''; } }, label: null, }; } private setHover(source: unknown[], no: number, obj: { chart: LitChartColumn; table: LitTable }): void { //@ts-ignore let data = source.find((it) => it.no === no); if (data) { //@ts-ignore data.isHover = true; obj.table!.setCurrentHover(data); } else { obj.table!.mouseOut(); } } getArrayDataBySize(type: string, arr: Array): unknown[] { let data: unknown[] = []; for (let obj of arr) { if (type === 'total') { data.push({ //@ts-ignore pid: obj.pid, //@ts-ignore pName: obj.pName, //@ts-ignore tid: obj.tid, //@ts-ignore tName: obj.tName, //@ts-ignore total: obj.big, size: 'big core', //@ts-ignore no: obj.no, //@ts-ignore timeStr: obj.bigTimeStr, }); data.push({ //@ts-ignore pid: obj.pid, //@ts-ignore pName: obj.pName, //@ts-ignore tid: obj.tid, //@ts-ignore tName: obj.tName, //@ts-ignore total: obj.mid, size: 'middle core', //@ts-ignore no: obj.no, //@ts-ignore timeStr: obj.midTimeStr, }); data.push({ //@ts-ignore pid: obj.pid, //@ts-ignore pName: obj.pName, //@ts-ignore tid: obj.tid, //@ts-ignore tName: obj.tName, //@ts-ignore total: obj.small, size: 'small core', //@ts-ignore no: obj.no, //@ts-ignore timeStr: obj.smallTimeStr, }); } else { data.push({ //@ts-ignore pid: obj.pid, //@ts-ignore pName: obj.pName, //@ts-ignore tid: obj.tid, //@ts-ignore tName: obj.tName, //@ts-ignore total: obj[type], //@ts-ignore no: obj.no, //@ts-ignore timeStr: obj[`${type}TimeStr`], }); } } return data; } queryLogicWorker(option: string, log: string, handler: (res: unknown) => void): void { let time = new Date().getTime(); procedurePool.submitWithName( 'logic0', option, { bigCores: CheckCpuSetting.big_cores, midCores: CheckCpuSetting.mid_cores, smallCores: CheckCpuSetting.small_cores, }, undefined, handler ); let durTime = new Date().getTime() - time; info(log, durTime); } getTableColumns(type: string): string { if (type === 'total') { return `${this.publicColumns}${this.bigColumn}${this.midColumn}${this.smallColumn}`; } else if (type === 'big') { return `${this.publicColumns}${this.bigColumn}`; } else if (type === 'mid') { return `${this.publicColumns}${this.midColumn}`; } else if (type === 'small') { return `${this.publicColumns}${this.smallColumn}`; } else { return ''; } } initHtml(): string { return Top20ThreadCpuUsageHtml; } }