diff --git a/ide/build.js b/ide/build.js deleted file mode 100644 index 17ea40aa71d11a237975315293478e11c628e01d..0000000000000000000000000000000000000000 --- a/ide/build.js +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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. - */ - -const path = require('path'); -const fs = require('fs'); -const childProcess = require('child_process'); -const os = require('os'); -const log4js = require('log4js'); - -const compileServer = true; -const outDir = 'dist'; - -const sdkWams = [ - 'trace_streamer_sdk_builtin.js', - 'trace_streamer_sdk_builtin.wasm', - 'trace_streamer_dubai_builtin.js', - 'trace_streamer_dubai_builtin.wasm', - 'trace_converter_builtin.js', - 'trace_converter_builtin.wasm', -]; - -const necessaryWams = [ - 'trace_streamer_builtin.js', - 'trace_streamer_builtin.wasm', - 'trace_converter_builtin.js', - 'trace_converter_builtin.wasm', -]; - -const staticPath = ['/src/img', '/server/cert', '/src/doc', '/src/figures']; - -const staticFiles = [ - '/server/version.txt', - '/src/index.html', - '/src/base-ui/icon.svg', - '/server/wasm.json', - '/server/server-config.txt', -]; - -const thirdParty = [ - { - srcFilePath: '/third-party/sql-wasm.wasm', - distFilePath: '/trace/database/sql-wasm.wasm', - }, - { - srcFilePath: '/third-party/sql-wasm.js', - distFilePath: '/trace/database/sql-wasm.js', - }, - { - srcFilePath: '/third-party/worker.sql-wasm.js', - distFilePath: '/trace/database/worker.sql-wasm.js', - }, -]; - -let log; - -function cpFile(from, to) { - if (fs.existsSync(from)) { - fs.writeFileSync(to, fs.readFileSync(from)); - log.info('cp file %s to %s', from, to); - } else { - log.warn('file %s is not exists', from, to); - } -} - -function checkEnvironment() { - let goVersion = childProcess.execSync('go version', { - encoding: 'utf-8', - }); - log.info('go is', goVersion); - let nodeVersion = childProcess.execSync('node -v', { - encoding: 'utf-8', - }); - log.info('node version is', nodeVersion); - let tscVersion = childProcess.execSync('tsc -v', { - encoding: 'utf-8', - }); - log.info('tsc version is', tscVersion); - if (goVersion == '' || nodeVersion == '' || tscVersion == '') { - return false; - } - let traceStreamer = path.normalize(path.join(__dirname, '/bin')); - if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.js')) { - log.error(traceStreamer + '/trace_streamer_builtin.js' + ' Must exist'); - return false; - } - if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.wasm')) { - log.error(traceStreamer + '/trace_streamer_builtin.wasm' + ' Must exist'); - return false; - } - return true; -} - -function initLog() { - log4js.configure({ - appenders: { - out: { type: 'stdout' }, - }, - categories: { - default: { appenders: ['out'], level: 'debug' }, - }, - }); - return log4js.getLogger('smartPerf'); -} - -function main() { - log = initLog(); - if (!checkEnvironment()) { - return; - } - // clean outDir - let outPath = path.normalize(path.join(__dirname, '/', outDir)); - if (checkDirExist(outPath)) { - log.info('delete the last compilation result'); - removeDir(outPath); - log.info('delete the last compilation success'); - } - // run tsc compile - log.info('start compiling typeScript code'); - let rootPath = path.join(__dirname, '/'); - childProcess.execSync('tsc -p ' + rootPath, { - encoding: 'utf-8', - }); - log.info('compiling typeScript code success'); - // run cp to mv all staticFile - staticFiles.forEach((value) => { - let filePath = path.join(__dirname, value); - let distFile; - if (value.startsWith('/src')) { - distFile = path.join(__dirname, outDir, value.substring(4, value.length + 1)); - } else if (value.startsWith('/server')) { - distFile = path.join(__dirname, outDir, value.substring(7, value.length + 1)); - } - cpFile(filePath, distFile); - }); - staticPath.forEach((value) => { - let pa = path.join(__dirname, value); - let distPath; - if (value.startsWith('/src')) { - distPath = path.join(__dirname, outDir, value.substring(4, value.length + 1)); - } else if (value.startsWith('/server')) { - distPath = path.join(__dirname, outDir, value.substring(7, value.length + 1)); - } - copyDirectory(pa, distPath); - }); - thirdParty.forEach((value) => { - let thirdFile = path.join(__dirname, value.srcFilePath); - let thirdDistFile = path.join(__dirname, outDir, value.distFilePath); - cpFile(thirdFile, thirdDistFile); - }); - let traceStreamer = path.normalize(path.join(__dirname, '/bin')); - if (checkDirExist(traceStreamer)) { - let dest = path.normalize(path.join(__dirname, outDir, '/bin')); - copyDirectory(traceStreamer, dest); - // to mv traceStream Wasm and js - if (sdkWams.length > 0) { - sdkWams.forEach((fileName) => { - cpFile(traceStreamer + '/' + fileName, rootPath + outDir + '/trace/database/' + fileName); - }); - } - if (necessaryWams.length > 0) { - necessaryWams.forEach((fileName) => { - cpFile(traceStreamer + '/' + fileName, rootPath + outDir + '/trace/database/' + fileName); - }); - } - } else { - log.error('traceStreamer dir is not Exits'); - return; - } - // compile server - if (compileServer) { - log.log('start compile server'); - let serverSrc = path.normalize(path.join(__dirname, '/server/main.go')); - let rs; - if (os.type() === 'Windows_NT') { - rs = childProcess.spawnSync('go', ['build', '-o', outPath, serverSrc], { - encoding: 'utf-8', - }); - } else { - rs = childProcess.spawnSync('go', ['build', '-o', outPath + '/main', serverSrc], { - encoding: 'utf-8', - }); - } - if (rs.status == 0) { - log.log('compile server success'); - } else { - log.error('compile server failed', rs); - } - } else { - log.warn('skip compile server'); - } - log.log('smartPerf compile success'); -} - -function copyDirectory(src, dest) { - if (checkDirExist(dest) == false) { - fs.mkdirSync(dest); - } - if (checkDirExist(src) == false) { - return false; - } - let directories = fs.readdirSync(src); - directories.forEach((value) => { - let filePath = path.join(src, value); - let fileSys = fs.statSync(filePath); - if (fileSys.isFile()) { - let destPath = path.join(dest, value); - log.info('cp file %s to %s', filePath, destPath); - fs.copyFileSync(filePath, destPath); - } else if (fileSys.isDirectory()) { - copyDirectory(filePath, path.join(dest, value)); - } - }); -} - -function checkDirExist(dirPath) { - return fs.existsSync(dirPath); -} - -function removeDir(outPath) { - let files = []; - if (fs.existsSync(outPath)) { - files = fs.readdirSync(outPath); - files.forEach((file, index) => { - let curPath = outPath + '/' + file; - if (fs.statSync(curPath).isDirectory()) { - removeDir(curPath); - } else { - fs.unlinkSync(curPath); - } - }); - fs.rmdirSync(outPath); - } -} - -main(); diff --git a/ide/src/base-ui/button/LitButton.ts b/ide/src/base-ui/button/LitButton.ts index 9c2c9b12db41cebea0d3d78c6742cb277ba0b344..e04eb065bbc1bf135fead4bd69ca46a18ecb66f9 100644 --- a/ide/src/base-ui/button/LitButton.ts +++ b/ide/src/base-ui/button/LitButton.ts @@ -128,10 +128,19 @@ export class LitButton extends BaseElement { initHtml(): string { return ` - -
- -
- `; + ` } initElements(): void { diff --git a/ide/src/base-ui/chart/pagenation/PageNation.ts b/ide/src/base-ui/chart/pagenation/PageNation.ts index 2039e69205e509b8537a271f13d35674a476e069..f78ef5db9a3274b81be7d0e347faf00c154ce72f 100644 --- a/ide/src/base-ui/chart/pagenation/PageNation.ts +++ b/ide/src/base-ui/chart/pagenation/PageNation.ts @@ -308,20 +308,24 @@ export class PageNation { } if (current == totalpage - 4) { // 左边5个 中间 ... 右边2个 - for (let i = 0; i < 2; i++) { - this.buildLi(origin, i, current); - } - span = document.createElement('span'); - span.innerText = '...'; - this.list.appendChild(span); - for (let i = totalpage - 7; i < totalpage; i++) { - this.buildLi(origin, i, current); - } + this.nodeAppendChild(origin,current,span,totalpage); return true; } return false; } + nodeAppendChild(origin: HTMLElement,current: number,span: any,totalpage: number):void{ + for (let i = 0; i < 2; i++) { + this.buildLi(origin, i, current); + } + span = document.createElement('span'); + span.innerText = '...'; + this.list.appendChild(span); + for (let i = totalpage - 7; i < totalpage; i++) { + this.buildLi(origin, i, current); + } + } + bindPageEvent() { this.element.addEventListener( 'click', diff --git a/ide/src/base-ui/chart/pie/LitChartPie.ts b/ide/src/base-ui/chart/pie/LitChartPie.ts index 73b2a4b822d08c28d886ecf1395fde5a97f8f4c3..5910d731476f10cd315ad208a733d0c48d7935ab 100644 --- a/ide/src/base-ui/chart/pie/LitChartPie.ts +++ b/ide/src/base-ui/chart/pie/LitChartPie.ts @@ -324,6 +324,10 @@ export class LitChartPie extends BaseElement { this.ctx!.stroke(); this.ctx?.closePath(); }); + this.setData(ease); + } + + setData(ease: boolean):void{ this.data .filter((it) => it.hover) .forEach((it) => { @@ -444,7 +448,18 @@ export class LitChartPie extends BaseElement { initHtml(): string { return ` - -
-
- -
-
-
`; + ` } } diff --git a/ide/src/base-ui/chart/scatter/LitChartScatter.ts b/ide/src/base-ui/chart/scatter/LitChartScatter.ts deleted file mode 100644 index cc9cff75a96e6bfd71e7da0baa894f48d142f79c..0000000000000000000000000000000000000000 --- a/ide/src/base-ui/chart/scatter/LitChartScatter.ts +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (C) 2023 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 { resizeCanvas } from '../helper'; -import { BaseElement, element } from '../../BaseElement'; -import { LitChartScatterConfig } from './LitChartScatterConfig'; - -@element('lit-chart-scatter') -export class LitChartScatter extends BaseElement { - private scatterTipEL: HTMLDivElement | null | undefined; - private labelsEL: HTMLDivElement | null | undefined; - canvas: HTMLCanvasElement | undefined | null; - canvas2: HTMLCanvasElement | undefined | null; - ctx: CanvasRenderingContext2D | undefined | null; - originX: number = 0; - finalX: number = 0; - originY: number = 0; - finalY: number = 0; - options: LitChartScatterConfig | undefined; - - set config(LitChartScatterConfig: LitChartScatterConfig) { - this.options = LitChartScatterConfig; - this.init(); - } - init(): void { - if (this.options) { - // 清楚上一次绘制的数据 - this.ctx?.clearRect(0, 0, this.clientWidth, this.clientHeight); - this.drawBackground(); - this.drawScatterChart(this.options); - //使用off-screen-canvas保存绘制的像素点 - this.setOffScreen(); - this.labelsEL!.innerText = this.options.title; - } - } - // 使用离屏技术保存绘制的像素点 - setOffScreen(): void { - this.canvas2 = document.createElement('canvas'); - this.canvas2.height = this.clientHeight; - this.canvas2.width = this.clientWidth; - let context2: CanvasRenderingContext2D | null = this.canvas2.getContext('2d'); - if (this.canvas?.width !== 0 && this.canvas?.height !== 0) { - context2!.drawImage(this.canvas!, 0, 0); - } - } - /*绘制渐变色背景*/ - drawBackground(): void { - let w: number = this.clientWidth; - let h: number = this.clientHeight; - let color: CanvasGradient = this.ctx?.createRadialGradient( - w / 2, - h / 2, - 0.2 * w, - w / 2, - h / 2, - 0.5 * w - )!; - color?.addColorStop(0, '#eaeaea'); - color?.addColorStop(1, '#ccc'); - if (this.options) { - this.options!.globalGradient = color; - } - this.ctx?.save(); - this.ctx!.fillStyle = color; - this.ctx?.fillRect(0, 0, w, h); - this.ctx?.restore(); - } - /** - * 绘制散点图 - */ - drawScatterChart(options: LitChartScatterConfig): void { - this.drawAxis(options); //绘制坐标轴 - this.drawYLabels(options); //绘制y轴坐标 - this.drawXLabels(options); //绘制x轴坐标 - let drawload: boolean = false; - if (options) { - drawload = options.drawload; - } - if (drawload) { - let load: Array = []; - if (options) { - load = options.load; - this.drawBalanceLine(load); //绘制均衡线 - this.drawLoadLine(load); //绘制最大负载线 - } - } - this.drawData(options); //绘制散点图 - } - /** - * 绘制坐标轴 - */ - drawAxis(options: LitChartScatterConfig): void { - let text: Array = new Array(); - if (options) { - text = options.axisLabel; - } - this.ctx!.font = '10px KATTI'; - this.ctx!.fillStyle = '#000000'; - this.ctx!.strokeStyle = '#000000'; - // 画x轴 - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, this.originY); - this.ctx?.lineTo(this.finalX, this.originY); - this.ctx?.fillText(text[0], this.finalX, this.originY); - this.ctx?.stroke(); - // 画Y轴 - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, this.originY); - this.ctx?.lineTo(this.originX, this.finalY); - this.ctx?.fillText(text[1], this.originX - 20, this.finalY - 10); - this.ctx?.stroke(); - } - /** - * 绘制y轴坐标 - */ - drawYLabels(options: LitChartScatterConfig): void { - const AXAIS_DELTA: number = 5; - const QUYU: number = 100; - // 添加原点刻度 - this.ctx!.font = '12px KATTI'; - this.ctx!.fillStyle = '#000000'; - this.ctx!.strokeStyle = '#000000'; - this.ctx?.fillText('0', this.originX - AXAIS_DELTA, this.originY + AXAIS_DELTA * 2); - let yAxis: Array = []; - if (options) { - yAxis = options.yAxisLabel; - } - // 画Y轴坐标尺 - for (let i = 0; i < yAxis.length; i++) { - let length1: number = - (this.originY - this.finalY - ((this.originY - this.finalY) % QUYU)) * - (yAxis[i] / yAxis[yAxis.length - 1]); - let length2: number = this.originY - length1; - let text: string = yAxis[i].toString(); - let x: number = this.originX - this.ctx?.measureText(text).width! - AXAIS_DELTA; - this.ctx?.beginPath(); - this.ctx?.moveTo(this.originX, length2); - this.ctx?.lineTo(this.originX + AXAIS_DELTA, length2); - this.ctx?.fillText(text, x, length2 + AXAIS_DELTA); - this.ctx?.stroke(); - } - } - /** - * 绘制x轴坐标 - */ - drawXLabels(options: LitChartScatterConfig): void { - // 画X轴坐标尺 - this.ctx!.fillStyle = '#000000'; - this.ctx!.strokeStyle = '#000000'; - const QUYU: number = 100; - const DELTA: number = 5; - let xAxis: Array = []; - if (options) { - xAxis = options.xAxisLabel; - } - for (let i = 0; i < xAxis.length; i++) { - let length3: number = - (this.finalX - this.originX - ((this.finalX - this.originX) % QUYU)) * - (xAxis[i] / xAxis[xAxis.length - 1]); - let length4: number = this.originX + length3; - this.ctx?.beginPath(); - this.ctx?.moveTo(length4, this.originY); - this.ctx?.lineTo(length4, this.originY - DELTA); - this.ctx?.fillText(xAxis[i].toString(), length4 - DELTA * 3, this.originY + DELTA * 2); - this.ctx?.stroke(); - } - } - - /** - * 绘制数据 - */ - drawData(options: LitChartScatterConfig): void { - let data: Array>> = []; - let yAxis: Array = []; - let xAxis: Array = []; - let colorPool: Array = new Array(); - let colorPoolText: Array = new Array(); - let rectY: number = this.clientHeight * 0.05; - const QUYU: number = 100; - const WIDTH_DELTA: number = 70; - if (options) { - data = options.data; - yAxis = options.yAxisLabel; - xAxis = options.xAxisLabel; - colorPool = options.colorPool(); - colorPoolText = options.colorPoolText(); - options.paintingData = []; - } - let xLength: number = this.finalX - this.originX - ((this.finalX - this.originX) % QUYU); - let yLength: number = this.originY - this.finalY - ((this.originY - this.finalY) % QUYU); - for (let i = 0; i < data.length; i++) { - for (let j = 0; j < data[i].length; j++) { - // 打点x坐标 - let x: number = this.originX + (data[i][j][0] / xAxis[xAxis.length - 1]) * xLength; - // 打点y坐标 - let y: number = this.originY - (data[i][j][1] / yAxis[yAxis.length - 1]) * yLength; - let r: number = 6; - if (i > 0) { - options.paintingData[data[i][j][2] - 1] = { - x, - y, - r, - c: data[i][j], - color: colorPool[i], - }; - } else { - options.paintingData.push({ - x, - y, - r, - c: data[i][j], - color: colorPool[i], - }); - } - this.drawCycle(x, y, r, 0.8, colorPool[i]); - } - if (data[i].length) { - rectY = rectY + 20; - this.ctx?.fillText(colorPoolText[i] + ': ', this.clientWidth - WIDTH_DELTA, rectY + 4); - this.drawCycle(this.clientWidth - (QUYU / 5), rectY, 7.5, 0.8, colorPool[i]); - } - } - } - /** - * 画圆点 - */ - drawCycle( - x: number, - y: number, - r: number, - transparency: number, - color: string - ): void { - this.ctx!.fillStyle = color; - this.ctx?.beginPath(); - this.ctx!.globalAlpha = transparency; - this.ctx?.arc(x, y, r, 0, Math.PI * 2, true); - this.ctx?.closePath(); - this.ctx?.fill(); - } - - /** - * 绘制最大负载线 - */ - drawLoadLine(data: Array): void { - let maxXAxis: number = 1; - const QUYU: number = 100; - const FOR_VALUE = 60; - if (this.options) { - maxXAxis = this.options.xAxisLabel[this.options.xAxisLabel.length - 1]; - } - // data[1]用来标注n Hz负载线 - let addr1: number = - this.originX + - (this.finalX - this.originX - ((this.finalX - this.originX) % QUYU)) * - (data[0] / maxXAxis); - let addr2: number = - (this.originY - this.finalY - ((this.originY - this.finalY) % QUYU)) / FOR_VALUE; - let y: number = this.originY; - this.ctx!.strokeStyle = '#ff0000'; - for (let i = 0; i < FOR_VALUE; i++) { - this.ctx?.beginPath(); - this.ctx?.moveTo(addr1, y); - y -= addr2; - this.ctx?.lineTo(addr1, y); - if (i % 2 !== 0) { - this.ctx?.stroke(); - } - } - this.ctx!.font = '10px KATTI'; - this.ctx!.fillStyle = '#ff0000'; - this.ctx?.fillText( - data[1] + 'Hz最大负载线', - addr1 - FOR_VALUE / 3, - this.originY - addr2 * FOR_VALUE - FOR_VALUE / 4 - ); - this.ctx!.fillStyle = '#000000'; - this.ctx?.fillText('过供给区', addr1 / 2, y + FOR_VALUE / 2); - this.ctx?.fillText('欠供给区', addr1 / 2, this.originY - this.finalY); - this.ctx?.fillText( - '超负载区', - addr1 + FOR_VALUE / 3, - (this.finalY + this.originY) / 2 - ); - } - - /** - * 绘制均衡线 - */ - drawBalanceLine(data: Array): void { - let maxXAxis: number = 1; - const QUYU: number = 100; - const FOR_VALUE = 60; - if (this.options) { - maxXAxis = this.options.xAxisLabel[this.options.xAxisLabel.length - 1]; - } - // data[1]用来标注n Hz均衡线 - let addr1: number = - ((this.finalX - this.originX - ((this.finalX - this.originX) % QUYU)) * - (data[0] / maxXAxis)) / FOR_VALUE; - let addr2: number = - (this.originY - this.finalY - ((this.originY - this.finalY) % QUYU)) / FOR_VALUE; - let x: number = this.originX; - let y: number = this.originY; - this.ctx!.strokeStyle = '#00ff00'; - for (let i = 0; i < FOR_VALUE; i++) { - this.ctx?.beginPath(); - this.ctx?.moveTo(x, y); - x += addr1; - y -= addr2; - this.ctx?.lineTo(x, y); - if (i % 2 === 0) { - this.ctx?.stroke(); - } - } - this.ctx?.save(); - this.ctx?.translate(addr1 * 25 + this.originX, addr2 * 40 + this.finalY); - this.ctx!.font = '10px KATTI'; - this.ctx!.fillStyle = '#ff0f00'; - this.ctx?.rotate(-Math.atan(addr2 / addr1)); - this.ctx?.fillText(data[1] + 'Hz均衡线', 0, 0); - this.ctx?.restore(); - } - - /*检测是否hover在散点之上*/ - checkHover( - options: LitChartScatterConfig | undefined, - pos: Object - ): Object | boolean { - let data: Array = []; - if (options) { - data = options.paintingData; - } - let found: boolean | Object = false; - for (let i = 0; i < data.length; i++) { - found = false; - // @ts-ignore - if ( - Math.sqrt( - // @ts-ignore - Math.pow(pos.x - data[i].x, 2) + Math.pow(pos.y - data[i].y, 2) - // @ts-ignore - ) < data[i].r - ) { - found = data[i]; - break; - } - } - return found; - } - - /*绘制hover状态*/ - paintHover(): void { - let obj: Object | null = this.options!.hoverData; - // @ts-ignore - let x: number = obj?.x; - // @ts-ignore - let y: number = obj?.y; - // @ts-ignore - let r: number = obj?.r; - // @ts-ignore - let c: string = obj?.color; - let step: number = 0.5; - this.ctx!.globalAlpha = 1; - this.ctx!.fillStyle = c; - for (let i = 0; i < 10; i++) { - this.ctx?.beginPath(); - this.ctx?.arc(x, y, r + i * step, 0, 2 * Math.PI, false); - this.ctx?.fill(); - this.ctx?.closePath(); - } - } - //利用离屏canvas恢复hover前的状态 - resetHoverWithOffScreen(): void { - let obj: Object | null = null; - const STEP_VALUE: number = 12; - const OUT_CYCLE: number = 2; - if (this.options) { - obj = this.options.hoverData; - } - if (!obj) { - return; - } - // @ts-ignore - let { x, y, r, c, color } = obj; - let step = 0.5; - this.ctx!.globalAlpha = 1; - for (let i = 10; i > 0; i--) { - this.ctx?.save(); - //绘制外圆范围 - this.ctx?.drawImage( - this.canvas2!, - x - r - STEP_VALUE * step, - y - r - STEP_VALUE * step, - OUT_CYCLE * (r + STEP_VALUE * step), - OUT_CYCLE * (r + STEP_VALUE * step), - x - r - STEP_VALUE * step, - y - r - STEP_VALUE * step, - OUT_CYCLE * (r + STEP_VALUE * step), - OUT_CYCLE * (r + STEP_VALUE * step) - ); - //绘制内圆 - this.ctx?.beginPath(); - this.ctx?.arc(x, y, r + i * step, 0, OUT_CYCLE * Math.PI, false); - this.ctx?.closePath(); - this.ctx!.fillStyle = color; - this.ctx!.globalAlpha = 0.8; - //填充内圆 - this.ctx?.fill(); - this.ctx?.restore(); - } - this.options!.hoverData = null; - } - /** - * 显示提示框 - */ - showTip(data: any): void { - const Y_DELTA: number = 70; - this.scatterTipEL!.style.display = 'flex'; - this.scatterTipEL!.style.top = `${data.y - Y_DELTA}px`; - this.scatterTipEL!.style.left = `${data.x}px`; - this.scatterTipEL!.innerHTML = this.options!.tip(data); - // @ts-ignore - this.options!.hoverEvent('CPU-FREQ', true, data.c[2] - 1); - } - /** - * 隐藏提示框 - */ - hideTip(): void { - this.scatterTipEL!.style.display = 'none'; - if (this.options) { - // @ts-ignore - this.options!.hoverEvent('CPU-FREQ', false); - } - } - - connectedCallback(): void { - super.connectedCallback(); - this.canvas = this.shadowRoot!.querySelector('#canvas'); - this.scatterTipEL = this.shadowRoot!.querySelector('#tip'); - this.ctx = this.canvas!.getContext('2d', { alpha: true }); - this.labelsEL = this.shadowRoot!.querySelector('#shape'); - resizeCanvas(this.canvas!); - this.originX = this.clientWidth * 0.1; - this.originY = this.clientHeight * 0.9; - this.finalX = this.clientWidth; - this.finalY = this.clientHeight * 0.1; - /*hover效果*/ - this.canvas!.onmousemove = (event) => { - let pos: Object = { - x: event.offsetX, - y: event.offsetY, - }; - let hoverPoint: Object | boolean = this.checkHover(this.options, pos); - /** - * 如果当前有聚焦点 - */ - if (hoverPoint) { - this.showTip(hoverPoint); - let samePoint: boolean = - this.options!.hoverData === hoverPoint ? true : false; - if (!samePoint) { - this.resetHoverWithOffScreen(); - this.options!.hoverData = hoverPoint; - } - this.paintHover(); - } else { - //使用离屏canvas恢复 - this.resetHoverWithOffScreen(); - this.hideTip(); - } - }; - } - - initElements(): void { - new ResizeObserver((entries, observer) => { - entries.forEach((it) => { - resizeCanvas(this.canvas!); - this.originX = this.clientWidth * 0.1; - this.originY = this.clientHeight * 0.95; - this.finalX = this.clientWidth * 0.9; - this.finalY = this.clientHeight * 0.1; - this.labelsEL!.innerText = ''; - this.init(); - }); - }).observe(this); - } - - initHtml(): string { - return ` - -
-
- -
-
-
`; - } -} diff --git a/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts b/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts deleted file mode 100644 index 586a7b3066d09a0f0835cc06d0a454453ab42dfb..0000000000000000000000000000000000000000 --- a/ide/src/base-ui/chart/scatter/LitChartScatterConfig.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2023 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. - */ - -export interface LitChartScatterConfig { - // y轴坐标数组 - yAxisLabel: Array; - // x轴坐标数组 - xAxisLabel: Array; - // 坐标轴名称 - axisLabel: Array; - // 用于判断是否绘制负载线及均衡线 - drawload: boolean; - // 用于存放最大负载线及均衡线的参数值 - load: Array; - // 打点数据 - data: Array>>; - // 用于存放绘图数据 - paintingData: Array; - // 用于存放移入点数据 - hoverData: Object | null; - // 渐变色信息 - globalGradient: CanvasGradient | undefined; - // 颜色池 - colorPool: () => Array; - // 移入事件 - hoverEvent: void; - // 图表名称 - title: string; - // 颜色数据名称 - colorPoolText: () => Array; - // 提示信息 - tip: (a: any) => string; -} \ No newline at end of file diff --git a/ide/src/base-ui/checkbox/LitCheckBox.ts b/ide/src/base-ui/checkbox/LitCheckBox.ts index 3a808a64a851dd1375ed27e9a1ba6a5c7fa1c47a..e3ca0ff51866975303381445b9431174306842dd 100644 --- a/ide/src/base-ui/checkbox/LitCheckBox.ts +++ b/ide/src/base-ui/checkbox/LitCheckBox.ts @@ -23,10 +23,6 @@ export class LitCheckBox extends BaseElement { return ['checked', 'value', 'disabled']; } - get disabled() { - return this.getAttribute('disabled') !== null; - } - set disabled(value) { if (value === null || value === false) { this.removeAttribute('disabled'); @@ -47,6 +43,10 @@ export class LitCheckBox extends BaseElement { } } + get disabled() { + return this.getAttribute('disabled') !== null; + } + get checked() { return this.getAttribute('checked') !== null; } @@ -69,7 +69,21 @@ export class LitCheckBox extends BaseElement { initHtml(): string { return ` - - - - `; + ` } initElements(): void { diff --git a/ide/src/base-ui/modal/LitModal.ts b/ide/src/base-ui/modal/LitModal.ts index 4f8800fe1ff2ef60a2e6b3f49989cc712f9a1cd8..7bdca3eaf3b32a3825b47f51e22d153e41acfad7 100644 --- a/ide/src/base-ui/modal/LitModal.ts +++ b/ide/src/base-ui/modal/LitModal.ts @@ -123,7 +123,28 @@ export class LitModal extends BaseElement { initHtml(): string { return ` - - - `; + ` } //当 custom element首次被插入文档DOM时,被调用。 initElements(): void { this.headerTitleElement = this.shadowRoot!.querySelector('#modal-title'); this.headerTitleElement!.textContent = this.title; - this.headerElement = this.shadowRoot!.querySelector('.header'); this.closeElement = this.shadowRoot!.querySelector('.close-icon'); this.cancelElement = this.shadowRoot!.querySelector('#cancel'); @@ -255,21 +260,9 @@ export class LitModal extends BaseElement { this.shadowRoot!.querySelector('.modal')!.onclick = (e) => { e.stopPropagation(); }; - this.onclick = (ev) => { - ev.stopPropagation(); - if (!this.resizeable) { - this.visible = false; - } - }; - this.cancelElement!.onclick = (ev) => { - this.dispatchEvent(new CustomEvent('onCancel', ev)); - }; - this.okElement!.onclick = (ev) => { - this.dispatchEvent(new CustomEvent('onOk', ev)); - }; + this.setClick(); if (this.moveable || this.resizeable) { if (this.resizeable) { - //move let resizeWidth = 8; this.resizing = false; let srcResizeClientX = 0, @@ -284,251 +277,268 @@ export class LitModal extends BaseElement { this.onmousemoveFunc = (e: any) => { e.stopPropagation(); srcResizeRect = this.modalElement!.getBoundingClientRect(); - if ( - e.clientX > srcResizeRect.left - resizeWidth && - e.clientX < srcResizeRect.left + resizeWidth && - e.clientY > srcResizeRect.top - resizeWidth && - e.clientY < srcResizeRect.top + resizeWidth - ) { - //left top - this.style.cursor = 'nwse-resize'; - if (!this.resizing) direction = 'left-top'; - } else if ( - e.clientX > srcResizeRect.right - resizeWidth && - e.clientX < srcResizeRect.right + resizeWidth && - e.clientY > srcResizeRect.top - resizeWidth && - e.clientY < srcResizeRect.top + resizeWidth - ) { - //right top - this.style.cursor = 'nesw-resize'; - if (!this.resizing) direction = 'right-top'; - } else if ( - e.clientX > srcResizeRect.left - resizeWidth && - e.clientX < srcResizeRect.left + resizeWidth && - e.clientY > srcResizeRect.bottom - resizeWidth && - e.clientY < srcResizeRect.bottom + resizeWidth - ) { - //left bottom - this.style.cursor = 'nesw-resize'; - if (!this.resizing) direction = 'left-bottom'; - } else if ( - e.clientX > srcResizeRect.right - resizeWidth && - e.clientX < srcResizeRect.right + resizeWidth && - e.clientY > srcResizeRect.bottom - resizeWidth && - e.clientY < srcResizeRect.bottom + resizeWidth - ) { - //right bottom - this.style.cursor = 'nwse-resize'; - if (!this.resizing) direction = 'right-bottom'; - } else if (e.clientX > srcResizeRect.left - resizeWidth && e.clientX < srcResizeRect.left + resizeWidth) { - //left - this.style.cursor = 'ew-resize'; - if (!this.resizing) direction = 'left'; - } else if (e.clientX < srcResizeRect.right + resizeWidth && e.clientX > srcResizeRect.right - resizeWidth) { - //right - this.style.cursor = 'ew-resize'; - if (!this.resizing) direction = 'right'; - } else if (e.clientY > srcResizeRect.top - resizeWidth && e.clientY < srcResizeRect.top + resizeWidth) { - //top - this.style.cursor = 'ns-resize'; - if (!this.resizing) direction = 'top'; - } else if (e.clientY < srcResizeRect.bottom + resizeWidth && e.clientY > srcResizeRect.bottom - resizeWidth) { - //bottom - this.style.cursor = 'ns-resize'; - if (!this.resizing) direction = 'bottom'; - } else { - this.style.cursor = ''; - if (!this.resizing) direction = ''; - } - if (this.resizing) { - let offsetResizeY = e.clientY - srcResizeClientY; - let offsetResizeX = e.clientX - srcResizeClientX; - if (direction === 'bottom') { - this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; - } else if (direction === 'top') { - this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; - this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; - } else if (direction === 'right') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; - } else if (direction === 'left') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; - } else if (direction === 'left-top') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; - this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; - this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; - } else if (direction === 'right-top') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; - this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; - this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; - } else if (direction === 'left-bottom') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; - this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; - } else if (direction === 'right-bottom') { - this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; - this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; - this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; - } - } - }; - this.onmousedownFunc = (e: any) => { - srcResizeRect = this.modalElement!.getBoundingClientRect(); - srcResizeClientX = e.clientX; - srcResizeClientY = e.clientY; - srcResizeHeight = srcResizeRect.height; - srcResizeWidth = srcResizeRect.width; - srcResizeRight = srcResizeRect.right; - srcResizeLeft = srcResizeRect.left; - srcResizeTop = srcResizeRect.top; - if ( - e.clientX > srcResizeRect.left - resizeWidth && - e.clientX < srcResizeRect.left + resizeWidth && - e.clientY > srcResizeRect.top - resizeWidth && - e.clientY < srcResizeRect.top + resizeWidth - ) { - //left top - this.resizing = true; - } else if ( - e.clientX > srcResizeRect.right - resizeWidth && - e.clientX < srcResizeRect.right + resizeWidth && - e.clientY > srcResizeRect.top - resizeWidth && - e.clientY < srcResizeRect.top + resizeWidth - ) { - //right top - this.resizing = true; - } else if ( - e.clientX > srcResizeRect.left - resizeWidth && - e.clientX < srcResizeRect.left + resizeWidth && - e.clientY > srcResizeRect.bottom - resizeWidth && - e.clientY < srcResizeRect.bottom + resizeWidth - ) { - //left bottom - this.resizing = true; - } else if ( - e.clientX > srcResizeRect.right - resizeWidth && - e.clientX < srcResizeRect.right + resizeWidth && - e.clientY > srcResizeRect.bottom - resizeWidth && - e.clientY < srcResizeRect.bottom + resizeWidth - ) { - //right bottom - this.resizing = true; - } else if (e.clientX > srcResizeRect.left - resizeWidth && e.clientX < srcResizeRect.left + resizeWidth) { - //left - this.resizing = true; - } else if (e.clientX < srcResizeRect.right + resizeWidth && e.clientX > srcResizeRect.right - resizeWidth) { - //right - this.resizing = true; - } else if (e.clientY > srcResizeRect.top - resizeWidth && e.clientY < srcResizeRect.top + resizeWidth) { - //top - this.resizing = true; - } else if (e.clientY < srcResizeRect.bottom + resizeWidth && e.clientY > srcResizeRect.bottom - resizeWidth) { - //bottom - this.resizing = true; - } else { - this.resizing = false; - } - if (this.resizing) document.body.style.userSelect = 'none'; + this.onmousemoveFuncRule(direction,e,srcResizeRect,resizeWidth); + this.resizingFunc(direction,e,srcResizeClientX,srcResizeClientY,srcResizeHeight,srcResizeWidth,srcResizeLeft,srcResizeTop); }; + this.setOnmousedownFunc(resizeWidth,srcResizeClientX,srcResizeClientY,srcResizeRect,srcResizeHeight,srcResizeWidth,srcResizeRight,srcResizeLeft,srcResizeTop); this.onmouseupFunc = (e: any) => { this.resizing = false; }; } + this.buildFunc(); + this.onmouseleave = this.onmouseup = (e) => { + if (this.onmouseleaveMoveFunc) this.onmouseleaveMoveFunc(e); + if (this.onmouseupFunc) this.onmouseupFunc(e); + document.body.style.userSelect = ''; + }; + } + } + + setClick():void{ + this.onclick = (ev) => { + ev.stopPropagation(); + if (!this.resizeable) { + this.visible = false; + } + }; + this.cancelElement!.onclick = (ev) => { + this.dispatchEvent(new CustomEvent('onCancel', ev)); + }; + this.okElement!.onclick = (ev) => { + this.dispatchEvent(new CustomEvent('onOk', ev)); + }; + } - if (this.moveable) { - this.down = false; - let srcClientX = 0; - let srcClientY = 0; - let srcLeft = 0; - let srcTop = 0; - let srcRight = 0; - let srcBottom = 0; - let clientRect; - let rootRect: any; + buildFunc():void{ + if (this.moveable) { + this.down = false; + let srcClientX = 0; + let srcClientY = 0; + let srcLeft = 0; + let srcTop = 0; + let srcRight = 0; + let srcBottom = 0; + let clientRect; + let rootRect: any; + this.onmousedownMoveFunc = (e: any) => { + if (this.resizing) return; + srcClientX = e.clientX; + srcClientY = e.clientY; + rootRect = this.getBoundingClientRect(); + clientRect = this.modalElement!.getBoundingClientRect(); + srcLeft = clientRect.left; + srcRight = clientRect.right; + srcTop = clientRect.top; + srcBottom = clientRect.bottom; + if ( + e.clientX > srcLeft + 10 && + e.clientX < srcRight - 10 && + e.clientY > srcTop + 10 && + e.clientY < srcTop + this.headerElement!.scrollHeight + ) { + this.down = true; + } else { + this.down = false; + } + if (this.down) document.body.style.userSelect = 'none'; + this.setOnmousemoveMoveFunc(e, srcClientX, srcClientY, srcLeft, srcTop, srcRight, srcBottom, clientRect, rootRect); + this.onmouseleaveMoveFunc = this.onmouseupMoveFunc = (e: any) => { + this.down = false; + this.headerElement!.style.cursor = ''; + }; + }; + } + this.onmousemove = (e) => { + if (this.onmousemoveFunc) this.onmousemoveFunc(e); + if (this.onmousemoveMoveFunc) this.onmousemoveMoveFunc(e); + }; + this.onmousedown = (e) => { + if (this.onmousedownFunc) this.onmousedownFunc(e); + if (this.onmousedownMoveFunc) this.onmousedownMoveFunc(e); + }; + } - this.onmousedownMoveFunc = (e: any) => { - if (this.resizing) return; - srcClientX = e.clientX; - srcClientY = e.clientY; - rootRect = this.getBoundingClientRect(); + setOnmousemoveMoveFunc(e:any,srcClientX:number,srcClientY:number,srcLeft:number,srcTop:number,srcRight:number,srcBottom:number,clientRect:any,rootRect:any):void{ + this.onmousemoveMoveFunc = (ev: any) => { + if (this.down) { + let offsetY = e.clientY - srcClientY; + let offsetX = e.clientX - srcClientX; + if (e.clientX > srcLeft + 10 && e.clientX < srcRight - 10 && e.clientY > srcTop + 10) { + this.headerElement!.style.cursor = 'move'; clientRect = this.modalElement!.getBoundingClientRect(); - srcLeft = clientRect.left; - srcRight = clientRect.right; - srcTop = clientRect.top; - srcBottom = clientRect.bottom; + //下面 rootRect.height 改成 this.scrollHeight 解决modal 过长会出现滚动条的情况 if ( - e.clientX > srcLeft + 10 && - e.clientX < srcRight - 10 && - e.clientY > srcTop + 10 && - e.clientY < srcTop + this.headerElement!.scrollHeight + ev.clientY - srcClientY + srcTop > 0 && + ev.clientY - srcClientY + srcTop < this.scrollHeight - clientRect.height ) { - this.down = true; + this.modalElement!.style.top = ev.clientY - srcClientY + srcTop + 'px'; } else { - this.down = false; + if (ev.clientY - srcClientY + srcTop <= 0) { + this.modalElement!.style.top = '0px'; + } else { + //下面 rootRect.height 改成 this.scrollHeight 解决modal 过长会出现滚动条的情况 + this.modalElement!.style.top = this.scrollHeight - clientRect.height + 'px'; + } } - if (this.down) document.body.style.userSelect = 'none'; - this.onmousemoveMoveFunc = (ev: any) => { - if (this.down) { - let offsetY = e.clientY - srcClientY; - let offsetX = e.clientX - srcClientX; - if (e.clientX > srcLeft + 10 && e.clientX < srcRight - 10 && e.clientY > srcTop + 10) { - this.headerElement!.style.cursor = 'move'; - clientRect = this.modalElement!.getBoundingClientRect(); - //下面 rootRect.height 改成 this.scrollHeight 解决modal 过长会出现滚动条的情况 - if ( - ev.clientY - srcClientY + srcTop > 0 && - ev.clientY - srcClientY + srcTop < this.scrollHeight - clientRect.height - ) { - this.modalElement!.style.top = ev.clientY - srcClientY + srcTop + 'px'; - } else { - if (ev.clientY - srcClientY + srcTop <= 0) { - this.modalElement!.style.top = '0px'; - } else { - //下面 rootRect.height 改成 this.scrollHeight 解决modal 过长会出现滚动条的情况 - this.modalElement!.style.top = this.scrollHeight - clientRect.height + 'px'; - } - } - //ev.clientX-srcClientX 鼠标移动像素 - if ( - ev.clientX - srcClientX + srcLeft > 0 && - ev.clientX - srcClientX + srcLeft < rootRect.width - clientRect.width - ) { - this.modalElement!.style.left = ev.clientX - srcClientX + srcLeft + clientRect.width / 2 + 'px'; - } else { - if (ev.clientX - srcClientX + srcLeft <= 0) { - this.modalElement!.style.left = clientRect.width / 2 + 'px'; - } else { - this.modalElement!.style.left = rootRect.width - clientRect.width + clientRect.width / 2 + 'px'; - } - } - } + //ev.clientX-srcClientX 鼠标移动像素 + if ( + ev.clientX - srcClientX + srcLeft > 0 && + ev.clientX - srcClientX + srcLeft < rootRect.width - clientRect.width + ) { + this.modalElement!.style.left = ev.clientX - srcClientX + srcLeft + clientRect.width / 2 + 'px'; + } else { + if (ev.clientX - srcClientX + srcLeft <= 0) { + this.modalElement!.style.left = clientRect.width / 2 + 'px'; + } else { + this.modalElement!.style.left = rootRect.width - clientRect.width + clientRect.width / 2 + 'px'; } - }; - this.onmouseleaveMoveFunc = this.onmouseupMoveFunc = (e: any) => { - this.down = false; - this.headerElement!.style.cursor = ''; - }; - }; + } + } } - this.onmousemove = (e) => { - if (this.onmousemoveFunc) this.onmousemoveFunc(e); - if (this.onmousemoveMoveFunc) this.onmousemoveMoveFunc(e); - }; - this.onmousedown = (e) => { - if (this.onmousedownFunc) this.onmousedownFunc(e); - if (this.onmousedownMoveFunc) this.onmousedownMoveFunc(e); - }; - this.onmouseleave = this.onmouseup = (e) => { - if (this.onmouseleaveMoveFunc) this.onmouseleaveMoveFunc(e); - if (this.onmouseupFunc) this.onmouseupFunc(e); - document.body.style.userSelect = ''; - }; + }; + } + + onmousemoveFuncRule(direction:string,e:any,srcResizeRect:any,resizeWidth:number):void{ + if ( + e.clientX > srcResizeRect.left - resizeWidth && + e.clientX < srcResizeRect.left + resizeWidth && + e.clientY > srcResizeRect.top - resizeWidth && + e.clientY < srcResizeRect.top + resizeWidth + ) { + this.style.cursor = 'nwse-resize'; + if (!this.resizing) direction = 'left-top'; + } else if ( + e.clientX > srcResizeRect.right - resizeWidth && + e.clientX < srcResizeRect.right + resizeWidth && + e.clientY > srcResizeRect.top - resizeWidth && + e.clientY < srcResizeRect.top + resizeWidth + ) { + this.style.cursor = 'nesw-resize'; + if (!this.resizing) direction = 'right-top'; + } else if ( + e.clientX > srcResizeRect.left - resizeWidth && + e.clientX < srcResizeRect.left + resizeWidth && + e.clientY > srcResizeRect.bottom - resizeWidth && + e.clientY < srcResizeRect.bottom + resizeWidth + ) { + this.style.cursor = 'nesw-resize'; + if (!this.resizing) direction = 'left-bottom'; + } else if ( + e.clientX > srcResizeRect.right - resizeWidth && + e.clientX < srcResizeRect.right + resizeWidth && + e.clientY > srcResizeRect.bottom - resizeWidth && + e.clientY < srcResizeRect.bottom + resizeWidth + ) { + this.style.cursor = 'nwse-resize'; + if (!this.resizing) direction = 'right-bottom'; + } else if (e.clientX > srcResizeRect.left - resizeWidth && e.clientX < srcResizeRect.left + resizeWidth) { + this.style.cursor = 'ew-resize'; + if (!this.resizing) direction = 'left'; + } else if (e.clientX < srcResizeRect.right + resizeWidth && e.clientX > srcResizeRect.right - resizeWidth) { + this.style.cursor = 'ew-resize'; + if (!this.resizing) direction = 'right'; + } else if (e.clientY > srcResizeRect.top - resizeWidth && e.clientY < srcResizeRect.top + resizeWidth) { + this.style.cursor = 'ns-resize'; + if (!this.resizing) direction = 'top'; + } else if (e.clientY < srcResizeRect.bottom + resizeWidth && e.clientY > srcResizeRect.bottom - resizeWidth) { + this.style.cursor = 'ns-resize'; + if (!this.resizing) direction = 'bottom'; + } else { + this.style.cursor = ''; + if (!this.resizing) direction = ''; } } + resizingFunc(direction:string,e:any,srcResizeClientX:number,srcResizeClientY:number,srcResizeHeight:number,srcResizeWidth:number,srcResizeLeft:number,srcResizeTop:number):void{ + if (this.resizing) { + let offsetResizeY = e.clientY - srcResizeClientY; + let offsetResizeX = e.clientX - srcResizeClientX; + if (direction === 'bottom') { + this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; + } else if (direction === 'top') { + this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; + this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; + } else if (direction === 'right') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; + } else if (direction === 'left') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; + } else if (direction === 'left-top') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; + this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; + this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; + } else if (direction === 'right-top') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; + this.modalElement!.style.top = srcResizeTop + offsetResizeY + 'px'; + this.modalElement!.style.height = srcResizeHeight - offsetResizeY + 'px'; + } else if (direction === 'left-bottom') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth - offsetResizeX + 'px'; + this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; + } else if (direction === 'right-bottom') { + this.modalElement!.style.left = srcResizeLeft + srcResizeWidth / 2 + offsetResizeX / 2 + 'px'; + this.modalElement!.style.width = srcResizeWidth + offsetResizeX + 'px'; + this.modalElement!.style.height = srcResizeHeight + offsetResizeY + 'px'; + } + } + } + + setOnmousedownFunc(resizeWidth:number,srcResizeClientX:number,srcResizeClientY:number,srcResizeRect:any,srcResizeHeight:number,srcResizeWidth:number,srcResizeRight:number,srcResizeLeft:number,srcResizeTop:number):void{ + this.onmousedownFunc = (e: any) => { + srcResizeRect = this.modalElement!.getBoundingClientRect(); + srcResizeClientX = e.clientX; + srcResizeClientY = e.clientY; + srcResizeHeight = srcResizeRect.height; + srcResizeWidth = srcResizeRect.width; + srcResizeRight = srcResizeRect.right; + srcResizeLeft = srcResizeRect.left; + srcResizeTop = srcResizeRect.top; + if ( + e.clientX > srcResizeRect.left - resizeWidth && + e.clientX < srcResizeRect.left + resizeWidth && + e.clientY > srcResizeRect.top - resizeWidth && + e.clientY < srcResizeRect.top + resizeWidth + ) { + this.resizing = true; + } else if ( + e.clientX > srcResizeRect.right - resizeWidth && + e.clientX < srcResizeRect.right + resizeWidth && + e.clientY > srcResizeRect.top - resizeWidth && + e.clientY < srcResizeRect.top + resizeWidth + ) { + this.resizing = true; + } else if ( + e.clientX > srcResizeRect.left - resizeWidth && + e.clientX < srcResizeRect.left + resizeWidth && + e.clientY > srcResizeRect.bottom - resizeWidth && + e.clientY < srcResizeRect.bottom + resizeWidth + ) { + this.resizing = true; + } else if ( + e.clientX > srcResizeRect.right - resizeWidth && + e.clientX < srcResizeRect.right + resizeWidth && + e.clientY > srcResizeRect.bottom - resizeWidth && + e.clientY < srcResizeRect.bottom + resizeWidth + ) { + this.resizing = true; + } else if (e.clientX > srcResizeRect.left - resizeWidth && e.clientX < srcResizeRect.left + resizeWidth) { + this.resizing = true; + } else if (e.clientX < srcResizeRect.right + resizeWidth && e.clientX > srcResizeRect.right - resizeWidth) { + this.resizing = true; + } else if (e.clientY > srcResizeRect.top - resizeWidth && e.clientY < srcResizeRect.top + resizeWidth) { + this.resizing = true; + } else if (e.clientY < srcResizeRect.bottom + resizeWidth && e.clientY > srcResizeRect.bottom - resizeWidth) { + this.resizing = true; + } else { + this.resizing = false; + } + if (this.resizing) document.body.style.userSelect = 'none'; + }; + } + //当 custom element从文档DOM中删除时,被调用。 disconnectedCallback() {} diff --git a/ide/src/base-ui/radiobox/LitRadioBox.ts b/ide/src/base-ui/radiobox/LitRadioBox.ts index 2b03964c012b4bd89859bf3cb4a84809959b86f3..797f2013520e3702ba8351c23105dd2d20c2bb9f 100644 --- a/ide/src/base-ui/radiobox/LitRadioBox.ts +++ b/ide/src/base-ui/radiobox/LitRadioBox.ts @@ -30,18 +30,15 @@ export class LitRadioBox extends BaseElement { return this.getAttribute('disabled') !== null; } - set disabled(value) { - if (value === null || value === false) { - this.removeAttribute('disabled'); - } else { - this.setAttribute('disabled', ''); - } - } get checked() { return this.getAttribute('checked') !== null; } + get name() { + return this.getAttribute('name'); + } + set checked(radioValue: boolean) { if (radioValue === null || !radioValue) { this.removeAttribute('checked'); @@ -50,23 +47,27 @@ export class LitRadioBox extends BaseElement { } } - get name() { - return this.getAttribute('name'); - } - get value() { let slot = this.shadowRoot?.getElementById('slot'); return slot!.textContent || this.textContent || ''; } - set value(value: string) { - this.setAttribute('value', value); + set disabled(value: boolean) { + if (value === null || value === false) { + this.removeAttribute('disabled'); + } else { + this.setAttribute('disabled', ''); + } } set dis(dis: string) { this.setAttribute('dis', dis); } + set value(value: string) { + this.setAttribute('value', value); + } + initHtml(): string { return ` - - - -
- -
-
-
-
-
-
-
-
-
上一页
-
1
- -
GO
-
下一页
-
-
- `; - } - - move1px() { - this.tableElement!.scrollTop = this.tableElement!.scrollTop + 1; + return litPageTableHtml; } - dataExportInit() { + dataExportInit(): void { let exportDiv = this.shadowRoot!.querySelector('.export'); exportDiv && - (exportDiv.onclick = () => { + (exportDiv.onclick = (): void => { this.exportData(); }); } - exportData() { - if (this.exportLoading || this.ds.length === 0) { - return; - } - this.exportLoading = true; - this.exportProgress!.loading = true; - let date = new Date(); - JSONToCSV.csvExport({ - columns: this.columns as any[], - tables: this.ds, - fileName: date.getTime() + '', - columnFormatter: this.itemTextHandleMap, - exportFormatter: this.exportTextHandleMap, - }).then((res) => { - this.exportLoading = false; - this.exportProgress!.loading = false; - }); + exportData(): void { + exportData(this); } formatExportData(dataSource: any[]): any[] { - if (dataSource == undefined || dataSource.length == 0) { - return []; - } - if (this.columns == undefined) { - return []; - } - return dataSource.map((item) => { - let formatData: any = {}; - this.columns!.forEach((column) => { - let dataIndex = column.getAttribute('data-index'); - let columnName = column.getAttribute('title'); - if (columnName == '') { - columnName = dataIndex; - } - if (dataIndex && columnName && item[dataIndex] != undefined) { - formatData[columnName] = item[dataIndex]; - } - }); - if (item.children != undefined) { - formatData.children = this.formatExportData(item.children); - } - return formatData; - }); - } - - recursionExportTableData(columns: any[], dataSource: any[]): string { - let concatStr = '\r\n'; - dataSource.forEach((item, index) => { - concatStr += columns - .map((column) => { - let dataIndex = column.getAttribute('data-index'); - return `"${item[dataIndex] || ''}" `; - }) - .join(','); - if (item.children != undefined) { - concatStr += this.recursionExportTableData(columns, item.children); - } - if (index != dataSource.length - 1) { - concatStr += '\r\n'; - } - }); - return concatStr; + return formatExportData(dataSource, this); } //当 custom element首次被插入文档DOM时,被调用。 - connectedCallback() { - this.colCount = this.tableColumns!.length; + connectedCallback(): void { this.dataExportInit(); - this.tableElement?.addEventListener('copy', (e) => { - // @ts-ignore - let clipboardData = e.clipboardData || window.clipboardData; - if (!clipboardData) return; - // @ts-ignore - let text = window.getSelection().toString(); - if (text) { - e.preventDefault(); - let length = this.tableColumns?.length || 1; - let strings = text.split('\n'); - let formatStr = ''; - for (let i = 0; i < strings.length; i++) { - if (i % length != 0) { - formatStr += ' '; - } - formatStr += strings[i]; - if (i != 0 && i % length == length - 1) { - formatStr += '\n'; - } - } - clipboardData.setData('text/plain', formatStr); - } - }); + addCopyEventListener(this); + this.colCount = this.tableColumns!.length; this.st?.addEventListener('slotchange', () => { this.theadElement!.innerHTML = ''; setTimeout(() => { this.columns = this.st!.assignedElements(); let rowElement = document.createElement('div'); rowElement.classList.add('th'); - if (this.selectable) { - let box = document.createElement('div'); - box.style.display = 'flex'; - box.style.justifyContent = 'center'; - box.style.alignItems = 'center'; - box.style.gridArea = '_checkbox_'; - box.classList.add('td'); - box.style.backgroundColor = '#ffffff66'; - let checkbox = document.createElement('lit-checkbox'); - checkbox.classList.add('row-checkbox-all'); - checkbox.onchange = (e: any) => { - this.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: any) => (a.checked = e.detail.checked)); - if (e.detail.checked) { - this.shadowRoot!.querySelectorAll('.tr').forEach((a) => a.setAttribute('checked', '')); - } else { - this.shadowRoot!.querySelectorAll('.tr').forEach((a) => a.removeAttribute('checked')); - } - }; - box.appendChild(checkbox); - rowElement.appendChild(box); - } - let area: Array = []; this.gridTemplateColumns = []; - let resolvingArea = (columns: any, x: any, y: any) => { - columns.forEach((a: any, i: any) => { - if (!area[y]) area[y] = []; - let key = a.getAttribute('key') || a.getAttribute('title'); - if (a.tagName === 'LIT-TABLE-GROUP') { - let len = a.querySelectorAll('lit-table-column').length; - let children = [...a.children].filter((a) => a.tagName !== 'TEMPLATE'); - if (children.length > 0) { - resolvingArea(children, x, y + 1); - } - for (let j = 0; j < len; j++) { - area[y][x] = { x, y, t: key }; - x++; - } - let h = document.createElement('div'); - h.classList.add('td'); - h.style.justifyContent = a.getAttribute('align'); - h.style.borderBottom = '1px solid #f0f0f0'; - h.style.gridArea = key; - h.innerText = a.title; - if (a.hasAttribute('fixed')) { - this.fixed(h, a.getAttribute('fixed'), '#42b983'); - } - rowElement.append(h); - } else if (a.tagName === 'LIT-TABLE-COLUMN') { - area[y][x] = { x, y, t: key }; - x++; - let h: any = document.createElement('div'); - h.classList.add('td'); - if (i > 0) { - let resizeDiv: HTMLDivElement = document.createElement('div'); - resizeDiv.classList.add('resize'); - h.appendChild(resizeDiv); - this.resizeEventHandler(rowElement, resizeDiv, i); - } - if (a.hasAttribute('order')) { - h.sortType = 0; - h.classList.add('td-order'); - h.style.position = 'relative'; - let NS = 'http://www.w3.org/2000/svg'; - let upSvg: any = document.createElementNS(NS, 'svg'); - let upPath: any = document.createElementNS(NS, 'path'); - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.setAttribute('viewBox', '0 0 1024 1024'); - upSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); - upSvg.classList.add('up-svg'); - upPath.setAttribute( - 'd', - 'M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z' - ); - upSvg.appendChild(upPath); - let downSvg: any = document.createElementNS(NS, 'svg'); - let downPath: any = document.createElementNS(NS, 'path'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('viewBox', '0 0 1024 1024'); - downSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); - downSvg.classList.add('down-svg'); - downPath.setAttribute( - 'd', - 'M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z' - ); - downSvg.appendChild(downPath); - if (i == 0) { - h.sortType = 0; // 默认以第一列 降序排序 作为默认排序 - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - } - upSvg.style.display = 'none'; - downSvg.style.display = 'none'; - h.appendChild(upSvg); - h.appendChild(downSvg); - h.onclick = () => { - if (this.isResize || this.resizeColumnIndex !== -1) { - return; - } - this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: any) => { - it.setAttribute('fill', 'let(--dark-color1,#212121)'); - it.sortType = 0; - it.style.display = 'none'; - }); - if (h.sortType == undefined || h.sortType == null) { - h.sortType = 0; - } else if (h.sortType === 2) { - h.sortType = 0; - } else { - h.sortType += 1; - } - switch (h.sortType) { - case 1: - this.theadElement!.setAttribute('sort', ''); - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'block'; - downSvg.style.display = 'none'; - break; - case 2: - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'none'; - downSvg.style.display = 'block'; - break; - default: - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'none'; - downSvg.style.display = 'none'; - this.theadElement!.removeAttribute('sort'); - break; - } - this.dispatchEvent( - new CustomEvent('column-click', { - detail: { - sort: h.sortType, - key: key, - }, - composed: true, - }) - ); - }; - } - h.style.justifyContent = a.getAttribute('align'); - this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); - h.style.gridArea = key; - let titleLabel = document.createElement('label'); - titleLabel.textContent = a.title; - h.appendChild(titleLabel); - if (a.hasAttribute('fixed')) { - this.fixed(h, a.getAttribute('fixed'), '#42b983'); - } - rowElement.append(h); - } - }); - }; - resolvingArea(this.columns, 0, 0); - area.forEach((rows, j, array) => { + let pageArea: Array = []; + addSelectAllBox(rowElement, this); + this.resolvingArea(this.columns, 0, 0, pageArea, rowElement); + pageArea.forEach((rows, j, array) => { for (let i = 0; i < this.colCount; i++) { if (!rows[i]) rows[i] = array[j - 1][i]; } }); if (this.selectable) { - let s = area.map((a) => '"_checkbox_ ' + a.map((aa: any) => aa.t).join(' ') + '"').join(' '); + let s = pageArea.map((a) => '"_checkbox_ ' + a.map((aa: any) => aa.t).join(' ') + '"').join(' '); rowElement.style.gridTemplateColumns = '60px ' + this.gridTemplateColumns.join(' '); - rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`; + rowElement.style.gridTemplateRows = `repeat(${pageArea.length},1fr)`; rowElement.style.gridTemplateAreas = s; } else { - let s = area.map((a) => '"' + a.map((aa: any) => aa.t).join(' ') + '"').join(' '); + let s = pageArea.map((a) => '"' + a.map((aa: any) => aa.t).join(' ') + '"').join(' '); rowElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); - rowElement.style.gridTemplateRows = `repeat(${area.length},1fr)`; + rowElement.style.gridTemplateRows = `repeat(${pageArea.length},1fr)`; rowElement.style.gridTemplateAreas = s; } this.theadElement!.innerHTML = ''; @@ -744,25 +273,125 @@ export class LitPageTable extends BaseElement { this.tableElement!.addEventListener('mouseout', (ev) => this.mouseOut()); } + resolvingArea(columns: any, x: any, y: any, area: Array, rowElement: HTMLDivElement) { + columns.forEach((a: any, i: any) => { + if (!area[y]) area[y] = []; + let key = a.getAttribute('key') || a.getAttribute('title'); + if (a.tagName === 'LIT-TABLE-GROUP') { + let childList = [...a.children].filter((a) => a.tagName !== 'TEMPLATE'); + let len = a.querySelectorAll('lit-table-column').length; + if (childList.length > 0) { + this.resolvingArea(childList, x, y + 1, area, rowElement); + } + for (let j = 0; j < len; j++) { + area[y][x] = { x, y, t: key }; + x++; + } + let head = document.createElement('div'); + head.classList.add('td'); + head.style.justifyContent = a.getAttribute('align'); + head.style.borderBottom = '1px solid #f0f0f0'; + head.style.gridArea = key; + head.innerText = a.title; + if (a.hasAttribute('fixed')) { + fixed(head, a.getAttribute('fixed'), '#42b983'); + } + rowElement.append(head); + } else if (a.tagName === 'LIT-TABLE-COLUMN') { + area[y][x] = { x, y, t: key }; + x++; + let h: any = document.createElement('div'); + h.classList.add('td'); + if (i > 0) { + let resizeDiv: HTMLDivElement = document.createElement('div'); + resizeDiv.classList.add('resize'); + h.appendChild(resizeDiv); + this.resizeEventHandler(rowElement, resizeDiv, i); + } + this.resolvingAreaColumnOrder(a, i, key, h); + h.style.justifyContent = a.getAttribute('align'); + this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); + h.style.gridArea = key; + let titleLabel = document.createElement('label'); + titleLabel.textContent = a.title; + h.appendChild(titleLabel); + if (a.hasAttribute('fixed')) { + fixed(h, a.getAttribute('fixed'), '#42b983'); + } + rowElement.append(h); + } + }); + }; + + resolvingAreaColumnOrder(column: any, index: number, key: string,head: any): void { + if (column.hasAttribute('order')) { + (head as any).sortType = 0; + head.classList.add('td-order'); + head.style.position = 'relative'; + let { upSvg, downSvg } = createDownUpSvg(index, head); + head.onclick = () => { + if (this.isResize || this.resizeColumnIndex !== -1) { + return; + } + this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: any) => { + it.setAttribute('fill', 'let(--dark-color1,#212121)'); + it.sortType = 0; + it.style.display = 'none'; + }); + if (head.sortType == undefined || head.sortType == null) { + head.sortType = 0; + } else if (head.sortType === 2) { + head.sortType = 0; + } else { + head.sortType += 1; + } + upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + upSvg.style.display = head.sortType === 1 ? 'block' : 'none'; + downSvg.style.display = head.sortType === 2 ? 'block' : 'none'; + switch (head.sortType) { + case 1: + this.theadElement!.setAttribute('sort', ''); + break; + case 2: + break; + default: + this.theadElement!.removeAttribute('sort'); + break; + } + this.dispatchEvent( + new CustomEvent('column-click', { + detail: { + sort: head.sortType, + key: key, + }, + composed: true, + }) + ); + }; + } + } + private isResize: boolean = false; private resizeColumnIndex: number = -1; private resizeDownX: number = 0; private columnMinWidth: number = 50; private beforeResizeWidth: number = 0; - resizeEventHandler(header: HTMLDivElement, element: HTMLDivElement, index: number) { + + resizeMouseMoveEventHandler(header: HTMLDivElement) { header.addEventListener('mousemove', (event) => { if (this.isResize) { - let width = event.clientX - this.resizeDownX; header.style.cursor = 'col-resize'; - let preWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth); + let width = event.clientX - this.resizeDownX; + let prePageWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth); for (let i = 0; i < header.childNodes.length; i++) { let node = header.childNodes.item(i) as HTMLDivElement; this.gridTemplateColumns[i] = `${node.clientWidth}px`; } - this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${preWidth}px`; + this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${prePageWidth}px`; header.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); let preNode = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; - preNode.style.width = `${preWidth}px`; + preNode.style.width = `${prePageWidth}px`; this.shadowRoot!.querySelectorAll('.tr').forEach((tr) => { tr.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); }); @@ -772,9 +401,13 @@ export class LitPageTable extends BaseElement { header.style.cursor = 'pointer'; } }); + } + + resizeEventHandler(header: HTMLDivElement, element: HTMLDivElement, index: number): void { + this.resizeMouseMoveEventHandler(header); header.addEventListener('mouseup', (event) => { - this.isResize = false; this.resizeDownX = 0; + this.isResize = false; header.style.cursor = 'pointer'; setTimeout(() => { this.resizeColumnIndex = -1; @@ -791,8 +424,8 @@ export class LitPageTable extends BaseElement { header.style.cursor = 'pointer'; }); element.addEventListener('mousedown', (event) => { - this.isResize = true; this.resizeColumnIndex = index; + this.isResize = true; this.resizeDownX = event.clientX; let pre = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; this.beforeResizeWidth = pre.clientWidth; @@ -804,49 +437,19 @@ export class LitPageTable extends BaseElement { } // Is called when the custom element is removed from the document DOM. - disconnectedCallback() {} + disconnectedCallback(): void {} // It is called when the custom element is moved to a new document. - adoptedCallback() {} + adoptedCallback(): void {} // It is called when a custom element adds, deletes, or modifies its own properties. - attributeChangedCallback(name: string, oldValue: string, newValue: string) {} - - fixed(td: HTMLElement, placement: string, bgColor: string) { - td.style.position = 'sticky'; - if (placement === 'left') { - td.style.left = '0px'; - td.style.boxShadow = '3px 0px 5px #33333333'; - } else if (placement === 'right') { - td.style.right = '0px'; - td.style.boxShadow = '-3px 0px 5px #33333333'; - } - } - - getCheckRows() { - // @ts-ignore - return [...this.shadowRoot!.querySelectorAll('div[class=tr][checked]')] - .map((a) => (a as any).data) - .map((a) => { - delete a['children']; - return a; - }); - } - - deleteRowsCondition(fn: any) { - this.shadowRoot!.querySelectorAll('div[class=tr]').forEach((tr) => { - // @ts-ignore - if (fn(tr.data)) { - tr.remove(); - } - }); - } + attributeChangedCallback(name: string, oldValue: string, newValue: string): void {} - meauseElementHeight(rowData: any) { + meauseElementHeight(rowData: any): number { return 27; } - meauseTreeElementHeight(rowData: any, depth: number) { + meauseTreeElementHeight(rowData: any, depth: number): number { return 27; } @@ -891,49 +494,57 @@ export class LitPageTable extends BaseElement { } }); this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px'); + this.addOnScrollListener(visibleObjects); + return visibleObjects; + } + + addOnScrollListener(visibleObjList: TableRowObject[]): void { this.tableElement && - (this.tableElement.onscroll = (event) => { - let tblScrollTop = this.tableElement!.scrollTop; - let skip = 0; - for (let i = 0; i < visibleObjects.length; i++) { - if ( - visibleObjects[i].top <= tblScrollTop && - visibleObjects[i].top + visibleObjects[i].height >= tblScrollTop - ) { - skip = i; - break; - } - } - let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); - if (reduce == 0) { - return; - } - while ( - reduce <= this.tableElement!.clientHeight && - this.currentRecycleList.length + skip < visibleObjects.length + (this.tableElement.onscroll = (event) => { + let tblScrollTop = this.tableElement!.scrollTop; + let skip = 0; + for (let i = 0; i < visibleObjList.length; i++) { + if ( + visibleObjList[i].top <= tblScrollTop && + visibleObjList[i].top + visibleObjList[i].height >= tblScrollTop ) { - let newTableElement = this.createNewTableElement(visibleObjects[skip]); - this.tbodyElement?.append(newTableElement); - this.currentRecycleList.push(newTableElement); - reduce += newTableElement.clientHeight; + skip = i; + break; } - this.startSkip = skip; - for (let i = 0; i < this.currentRecycleList.length; i++) { - this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip]); - } - }); - return visibleObjects; + } + let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); + if (reduce == 0) { + return; + } + while ( + reduce <= this.tableElement!.clientHeight && + this.currentRecycleList.length + skip < visibleObjList.length + ) { + let newTableElement = this.createNewTableElement(visibleObjList[skip]); + this.tbodyElement?.append(newTableElement); + this.currentRecycleList.push(newTableElement); + reduce += newTableElement.clientHeight; + } + this.startSkip = skip; + for (let i = 0; i < this.currentRecycleList.length; i++) { + this.freshCurrentLine(this.currentRecycleList[i], visibleObjList[i + skip]); + } + }); } - meauseTreeRowElement(list: any[]): TableRowObject[] { + measureReset(): void { this.meauseRowElement = undefined; this.tbodyElement!.innerHTML = ''; this.treeElement!.innerHTML = ''; + this.currentRecycleList = []; + this.currentTreeDivList = []; + } + + meauseTreeRowElement(list: any[]): TableRowObject[] { + this.measureReset(); let headHeight = this.theadElement?.clientHeight || 0; let totalHeight = 0; let visibleObjects: TableRowObject[] = []; - this.currentRecycleList = []; - this.currentTreeDivList = []; let resetAllHeight = (list: any[], depth: number, parentNode?: TableRowObject) => { list.forEach((item) => { let tableRowObject = new TableRowObject(); @@ -941,16 +552,15 @@ export class LitPageTable extends BaseElement { tableRowObject.data = item; tableRowObject.top = totalHeight; tableRowObject.height = this.meauseTreeElementHeight(tableRowObject, depth); - if (parentNode != undefined) { + if (parentNode !== undefined) { parentNode.children.push(tableRowObject); } - if ( - Math.max(totalHeight, this.tableElement!.scrollTop) <= - Math.min( - totalHeight + tableRowObject.height, - this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight - ) - ) { + let maxHeight = Math.max(totalHeight, this.tableElement!.scrollTop); + let minHeight = Math.min( + totalHeight + tableRowObject.height, + this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight + ); + if (maxHeight <= minHeight) { let newTableElement = this.createNewTreeTableElement(tableRowObject); newTableElement.style.transform = `translateY(${totalHeight}px)`; this.tbodyElement?.append(newTableElement); @@ -968,7 +578,7 @@ export class LitPageTable extends BaseElement { resetAllHeight(item.children, depth + 1, tableRowObject); } } else { - if (item.children != undefined && item.children.length > 0) { + if (item.children !== undefined && item.children.length > 0) { resetAllHeight(item.children, depth + 1, tableRowObject); } } @@ -977,42 +587,46 @@ export class LitPageTable extends BaseElement { resetAllHeight(list, 0); this.tbodyElement && (this.tbodyElement.style.height = totalHeight + 'px'); this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px'; + this.addTreeRowScrollListener(); + return visibleObjects; + } + + addTreeRowScrollListener(): void { this.tableElement && - (this.tableElement.onscroll = (event) => { - let visibleObjects = this.recycleDs.filter((item) => { - return !item.rowHidden; - }); - let top = this.tableElement!.scrollTop; - this.treeElement!.style.transform = `translateY(${top}px)`; - let skip = 0; - for (let index = 0; index < visibleObjects.length; index++) { - if (visibleObjects[index].top <= top && visibleObjects[index].top + visibleObjects[index].height >= top) { - skip = index; - break; - } - } - let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); - if (reduce == 0) { - return; - } - while (reduce <= this.tableElement!.clientHeight) { - let newTableElement = this.createNewTreeTableElement(visibleObjects[skip]); - this.tbodyElement?.append(newTableElement); - if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + 'px'; - } - this.currentRecycleList.push(newTableElement); - reduce += newTableElement.clientHeight; + (this.tableElement.onscroll = (event) => { + let visibleObjs = this.recycleDs.filter((item) => { + return !item.rowHidden; + }); + let top = this.tableElement!.scrollTop; + this.treeElement!.style.transform = `translateY(${top}px)`; + let skip = 0; + for (let index = 0; index < visibleObjs.length; index++) { + if (visibleObjs[index].top <= top && visibleObjs[index].top + visibleObjs[index].height >= top) { + skip = index; + break; } - for (let i = 0; i < this.currentRecycleList.length; i++) { - this.freshCurrentLine( - this.currentRecycleList[i], - visibleObjects[i + skip], - this.treeElement?.children[i] as HTMLElement - ); + } + let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); + if (reduce == 0) { + return; + } + while (reduce <= this.tableElement!.clientHeight) { + let newTableElement = this.createNewTreeTableElement(visibleObjs[skip]); + this.tbodyElement?.append(newTableElement); + if (this.treeElement?.lastChild) { + (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjs[skip].height + 'px'; } - }); - return visibleObjects; + this.currentRecycleList.push(newTableElement); + reduce += newTableElement.clientHeight; + } + for (let i = 0; i < this.currentRecycleList.length; i++) { + this.freshCurrentLine( + this.currentRecycleList[i], + visibleObjs[i + skip], + this.treeElement?.children[i] as HTMLElement + ); + } + }); } createNewTreeTableElement(rowData: TableRowObject): any { @@ -1026,74 +640,10 @@ export class LitPageTable extends BaseElement { this?.columns?.forEach((column: any, index) => { let dataIndex = column.getAttribute('data-index') || '1'; let td: any; - let text = this.formatName(dataIndex, rowData.data[dataIndex]); if (index === 0) { - if (column.template) { - td = column.template.render(rowData.data).content.cloneNode(true); - td.template = column.template; - td.title = text; - } else { - td = document.createElement('div'); - td.innerHTML = text; - td.dataIndex = dataIndex; - td.title = text; - } - if (rowData.data.children && rowData.data.children.length > 0 && !rowData.data.hasNext) { - let btn = this.createExpandBtn(rowData); - td.insertBefore(btn, td.firstChild); - } - if (rowData.data.hasNext) { - td.title = rowData.data.objectName; - let btn = this.createBtn(rowData); - td.insertBefore(btn, td.firstChild); - } - td.style.paddingLeft = rowData.depth * 15 + 'px'; - if (!rowData.data.children || rowData.data.children.length === 0) { - td.style.paddingLeft = 15 * rowData.depth + 16 + 'px'; - } - (td as any).data = rowData.data; - td.classList.add('tree-first-body'); - td.style.position = 'absolute'; - td.style.top = '0px'; - td.style.left = '0px'; - td.onmouseenter = () => { - let indexOf = this.currentTreeDivList.indexOf(td); - this.currentRecycleList.forEach((row) => { - row.classList.remove('mouse-in'); - }); - if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML != '') { - this.setMouseIn(true, [newTableElement]); - } - }; - td.onmouseleave = () => { - let indexOf = this.currentTreeDivList.indexOf(td); - if (indexOf >= 0 && indexOf < this.currentRecycleList.length) { - this.setMouseIn(false, [newTableElement]); - } - }; - td.onclick = () => { - let indexOf = this.currentTreeDivList.indexOf(td); - this.dispatchRowClickEvent(rowData, [td, newTableElement]); - }; - this.setHighLight(rowData.data.isSearch, td); - this.treeElement!.style.width = column.getAttribute('width'); - this.treeElement?.append(td); - this.currentTreeDivList.push(td); + td = this.firstElementTdHandler(newTableElement, dataIndex, rowData, column); } else { - td = document.createElement('div'); - td.classList.add('td'); - td.style.overflow = 'hidden'; - td.style.textOverflow = 'ellipsis'; - td.style.whiteSpace = 'nowrap'; - td.title = text; - td.dataIndex = dataIndex; - td.style.justifyContent = column.getAttribute('align') || 'flex-start'; - if (column.template) { - td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); - td.template = column.template; - } else { - td.innerHTML = text; - } + td = this.otherElementHandler(dataIndex, rowData, column); newTableElement.append(td); } }); @@ -1108,6 +658,11 @@ export class LitPageTable extends BaseElement { newTableElement.style.left = '0px'; newTableElement.style.cursor = 'pointer'; this.setHighLight(rowData.data.isSearch, newTableElement); + this.addRowElementEvent(newTableElement, rowData); + return newTableElement; + } + + addRowElementEvent(newTableElement: HTMLDivElement, rowData: any): void { newTableElement.onmouseenter = () => { if ((newTableElement as any).data.isSelected) return; let indexOf = this.currentRecycleList.indexOf(newTableElement); @@ -1129,19 +684,99 @@ export class LitPageTable extends BaseElement { let indexOf = this.currentRecycleList.indexOf(newTableElement); this.dispatchRowClickEvent(rowData, [this.treeElement?.children[indexOf] as HTMLElement, newTableElement]); }; - return newTableElement; } - createBtn(rowData: any) { + firstElementTdHandler(newTableElement: HTMLDivElement, dataIndex: string, rowData: any, column: any) { + let td: any; + let text = formatName(dataIndex, rowData.data[dataIndex], this); + if (column.template) { + td = column.template.render(rowData.data).content.cloneNode(true); + td.template = column.template; + td.title = text; + } else { + td = document.createElement('div'); + td.innerHTML = text; + td.dataIndex = dataIndex; + td.title = text; + } + if (rowData.data.children && rowData.data.children.length > 0 && !rowData.data.hasNext) { + let btn = this.createExpandBtn(rowData); + td.insertBefore(btn, td.firstChild); + } + if (rowData.data.hasNext) { + td.title = rowData.data.objectName; + let btn = this.createBtn(rowData); + td.insertBefore(btn, td.firstChild); + } + td.style.paddingLeft = rowData.depth * iconWidth + 'px'; + if (!rowData.data.children || rowData.data.children.length === 0) { + td.style.paddingLeft = iconWidth * rowData.depth + iconWidth + iconPadding * 2 + 'px'; + } + (td as any).data = rowData.data; + td.classList.add('tree-first-body'); + td.style.position = 'absolute'; + td.style.top = '0px'; + td.style.left = '0px'; + this.addFirstElementEvent(td, newTableElement, rowData); + this.setHighLight(rowData.data.isSearch, td); + this.treeElement!.style.width = column.getAttribute('width'); + this.treeElement?.append(td); + this.currentTreeDivList.push(td); + return td; + } + + addFirstElementEvent(td: HTMLDivElement, tr: HTMLDivElement, rowData: any): void { + td.onmouseenter = () => { + let indexOf = this.currentTreeDivList.indexOf(td); + this.currentRecycleList.forEach((row) => { + row.classList.remove('mouse-in'); + }); + if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML != '') { + this.setMouseIn(true, [td]); + } + }; + td.onmouseleave = () => { + let indexOf = this.currentTreeDivList.indexOf(td); + if (indexOf >= 0 && indexOf < this.currentRecycleList.length) { + this.setMouseIn(false, [td]); + } + }; + td.onclick = () => { + let indexOf = this.currentTreeDivList.indexOf(td); + this.dispatchRowClickEvent(rowData, [td, tr]); + }; + } + + otherElementHandler(dataIndex: string, rowData: any, column: any) { + let text = formatName(dataIndex, rowData.data[dataIndex], this); + let td: any = document.createElement('div'); + td = document.createElement('div'); + td.classList.add('td'); + td.style.overflow = 'hidden'; + td.style.textOverflow = 'ellipsis'; + td.style.whiteSpace = 'nowrap'; + td.title = text; + td.dataIndex = dataIndex; + td.style.justifyContent = column.getAttribute('align') || 'flex-start'; + if (column.template) { + td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); + td.template = column.template; + } else { + td.innerHTML = text; + } + return td; + } + + createBtn(row: any): any { let btn: any = document.createElement('lit-icon'); btn.classList.add('tree-icon'); - if (rowData.data.expanded) { + if (row.data.expanded) { btn.name = 'plus-square'; } else { btn.name = 'minus-square'; } btn.addEventListener('click', (e: any) => { - rowData.data.status = false; + row.data.status = false; const resetNodeHidden = (hidden: boolean, rowData: any) => { if (hidden) { rowData.children.forEach((child: any) => { @@ -1155,15 +790,15 @@ export class LitPageTable extends BaseElement { } }; - if (rowData.data.expanded) { - rowData.data.status = true; - this.dispatchRowClickEventIcon(rowData, [btn]); - rowData.data.expanded = false; - resetNodeHidden(true, rowData); + if (row.data.expanded) { + row.data.status = true; + this.dispatchRowClickEventIcon(row, [btn]); + row.data.expanded = false; + resetNodeHidden(true, row); } else { - rowData.data.expanded = true; - rowData.data.status = false; - resetNodeHidden(false, rowData); + row.data.expanded = true; + row.data.status = false; + resetNodeHidden(false, row); } this.reMeauseHeight(); e.stopPropagation(); @@ -1171,11 +806,11 @@ export class LitPageTable extends BaseElement { return btn; } - createExpandBtn(rowData: any) { + createExpandBtn(row: any): any { let btn: any = document.createElement('lit-icon'); btn.classList.add('tree-icon'); // @ts-ignore - if (rowData.expanded) { + if (row.expanded) { btn.name = 'minus-square'; } else { btn.name = 'plus-square'; @@ -1199,12 +834,12 @@ export class LitPageTable extends BaseElement { } }; - if (rowData.expanded) { - rowData.expanded = false; - resetNodeHidden(true, rowData); + if (row.expanded) { + row.expanded = false; + resetNodeHidden(true, row); } else { - rowData.expanded = true; - resetNodeHidden(false, rowData); + row.expanded = true; + resetNodeHidden(false, row); } this.reMeauseHeight(); e.stopPropagation(); @@ -1212,66 +847,71 @@ export class LitPageTable extends BaseElement { return btn; } - reMeauseHeight() { - if (this.currentRecycleList.length == 0) { - return; - } - let totalHeight = 0; + getVisibleObjs() { + let totalH = 0; this.recycleDs.forEach((it) => { if (!it.rowHidden) { - it.top = totalHeight; - totalHeight += it.height; + it.top = totalH; + totalH += it.height; } }); - this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px'); + this.tbodyElement && (this.tbodyElement.style.height = totalH + (this.isScrollXOutSide ? 0 : 0) + 'px'); this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px'; - let visibleObjects = this.recycleDs.filter((item) => { + let visibleObjs = this.recycleDs.filter((item) => { return !item.rowHidden; }); let top = this.tableElement!.scrollTop; let skip = 0; - for (let i = 0; i < visibleObjects.length; i++) { - if (visibleObjects[i].top <= top && visibleObjects[i].top + visibleObjects[i].height >= top) { + for (let i = 0; i < visibleObjs.length; i++) { + if (visibleObjs[i].top <= top && visibleObjs[i].top + visibleObjs[i].height >= top) { skip = i; break; } } let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); - if (reduce == 0) { + return { visibleObjs, skip, reduce }; + } + + reMeauseHeight(): void { + if (this.currentRecycleList.length === 0) { + return; + } + let { visibleObjs, skip, reduce } = this.getVisibleObjs(); + if (reduce === 0) { return; } while (reduce <= this.tableElement!.clientHeight) { - let newTableElement; + let rowElement; if (this.hasAttribute('tree')) { - newTableElement = this.createNewTreeTableElement(visibleObjects[skip]); + rowElement = this.createNewTreeTableElement(visibleObjs[skip]); } else { - newTableElement = this.createNewTableElement(visibleObjects[skip]); + rowElement = this.createNewTableElement(visibleObjs[skip]); } - this.tbodyElement?.append(newTableElement); + this.tbodyElement?.append(rowElement); if (this.hasAttribute('tree')) { if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + 'px'; + (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjs[skip].height + 'px'; } } - this.currentRecycleList.push(newTableElement); - reduce += newTableElement.clientHeight; + this.currentRecycleList.push(rowElement); + reduce += rowElement.clientHeight; } for (let i = 0; i < this.currentRecycleList.length; i++) { if (this.hasAttribute('tree')) { this.freshCurrentLine( this.currentRecycleList[i], - visibleObjects[i + skip], + visibleObjs[i + skip], this.treeElement?.children[i] as HTMLElement ); } else { - this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip]); + this.freshCurrentLine(this.currentRecycleList[i], visibleObjs[i + skip]); } } } createNewTableElement(rowData: any): any { - let newTableElement = document.createElement('div'); - newTableElement.classList.add('tr'); + let rowElement = document.createElement('div'); + rowElement.classList.add('tr'); this?.columns?.forEach((column: any) => { let dataIndex = column.getAttribute('data-index') || '1'; let td: any; @@ -1282,7 +922,7 @@ export class LitPageTable extends BaseElement { td.style.whiteSpace = 'nowrap'; td.dataIndex = dataIndex; td.style.justifyContent = column.getAttribute('align') || 'flex-start'; - let text = this.formatName(dataIndex, rowData.data[dataIndex]); + let text = formatName(dataIndex, rowData.data[dataIndex], this); td.title = text; if (column.template) { td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); @@ -1290,27 +930,27 @@ export class LitPageTable extends BaseElement { } else { td.innerHTML = text; } - newTableElement.append(td); + rowElement.append(td); }); - newTableElement.onclick = () => { - this.dispatchRowClickEvent(rowData, [newTableElement]); + rowElement.onclick = () => { + this.dispatchRowClickEvent(rowData, [rowElement]); }; - newTableElement.onmouseover = () => { - this.dispatchRowHoverEvent(rowData, [newTableElement]); + rowElement.onmouseover = () => { + this.dispatchRowHoverEvent(rowData, [rowElement]); }; if (rowData.data.isSelected != undefined) { - this.setSelectedRow(rowData.data.isSelected, [newTableElement]); + this.setSelectedRow(rowData.data.isSelected, [rowElement]); } - (newTableElement as any).data = rowData.data; - newTableElement.style.cursor = 'pointer'; - newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); - newTableElement.style.position = 'absolute'; - newTableElement.style.top = '0px'; - newTableElement.style.left = '0px'; + (rowElement as any).data = rowData.data; + rowElement.style.cursor = 'pointer'; + rowElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); + rowElement.style.position = 'absolute'; + rowElement.style.top = '0px'; + rowElement.style.left = '0px'; if (this.getItemTextColor) { - newTableElement.style.color = this.getItemTextColor(rowData.data); + rowElement.style.color = this.getItemTextColor(rowData.data); } - return newTableElement; + return rowElement; } freshCurrentLine(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement) { @@ -1326,46 +966,10 @@ export class LitPageTable extends BaseElement { element.childNodes.forEach((child) => { if (child.nodeType != 1) return; childIndex++; - let idx = firstElement != undefined ? childIndex + 1 : childIndex; - if (firstElement != undefined && childIndex == 0) { - this.setHighLight(rowObject.data.isSearch, firstElement); - (firstElement as any).data = rowObject.data; - if ((this.columns![0] as any).template) { - firstElement.innerHTML = (this.columns![0] as any).template - .render(rowObject.data) - .content.cloneNode(true).innerHTML; - } else { - let dataIndex = this.columns![0].getAttribute('data-index') || '1'; - let text = this.formatName(dataIndex, rowObject.data[dataIndex]); - firstElement.innerHTML = text; - firstElement.title = text; - } - if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) { - let btn = this.createExpandBtn(rowObject); - firstElement.insertBefore(btn, firstElement.firstChild); - } - firstElement.style.paddingLeft = 15 * rowObject.depth + 'px'; - if (!rowObject.children || rowObject.children.length === 0) { - firstElement.style.paddingLeft = 15 * rowObject.depth + 16 + 'px'; - } - if (rowObject.data.hasNext) { - let btn = this.createBtn(rowObject); - firstElement.title = rowObject.data.objectName; - firstElement.insertBefore(btn, firstElement.firstChild); - firstElement.style.paddingLeft = 15 * rowObject.depth + 'px'; - } - firstElement.onclick = () => { - this.dispatchRowClickEvent(rowObject, [firstElement, element]); - }; - firstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; - if (rowObject.data.isSelected != undefined) { - this.setSelectedRow(rowObject.data.isSelected, [firstElement]); - } else { - this.setSelectedRow(false, [firstElement]); - } - } + let idx = firstElement !== undefined ? childIndex + 1 : childIndex; + this.freshLineFirstElementHandler(firstElement, rowObject, childIndex); let dataIndex = this.columns![idx].getAttribute('data-index') || '1'; - let text = this.formatName(dataIndex, rowObject.data[dataIndex]); + let text = formatName(dataIndex, rowObject.data[dataIndex], this); if ((this.columns![idx] as any).template) { (child as HTMLElement).innerHTML = ''; (child as HTMLElement).appendChild( @@ -1377,31 +981,75 @@ export class LitPageTable extends BaseElement { (child as HTMLElement).title = text; } }); - if (element.style.display == 'none') { + this.freshLineStyleAndEvents(element, rowObject, firstElement); + } + + freshLineFirstElementHandler(rowFirstElement: any, rowObject: TableRowObject, childIndex: number): void { + if (rowFirstElement !== undefined && childIndex === 0) { + this.setHighLight(rowObject.data.isSearch, rowFirstElement); + (rowFirstElement as any).data = rowObject.data; + if ((this.columns![0] as any).template) { + rowFirstElement.innerHTML = (this.columns![0] as any).template + .render(rowObject.data) + .content.cloneNode(true).innerHTML; + } else { + let dataIndex = this.columns![0].getAttribute('data-index') || '1'; + let text = formatName(dataIndex, rowObject.data[dataIndex], this); + rowFirstElement.innerHTML = text; + rowFirstElement.title = text; + } + if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) { + let btn = this.createExpandBtn(rowObject); + rowFirstElement.insertBefore(btn, rowFirstElement.firstChild); + } + rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; + if (!rowObject.children || rowObject.children.length === 0) { + rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + iconWidth + iconPadding * 2 + 'px'; + } + if (rowObject.data.hasNext) { + let btn = this.createBtn(rowObject); + rowFirstElement.title = rowObject.data.objectName; + rowFirstElement.insertBefore(btn, rowFirstElement.firstChild); + rowFirstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; + } + rowFirstElement.onclick = () => { + this.dispatchRowClickEvent(rowObject, [rowFirstElement, element]); + }; + rowFirstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; + if (rowObject.data.isSelected !== undefined) { + this.setSelectedRow(rowObject.data.isSelected, [rowFirstElement]); + } else { + this.setSelectedRow(false, [rowFirstElement]); + } + } + } + + freshLineStyleAndEvents(element: HTMLElement, rowData: TableRowObject, firstElement?: HTMLElement): void { + if (element.style.display === 'none') { element.style.display = 'grid'; } - element.style.transform = `translateY(${rowObject.top}px)`; - if (firstElement && firstElement.style.display == 'none') { + element.style.transform = `translateY(${rowData.top}px)`; + if (firstElement && firstElement.style.display === 'none') { firstElement.style.display = 'flex'; } element.onclick = (e) => { - if (firstElement != undefined) { - this.dispatchRowClickEvent(rowObject, [firstElement, element]); + if (firstElement !== undefined) { + this.dispatchRowClickEvent(rowData, [firstElement, element]); } else { - this.dispatchRowClickEvent(rowObject, [element]); + this.dispatchRowClickEvent(rowData, [element]); } }; element.onmouseenter = () => { - this.dispatchRowHoverEvent(rowObject, [element]); + this.dispatchRowHoverEvent(rowData, [element]); }; - (element as any).data = rowObject.data; - if (rowObject.data.isSelected != undefined) { - this.setSelectedRow(rowObject.data.isSelected, [element]); + (element as any).data = rowData.data; + if (rowData.data.isSelected !== undefined) { + this.setSelectedRow(rowData.data.isSelected, [element]); } else { this.setSelectedRow(false, [element]); } - if (rowObject.data.isHover != undefined) { - this.setMouseIn(rowObject.data.isHover, [element]); + if (rowData.data.isHover !== undefined) { + this.setMouseIn(rowData.data.isHover, [element]); } else { this.setMouseIn(false, [element]); } @@ -1410,10 +1058,12 @@ export class LitPageTable extends BaseElement { } } - setSelectedRow(isSelected: boolean, rows: any[]) { + setSelectedRow(isSelected: boolean, rows: any[]): void { if (isSelected) { rows.forEach((row) => { - if (row.classList.contains('mouse-in')) row.classList.remove('mouse-in'); + if (row.classList.contains('mouse-in')) { + row.classList.remove('mouse-in'); + } row.classList.add('mouse-select'); }); } else { @@ -1423,7 +1073,7 @@ export class LitPageTable extends BaseElement { } } - setMouseIn(isMouseIn: boolean, rows: any[]) { + setMouseIn(isMouseIn: boolean, rows: any[]): void { if (isMouseIn) { rows.forEach((row) => { row.classList.add('mouse-in'); @@ -1435,7 +1085,7 @@ export class LitPageTable extends BaseElement { } } - scrollToData(data: any) { + scrollToData(data: any): void { if (this.recycleDs.length > 0) { let filter = this.recycleDs.filter((item) => { return item.data == data; @@ -1447,12 +1097,12 @@ export class LitPageTable extends BaseElement { } } - expandList(datasource: any[]) { - let filter = this.recycleDs.filter((item) => { + expandList(datasource: any[]): void { + let source = this.recycleDs.filter((item) => { return datasource.indexOf(item.data) != -1; }); - if (filter.length > 0) { - filter.forEach((item) => { + if (source.length > 0) { + source.forEach((item) => { item.expanded = true; item.rowHidden = false; }); @@ -1460,7 +1110,7 @@ export class LitPageTable extends BaseElement { this.reMeauseHeight(); } - clearAllSelection(rowObjectData: any = undefined) { + clearAllSelection(rowObjectData: any = undefined): void { this.recycleDs.forEach((item) => { if (rowObjectData || (item.data != rowObjectData && item.data.isSelected)) { item.data.isSelected = false; @@ -1470,7 +1120,7 @@ export class LitPageTable extends BaseElement { this.setSelectedRow(false, this.currentRecycleList); } - clearAllHover(rowObjectData: any) { + clearAllHover(rowObjectData: any): void { this.recycleDs.forEach((item) => { if (item.data != rowObjectData && item.data.isHover) { item.data.isHover = false; @@ -1480,7 +1130,7 @@ export class LitPageTable extends BaseElement { this.setMouseIn(false, this.currentRecycleList); } - mouseOut() { + mouseOut(): void { this.recycleDs.forEach((item) => (item.data.isHover = false)); this.setMouseIn(false, this.currentTreeDivList); this.setMouseIn(false, this.currentRecycleList); @@ -1494,7 +1144,7 @@ export class LitPageTable extends BaseElement { ); } - setCurrentSelection(data: any) { + setCurrentSelection(data: any): void { if (data.isSelected != undefined) { this.currentTreeDivList.forEach((item) => { if ((item as any).data == data) { @@ -1509,7 +1159,7 @@ export class LitPageTable extends BaseElement { } } - setCurrentHover(data: any) { + setCurrentHover(data: any): void { this.setMouseIn(false, this.currentTreeDivList); this.setMouseIn(false, this.currentRecycleList); if (data.isHover != undefined) { @@ -1545,13 +1195,13 @@ export class LitPageTable extends BaseElement { ); } - dispatchRowClickEvent(rowObject: any, elements: any[]) { + dispatchRowClickEvent(rowObject: any, elements: any[]): void { this.dispatchEvent( new CustomEvent('row-click', { detail: { ...rowObject.data, data: rowObject.data, - callBack: (isSelected: boolean) => { + callBack: (isSelected: boolean): void => { //是否爲单选 if (isSelected) { this.clearAllSelection(rowObject.data); @@ -1564,12 +1214,12 @@ export class LitPageTable extends BaseElement { ); } - dispatchRowHoverEvent(rowObject: any, elements: any[]) { + dispatchRowHoverEvent(rowObject: any, elements: any[]): void { this.dispatchEvent( new CustomEvent('row-hover', { detail: { data: rowObject.data, - callBack: () => { + callBack: (): void => { this.clearAllHover(rowObject.data); this.setMouseIn(rowObject.data.isHover, elements); }, @@ -1578,19 +1228,7 @@ export class LitPageTable extends BaseElement { }) ); } - - formatName(key: string, name: any) { - let content = name; - if (this.itemTextHandleMap.has(key)) { - content = this.itemTextHandleMap.get(key)?.(name) || ''; - } - if (content !== undefined && content !== null) { - return content.toString().replace(//g, '>'); - } - return ''; - } - - setHighLight(isSearch: boolean, element: any) { + setHighLight(isSearch: boolean, element: any): void { if (isSearch) { element.setAttribute('high-light', ''); } else { diff --git a/ide/src/base-ui/table/LitTableHtml.ts b/ide/src/base-ui/table/LitTableHtml.ts new file mode 100644 index 0000000000000000000000000000000000000000..a907921b54cfc18b1c7be3130af41ac15f90f86e --- /dev/null +++ b/ide/src/base-ui/table/LitTableHtml.ts @@ -0,0 +1,687 @@ +/* + * 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 {JSONToCSV} from "../utils/CSVFormater"; + +export const iconWidth = 20; +export const iconPadding = 5; + +export const litPageTableHtml = ` + + + + +
+ +
+
+
+
+
+
+
+
+
上一页
+
1
+ +
GO
+
下一页
+
+
+ `; + +export const litTableHtml = ` + + + + +
+ +
+
+
+
+
+
+
+
+ `; + +export function createDownUpSvg(index: number, head: any) { + let NS = 'http://www.w3.org/2000/svg'; + let upSvg: any = document.createElementNS(NS, 'svg'); + let upPath: any = document.createElementNS(NS, 'path'); + upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + upSvg.setAttribute('viewBox', '0 0 1024 1024'); + upSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); + upSvg.classList.add('up-svg'); + upPath.setAttribute( + 'd', + 'M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z' + ); + upSvg.appendChild(upPath); + let downSvg: any = document.createElementNS(NS, 'svg'); + let downPath: any = document.createElementNS(NS, 'path'); + downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + downSvg.setAttribute('viewBox', '0 0 1024 1024'); + downSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); + downSvg.classList.add('down-svg'); + downPath.setAttribute( + 'd', + 'M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z' + ); + downSvg.appendChild(downPath); + if (index == 0) { + head.sortType = 0; // 默认以第一列 降序排序 作为默认排序 + upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + } + upSvg.style.display = 'none'; + downSvg.style.display = 'none'; + head.appendChild(upSvg); + head.appendChild(downSvg); + return {upSvg, downSvg} +} + +export function exportData(that: any): void { + if (that.exportLoading || that.ds.length === 0) { + return; + } + that.exportLoading = true; + that.exportProgress!.loading = true; + let date = new Date(); + JSONToCSV.csvExport({ + columns: that.columns as any[], + tables: that.ds, + fileName: `${date.getTime()}`, + columnFormatter: that.itemTextHandleMap, + exportFormatter: that.exportTextHandleMap, + }).then((res) => { + that.exportLoading = false; + that.exportProgress!.loading = false; + }); +} + +export function formatExportData(dataSource: any[], that: any): any[] { + if (dataSource === undefined || dataSource.length === 0) { + return []; + } + if (that.columns === undefined) { + return []; + } + return dataSource.map((item) => { + let formatData: any = {}; + that.columns!.forEach((column: any) => { + let dataIndex = column.getAttribute('data-index'); + let columnName = column.getAttribute('title'); + if (columnName === '') { + columnName = dataIndex; + } + if (dataIndex && columnName && item[dataIndex] != undefined) { + formatData[columnName] = item[dataIndex]; + } + }); + if (item.children !== undefined) { + formatData.children = formatExportData(item.children, that); + } + return formatData; + }); +} + +export function recursionExportTableData(columns: any[], dataSource: any[]): string { + let concatStr = '\r\n'; + dataSource.forEach((item, index) => { + concatStr += columns + .map((column) => { + let dataIndex = column.getAttribute('data-index'); + return `"${item[dataIndex] || ''}" `; + }) + .join(','); + if (item.children !== undefined) { + concatStr += recursionExportTableData(columns, item.children); + } + if (index !== dataSource.length - 1) { + concatStr += '\r\n'; + } + }); + return concatStr; +} + +export function addCopyEventListener(that: any): void { + that.tableElement?.addEventListener('copy', (e: any) => { + // @ts-ignore + let clipboardData = e.clipboardData || window.clipboardData; + if (!clipboardData) return; + // @ts-ignore + let text = window.getSelection().toString(); + if (text) { + e.preventDefault(); + let length = that.tableColumns?.length || 1; + let strings = text.split('\n'); + let formatStr = ''; + for (let i = 0; i < strings.length; i++) { + if (i % length != 0) { + formatStr += ' '; + } + formatStr += strings[i]; + if (i !== 0 && i % length === length - 1) { + formatStr += '\n'; + } + } + clipboardData.setData('text/plain', formatStr); + } + }); +} + +export function addSelectAllBox(rowElement: HTMLDivElement, that: any): void { + if (that.selectable) { + let box = document.createElement('div'); + box.style.display = 'flex'; + box.style.justifyContent = 'center'; + box.style.alignItems = 'center'; + box.style.gridArea = '_checkbox_'; + box.classList.add('td'); + box.style.backgroundColor = '#ffffff66'; + let checkbox = document.createElement('lit-checkbox'); + checkbox.classList.add('row-checkbox-all'); + checkbox.onchange = (e: any) => { + that.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: any) => (a.checked = e.detail.checked)); + if (e.detail.checked) { + that.shadowRoot!.querySelectorAll('.tr').forEach((a: any) => a.setAttribute('checked', '')); + } else { + that.shadowRoot!.querySelectorAll('.tr').forEach((a: any) => a.removeAttribute('checked')); + } + }; + box.appendChild(checkbox); + rowElement.appendChild(box); + } +} + +export function fixed(td: HTMLElement, placement: string, bgColor: string): void { + td.style.position = 'sticky'; + if (placement === 'left') { + td.style.left = '0px'; + td.style.boxShadow = '3px 0px 5px #33333333'; + } else if (placement === 'right') { + td.style.right = '0px'; + td.style.boxShadow = '-3px 0px 5px #33333333'; + } +} + +export function formatName(key: string, name: any, that: any): any { + let content = name; + if (that.itemTextHandleMap.has(key)) { + content = that.itemTextHandleMap.get(key)?.(name) || ''; + } + if (content !== undefined && content !== null) { + return content.toString().replace(//g, '>'); + } + return ''; +} \ No newline at end of file diff --git a/ide/src/base-ui/table/lit-table.ts b/ide/src/base-ui/table/lit-table.ts index 7cb7ea453b2dcdd7f1aa6182f3bc9c5715099211..e6724e7a3a71b883a9a7f034989f96fb307c1c36 100644 --- a/ide/src/base-ui/table/lit-table.ts +++ b/ide/src/base-ui/table/lit-table.ts @@ -19,13 +19,24 @@ import { element } from '../BaseElement'; import '../utils/Template'; import { TableRowObject } from './TableRowObject'; import { ExcelFormater } from '../utils/ExcelFormater'; -import { JSONToCSV } from '../utils/CSVFormater'; +import { LitIcon } from '../icon/LitIcon'; import { NodeType } from '../../js-heap/model/DatabaseStruct'; import { ConstructorType } from '../../js-heap/model/UiStruct'; -import { LitIcon } from '../icon/LitIcon'; import { JsCpuProfilerStatisticsStruct } from '../../trace/bean/JsStruct'; -const iconWidth = 20; -const iconPadding = 5; +import { + iconPadding, + iconWidth, + createDownUpSvg, + litTableHtml, + exportData, + formatExportData, + recursionExportTableData, + addCopyEventListener, + addSelectAllBox, + fixed, + formatName +} from './LitTableHtml'; + @element('lit-table') export class LitTable extends HTMLElement { meauseRowElement: HTMLDivElement | undefined; @@ -35,25 +46,23 @@ export class LitTable extends HTMLElement { public getItemTextColor?: (data: any) => string; public itemTextHandleMap: Map string> = new Map string>(); public exportTextHandleMap: Map string> = new Map string>(); - private ds: Array = []; + public ds: Array = []; public recycleDs: Array = []; + public gridTemplateColumns: Array = []; + public tableColumns: NodeListOf | undefined; + public treeElement: HTMLDivElement | undefined | null; + public columns: Array | null | undefined; + public exportLoading: boolean = false; + public exportProgress: LitProgressBar | null | undefined; + public tableElement: HTMLDivElement | null | undefined; private normalDs: Array = []; - private gridTemplateColumns: Array = []; /*Grid css layout descriptions are obtained according to the clustern[] nested structure*/ private st: HTMLSlotElement | null | undefined; - private tableElement: HTMLDivElement | null | undefined; - private exportProgress: LitProgressBar | null | undefined; private theadElement: HTMLDivElement | null | undefined; - private columns: Array | null | undefined; private tbodyElement: HTMLDivElement | undefined | null; - private treeElement: HTMLDivElement | undefined | null; - private tableColumns: NodeListOf | undefined; private colCount: number = 0; - private currentScrollTop: number = 0; private isRecycleList: boolean = true; private isScrollXOutSide: boolean = false; - private exportLoading: boolean = false; - private _loading: boolean = false; private value: Array = []; private _mode = TableMode.Expand; private columnResizeEnable: boolean = true; @@ -62,253 +71,7 @@ export class LitTable extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); - shadowRoot.innerHTML = ` - - - - -
- -
-
-
-
-
-
-
-
- `; + shadowRoot.innerHTML = litTableHtml; } static get observedAttributes(): string[] { @@ -330,7 +93,6 @@ export class LitTable extends HTMLElement { } set loading(value: boolean) { - this._loading = value; this.exportProgress!.loading = value; } @@ -407,7 +169,6 @@ export class LitTable extends HTMLElement { this.isRecycleList = true; this.ds = value; if (this.rememberScrollTop) { - this.currentScrollTop = this.tableElement!.scrollTop; this.tableElement!.scrollTop = 0; this.tableElement!.scrollLeft = 0; } else { @@ -464,22 +225,7 @@ export class LitTable extends HTMLElement { } exportData(): void { - if (this.exportLoading || this.ds.length === 0) { - return; - } - this.exportLoading = true; - this.exportProgress!.loading = true; - let date = new Date(); - JSONToCSV.csvExport({ - columns: this.columns as any[], - tables: this.ds, - fileName: `${date.getTime()}`, - columnFormatter: this.itemTextHandleMap, - exportFormatter: this.exportTextHandleMap, - }).then((res) => { - this.exportLoading = false; - this.exportProgress!.loading = false; - }); + exportData(this); } exportExcelData(): void { @@ -497,29 +243,7 @@ export class LitTable extends HTMLElement { } formatExportData(dataSource: any[]): any[] { - if (dataSource === undefined || dataSource.length === 0) { - return []; - } - if (this.columns === undefined) { - return []; - } - return dataSource.map((item) => { - let formatData: any = {}; - this.columns!.forEach((column) => { - let dataIndex = column.getAttribute('data-index'); - let columnName = column.getAttribute('title'); - if (columnName === '') { - columnName = dataIndex; - } - if (dataIndex && columnName && item[dataIndex] != undefined) { - formatData[columnName] = item[dataIndex]; - } - }); - if (item.children !== undefined) { - formatData.children = this.formatExportData(item.children); - } - return formatData; - }); + return formatExportData(dataSource, this); } formatExportCsvData(dataSource: any[]): string { @@ -538,29 +262,10 @@ export class LitTable extends HTMLElement { } return columnName; }).join(','); - str += this.recursionExportTableData(this.columns, dataSource); + str += recursionExportTableData(this.columns, dataSource); return str; } - recursionExportTableData(columns: any[], dataSource: any[]): string { - let concatStr = '\r\n'; - dataSource.forEach((item, index) => { - concatStr += columns - .map((column) => { - let dataIndex = column.getAttribute('data-index'); - return `"${item[dataIndex] || ''}" `; - }) - .join(','); - if (item.children !== undefined) { - concatStr += this.recursionExportTableData(columns, item.children); - } - if (index !== dataSource.length - 1) { - concatStr += '\r\n'; - } - }); - return concatStr; - } - injectColumns(): void { this.columns = this.st!.assignedElements(); this.columns.forEach((column) => { @@ -601,246 +306,17 @@ export class LitTable extends HTMLElement { this.tableColumns = this.querySelectorAll('lit-table-column'); this.colCount = this.tableColumns!.length; this.dataExportInit(); - this.tableElement?.addEventListener('copy', (e) => { - // @ts-ignore - let clipboardData = e.clipboardData || window.clipboardData; - if (!clipboardData) return; - // @ts-ignore - let text = window.getSelection().toString(); - if (text) { - e.preventDefault(); - let length = this.tableColumns?.length || 1; - let strings = text.split('\n'); - let formatStr = ''; - for (let i = 0; i < strings.length; i++) { - if (i % length != 0) { - formatStr += ' '; - } - formatStr += strings[i]; - if (i !== 0 && i % length === length - 1) { - formatStr += '\n'; - } - } - clipboardData.setData('text/plain', formatStr); - } - }); + addCopyEventListener(this); this.st?.addEventListener('slotchange', () => { this.theadElement!.innerHTML = ''; setTimeout(() => { this.columns = this.st!.assignedElements(); let rowElement = document.createElement('div'); rowElement.classList.add('th'); - if (this.selectable) { - let box = document.createElement('div'); - box.style.display = 'flex'; - box.style.justifyContent = 'center'; - box.style.alignItems = 'center'; - box.style.gridArea = '_checkbox_'; - box.classList.add('td'); - box.style.backgroundColor = '#ffffff66'; - let checkbox = document.createElement('lit-checkbox'); - checkbox.classList.add('row-checkbox-all'); - checkbox.onchange = (e: any) => { - this.shadowRoot!.querySelectorAll('.row-checkbox').forEach((a: any) => (a.checked = e.detail.checked)); - if (e.detail.checked) { - this.shadowRoot!.querySelectorAll('.tr').forEach((a) => a.setAttribute('checked', '')); - } else { - this.shadowRoot!.querySelectorAll('.tr').forEach((a) => a.removeAttribute('checked')); - } - }; - box.appendChild(checkbox); - rowElement.appendChild(box); - } + addSelectAllBox(rowElement, this); let area: Array = []; this.gridTemplateColumns = []; - let resolvingArea = (columns: any, x: any, y: any) => { - columns.forEach((a: any, i: any) => { - if (!area[y]) area[y] = []; - let key = a.getAttribute('key') || a.getAttribute('title'); - if (a.tagName === 'LIT-TABLE-GROUP') { - let len = a.querySelectorAll('lit-table-column').length; - let children = [...a.children].filter((a) => a.tagName !== 'TEMPLATE'); - if (children.length > 0) { - resolvingArea(children, x, y + 1); - } - for (let j = 0; j < len; j++) { - area[y][x] = { x, y, t: key }; - x++; - } - let h = document.createElement('div'); - h.classList.add('td'); - h.style.justifyContent = a.getAttribute('align'); - h.style.borderBottom = '1px solid #f0f0f0'; - h.style.gridArea = key; - h.innerText = a.title; - if (a.hasAttribute('fixed')) { - this.fixed(h, a.getAttribute('fixed'), '#42b983'); - } - rowElement.append(h); - } else if (a.tagName === 'LIT-TABLE-COLUMN') { - area[y][x] = { x, y, t: key }; - x++; - let h: any = document.createElement('div'); - h.classList.add('td'); - if ((this.hasAttribute('tree') && i > 1) || (!this.hasAttribute('tree') && i > 0)) { - let resizeDiv: HTMLDivElement = document.createElement('div'); - resizeDiv.classList.add('resize'); - h.appendChild(resizeDiv); - this.resizeEventHandler(rowElement, resizeDiv, i); - } - if (a.hasAttribute('retract')) { - let expand = document.createElement('div'); - expand.classList.add('expand'); - expand.style.display = 'grid'; - h.append(expand); - let top = document.createElement('lit-icon') as LitIcon; - top.classList.add('top'); - top.name = 'up'; - expand.append(top); - let bottom = document.createElement('lit-icon') as LitIcon; - bottom.classList.add('bottom'); - bottom.name = 'down'; - expand.append(bottom); - - expand.addEventListener('click', (e) => { - if (top.name == 'up' && bottom.name == 'down') { - top.name = 'down'; - bottom.name = 'up'; - // 一键展开 - this.setStatus(this.value, true); - this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Expand); - } else { - top.name = 'up'; - bottom.name = 'down'; - // 一键收起 - this.setStatus(this.value, false); - this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Retract); - } - e.stopPropagation(); - }); - } - if (a.hasAttribute('order')) { - h.sortType = 0; - h.classList.add('td-order'); - h.style.position = 'relative'; - let NS = 'http://www.w3.org/2000/svg'; - let upSvg: any = document.createElementNS(NS, 'svg'); - let upPath: any = document.createElementNS(NS, 'path'); - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.setAttribute('viewBox', '0 0 1024 1024'); - upSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); - upSvg.classList.add('up-svg'); - upPath.setAttribute( - 'd', - 'M858.9 689L530.5 308.2c-9.4-10.9-27.5-10.9-37 0L165.1 689c-12.2 14.2-1.2 35 18.5 35h656.8c19.7 0 30.7-20.8 18.5-35z' - ); - upSvg.appendChild(upPath); - let downSvg: any = document.createElementNS(NS, 'svg'); - let downPath: any = document.createElementNS(NS, 'path'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('viewBox', '0 0 1024 1024'); - downSvg.setAttribute('stroke', 'let(--dark-color1,#212121)'); - downSvg.classList.add('down-svg'); - downPath.setAttribute( - 'd', - 'M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z' - ); - downSvg.appendChild(downPath); - if (i == 0) { - h.sortType = 0; // 默认以第一列 降序排序 作为默认排序 - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - } - upSvg.style.display = 'none'; - downSvg.style.display = 'none'; - h.appendChild(upSvg); - h.appendChild(downSvg); - h.onclick = () => { - if (this.isResize || this.resizeColumnIndex !== -1) { - return; - } - this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: any) => { - it.setAttribute('fill', 'let(--dark-color1,#212121)'); - it.sortType = 0; - it.style.display = 'none'; - }); - if (h.sortType == undefined || h.sortType == null) { - h.sortType = 0; - } else if (h.sortType === 2) { - h.sortType = 0; - } else { - h.sortType += 1; - } - switch (h.sortType) { - case 1: - this.theadElement!.setAttribute('sort', ''); - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'block'; - downSvg.style.display = 'none'; - break; - case 2: - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'none'; - downSvg.style.display = 'block'; - break; - default: - upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); - upSvg.style.display = 'none'; - downSvg.style.display = 'none'; - this.theadElement!.removeAttribute('sort'); - break; - } - this.dispatchEvent( - new CustomEvent('column-click', { - detail: { - sort: h.sortType, - key: key, - }, - composed: true, - }) - ); - }; - } - if (a.hasAttribute('button')) { - let buttonIcon = document.createElement('button'); - buttonIcon.innerHTML = 'GetBusyTime(ms)'; - buttonIcon.classList.add('button-icon'); - h.appendChild(buttonIcon); - buttonIcon.addEventListener('click', (event) => { - this.dispatchEvent( - new CustomEvent('button-click', { - detail: { - key: key, - }, - composed: true, - }) - ); - event.stopPropagation(); - }); - } - h.style.justifyContent = a.getAttribute('align'); - this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); - h.style.gridArea = key; - - let labelArr = a.title.split('/'); - for (let i = 0; i < labelArr.length; i++) { - let titleLabel = document.createElement('label'); - titleLabel.style.cursor = 'pointer'; - i == 0 ? (titleLabel.textContent = labelArr[i]) : (titleLabel.textContent = '/' + labelArr[i]); - h.appendChild(titleLabel); - } - - if (a.hasAttribute('fixed')) { - this.fixed(h, a.getAttribute('fixed'), '#42b983'); - } - rowElement.append(h); - } - }); - }; - resolvingArea(this.columns, 0, 0); + this.resolvingArea(this.columns, 0, 0, area, rowElement); area.forEach((rows, j, array) => { for (let i = 0; i < this.colCount; i++) { if (!rows[i]) rows[i] = array[j - 1][i]; @@ -862,11 +338,173 @@ export class LitTable extends HTMLElement { this.treeElement!.style.top = this.theadElement?.clientHeight + 'px'; }); }); - this.shadowRoot!.addEventListener('load', function (event) {}); this.tableElement!.addEventListener('mouseout', (ev) => this.mouseOut()); } + resolvingArea(columns: any, x: any, y: any, area: Array, rowElement: HTMLDivElement) { + columns.forEach((a: any, i: any) => { + if (!area[y]) area[y] = []; + let key = a.getAttribute('key') || a.getAttribute('title'); + if (a.tagName === 'LIT-TABLE-GROUP') { + let len = a.querySelectorAll('lit-table-column').length; + let children = [...a.children].filter((a) => a.tagName !== 'TEMPLATE'); + if (children.length > 0) { + this.resolvingArea(children, x, y + 1, area, rowElement); + } + for (let j = 0; j < len; j++) { + area[y][x] = { x, y, t: key }; + x++; + } + let h = document.createElement('div'); + h.classList.add('td'); + h.style.justifyContent = a.getAttribute('align'); + h.style.borderBottom = '1px solid #f0f0f0'; + h.style.gridArea = key; + h.innerText = a.title; + if (a.hasAttribute('fixed')) { + fixed(h, a.getAttribute('fixed'), '#42b983'); + } + rowElement.append(h); + } else if (a.tagName === 'LIT-TABLE-COLUMN') { + area[y][x] = { x, y, t: key }; + x++; + let head = this.resolvingAreaColumn(rowElement, a, i, key); + this.gridTemplateColumns.push(a.getAttribute('width') || '1fr'); + let labelArr = a.title.split('/'); + for (let i = 0; i < labelArr.length; i++) { + let titleLabel = document.createElement('label'); + titleLabel.style.cursor = 'pointer'; + i == 0 ? (titleLabel.textContent = labelArr[i]) : (titleLabel.textContent = '/' + labelArr[i]); + head.appendChild(titleLabel); + } + if (a.hasAttribute('fixed')) { + fixed(head, a.getAttribute('fixed'), '#42b983'); + } + rowElement.append(head); + } + }); + }; + + resolvingAreaColumn(rowElement: HTMLDivElement, column: any, index: number, key: string): HTMLDivElement { + let head: any = document.createElement('div'); + head.classList.add('td'); + if ((this.hasAttribute('tree') && index > 1) || (!this.hasAttribute('tree') && index > 0)) { + let resizeDiv: HTMLDivElement = document.createElement('div'); + resizeDiv.classList.add('resize'); + head.appendChild(resizeDiv); + this.resizeEventHandler(rowElement, resizeDiv, index); + } + this.resolvingAreaColumnRetract(column, head); + this.resolvingAreaColumnOrder(column, index, key, head); + this.resolvingAreaColumnButton(column, key, head); + head.style.justifyContent = column.getAttribute('align'); + head.style.gridArea = key; + return head; + } + + resolvingAreaColumnRetract(column: any, columnHead: HTMLDivElement): void { + if (column.hasAttribute('retract')) { + let expand = document.createElement('div'); + expand.classList.add('expand'); + expand.style.display = 'grid'; + columnHead.append(expand); + let top = document.createElement('lit-icon') as LitIcon; + top.classList.add('top'); + top.name = 'up'; + expand.append(top); + let bottom = document.createElement('lit-icon') as LitIcon; + bottom.classList.add('bottom'); + bottom.name = 'down'; + expand.append(bottom); + expand.addEventListener('click', (e) => { + if (top.name == 'up' && bottom.name == 'down') { + top.name = 'down'; + bottom.name = 'up'; + // 一键展开 + this.setStatus(this.value, true); + this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Expand); + } else { + top.name = 'up'; + bottom.name = 'down'; + // 一键收起 + this.setStatus(this.value, false); + this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Retract); + } + e.stopPropagation(); + }); + } + } + + resolvingAreaColumnButton(column: any, key: string, head: HTMLDivElement) { + if (column.hasAttribute('button')) { + let buttonIcon = document.createElement('button'); + buttonIcon.innerHTML = 'GetBusyTime(ms)'; + buttonIcon.classList.add('button-icon'); + head.appendChild(buttonIcon); + buttonIcon.addEventListener('click', (event) => { + this.dispatchEvent( + new CustomEvent('button-click', { + detail: { + key: key, + }, + composed: true, + }) + ); + event.stopPropagation(); + }); + } + } + + resolvingAreaColumnOrder(column: any, index: number, key: string,columnHead: any): void { + if (column.hasAttribute('order')) { + (columnHead as any).sortType = 0; + columnHead.classList.add('td-order'); + columnHead.style.position = 'relative'; + let { upSvg, downSvg } = createDownUpSvg(index, columnHead); + columnHead.onclick = () => { + if (this.isResize || this.resizeColumnIndex !== -1) { + return; + } + this?.shadowRoot?.querySelectorAll('.td-order svg').forEach((it: any) => { + it.setAttribute('fill', 'let(--dark-color1,#212121)'); + it.sortType = 0; + it.style.display = 'none'; + }); + if (columnHead.sortType == undefined || columnHead.sortType == null) { + columnHead.sortType = 0; + } else if (columnHead.sortType === 2) { + columnHead.sortType = 0; + } else { + columnHead.sortType += 1; + } + upSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + downSvg.setAttribute('fill', 'let(--dark-color1,#212121)'); + upSvg.style.display = columnHead.sortType === 1 ? 'block' : 'none'; + downSvg.style.display = columnHead.sortType === 2 ? 'block' : 'none'; + switch (columnHead.sortType) { + case 1: + this.theadElement!.setAttribute('sort', ''); + break; + case 2: + break; + default: + this.theadElement!.removeAttribute('sort'); + break; + } + this.dispatchEvent( + new CustomEvent('column-click', { + detail: { + sort: columnHead.sortType, + key: key, + }, + composed: true, + }) + ); + }; + } + } + private isResize: boolean = false; private resizeColumnIndex: number = -1; private resizeDownX: number = 0; @@ -874,33 +512,7 @@ export class LitTable extends HTMLElement { private beforeResizeWidth: number = 0; resizeEventHandler(header: HTMLDivElement, element: HTMLDivElement, index: number): void { - header.addEventListener('mousemove', (event) => { - if (!this.columnResizeEnable) return; - if (this.isResize) { - let width = event.clientX - this.resizeDownX; - header.style.cursor = 'col-resize'; - let preWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth); - for (let i = 0; i < header.childNodes.length; i++) { - let node = header.childNodes.item(i) as HTMLDivElement; - this.gridTemplateColumns[i] = `${node.clientWidth}px`; - } - this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${preWidth}px`; - header.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); - let preNode = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; - preNode.style.width = `${preWidth}px`; - this.shadowRoot!.querySelectorAll('.tr').forEach((tr) => { - if (this.hasAttribute('tree')) { - tr.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' '); - } else { - tr.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); - } - }); - event.preventDefault(); - event.stopPropagation(); - } else { - header.style.cursor = 'pointer'; - } - }); + this.resizeMouseMoveEventHandler(header); header.addEventListener('mouseup', (event) => { if (!this.columnResizeEnable) return; this.isResize = false; @@ -937,26 +549,38 @@ export class LitTable extends HTMLElement { }); } - // Is called when the custom element is removed from the document DOM. - disconnectedCallback(): void {} + resizeMouseMoveEventHandler(header: HTMLDivElement) { + header.addEventListener('mousemove', (event) => { + if (!this.columnResizeEnable) return; + if (this.isResize) { + let width = event.clientX - this.resizeDownX; + header.style.cursor = 'col-resize'; + let preWidth = Math.max(this.beforeResizeWidth + width, this.columnMinWidth); + for (let i = 0; i < header.childNodes.length; i++) { + let node = header.childNodes.item(i) as HTMLDivElement; + this.gridTemplateColumns[i] = `${node.clientWidth}px`; + } + this.gridTemplateColumns[this.resizeColumnIndex - 1] = `${preWidth}px`; + header.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); + let preNode = header.childNodes.item(this.resizeColumnIndex - 1) as HTMLDivElement; + preNode.style.width = `${preWidth}px`; + this.shadowRoot!.querySelectorAll('.tr').forEach((tr) => { + if (this.hasAttribute('tree')) { + tr.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' '); + } else { + tr.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); + } + }); + event.preventDefault(); + event.stopPropagation(); + } else { + header.style.cursor = 'pointer'; + } + }); + } - // It is called when the custom element is moved to a new document. adoptedCallback(): void {} - // It is called when a custom element adds, deletes, or modifies its own properties. - attributeChangedCallback(name: string, oldValue: string, newValue: string): void {} - - fixed(td: HTMLElement, placement: string, bgColor: string): void { - td.style.position = 'sticky'; - if (placement === 'left') { - td.style.left = '0px'; - td.style.boxShadow = '3px 0px 5px #33333333'; - } else if (placement === 'right') { - td.style.right = '0px'; - td.style.boxShadow = '-3px 0px 5px #33333333'; - } - } - getCheckRows(): any[] { // @ts-ignore return [...this.shadowRoot!.querySelectorAll('div[class=tr][checked]')] @@ -984,12 +608,7 @@ export class LitTable extends HTMLElement { return 27; } - meauseAllRowHeight(list: any[]): TableRowObject[] { - this.tbodyElement!.innerHTML = ''; - this.meauseRowElement = undefined; - let head = this.shadowRoot!.querySelector('.th'); - this.tbodyElement && (this.tbodyElement.style.width = head?.clientWidth + 'px'); - this.currentRecycleList = []; + getVisibleObjects(list: any[]) { let headHeight = 0; let totalHeight = headHeight; let visibleObjects: TableRowObject[] = []; @@ -1004,10 +623,7 @@ export class LitTable extends HTMLElement { Math.max(totalHeight, this.tableElement!.scrollTop + headHeight) <= Math.min(totalHeight + height, this.tableElement!.scrollTop + this.tableElement!.clientHeight + headHeight) ) { - let newTableElement = this.createNewTableElement(tableRowObject); - newTableElement.style.transform = `translateY(${totalHeight}px)`; - this.tbodyElement?.append(newTableElement); - this.currentRecycleList.push(newTableElement); + let newTableElement = this.addTableElement(tableRowObject, false,false, true, totalHeight); let td = newTableElement?.querySelectorAll('.td'); if (tableRowObject.data.rowName === 'cpu-profiler') { td[0].innerHTML = ''; @@ -1028,6 +644,16 @@ export class LitTable extends HTMLElement { itemHandler(item, index); } }); + return { visibleObjects, totalHeight }; + } + + meauseAllRowHeight(list: any[]): TableRowObject[] { + this.tbodyElement!.innerHTML = ''; + this.meauseRowElement = undefined; + let head = this.shadowRoot!.querySelector('.th'); + this.tbodyElement && (this.tbodyElement.style.width = head?.clientWidth + 'px'); + this.currentRecycleList = []; + let { visibleObjects, totalHeight } = this.getVisibleObjects(list); this.tbodyElement && (this.tbodyElement.style.height = totalHeight + (this.isScrollXOutSide ? 0 : 0) + 'px'); this.tableElement && (this.tableElement.onscroll = (event) => { @@ -1047,23 +673,25 @@ export class LitTable extends HTMLElement { return; } while (reduce <= this.tableElement!.clientHeight) { - let newTableElement = this.createNewTableElement(visibleObjects[skip]); - this.tbodyElement?.append(newTableElement); - this.currentRecycleList.push(newTableElement); + let newTableElement = this.addTableElement(visibleObjects[skip], false,false, false); reduce += newTableElement.clientHeight; } for (let i = 0; i < this.currentRecycleList.length; i++) { - this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip]); - if (visibleObjects[i + skip]) { - if (visibleObjects[i + skip].data.rowName === 'cpu-profiler') { - this.createTextColor(visibleObjects[i + skip], this.currentRecycleList[i].childNodes[0]); - } - } + this.freshLineHandler(i, skip, visibleObjects); } }); return visibleObjects; } + freshLineHandler(index: number, skip: number, visibleObjects: TableRowObject[]){ + this.freshCurrentLine(this.currentRecycleList[index], visibleObjects[index + skip]); + if (visibleObjects[index + skip]) { + if (visibleObjects[index + skip].data.rowName === 'cpu-profiler') { + this.createTextColor(visibleObjects[index + skip], this.currentRecycleList[index].childNodes[0]); + } + } + } + newTableRowObject(item: any, totalHeight: number, depth: number, parentNode?: TableRowObject): TableRowObject { let tableRowObject = new TableRowObject(); tableRowObject.depth = depth; @@ -1076,74 +704,90 @@ export class LitTable extends HTMLElement { return tableRowObject; } - meauseTreeRowElement(list: any[], form?: RedrawTreeForm): TableRowObject[] { + resetAllHeight( + list: any[], + depth: number, + totalHeight: number, + visibleObjects: TableRowObject[], + parentNode?: TableRowObject, + form?: RedrawTreeForm + ) { + let headHeight = this.theadElement?.clientHeight || 0; + list.forEach((item) => { + let tableRowObject = this.newTableRowObject(item, totalHeight, depth, parentNode); + if (this._mode === TableMode.Expand && form === RedrawTreeForm.Retract && !item.status) { + tableRowObject.expanded = false; + } else if (this._mode === TableMode.Expand && form === RedrawTreeForm.Default) { + tableRowObject.expanded = true; + } + if ( + (this._mode === TableMode.Retract && !item.status) || + (this._mode === TableMode.Expand && !item.status && form !== RedrawTreeForm.Expand) + ) { + tableRowObject.expanded = false; + if (item.children != undefined && item.children.length > 0) { + this.newTableRowObject(item, totalHeight, depth, tableRowObject); + } + } + if ( + Math.max(totalHeight, this.tableElement!.scrollTop) <= + Math.min( + totalHeight + tableRowObject.height, + this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight + ) + ) { + this.addTableElement(tableRowObject,true, false, true, totalHeight); + } + totalHeight += tableRowObject.height; + visibleObjects.push(tableRowObject); + this.resetAllHeightChildrenHandler(item, depth, totalHeight, visibleObjects, tableRowObject, form); + }); + } + + resetAllHeightChildrenHandler( + item: any, + depth: number, + totalHeight: number, + visibleObjects: TableRowObject[], + tableRowObject?: TableRowObject, + form?: RedrawTreeForm + ) { + if (item.hasNext) { + // js memory的表格 + if (item.parents != undefined && item.parents.length > 0 && item.status) { + this.resetAllHeight(item.parents, depth + 1, totalHeight, visibleObjects, tableRowObject); + } else if (item.children != undefined && item.children.length > 0 && item.status) { + this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject); + } + } else { + // 其他数据 + if ( + item.children != undefined && + item.children.length > 0 && + form === RedrawTreeForm.Expand && + this._mode === TableMode.Expand + ) { + item.status = true; + this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject); + } else if (item.children != undefined && item.children.length > 0 && item.status) { + this.resetAllHeight(item.children, depth + 1, totalHeight, visibleObjects, tableRowObject); + } + } + } + + measureReset(): void { this.meauseRowElement = undefined; this.tbodyElement!.innerHTML = ''; this.treeElement!.innerHTML = ''; - let headHeight = this.theadElement?.clientHeight || 0; - let totalHeight = 0; - let visibleObjects: TableRowObject[] = []; this.currentRecycleList = []; this.currentTreeDivList = []; - let resetAllHeight = (list: any[], depth: number, parentNode?: TableRowObject) => { - list.forEach((item) => { - let tableRowObject = this.newTableRowObject(item, totalHeight, depth, parentNode); - if (this._mode === TableMode.Expand && form === RedrawTreeForm.Retract && !item.status) { - tableRowObject.expanded = false; - } else if (this._mode === TableMode.Expand && form === RedrawTreeForm.Default) { - tableRowObject.expanded = true; - } + } - if ( - (this._mode === TableMode.Retract && !item.status) || - (this._mode === TableMode.Expand && !item.status && form !== RedrawTreeForm.Expand) - ) { - tableRowObject.expanded = false; - if (item.children != undefined && item.children.length > 0) { - this.newTableRowObject(item, totalHeight, depth, tableRowObject); - } - } - if ( - Math.max(totalHeight, this.tableElement!.scrollTop) <= - Math.min( - totalHeight + tableRowObject.height, - this.tableElement!.scrollTop + this.tableElement!.clientHeight - headHeight - ) - ) { - let newTableElement = this.createNewTreeTableElement(tableRowObject); - newTableElement.style.transform = `translateY(${totalHeight}px)`; - this.tbodyElement?.append(newTableElement); - if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = tableRowObject.height + 'px'; - } - this.currentRecycleList.push(newTableElement); - } - totalHeight += tableRowObject.height; - visibleObjects.push(tableRowObject); - if (item.hasNext) { - // js memory的表格 - if (item.parents != undefined && item.parents.length > 0 && item.status) { - resetAllHeight(item.parents, depth + 1, tableRowObject); - } else if (item.children != undefined && item.children.length > 0 && item.status) { - resetAllHeight(item.children, depth + 1, tableRowObject); - } - } else { - // 其他数据 - if ( - item.children != undefined && - item.children.length > 0 && - form === RedrawTreeForm.Expand && - this._mode === TableMode.Expand - ) { - item.status = true; - resetAllHeight(item.children, depth + 1, tableRowObject); - } else if (item.children != undefined && item.children.length > 0 && item.status) { - resetAllHeight(item.children, depth + 1, tableRowObject); - } - } - }); - }; - resetAllHeight(list, 0); + meauseTreeRowElement(list: any[], form?: RedrawTreeForm): TableRowObject[] { + this.measureReset(); + let visibleObjects: TableRowObject[] = []; + let totalHeight = 0; + this.resetAllHeight(list,0, totalHeight, visibleObjects); this.tbodyElement && (this.tbodyElement.style.height = totalHeight + 'px'); this.treeElement!.style.height = this.tableElement!.clientHeight - this.theadElement!.clientHeight + 'px'; this.tableElement && @@ -1166,24 +810,14 @@ export class LitTable extends HTMLElement { this.tableElement!.scrollTop >= this.value.length * visibleObjects[0].height && this.currentRecycleList.length === 0 ) { - let newTableElement = this.createNewTreeTableElement(visibleObjects[skip]); - this.tbodyElement?.append(newTableElement); - if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + 'px'; - } - this.currentRecycleList.push(newTableElement); + this.addTableElement(visibleObjects[skip], true, false, false); } let reduce = this.currentRecycleList.map((item) => item.clientHeight).reduce((a, b) => a + b, 0); if (reduce == 0) { return; } while (reduce <= this.tableElement!.clientHeight) { - let newTableElement = this.createNewTreeTableElement(visibleObjects[skip]); - this.tbodyElement?.append(newTableElement); - if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + 'px'; - } - this.currentRecycleList.push(newTableElement); + let newTableElement = this.addTableElement(visibleObjects[skip], true, false, false); reduce += newTableElement.clientHeight; } for (let i = 0; i < this.currentRecycleList.length; i++) { @@ -1196,160 +830,72 @@ export class LitTable extends HTMLElement { }); return visibleObjects; } - - createNewTreeTableElement(rowData: TableRowObject): any { - let newTableElement = document.createElement('div'); - newTableElement.classList.add('tr'); - let treeTop = 0; - if (this.treeElement!.children?.length > 0) { - let transX = Number((this.treeElement?.lastChild as HTMLElement).style.transform.replace(/[^0-9]/gi, '')); - treeTop += transX + rowData.height; - } - this?.columns?.forEach((column: any, index) => { - let dataIndex = column.getAttribute('data-index') || '1'; - let td: any; - if (index === 0) { - let text = this.formatName(dataIndex, rowData.data[dataIndex]); - if (column.template) { - td = column.template.render(rowData.data).content.cloneNode(true); - td.template = column.template; - td.title = rowData.data[dataIndex]; - } else { - td = document.createElement('div'); - if (rowData.data.rowName === 'js-memory' || rowData.data.rowName === 'cpu-profiler') { - td.innerHTML = ''; - } else { - td.innerHTML = text; - } - td.dataIndex = dataIndex; - if (text.indexOf('<') === -1) { - td.title = text; - } - } - if (rowData.data.children && rowData.data.children.length > 0 && !rowData.data.hasNext) { - let btn = this.createExpandBtn(rowData); - td.insertBefore(btn, td.firstChild); - } - if (rowData.data.hasNext) { - td.title = rowData.data.objectName; - let btn = this.createBtn(rowData); - td.insertBefore(btn, td.firstChild); - } - td.style.paddingLeft = rowData.depth * iconWidth + 'px'; - if (!rowData.data.children || rowData.data.children.length === 0) { - td.style.paddingLeft = iconWidth * rowData.depth + iconWidth + iconPadding * 2 + 'px'; - } - if (rowData.data.rowName === 'js-memory') { - let nodeText = document.createElement('text'); - nodeText.classList.add('nodeName'); - nodeText.textContent = rowData.data.nodeName; - td.append(nodeText); - let countText = document.createElement('text'); - countText.classList.add('countName'); - countText.textContent = rowData.data.count; - td.append(countText); - let nodeIdText = document.createElement('text'); - nodeIdText.classList.add('nodeIdText'); - nodeIdText.textContent = rowData.data.nodeId; - td.append(nodeIdText); - if (rowData.data.edgeName != '') { - let edgeNameText = document.createElement('text'); - edgeNameText.classList.add('edgeNameText'); - edgeNameText.textContent = rowData.data.edgeName; - td.insertBefore(edgeNameText, nodeText); - let span = document.createElement('span'); - span.classList.add('span'); - if (rowData.data.type === ConstructorType.RetainersType) { - span.textContent = '\xa0' + 'in' + '\xa0'; - nodeIdText.textContent = ` @${rowData.data.id}`; - } else { - span.textContent = '\xa0' + '::' + '\xa0'; - } - edgeNameText.append(span); - } - if ( - (rowData.data.nodeType == NodeType.STRING || - rowData.data.nodeType == NodeType.CONCATENATED_STRING || - rowData.data.nodeType == NodeType.SLICED_STRING) && - rowData.data.type != ConstructorType.ClassType - ) { - nodeText.style.color = '#d53d3d'; - nodeText.textContent = '"' + rowData.data.nodeName + '"'; - } - td.title = rowData.data.objectName; - } - if (rowData.data.rowName === 'cpu-profiler') { - this.createTextColor(rowData, td); - } - (td as any).data = rowData.data; - td.classList.add('tree-first-body'); - td.style.position = 'absolute'; - td.style.top = '0px'; - td.style.left = '0px'; - td.onmouseenter = () => { - let indexOf = this.currentTreeDivList.indexOf(td); - this.currentRecycleList.forEach((row) => { - row.classList.remove('mouse-in'); - }); - if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML != '') { - this.setMouseIn(true, [newTableElement]); - } - }; - td.onmouseleave = () => { - let indexOf = this.currentTreeDivList.indexOf(td); - if (indexOf >= 0 && indexOf < this.currentRecycleList.length) { - this.setMouseIn(false, [newTableElement]); - } - }; - td.onmouseup = (e: MouseEvent) => { - let indexOf = this.currentTreeDivList.indexOf(td); - this.dispatchRowClickEvent(rowData, [td, newTableElement], e); - }; - this.setHighLight(rowData.data.isSearch, td); - this.treeElement!.style.width = column.getAttribute('width'); - this.treeElement?.append(td); - this.currentTreeDivList.push(td); - } else { - td = document.createElement('div'); - td.classList.add('td'); - td.style.overflow = 'hidden'; - td.style.textOverflow = 'ellipsis'; - td.style.whiteSpace = 'nowrap'; - let text = this.formatName(dataIndex, rowData.data[dataIndex]); - if (text.indexOf('<') === -1) { - if (dataIndex === 'selfTimeStr' && rowData.data.chartFrameChildren) { - td.title = rowData.data.selfTime + 'ns'; - } else if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) { - td.title = rowData.data.totalTime + 'ns'; - } else { - td.title = text; - } - } - td.dataIndex = dataIndex; - td.style.justifyContent = column.getAttribute('align') || 'flex-start'; - if (column.template) { - td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); - td.template = column.template; - } else { - td.innerHTML = text; + + private addTableElement( + rowData: TableRowObject, + isTree: boolean, + last: boolean, + translate: boolean, + totalHeight?: number + ) { + let newTableElement; + if (isTree) { + newTableElement = this.createNewTreeTableElement(rowData); + } else { + newTableElement = this.createNewTableElement(rowData); + } + if (translate) { + newTableElement.style.transform = `translateY(${totalHeight}px)`; + } + this.tbodyElement?.append(newTableElement); + if (last) { + if (this.hasAttribute('tree')) { + if (this.treeElement?.lastChild) { + (this.treeElement?.lastChild as HTMLElement).style.height = rowData.height + 'px'; } - newTableElement.append(td); + } + } + this.currentRecycleList.push(newTableElement); + return newTableElement; + } + + createNewTreeTableElement(rowData: TableRowObject): any { + let rowTreeElement = document.createElement('div'); + rowTreeElement.classList.add('tr'); + let treeTop = 0; + if (this.treeElement!.children?.length > 0) { + let transX = Number((this.treeElement?.lastChild as HTMLElement).style.transform.replace(/[^0-9]/gi, '')); + treeTop += transX + rowData.height; + } + this?.columns?.forEach((column: any, index) => { + let dataIndex = column.getAttribute('data-index') || '1'; + let td: any; + if (index === 0) { + td = this.firstElementTdHandler(rowTreeElement, dataIndex, rowData, column); + } else { + td = this.otherElementHandler(dataIndex, rowData, column); + rowTreeElement.append(td); } }); let lastChild = this.treeElement?.lastChild as HTMLElement; if (lastChild) { lastChild.style.transform = `translateY(${treeTop}px)`; } - (newTableElement as any).data = rowData.data; - newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' '); - newTableElement.style.position = 'absolute'; - newTableElement.style.top = '0px'; - newTableElement.style.left = '0px'; - newTableElement.style.cursor = 'pointer'; - this.setHighLight(rowData.data.isSearch, newTableElement); - newTableElement.onmouseenter = () => { - if ((newTableElement as any).data.isSelected) return; - let indexOf = this.currentRecycleList.indexOf(newTableElement); + (rowTreeElement as any).data = rowData.data; + rowTreeElement.style.gridTemplateColumns = this.gridTemplateColumns.slice(1).join(' '); + rowTreeElement.style.position = 'absolute'; + rowTreeElement.style.top = '0px'; + rowTreeElement.style.left = '0px'; + rowTreeElement.style.cursor = 'pointer'; + this.setHighLight(rowData.data.isSearch, rowTreeElement); + this.addRowElementEvent(rowTreeElement, rowData); + return rowTreeElement; + } + + addRowElementEvent(rowTreeElement: HTMLDivElement, rowData: any): void { + rowTreeElement.onmouseenter = () => { + if ((rowTreeElement as any).data.isSelected) return; + let indexOf = this.currentRecycleList.indexOf(rowTreeElement); this.currentTreeDivList.forEach((row) => { row.classList.remove('mouse-in'); }); @@ -1357,20 +903,195 @@ export class LitTable extends HTMLElement { this.setMouseIn(true, [this.treeElement?.children[indexOf] as HTMLElement]); } }; - newTableElement.onmouseleave = () => { - if ((newTableElement as any).data.isSelected) return; - let indexOf = this.currentRecycleList.indexOf(newTableElement); + rowTreeElement.onmouseleave = () => { + if ((rowTreeElement as any).data.isSelected) return; + let indexOf = this.currentRecycleList.indexOf(rowTreeElement); if (indexOf >= 0 && indexOf < this.treeElement!.children.length) { this.setMouseIn(false, [this.treeElement?.children[indexOf] as HTMLElement]); } }; + rowTreeElement.onmouseup = (e: MouseEvent) => { + let indexOf = this.currentRecycleList.indexOf(rowTreeElement); + this.dispatchRowClickEvent(rowData, [this.treeElement?.children[indexOf] as HTMLElement, rowTreeElement], e); + }; + } + + firstElementTdHandler(tr: HTMLDivElement, dataIndex: string, row: any, column: any) { + let td: any; + let text = formatName(dataIndex, row.data[dataIndex], this); + if (column.template) { + td = column.template.render(row.data).content.cloneNode(true); + td.template = column.template; + td.title = row.data[dataIndex]; + } else { + td = document.createElement('div'); + if (row.data.rowName === 'js-memory' || row.data.rowName === 'cpu-profiler') { + td.innerHTML = ''; + } else { + td.innerHTML = text; + } + td.dataIndex = dataIndex; + if (text.indexOf('<') === -1) { + td.title = text; + } + } + if (row.data.children && row.data.children.length > 0 && !row.data.hasNext) { + let btn = this.createExpandBtn(row); + td.insertBefore(btn, td.firstChild); + } + if (row.data.hasNext) { + td.title = row.data.objectName; + let btn = this.createBtn(row); + td.insertBefore(btn, td.firstChild); + } + td.style.paddingLeft = row.depth * iconWidth + 'px'; + if (!row.data.children || row.data.children.length === 0) { + td.style.paddingLeft = iconWidth * row.depth + iconWidth + iconPadding * 2 + 'px'; + } + this.jsMemoryHandler(row, td); + if (row.data.rowName === 'cpu-profiler') { + this.createTextColor(row, td); + } + (td as any).data = row.data; + td.classList.add('tree-first-body'); + td.style.position = 'absolute'; + td.style.top = '0px'; + td.style.left = '0px'; + this.addFirstElementEvent(td, tr, row); + this.setHighLight(row.data.isSearch, td); + this.treeElement!.style.width = column.getAttribute('width'); + this.treeElement?.append(td); + this.currentTreeDivList.push(td); + return td; + } + + addFirstElementEvent(td: HTMLDivElement, tr: HTMLDivElement, rowData: any): void { + td.onmouseenter = () => { + let indexOf = this.currentTreeDivList.indexOf(td); + this.currentRecycleList.forEach((row) => { + row.classList.remove('mouse-in'); + }); + if (indexOf >= 0 && indexOf < this.currentRecycleList.length && td.innerHTML != '') { + this.setMouseIn(true, [tr]); + } + }; + td.onmouseleave = () => { + let indexOf = this.currentTreeDivList.indexOf(td); + if (indexOf >= 0 && indexOf < this.currentRecycleList.length) { + this.setMouseIn(false, [tr]); + } + }; + td.onmouseup = (e: MouseEvent) => { + let indexOf = this.currentTreeDivList.indexOf(td); + this.dispatchRowClickEvent(rowData, [td, tr], e); + }; + } + + otherElementHandler(dataIndex: string, rowData: any, column: any) { + let tdDiv: any = document.createElement('div'); + tdDiv.classList.add('td'); + tdDiv.style.overflow = 'hidden'; + tdDiv.style.textOverflow = 'ellipsis'; + tdDiv.style.whiteSpace = 'nowrap'; + let text = formatName(dataIndex, rowData.data[dataIndex], this); + if (text.indexOf('<') === -1) { + if (dataIndex === 'selfTimeStr' && rowData.data.chartFrameChildren) { + tdDiv.title = rowData.data.selfTime + 'ns'; + } else if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) { + tdDiv.title = rowData.data.totalTime + 'ns'; + } else { + tdDiv.title = text; + } + } + tdDiv.dataIndex = dataIndex; + tdDiv.style.justifyContent = column.getAttribute('align') || 'flex-start'; + if (column.template) { + tdDiv.appendChild(column.template.render(rowData.data).content.cloneNode(true)); + tdDiv.template = column.template; + } else { + tdDiv.innerHTML = text; + } + return tdDiv; + } + + createNewTableElement(rowData: any): any { + let newTableElement = document.createElement('div'); + newTableElement.classList.add('tr'); + this?.columns?.forEach((column: any) => { + let dataIndex = column.getAttribute('data-index') || '1'; + let td = this.createColumnTd(dataIndex, column, rowData); + newTableElement.append(td); + }); newTableElement.onmouseup = (e: MouseEvent) => { - let indexOf = this.currentRecycleList.indexOf(newTableElement); - this.dispatchRowClickEvent(rowData, [this.treeElement?.children[indexOf] as HTMLElement, newTableElement], e); + this.dispatchRowClickEvent(rowData, [newTableElement], e); }; + newTableElement.onmouseenter = () => { + this.dispatchRowHoverEvent(rowData, [newTableElement]); + }; + if (rowData.data.isSelected != undefined) { + this.setSelectedRow(rowData.data.isSelected, [newTableElement]); + } + (newTableElement as any).data = rowData.data; + newTableElement.style.cursor = 'pointer'; + newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); + newTableElement.style.position = 'absolute'; + newTableElement.style.top = '0px'; + newTableElement.style.left = '0px'; + if (this.getItemTextColor) { + newTableElement.style.color = this.getItemTextColor(rowData.data); + } return newTableElement; } + createColumnTd(dataIndex: string, column: any, rowData: any): any { + let td: any; + td = document.createElement('div'); + td.classList.add('td'); + td.style.overflow = 'hidden'; + td.style.textOverflow = 'ellipsis'; + td.style.whiteSpace = 'nowrap'; + td.dataIndex = dataIndex; + td.style.justifyContent = column.getAttribute('align') || 'flex-start'; + let text = formatName(dataIndex, rowData.data[dataIndex], this); + if (text.indexOf('<') === -1) { + if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) { + td.title = rowData.data.totalTime + 'ns'; + } else { + td.title = text; + } + } + // 如果表格中有模板的情况,将模板中的数据放进td中,没有模板,直接将文本放进td + // 但是对于Current Selection tab页来说,表格前两列是时间,第三列是input标签,第四列是button标签 + // 而第一行的数据只有第四列一个button,和模板中的数据并不一样,所以要特别处理一下 + if (column.template) { + if (dataIndex === 'color' && rowData.data.colorEl === undefined) { + td.innerHTML = ''; + td.template = ''; + } else if (dataIndex === 'operate' && rowData.data.operate && rowData.data.operate.innerHTML === 'RemoveAll') { + let removeAll = document.createElement('button'); + removeAll.className = 'removeAll'; + removeAll.innerHTML = 'RemoveAll'; + removeAll.style.background = 'var(--dark-border1,#262f3c)'; + removeAll.style.color = 'white'; + removeAll.style.borderRadius = '10px'; + removeAll.style.fontSize = '10px'; + removeAll.style.height = '18px'; + removeAll.style.lineHeight = '18px'; + removeAll.style.minWidth = '7em'; + removeAll.style.border = 'none'; + removeAll.style.cursor = 'pointer'; + removeAll.style.outline = 'inherit'; + td.appendChild(removeAll); + } else { + td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); + td.template = column.template; + } + } else { + td.innerHTML = text; + } + return td; + } + createBtn(rowData: any): any { let btn: any = document.createElement('lit-icon'); btn.classList.add('tree-icon'); @@ -1412,6 +1133,34 @@ export class LitTable extends HTMLElement { return btn; } + resetExpandNodeHidden = (hidden: boolean, rowData: any) => { + if (rowData.children.length > 0) { + if (hidden) { + rowData.children.forEach((child: any) => { + child.rowHidden = true; + this.resetExpandNodeHidden(hidden, child); + }); + } else { + rowData.children.forEach((child: any) => { + child.rowHidden = !rowData.expanded; + if (rowData.expanded) { + this.resetExpandNodeHidden(hidden, child); + } + }); + } + } + }; + + setChildrenStatus(rowData:any, data: any) { + for (let d of data) { + if (rowData.data === d) { + d.status = false; + } + if (d.children != undefined && d.children.length > 0) { + this.setChildrenStatus(rowData, d.children); + } + } + } createExpandBtn(rowData: any): any { let btn: any = document.createElement('lit-icon'); btn.classList.add('tree-icon'); @@ -1423,57 +1172,28 @@ export class LitTable extends HTMLElement { } btn.onmouseup = (e: MouseEvent) => { if (e.button === 0) { - const resetNodeHidden = (hidden: boolean, rowData: any) => { - if (rowData.children.length > 0) { - if (hidden) { - rowData.children.forEach((child: any) => { - child.rowHidden = true; - resetNodeHidden(hidden, child); - }); - } else { - rowData.children.forEach((child: any) => { - child.rowHidden = !rowData.expanded; - if (rowData.expanded) { - resetNodeHidden(hidden, child); - } - }); - } - } - }; - if (rowData.expanded && this._mode === TableMode.Retract) { rowData.data.status = false; rowData.expanded = false; - resetNodeHidden(true, rowData); + this.resetExpandNodeHidden(true, rowData); } else if (!rowData.expanded && this._mode === TableMode.Retract) { rowData.expanded = true; rowData.data.status = true; this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Retract); - resetNodeHidden(false, rowData); + this.resetExpandNodeHidden(false, rowData); } - if (this._mode === TableMode.Expand && rowData.expanded) { // 点击收起的时候将点击的那条数据的status改为false - setChildrenStatus(this.value); - function setChildrenStatus(data: any) { - for (let d of data) { - if (rowData.data === d) { - d.status = false; - } - if (d.children != undefined && d.children.length > 0) { - setChildrenStatus(d.children); - } - } - } + this.setChildrenStatus(rowData, this.value); rowData.expanded = false; - resetNodeHidden(true, rowData); + this.resetExpandNodeHidden(true, rowData); } else if (this._mode === TableMode.Expand && !rowData.expanded) { if (rowData.data.children) { rowData.data.status = true; } this.recycleDs = this.meauseTreeRowElement(this.value, RedrawTreeForm.Default); rowData.expanded = true; - resetNodeHidden(false, rowData); + this.resetExpandNodeHidden(false, rowData); } this.reMeauseHeight(); } @@ -1511,19 +1231,8 @@ export class LitTable extends HTMLElement { return; } while (reduce <= this.tableElement!.clientHeight + 1) { - let newTableElement; - if (this.hasAttribute('tree')) { - newTableElement = this.createNewTreeTableElement(visibleObjects[skip]); - } else { - newTableElement = this.createNewTableElement(visibleObjects[skip]); - } - this.tbodyElement?.append(newTableElement); - if (this.hasAttribute('tree')) { - if (this.treeElement?.lastChild) { - (this.treeElement?.lastChild as HTMLElement).style.height = visibleObjects[skip].height + 'px'; - } - } - this.currentRecycleList.push(newTableElement); + let isTree = this.hasAttribute('tree'); + let newTableElement = this.addTableElement(visibleObjects[skip], isTree, isTree, false); reduce += newTableElement.clientHeight; } for (let i = 0; i < this.currentRecycleList.length; i++) { @@ -1534,87 +1243,9 @@ export class LitTable extends HTMLElement { this.treeElement?.children[i] as HTMLElement ); } else { - this.freshCurrentLine(this.currentRecycleList[i], visibleObjects[i + skip]); - if (visibleObjects[i + skip]) { - if (visibleObjects[i + skip].data.rowName === 'cpu-profiler') { - this.createTextColor(visibleObjects[i + skip], this.currentRecycleList[i].childNodes[0]); - } - } - } - } - } - - createNewTableElement(rowData: any): any { - let newTableElement = document.createElement('div'); - newTableElement.classList.add('tr'); - this?.columns?.forEach((column: any) => { - let dataIndex = column.getAttribute('data-index') || '1'; - let td: any; - td = document.createElement('div'); - td.classList.add('td'); - td.style.overflow = 'hidden'; - td.style.textOverflow = 'ellipsis'; - td.style.whiteSpace = 'nowrap'; - td.dataIndex = dataIndex; - td.style.justifyContent = column.getAttribute('align') || 'flex-start'; - let text = this.formatName(dataIndex, rowData.data[dataIndex]); - if (text.indexOf('<') === -1) { - if (dataIndex === 'totalTimeStr' && rowData.data.chartFrameChildren) { - td.title = rowData.data.totalTime + 'ns'; - } else { - td.title = text; - } - } - // 如果表格中有模板的情况,将模板中的数据放进td中,没有模板,直接将文本放进td - // 但是对于Current Selection tab页来说,表格前两列是时间,第三列是input标签,第四列是button标签 - // 而第一行的数据只有第四列一个button,和模板中的数据并不一样,所以要特别处理一下 - if (column.template) { - if (dataIndex === 'color' && rowData.data.colorEl === undefined) { - td.innerHTML = ''; - td.template = ''; - } else if (dataIndex === 'operate' && rowData.data.operate && rowData.data.operate.innerHTML === 'RemoveAll') { - let removeAll = document.createElement('button'); - removeAll.className = 'removeAll'; - removeAll.innerHTML = 'RemoveAll'; - removeAll.style.background = 'var(--dark-border1,#262f3c)'; - removeAll.style.color = 'white'; - removeAll.style.borderRadius = '10px'; - removeAll.style.fontSize = '10px'; - removeAll.style.height = '18px'; - removeAll.style.lineHeight = '18px'; - removeAll.style.minWidth = '7em'; - removeAll.style.border = 'none'; - removeAll.style.cursor = 'pointer'; - removeAll.style.outline = 'inherit'; - td.appendChild(removeAll); - } else { - td.appendChild(column.template.render(rowData.data).content.cloneNode(true)); - td.template = column.template; - } - } else { - td.innerHTML = text; + this.freshLineHandler(i, skip, visibleObjects); } - newTableElement.append(td); - }); - newTableElement.onmouseup = (e: MouseEvent) => { - this.dispatchRowClickEvent(rowData, [newTableElement], e); - }; - newTableElement.onmouseenter = () => { - this.dispatchRowHoverEvent(rowData, [newTableElement]); - }; - if (rowData.data.isSelected != undefined) { - this.setSelectedRow(rowData.data.isSelected, [newTableElement]); } - (newTableElement as any).data = rowData.data; - newTableElement.style.cursor = 'pointer'; - newTableElement.style.gridTemplateColumns = this.gridTemplateColumns.join(' '); - newTableElement.style.position = 'absolute'; - newTableElement.style.top = '0px'; - newTableElement.style.left = '0px'; - if (this.getItemTextColor) { - newTableElement.style.color = this.getItemTextColor(rowData.data); - } - return newTableElement; } getWheelStatus(element: any): void { @@ -1642,61 +1273,14 @@ export class LitTable extends HTMLElement { tblRowElement.data = rowData; let gridTemplateColumns: Array = []; // If the table is configured with selectable (select row mode) add a checkbox at the head of the line alone - if (this.selectable) { - let tblBox = document.createElement('div'); - tblBox.style.display = 'flex'; - tblBox.style.justifyContent = 'center'; - tblBox.style.alignItems = 'center'; - tblBox.classList.add('td'); - let checkbox = document.createElement('lit-checkbox'); - checkbox.classList.add('row-checkbox'); - checkbox.onchange = (e: any) => { - // Checkbox checking affects whether the div corresponding to the row has a checked attribute for marking - if (e.detail.checked) { - tblRowElement.setAttribute('checked', ''); - } else { - tblRowElement.removeAttribute('checked'); - } - }; - this.getWheelStatus(tblBox); - tblBox.appendChild(checkbox); - tblRowElement.appendChild(tblBox); - } + this.renderTableRowSelect(tblRowElement); this.tableColumns!.forEach((tblColumn) => { tblColumn.addEventListener('contextmenu', (e) => { e.preventDefault(); }); let dataIndex = tblColumn.getAttribute('data-index') || '1'; gridTemplateColumns.push(tblColumn.getAttribute('width') || '1fr'); - if (tblColumn.template) { - // If you customize the rendering, you get the nodes from the template - // @ts-ignore - let cloneNode = tblColumn.template.render(rowData).content.cloneNode(true); - let tblCustomDiv = document.createElement('div'); - tblCustomDiv.classList.add('td'); - tblCustomDiv.style.wordBreak = 'break-all'; - tblCustomDiv.style.whiteSpace = 'pre-wrap'; - tblCustomDiv.style.justifyContent = tblColumn.getAttribute('align') || ''; - if (tblColumn.hasAttribute('fixed')) { - this.fixed(tblCustomDiv, tblColumn.getAttribute('fixed') || '', '#ffffff'); - } - this.getWheelStatus(tblCustomDiv); - tblCustomDiv.append(cloneNode); - tblRowElement.append(tblCustomDiv); - } else { - let tblDiv = document.createElement('div'); - tblDiv.classList.add('td'); - tblDiv.style.wordBreak = 'break-all'; - tblDiv.style.whiteSpace = 'pre-wrap'; - tblDiv.title = rowData[dataIndex]; - tblDiv.style.justifyContent = tblColumn.getAttribute('align') || ''; - if (tblColumn.hasAttribute('fixed')) { - this.fixed(tblDiv, tblColumn.getAttribute('fixed') || '', '#ffffff'); - } - this.getWheelStatus(tblDiv); - tblDiv.innerHTML = this.formatName(dataIndex, rowData[dataIndex]); - tblRowElement.append(tblDiv); - } + this.renderTableRowColumnElement(tblColumn, tblRowElement, dataIndex, rowData); }); if (this.selectable) { // If the table with selection is preceded by a 60px column @@ -1704,29 +1288,88 @@ export class LitTable extends HTMLElement { } else { tblRowElement.style.gridTemplateColumns = gridTemplateColumns.join(' '); } - tblRowElement.onmouseup = (e: MouseEvent) => { - this.dispatchEvent( - new CustomEvent('row-click', { - detail: { - rowData, - data: rowData, - callBack: (isSelected: boolean) => { - //是否爲单选 - if (isSelected) { - this.clearAllSelection(rowData); - } - this.setSelectedRow(rowData.isSelected, [tblRowElement]); - }, - }, - composed: true, - }) - ); - }; + this.renderTableRowElementEvent(tblRowElement, rowData); this.normalDs.push(tblRowElement); this.tbodyElement!.append(tblRowElement); }); } + renderTableRowSelect(tblRowElement: HTMLDivElement): void { + if (this.selectable) { + let tblBox = document.createElement('div'); + tblBox.style.display = 'flex'; + tblBox.style.justifyContent = 'center'; + tblBox.style.alignItems = 'center'; + tblBox.classList.add('td'); + let checkbox = document.createElement('lit-checkbox'); + checkbox.classList.add('row-checkbox'); + checkbox.onchange = (e: any) => { + // Checkbox checking affects whether the div corresponding to the row has a checked attribute for marking + if (e.detail.checked) { + tblRowElement.setAttribute('checked', ''); + } else { + tblRowElement.removeAttribute('checked'); + } + }; + this.getWheelStatus(tblBox); + tblBox.appendChild(checkbox); + tblRowElement.appendChild(tblBox); + } + } + + renderTableRowColumnElement(tblColumn: LitTableColumn, tblRowElement: HTMLDivElement, dataIndex: string, rowData: any): void { + if (tblColumn.template) { + // If you customize the rendering, you get the nodes from the template + // @ts-ignore + let cloneNode = tblColumn.template.render(rowData).content.cloneNode(true); + let tblCustomDiv = document.createElement('div'); + tblCustomDiv.classList.add('td'); + tblCustomDiv.style.wordBreak = 'break-all'; + tblCustomDiv.style.whiteSpace = 'pre-wrap'; + tblCustomDiv.style.justifyContent = tblColumn.getAttribute('align') || ''; + if (tblColumn.hasAttribute('fixed')) { + fixed(tblCustomDiv, tblColumn.getAttribute('fixed') || '', '#ffffff'); + } + this.getWheelStatus(tblCustomDiv); + tblCustomDiv.append(cloneNode); + tblRowElement.append(tblCustomDiv); + } else { + let tblDiv = document.createElement('div'); + tblDiv.classList.add('td'); + tblDiv.style.wordBreak = 'break-all'; + tblDiv.style.whiteSpace = 'pre-wrap'; + tblDiv.title = rowData[dataIndex]; + tblDiv.style.justifyContent = tblColumn.getAttribute('align') || ''; + if (tblColumn.hasAttribute('fixed')) { + fixed(tblDiv, tblColumn.getAttribute('fixed') || '', '#ffffff'); + } + this.getWheelStatus(tblDiv); + tblDiv.innerHTML = formatName(dataIndex, rowData[dataIndex], this); + tblRowElement.append(tblDiv); + } + } + + renderTableRowElementEvent(tblRowElement: HTMLDivElement, rowData: any): void { + tblRowElement.onmouseup = (e: MouseEvent) => { + this.dispatchEvent( + new CustomEvent('row-click', { + detail: { + rowData, + data: rowData, + callBack: (isSelected: boolean) => { + //是否爲单选 + if (isSelected) { + this.clearAllSelection(rowData); + } + this.setSelectedRow(rowData.isSelected, [tblRowElement]); + }, + }, + composed: true, + }) + ); + }; + } + freshCurrentLine(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement): void { if (!rowObject) { if (firstElement) { @@ -1741,92 +1384,10 @@ export class LitTable extends HTMLElement { if (child.nodeType != 1) return; childIndex++; let idx = firstElement !== undefined ? childIndex + 1 : childIndex; - if (firstElement !== undefined && childIndex === 0) { - this.setHighLight(rowObject.data.isSearch, firstElement); - (firstElement as any).data = rowObject.data; - if ((this.columns![0] as any).template) { - firstElement.innerHTML = (this.columns![0] as any).template - .render(rowObject.data) - .content.cloneNode(true).innerHTML; - } else { - let dataIndex = this.columns![0].getAttribute('data-index') || '1'; - let text = this.formatName(dataIndex, rowObject.data[dataIndex]); - if (rowObject.data.rowName === 'js-memory' || rowObject.data.rowName === 'cpu-profiler') { - firstElement.innerHTML = ''; - } else { - firstElement.innerHTML = text; - } - firstElement.title = text; - } - if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) { - let btn = this.createExpandBtn(rowObject); - firstElement.insertBefore(btn, firstElement.firstChild); - } - firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; - if (!rowObject.children || rowObject.children.length === 0) { - firstElement.style.paddingLeft = iconWidth * rowObject.depth + iconWidth + iconPadding * 2 + 'px'; - } - if (rowObject.data.hasNext) { - let btn = this.createBtn(rowObject); - firstElement.title = rowObject.data.objectName; - firstElement.insertBefore(btn, firstElement.firstChild); - firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; - } - if (rowObject.data.rowName === 'js-memory') { - let nodeText = document.createElement('text'); - nodeText.classList.add('nodeName'); - nodeText.textContent = rowObject.data.nodeName; - firstElement.append(nodeText); - let countText = document.createElement('text'); - countText.classList.add('countName'); - countText.textContent = rowObject.data.count; - firstElement.append(countText); - let nodeIdText = document.createElement('text'); - nodeIdText.classList.add('nodeIdText'); - nodeIdText.textContent = rowObject.data.nodeId; - firstElement.append(nodeIdText); - if (rowObject.data.edgeName != '') { - let edgeNameText = document.createElement('text'); - edgeNameText.classList.add('edgeNameText'); - edgeNameText.textContent = rowObject.data.edgeName; - firstElement.insertBefore(edgeNameText, nodeText); - let span = document.createElement('span'); - span.classList.add('span'); - if (rowObject.data.type === ConstructorType.RetainersType) { - span.textContent = '\xa0' + 'in' + '\xa0'; - nodeIdText.textContent = ` @${rowObject.data.id}`; - } else { - span.textContent = '\xa0' + '::' + '\xa0'; - } - edgeNameText.append(span); - } - if ( - (rowObject.data.nodeType === NodeType.STRING || - rowObject.data.nodeType === NodeType.CONCATENATED_STRING || - rowObject.data.nodeType === NodeType.SLICED_STRING) && - rowObject.data.type != ConstructorType.ClassType - ) { - nodeText.style.color = '#d53d3d'; - nodeText.textContent = '"' + rowObject.data.nodeName + '"'; - } - firstElement.title = rowObject.data.objectName; - } - if (rowObject.data.rowName === 'cpu-profiler') { - this.createTextColor(rowObject, firstElement); - } - firstElement.onmouseup = (e: MouseEvent) => { - this.dispatchRowClickEvent(rowObject, [firstElement, element], e); - }; - firstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; - if (rowObject.data.isSelected !== undefined) { - this.setSelectedRow(rowObject.data.isSelected, [firstElement]); - } else { - this.setSelectedRow(false, [firstElement]); - } - } + this.freshLineFirstElementHandler(firstElement, rowObject, childIndex); if (idx < this.columns!.length) { let dataIndex = this.columns![idx].getAttribute('data-index') || '1'; - let text = this.formatName(dataIndex, rowObject.data[dataIndex]); + let text = formatName(dataIndex, rowObject.data[dataIndex], this); if ((this.columns![idx] as any).template) { (child as HTMLElement).innerHTML = ''; (child as HTMLElement).appendChild( @@ -1847,6 +1408,10 @@ export class LitTable extends HTMLElement { } } }); + this.freshLineStyleAndEvents(element, rowObject, firstElement); + } + + freshLineStyleAndEvents(element: HTMLElement, rowObject: TableRowObject, firstElement?: HTMLElement): void { if (element.style.display === 'none') { element.style.display = 'grid'; } @@ -1880,6 +1445,54 @@ export class LitTable extends HTMLElement { } } + freshLineFirstElementHandler(firstElement: any, rowObject: TableRowObject, childIndex: number): void { + if (firstElement !== undefined && childIndex === 0) { + this.setHighLight(rowObject.data.isSearch, firstElement); + (firstElement as any).data = rowObject.data; + if ((this.columns![0] as any).template) { + firstElement.innerHTML = (this.columns![0] as any).template + .render(rowObject.data) + .content.cloneNode(true).innerHTML; + } else { + let dataIndex = this.columns![0].getAttribute('data-index') || '1'; + let text = formatName(dataIndex, rowObject.data[dataIndex], this); + if (rowObject.data.rowName === 'js-memory' || rowObject.data.rowName === 'cpu-profiler') { + firstElement.innerHTML = ''; + } else { + firstElement.innerHTML = text; + } + firstElement.title = text; + } + if (rowObject.children && rowObject.children.length > 0 && !rowObject.data.hasNext) { + let btn = this.createExpandBtn(rowObject); + firstElement.insertBefore(btn, firstElement.firstChild); + } + firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; + if (!rowObject.children || rowObject.children.length === 0) { + firstElement.style.paddingLeft = iconWidth * rowObject.depth + iconWidth + iconPadding * 2 + 'px'; + } + if (rowObject.data.hasNext) { + let btn = this.createBtn(rowObject); + firstElement.title = rowObject.data.objectName; + firstElement.insertBefore(btn, firstElement.firstChild); + firstElement.style.paddingLeft = iconWidth * rowObject.depth + 'px'; + } + this.jsMemoryHandler(rowObject, firstElement); + if (rowObject.data.rowName === 'cpu-profiler') { + this.createTextColor(rowObject, firstElement); + } + firstElement.onmouseup = (e: MouseEvent) => { + this.dispatchRowClickEvent(rowObject, [firstElement, element], e); + }; + firstElement.style.transform = `translateY(${rowObject.top - this.tableElement!.scrollTop}px)`; + if (rowObject.data.isSelected !== undefined) { + this.setSelectedRow(rowObject.data.isSelected, [firstElement]); + } else { + this.setSelectedRow(false, [firstElement]); + } + } + } + setSelectedRow(isSelected: boolean, rows: any[]): void { if (isSelected) { rows.forEach((row) => { @@ -2107,17 +1720,6 @@ export class LitTable extends HTMLElement { ); } - formatName(key: string, name: any): any { - let content = name; - if (this.itemTextHandleMap.has(key)) { - content = this.itemTextHandleMap.get(key)?.(name) || ''; - } - if (content !== undefined && content !== null) { - return content.toString().replace(//g, '>'); - } - return ''; - } - setHighLight(isSearch: boolean, element: any): void { if (isSearch) { element.setAttribute('high-light', ''); @@ -2140,6 +1742,48 @@ export class LitTable extends HTMLElement { } divElement.title = rowData.data.symbolName; } + + jsMemoryHandler(rowData: any, td: any) { + if (rowData.data.rowName === 'js-memory') { + let nodeText = document.createElement('text'); + nodeText.classList.add('nodeName'); + nodeText.textContent = rowData.data.nodeName; + td.append(nodeText); + let countText = document.createElement('text'); + countText.classList.add('countName'); + countText.textContent = rowData.data.count; + td.append(countText); + let nodeIdText = document.createElement('text'); + nodeIdText.classList.add('nodeIdText'); + nodeIdText.textContent = rowData.data.nodeId; + td.append(nodeIdText); + if (rowData.data.edgeName != '') { + let edgeNameText = document.createElement('text'); + edgeNameText.classList.add('edgeNameText'); + edgeNameText.textContent = rowData.data.edgeName; + td.insertBefore(edgeNameText, nodeText); + let span = document.createElement('span'); + span.classList.add('span'); + if (rowData.data.type === ConstructorType.RetainersType) { + span.textContent = '\xa0' + 'in' + '\xa0'; + nodeIdText.textContent = ` @${rowData.data.id}`; + } else { + span.textContent = '\xa0' + '::' + '\xa0'; + } + edgeNameText.append(span); + } + if ( + (rowData.data.nodeType === NodeType.STRING || + rowData.data.nodeType === NodeType.CONCATENATED_STRING || + rowData.data.nodeType === NodeType.SLICED_STRING) && + rowData.data.type !== ConstructorType.ClassType + ) { + nodeText.style.color = '#d53d3d'; + nodeText.textContent = '"' + rowData.data.nodeName + '"'; + } + td.title = rowData.data.objectName; + } + } } // 表格默认是展开还是收起的 diff --git a/ide/src/base-ui/tabs/lit-tabs.html.ts b/ide/src/base-ui/tabs/lit-tabs.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..dc81b65c8c74421eb1559db27ce1c4ad6f32faf8 --- /dev/null +++ b/ide/src/base-ui/tabs/lit-tabs.html.ts @@ -0,0 +1,412 @@ +/* + * 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. + */ + +export const LitTabsHtml = ` + + +
+ +
+ NEED CONTENT +
+
+ `; \ No newline at end of file diff --git a/ide/src/base-ui/tabs/lit-tabs.ts b/ide/src/base-ui/tabs/lit-tabs.ts index 1187d8bc7242b6a7f8f1b7b11c954536fb57b104..022f725cbfc1be4142694ce091956fe564be4da3 100644 --- a/ide/src/base-ui/tabs/lit-tabs.ts +++ b/ide/src/base-ui/tabs/lit-tabs.ts @@ -16,6 +16,7 @@ import { element } from '../BaseElement'; import { LitTabpane } from './lit-tabpane'; import { SpStatisticsHttpUtil } from '../../statistics/util/SpStatisticsHttpUtil'; +import {LitTabsHtml} from "./lit-tabs.html"; @element('lit-tabs') export class LitTabs extends HTMLElement { @@ -27,403 +28,7 @@ export class LitTabs extends HTMLElement { constructor() { super(); const shadowRoot = this.attachShadow({ mode: 'open' }); - shadowRoot.innerHTML = ` - - -
- -
- NEED CONTENT -
-
- `; + shadowRoot.innerHTML = LitTabsHtml; } static get observedAttributes() { @@ -583,54 +188,7 @@ export class LitTabs extends HTMLElement { } }); } - let navHtml = ''; - elements - ?.map((it) => it as LitTabpane) - .forEach((a) => { - if (a.disabled) { - navHtml += ``; - } else if (a.hidden) { - navHtml += ``; - } else { - if (a.key === this.activekey) { - navHtml += ``; - } else { - navHtml += ``; - } - } - }); - this.nav!.innerHTML = navHtml; - this.initTabPos(); - this.nav!.querySelectorAll('.close-icon').forEach((a) => { - a.onclick = (e) => { - e.stopPropagation(); - const closeKey = (e.target! as HTMLElement).parentElement!.dataset.key; - this.dispatchEvent( - new CustomEvent('close-handler', { - detail: { key: closeKey }, - composed: true, - }) - ); - }; - }); + this.setItemNode(elements); }); this.nav!.onclick = (e) => { if ((e.target! as HTMLElement).closest('div')!.hasAttribute('data-disabled')) return; @@ -653,6 +211,57 @@ export class LitTabs extends HTMLElement { }).observe(this.shadowRoot!.querySelector('#tab-filling')!); } + setItemNode(elements: Element[] | undefined ):void{ + let navHtml:string = ''; + elements + ?.map((it) => it as LitTabpane) + .forEach((a) => { + if (a.disabled) { + navHtml += ``; + } else if (a.hidden) { + navHtml += ``; + } else { + if (a.key === this.activekey) { + navHtml += ``; + } else { + navHtml += ``; + } + } + }); + this.nav!.innerHTML = navHtml; + this.initTabPos(); + this.nav!.querySelectorAll('.close-icon').forEach((a) => { + a.onclick = (e) => { + e.stopPropagation(); + const closeKey = (e.target! as HTMLElement).parentElement!.dataset.key; + this.dispatchEvent( + new CustomEvent('close-handler', { + detail: { key: closeKey }, + composed: true, + }) + ); + }; + }); + } + activeByKey(key: string, isValid: boolean = true) { if (key === null || key === undefined) return; //如果没有key 不做相应 this.nav!.querySelectorAll('.nav-item').forEach((a) => { @@ -661,49 +270,7 @@ export class LitTabs extends HTMLElement { } if (a.getAttribute('data-key') === key) { a.setAttribute('data-selected', 'true'); - if (isValid) { - let span = a.querySelector('span') as HTMLSpanElement; - let title = span.innerText; - let rowType = document - .querySelector('sp-application')! - .shadowRoot?.querySelector('sp-system-trace')! - .getAttribute('clickRow'); - if (title === 'Counters' || title === 'Thread States') { - title += `(${rowType})`; - } - if (title === 'Analysis') { - let rowId = document - .querySelector('sp-application')! - .shadowRoot?.querySelector('sp-system-trace')! - .getAttribute('rowId'); - if (rowId!.indexOf('DiskIOLatency') > -1) { - title += '(disk-io)'; - } else if (rowId!.indexOf('VirtualMemory') > -1) { - title += '(virtual-memory-cell)'; - } else { - title += `(${rowType})`; - } - } - if (title === 'Slices' || title === 'Current Selection') { - let rowName = document - .querySelector('sp-application')! - .shadowRoot?.querySelector('sp-system-trace')! - .getAttribute('rowName'); - if (rowName && rowName!.indexOf('deliverInputEvent') > -1) { - title += '(deliverInputEvent)'; - } else { - let rowType = document - .querySelector('sp-application')! - .shadowRoot?.querySelector('sp-system-trace')! - .getAttribute('clickRow'); - title += `(${rowType})`; - } - } - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: title, - action: 'trace_tab', - }); - } + this.byKeyIsValid(isValid,a) } else { a.removeAttribute('data-selected'); } @@ -721,6 +288,52 @@ export class LitTabs extends HTMLElement { }); } + byKeyIsValid(isValid:boolean,a:Element):void{ + if (isValid) { + let span = a.querySelector('span') as HTMLSpanElement; + let title = span.innerText; + let rowType = document + .querySelector('sp-application')! + .shadowRoot?.querySelector('sp-system-trace')! + .getAttribute('clickRow'); + if (title === 'Counters' || title === 'Thread States') { + title += `(${rowType})`; + } + if (title === 'Analysis') { + let rowId = document + .querySelector('sp-application')! + .shadowRoot?.querySelector('sp-system-trace')! + .getAttribute('rowId'); + if (rowId!.indexOf('DiskIOLatency') > -1) { + title += '(disk-io)'; + } else if (rowId!.indexOf('VirtualMemory') > -1) { + title += '(virtual-memory-cell)'; + } else { + title += `(${rowType})`; + } + } + if (title === 'Slices' || title === 'Current Selection') { + let rowName = document + .querySelector('sp-application')! + .shadowRoot?.querySelector('sp-system-trace')! + .getAttribute('rowName'); + if (rowName && rowName!.indexOf('deliverInputEvent') > -1) { + title += '(deliverInputEvent)'; + } else { + let rowType = document + .querySelector('sp-application')! + .shadowRoot?.querySelector('sp-system-trace')! + .getAttribute('clickRow'); + title += `(${rowType})`; + } + } + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: title, + action: 'trace_tab', + }); + } + } + activePane(key: string) { if (key === null || key === undefined) return false; let tbp = this.querySelector(`lit-tabpane[key='${key}']`); diff --git a/ide/src/base-ui/tree/LitTree.ts b/ide/src/base-ui/tree/LitTree.ts index a5f9e04955bfcd0070bf1e6fa2ca19fe25fa4097..f3d5876498ddd3d823040d8024046112265a27d6 100644 --- a/ide/src/base-ui/tree/LitTree.ts +++ b/ide/src/base-ui/tree/LitTree.ts @@ -17,7 +17,7 @@ import './LitTreeNode'; import { BaseElement, element } from '../BaseElement'; import { type LitTreeNode } from './LitTreeNode'; -export interface TreeItemData { +export interface TreeItemData { key: string; title: string; icon?: string; //节点的自定义图标 设置show-icon才会生效 @@ -95,6 +95,10 @@ export class LitTree extends BaseElement { this.proxyData = new Proxy(this._treeData, handler); } + get multiple(): boolean { + return this.hasAttribute('multiple'); + } + set multiple(value: boolean) { if (value) { this.setAttribute('multiple', ''); @@ -103,10 +107,6 @@ export class LitTree extends BaseElement { } } - get multiple(): boolean { - return this.hasAttribute('multiple'); - } - get treeData(): TreeItemData[] { return this.proxyData; } @@ -177,98 +177,22 @@ export class LitTree extends BaseElement { } drawTree(parent: any, array: Array, topDepth: boolean = false): void { - let that = this; - array.forEach((a) => { - let li = document.createElement('li'); + array.forEach((a:TreeItemData) => { + let li: HTMLLIElement = document.createElement('li'); let node: LitTreeNode = document.createElement('lit-tree-node') as LitTreeNode; node.title = a.title; node.setAttribute('key', a.key); node.topDepth = topDepth; - if (this.hasAttribute('dragable')) { - node.draggable = true; - document.ondragover = function (e) { - e.preventDefault(); - }; - //在拖动目标上触发事件 (源元素) - node.ondrag = (ev) => this.onDrag(ev); //元素正在拖动时触发 - node.ondragstart = (ev) => this.onDragStart(ev); //用户开始拖动元素时触发 - node.ondragend = (ev) => this.onDragEnd(ev); // 用户完成元素拖动后触发 - //释放目标时触发的事件: - node.ondragenter = (ev) => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 - node.ondragover = (ev) => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 - node.ondragleave = (ev) => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 - node.ondrop = (ev) => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 - } - node.selected = a.selected || false; //是否选中行 - node.checked = a.checked || false; // 是否勾选 - node.data = a; - node.addEventListener('change', (e: any): void => { - if (e.detail && !this.multiple) { - this.nodeList.forEach((item) => { - item.checked = item.data!.key === node.data!.key; - item.data!.checked = item.checked; - }); - } - var litTreeNodes = this.nodeList.filter((it) => it.checked); - if (litTreeNodes.length === 0) { - node.checked = true; - node.data!.checked = true; - } - that.dispatchEvent(new CustomEvent('onChange', { detail: { data: (node as any).data, checked: e.detail } })); - }); - node.multiple = this.hasAttribute('multiple'); - node.checkable = this.getAttribute('checkable') || 'false'; - this.nodeList.push(node); + this.treeNodeDragable(node,a); // @ts-ignore li.data = a; li.append(node); parent.append(li); - let ul = document.createElement('ul'); + let ul: HTMLUListElement = document.createElement('ul'); // @ts-ignore ul.open = 'true'; ul.style.transition = '.3s all'; - if (a.children && a.children.length > 0) { - if (this.hasAttribute('show-icon')) { - if (a.icon) { - (node as any).iconName = a.icon; - } else { - (node as any).iconName = 'folder'; - } - } else { - node.iconName = ''; - } - node.arrow = true; - li.append(ul); - this.drawTree(ul, a.children); - } else { - if (this.hasAttribute('show-icon')) { - if (a.icon) { - node.iconName = a.icon; - } else { - node.iconName = 'file'; - } - } else { - node.iconName = ''; - } - node.arrow = false; - } - li.onclick = (e): void => { - e.stopPropagation(); - if (this.hasAttribute('foldable')) { - // @ts-ignore - if (li.data.children && li.data.children.length > 0) { - node.autoExpand(); - } else { - // @ts-ignore - this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); - this.selectedNode(node); - } - } else { - // @ts-ignore - this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); - this.selectedNode(node); - } - }; + this.addEvent(a,node,li,ul); // node 添加右键菜单功能 node.oncontextmenu = (ev): void => { ev.preventDefault(); @@ -288,6 +212,90 @@ export class LitTree extends BaseElement { }; } + treeNodeDragable(node: LitTreeNode,a:TreeItemData):void{ + let that = this; + if (this.hasAttribute('dragable')) { + node.draggable = true; + document.ondragover = function (e) { + e.preventDefault(); + }; + //在拖动目标上触发事件 (源元素) + node.ondrag = (ev) => this.onDrag(ev); //元素正在拖动时触发 + node.ondragstart = (ev) => this.onDragStart(ev); //用户开始拖动元素时触发 + node.ondragend = (ev) => this.onDragEnd(ev); // 用户完成元素拖动后触发 + //释放目标时触发的事件: + node.ondragenter = (ev) => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 + node.ondragover = (ev) => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 + node.ondragleave = (ev) => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 + node.ondrop = (ev) => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 + } + node.selected = a.selected || false; //是否选中行 + node.checked = a.checked || false; // 是否勾选 + node.data = a; + node.addEventListener('change', (e: any): void => { + if (e.detail && !this.multiple) { + this.nodeList.forEach((item) => { + item.checked = item.data!.key === node.data!.key; + item.data!.checked = item.checked; + }); + } + var litTreeNodes = this.nodeList.filter((it) => it.checked); + if (litTreeNodes.length === 0) { + node.checked = true; + node.data!.checked = true; + } + that.dispatchEvent(new CustomEvent('onChange', { detail: { data: (node as any).data, checked: e.detail } })); + }); + node.multiple = this.hasAttribute('multiple'); + node.checkable = this.getAttribute('checkable') || 'false'; + this.nodeList.push(node); + } + + addEvent(a:TreeItemData,node: LitTreeNode,li: HTMLLIElement,ul: HTMLUListElement):void{ + if (a.children && a.children.length > 0) { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + (node as any).iconName = a.icon; + } else { + (node as any).iconName = 'folder'; + } + } else { + node.iconName = ''; + } + node.arrow = true; + li.append(ul); + this.drawTree(ul, a.children); + } else { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + node.iconName = a.icon; + } else { + node.iconName = 'file'; + } + } else { + node.iconName = ''; + } + node.arrow = false; + } + li.onclick = (e): void => { + e.stopPropagation(); + if (this.hasAttribute('foldable')) { + // @ts-ignore + if (li.data.children && li.data.children.length > 0) { + node.autoExpand(); + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); + this.selectedNode(node); + } + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', { detail: li.data })); + this.selectedNode(node); + } + }; + } + //取消所有节点的选中状态 然后选中当前node节点 selectedNode(node: LitTreeNode | null | undefined): void { this.shadowRoot!.querySelectorAll('lit-tree-node').forEach((a) => { @@ -451,10 +459,11 @@ export class LitTree extends BaseElement { if (!parent) { parent = this.shadowRoot!.querySelector('#root'); } - let li = document.createElement('li'); - let insertNode = document.createElement('lit-tree-node') as LitTreeNode; + let li: HTMLLIElement = document.createElement('li'); + let insertNode: LitTreeNode = document.createElement('lit-tree-node') as LitTreeNode; insertNode.title = a.title; insertNode.setAttribute('key', a.key); + this.setDragableOfEvent(insertNode); if (this.hasAttribute('dragable')) { insertNode.draggable = true; document.ondragover = function (e): void { @@ -488,10 +497,42 @@ export class LitTree extends BaseElement { li.data = a; li.append(insertNode); parent.append(li); - let ul = document.createElement('ul'); + let ul: HTMLUListElement = document.createElement('ul'); // @ts-ignore ul.open = 'true'; ul.style.transition = '.3s all'; + this.setChildren(a,insertNode,li,ul); + // node 添加右键菜单功能 + insertNode.oncontextmenu = (ev): void => { + ev.preventDefault(); + this.selectedNode(insertNode); + this.currentSelectedNode = insertNode; + this.currentSelectedData = insertNode.data; + this.contextMenu!.style.display = 'block'; + this.contextMenu!.style.left = ev.pageX + 'px'; + this.contextMenu!.style.top = ev.pageY + 'px'; + }; + } + + setDragableOfEvent(insertNode: LitTreeNode):void{ + if (this.hasAttribute('dragable')) { + insertNode.draggable = true; + document.ondragover = function (e): void { + e.preventDefault(); + }; + //在拖动目标上触发事件 (源元素) + insertNode.ondrag = (ev): void => this.onDrag(ev); //元素正在拖动时触发 + insertNode.ondragstart = (ev): undefined => this.onDragStart(ev); //用户开始拖动元素时触发 + insertNode.ondragend = (ev): undefined => this.onDragEnd(ev); // 用户完成元素拖动后触发 + //释放目标时触发的事件: + insertNode.ondragenter = (ev): undefined => this.onDragEnter(ev); //当被鼠标拖动的对象进入其容器范围内时触发此事件 + insertNode.ondragover = (ev): undefined => this.onDragOver(ev); //当某被拖动的对象在另一对象容器范围内拖动时触发此事件 + insertNode.ondragleave = (ev): undefined => this.onDragLeave(ev); //当被鼠标拖动的对象离开其容器范围内时触发此事件 + insertNode.ondrop = (ev): undefined => this.onDrop(ev); //在一个拖动过程中,释放鼠标键时触发此事件 + } + } + + setChildren(a:any,insertNode: LitTreeNode,li: HTMLLIElement,ul: HTMLUListElement):void{ if (a.children && a.children.length > 0) { if (this.hasAttribute('show-icon')) { if (a.icon) { @@ -534,16 +575,6 @@ export class LitTree extends BaseElement { this.selectedNode(insertNode); } }; - // node 添加右键菜单功能 - insertNode.oncontextmenu = (ev): void => { - ev.preventDefault(); - this.selectedNode(insertNode); - this.currentSelectedNode = insertNode; - this.currentSelectedData = insertNode.data; - this.contextMenu!.style.display = 'block'; - this.contextMenu!.style.left = ev.pageX + 'px'; - this.contextMenu!.style.top = ev.pageY + 'px'; - }; } initElements(): void { diff --git a/ide/src/base-ui/tree/LitTreeNode.html.ts b/ide/src/base-ui/tree/LitTreeNode.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..de67bc0f4bb6cf17077acb2ebc7b445804a42c43 --- /dev/null +++ b/ide/src/base-ui/tree/LitTreeNode.html.ts @@ -0,0 +1,168 @@ +/* + * 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. + */ + +export const LitTreeNodeHtmlStyle = ` + + `; \ No newline at end of file diff --git a/ide/src/base-ui/tree/LitTreeNode.ts b/ide/src/base-ui/tree/LitTreeNode.ts index 1b00ad969b2abfb315d83b79245fa0b3b07dccf0..87f85875033830f0f925cacedb2993a42d7102f1 100644 --- a/ide/src/base-ui/tree/LitTreeNode.ts +++ b/ide/src/base-ui/tree/LitTreeNode.ts @@ -17,6 +17,7 @@ import '../icon/LitIcon'; import { BaseElement, element } from '../BaseElement'; import { type LitIcon } from '../icon/LitIcon'; import { type TreeItemData } from './LitTree'; +import {LitTreeNodeHtmlStyle} from "./LitTreeNode.html"; @element('lit-tree-node') export class LitTreeNode extends BaseElement { @@ -166,156 +167,7 @@ export class LitTreeNode extends BaseElement { initHtml(): string { return ` -
diff --git a/ide/src/index.ts b/ide/src/index.ts index bd5dd96a23dafe4a5a1f69d01d2a56ba96ae312b..1b1fba76d9d0289410310e7f9f3c49c7d0177aba 100644 --- a/ide/src/index.ts +++ b/ide/src/index.ts @@ -13,5 +13,4 @@ * limitations under the License. */ import './trace/SpApplication'; -import { SpApplication } from './trace/SpApplication'; document.body.innerHTML = ''; diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index 8919f6601065f0caa7e1166cd317e5486234ba29..b93a14e3890bde6ce7709cf47a62382ef550ffb4 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -42,7 +42,6 @@ import { error, info, log } from '../log/Log'; import { LitMainMenuGroup } from '../base-ui/menu/LitMainMenuGroup'; import { LitMainMenuItem } from '../base-ui/menu/LitMainMenuItem'; import { LitIcon } from '../base-ui/icon/LitIcon'; -import { Cmd } from '../command/Cmd'; import { TraceRow } from './component/trace/base/TraceRow'; import { SpSchedulingAnalysis } from './component/schedulingAnalysis/SpSchedulingAnalysis'; import './component/trace/base/TraceRowConfig'; @@ -59,9 +58,15 @@ import { type SpKeyboard } from './component/SpKeyboard'; import './component/SpKeyboard'; import { parseKeyPathJson } from './component/Utils'; import { Utils } from './component/trace/base/Utils'; -import "../base-ui/chart/scatter/LitChartScatter"; -import {SpApplicationHtml} from "./SpApplication.html"; -import {queryExistFtrace} from "./database/sql/SqlLite.sql"; +import { + applicationHtml, + clearTraceFileCache, + findFreeSizeAlgorithm, + indexedDataToBufferData, + postLog, + readTraceFileBuffer, +} from './SpApplicationPublicFunc'; +import { queryExistFtrace } from './database/sql/SqlLite.sql'; @element('sp-application') export class SpApplication extends BaseElement { @@ -96,7 +101,34 @@ export class SpApplication extends BaseElement { static skinChange2: Function | null | undefined = null; skinChangeArray: Array = []; private rootEL: HTMLDivElement | undefined | null; + private spWelcomePage: SpWelcomePage | undefined | null; + private spMetrics: SpMetrics | undefined | null; + private spQuerySQL: SpQuerySQL | undefined | null; + private spInfoAndStats: SpInfoAndStats | undefined | null; + private spSystemTrace: SpSystemTrace | undefined | null; private spHelp: SpHelp | undefined | null; + private spKeyboard: SpKeyboard | undefined | null; + private spFlags: SpFlags | undefined | null; + private spRecordTrace: SpRecordTrace | undefined | null; + private spRecordTemplate: SpRecordTrace | undefined | null; + private spSchedulingAnalysis: SpSchedulingAnalysis | undefined | null; + private mainMenu: LitMainMenu | undefined | null; + private menu: HTMLDivElement | undefined | null; + private progressEL: LitProgressBar | undefined | null; + private litSearch: LitSearch | undefined | null; + private litRecordSearch: LitSearch | undefined | null; + private sidebarButton: HTMLDivElement | undefined | null; + private chartFilter: TraceRowConfig | undefined | null; + private cutTraceFile: HTMLImageElement | undefined | null; + private longTracePage: HTMLDivElement | undefined | null; + private customColor: CustomThemeColor | undefined | null; + private filterConfig: LitIcon | undefined | null; + private configClose: LitIcon | undefined | null; + // 关键路径标识 + private importConfigDiv: HTMLInputElement | undefined | null; + private closeKeyPath: HTMLDivElement | undefined | null; + private importFileBt: HTMLInputElement | undefined | null; + private childComponent: Array | undefined | null; private keyCodeMap = { 61: true, 107: true, @@ -112,11 +144,11 @@ export class SpApplication extends BaseElement { private pageTimStamp: number = 0; private currentPageNum: number = 1; - static get observedAttributes() { + static get observedAttributes(): Array { return ['server', 'sqlite', 'wasm', 'dark', 'vs', 'query-sql', 'subsection']; } - get dark() { + get dark(): boolean { return this.hasAttribute('dark'); } @@ -143,16 +175,6 @@ export class SpApplication extends BaseElement { } } - get vs(): boolean { - return this.hasAttribute('vs'); - } - - set vs(isVs: boolean) { - if (isVs) { - this.setAttribute('vs', ''); - } - } - get sqlite(): boolean { return this.hasAttribute('sqlite'); } @@ -201,1261 +223,470 @@ export class SpApplication extends BaseElement { return this.hasAttribute('search'); } - addSkinListener(handler: Function) { + addSkinListener(handler: Function): void { this.skinChangeArray.push(handler); } - removeSkinListener(handler: Function) { + removeSkinListener(handler: Function): void { this.skinChangeArray.splice(this.skinChangeArray.indexOf(handler), 1); } initHtml(): string { - return SpApplicationHtml; + return applicationHtml; } - initElements() { + initPlugin(): void { SpStatisticsHttpUtil.initStatisticsServerConfig(); SpStatisticsHttpUtil.addUserVisitAction('visit'); LongTraceDBUtils.getInstance().createDBAndTable().then(); - let that = this; + } + + initElements(): void { + this.initPlugin(); this.querySql = true; this.rootEL = this.shadowRoot!.querySelector('.root'); - let spWelcomePage = this.shadowRoot!.querySelector('#sp-welcome') as SpWelcomePage; - let spMetrics = this.shadowRoot!.querySelector('#sp-metrics') as SpMetrics; // new SpMetrics(); - let spQuerySQL = this.shadowRoot!.querySelector('#sp-query-sql') as SpQuerySQL; // new SpQuerySQL(); - let spInfoAndStats = this.shadowRoot!.querySelector('#sp-info-and-stats') as SpInfoAndStats; // new SpInfoAndStats(); - let spSystemTrace = this.shadowRoot!.querySelector('#sp-system-trace'); + this.spWelcomePage = this.shadowRoot!.querySelector('#sp-welcome') as SpWelcomePage; + this.spMetrics = this.shadowRoot!.querySelector('#sp-metrics') as SpMetrics; // new SpMetrics(); + this.spQuerySQL = this.shadowRoot!.querySelector('#sp-query-sql') as SpQuerySQL; // new SpQuerySQL(); + this.spInfoAndStats = this.shadowRoot!.querySelector('#sp-info-and-stats'); // new SpInfoAndStats(); + this.spSystemTrace = this.shadowRoot!.querySelector('#sp-system-trace'); this.spHelp = this.shadowRoot!.querySelector('#sp-help'); - let SpKeyboard = this.shadowRoot!.querySelector('#sp-keyboard') as SpKeyboard; - let spFlags = this.shadowRoot!.querySelector('#sp-flags') as SpFlags; - let spRecordTrace = this.shadowRoot!.querySelector('#sp-record-trace'); - let spRecordTemplate = this.shadowRoot!.querySelector('#sp-record-template'); - let spSchedulingAnalysis = this.shadowRoot!.querySelector( - '#sp-scheduling-analysis' - ) as SpSchedulingAnalysis; - let mainMenu = this.shadowRoot?.querySelector('#main-menu') as LitMainMenu; - let menu = mainMenu.shadowRoot?.querySelector('.menu-button') as HTMLDivElement; - let progressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; - let litSearch = this.shadowRoot?.querySelector('#lit-search') as LitSearch; - let litRecordSearch = this.shadowRoot?.querySelector('#lit-record-search') as LitSearch; - let sidebarButton: HTMLDivElement | undefined | null = this.shadowRoot?.querySelector('.sidebar-button'); - let chartFilter = this.shadowRoot?.querySelector('.chart-filter') as TraceRowConfig; - let cutTraceFile = this.shadowRoot?.querySelector('.cut-trace-file') as HTMLImageElement; - let longTracePage = that.shadowRoot!.querySelector('.long_trace_page') as HTMLDivElement; - cutTraceFile.addEventListener('click', () => { - this.croppingFile(progressEL, litSearch); - }); - let customColor = this.shadowRoot?.querySelector('.custom-color') as CustomThemeColor; - mainMenu!.setAttribute('main_menu', '1'); - chartFilter!.setAttribute('mode', ''); - chartFilter!.setAttribute('hidden', ''); - customColor!.setAttribute('mode', ''); - customColor!.setAttribute('hidden', ''); - let childNodes = [ - spSystemTrace, - spRecordTrace, - spWelcomePage, - spMetrics, - spQuerySQL, - spSchedulingAnalysis, - spInfoAndStats, - this.spHelp, - spRecordTemplate, - spFlags, - SpKeyboard, - ]; - document.addEventListener('visibilitychange', function () { - if (document.visibilityState === 'visible') { - validateFileCacheLost(); - if (window.localStorage.getItem('Theme') == 'dark') { - that.changeTheme(Theme.DARK); - } else { - that.changeTheme(Theme.LIGHT); - } - } - }); - this.addEventListener('copy', function (event) { - let clipdata = event.clipboardData; - let value = clipdata!.getData('text/plain'); - let searchValue = value.toString().trim(); - clipdata!.setData('text/plain', searchValue); - }); - window.subscribe(window.SmartEvent.UI.MenuTrace, () => showContent(spSystemTrace!)); - window.subscribe(window.SmartEvent.UI.Error, (err) => { - litSearch.setPercent(err, -1); - progressEL.loading = false; - that.freshMenuDisable(false); - }); - window.subscribe(window.SmartEvent.UI.Loading, (arg: { loading: boolean; text?: string }) => { - if (arg.text) { - litSearch.setPercent(arg.text || '', arg.loading ? -1 : 101); - } - window.publish(window.SmartEvent.UI.MouseEventEnable, { - mouseEnable: !arg.loading, - }); - progressEL.loading = arg.loading; - }); - - litSearch.addEventListener('focus', () => { - window.publish(window.SmartEvent.UI.KeyboardEnable, { - enable: false, - }); - }); - litSearch.addEventListener('blur', () => { - window.publish(window.SmartEvent.UI.KeyboardEnable, { - enable: true, - }); - }); - litSearch.addEventListener('previous-data', (ev: any) => { - litSearch.index = spSystemTrace!.showStruct(true, litSearch.index, litSearch.list); - litSearch.blur(); - }); - litSearch.addEventListener('next-data', (ev: any) => { - litSearch.index = spSystemTrace!.showStruct(false, litSearch.index, litSearch.list); - litSearch.blur(); - }); - // 翻页事件 - litSearch.addEventListener('retarget-data', (ev: any) => { - litSearch.index = spSystemTrace!.showStruct(true, ev.detail.value, litSearch.list, ev.detail.value); - litSearch.blur(); - }); - litSearch.valueChangeHandler = (value: string) => { - litSearch!.isClearValue = false; - if (value.length > 0) { - let list: any[] = []; - progressEL.loading = true; - spSystemTrace!.searchCPU(value).then((cpus) => { - list = cpus; - spSystemTrace!.searchFunction(list, value).then((mixedResults) => { - if (litSearch.searchValue != '') { - litSearch.list = spSystemTrace!.searchSdk(mixedResults, value); - litSearch.index = spSystemTrace!.showStruct(false, -1, litSearch.list); - } - progressEL.loading = false; - }); - }); - } else { - let indexEL = litSearch.shadowRoot!.querySelector('#index'); - indexEL!.textContent = '0'; - litSearch.list = []; - spSystemTrace?.visibleRows.forEach((it) => { - it.highlight = false; - it.draw(); - }); - spSystemTrace?.timerShaftEL?.removeTriangle('inverted'); - } - }; - spSystemTrace?.addEventListener('trace-previous-data', (ev: any) => { - litSearch.index = spSystemTrace!.showStruct(true, litSearch.index, litSearch.list); - }); - spSystemTrace?.addEventListener('trace-next-data', (ev: any) => { - litSearch.index = spSystemTrace!.showStruct(false, litSearch.index, litSearch.list); - }); - - let filterConfig = this.shadowRoot?.querySelector('.filter-config') as LitIcon; - let configClose = this.shadowRoot + this.spKeyboard = this.shadowRoot!.querySelector('#sp-keyboard') as SpKeyboard; + this.spFlags = this.shadowRoot!.querySelector('#sp-flags') as SpFlags; + this.spRecordTrace = this.shadowRoot!.querySelector('#sp-record-trace'); + this.spRecordTemplate = this.shadowRoot!.querySelector('#sp-record-template'); + this.spSchedulingAnalysis = this.shadowRoot!.querySelector('#sp-scheduling-analysis'); + this.mainMenu = this.shadowRoot?.querySelector('#main-menu') as LitMainMenu; + this.menu = this.mainMenu.shadowRoot?.querySelector('.menu-button') as HTMLDivElement; + this.progressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; + this.litSearch = this.shadowRoot?.querySelector('#lit-search') as LitSearch; + this.litRecordSearch = this.shadowRoot?.querySelector('#lit-record-search') as LitSearch; + this.sidebarButton = this.shadowRoot?.querySelector('.sidebar-button'); + this.chartFilter = this.shadowRoot?.querySelector('.chart-filter') as TraceRowConfig; + this.cutTraceFile = this.shadowRoot?.querySelector('.cut-trace-file') as HTMLImageElement; + this.longTracePage = this.shadowRoot!.querySelector('.long_trace_page') as HTMLDivElement; + this.customColor = this.shadowRoot?.querySelector('.custom-color') as CustomThemeColor; + this.filterConfig = this.shadowRoot?.querySelector('.filter-config') as LitIcon; + this.configClose = this.shadowRoot ?.querySelector('.chart-filter')! .shadowRoot?.querySelector('.config-close'); - filterConfig.addEventListener('click', (ev) => { - if (this!.hasAttribute('chart_filter')) { - this!.removeAttribute('chart_filter'); - chartFilter!.setAttribute('hidden', ''); - } else { - this!.removeAttribute('custom-color'); - customColor!.setAttribute('hidden', ''); - customColor.cancelOperate(); - this!.setAttribute('chart_filter', ''); - chartFilter!.removeAttribute('hidden'); - } - }); - configClose!.addEventListener('click', (ev) => { - if (this.hasAttribute('chart_filter')) { - this!.removeAttribute('chart_filter'); - } - }); - - let customColorShow = this.shadowRoot - ?.querySelector('lit-main-menu')! - .shadowRoot!.querySelector('.customColor') as HTMLDivElement; - customColorShow.addEventListener('click', (ev) => { - if (this!.hasAttribute('custom-color')) { - this!.removeAttribute('custom-color'); - customColor!.setAttribute('hidden', ''); - customColor.cancelOperate(); - } else { - this!.removeAttribute('chart_filter'); - chartFilter!.setAttribute('hidden', ''); - this!.setAttribute('custom-color', ''); - customColor!.removeAttribute('hidden'); - } - }); - // 关键路径标识 - const importConfigDiv = this.shadowRoot?.querySelector('#import-key-path'); - const closeKeyPath = this.shadowRoot?.querySelector('#close-key-path'); - - const importFileBt = this.shadowRoot?.querySelector('#import-config'); - importFileBt?.addEventListener('change', (): void => { - let files = importFileBt!.files; - if (files && files.length === 1) { - const reader = new FileReader(); - reader.readAsText(files[0], 'UTF-8'); - reader.onload = (e) => { - if (e.target?.result) { - try { - const result = parseKeyPathJson(e.target.result as string); - window.publish(window.SmartEvent.UI.KeyPath, result); - closeKeyPath!.style.display = 'block'; - } catch { - error('json Parse Failed'); - litSearch.setPercent('Json Parse Failed!', -1); - window.setTimeout(() => { - litSearch.setPercent('Json Parse Failed!', 101); - }, 1000); - } - } else { - window.publish(window.SmartEvent.UI.KeyPath, []); - closeKeyPath!.style.display = 'none'; - } - }; - } - importFileBt!.files = null; - importFileBt!.value = ''; - }); - - if (closeKeyPath) { - closeKeyPath.addEventListener('click', (): void => { - window.publish(window.SmartEvent.UI.KeyPath, []); - closeKeyPath.style.display = 'none'; - }); + this.importConfigDiv = this.shadowRoot?.querySelector('#import-key-path'); + this.closeKeyPath = this.shadowRoot?.querySelector('#close-key-path'); + this.importFileBt = this.shadowRoot?.querySelector('#import-config'); + this.initElementsAttr(); + this.initEvents(); + this.initCustomEvents(); + this.initCustomColorHandler(); + this.initImportConfigEvent(); + this.initSlideMenuEvents(); + this.initMenus(); + this.initGlobalEvents(); + this.initDocumentListener(); + let urlParams = new URL(window.location.href).searchParams; + if (urlParams && urlParams.get('trace') && urlParams.get('link')) { + this.openLineFileHandler(urlParams); + } else { + this.openMenu(true); } + } - //打开侧边栏 - sidebarButton!.onclick = (e) => { - let menu: HTMLDivElement | undefined | null = this.shadowRoot?.querySelector('#main-menu'); - let menuButton: HTMLElement | undefined | null = this.shadowRoot?.querySelector('.sidebar-button'); - if (menu) { - menu.style.width = `248px`; - // @ts-ignore - menu.style.zIndex = 2000; - menu.style.display = `flex`; - } - if (menuButton) { - menuButton.style.width = `0px`; - importConfigDiv!.style.left = '5px'; - closeKeyPath!.style.left = '25px'; - } - }; - let icon: HTMLDivElement | undefined | null = this.shadowRoot - ?.querySelector('#main-menu') - ?.shadowRoot?.querySelector('div.header > div'); - icon!.style.pointerEvents = 'none'; - icon!.onclick = (e) => { - let menu: HTMLElement | undefined | null = this.shadowRoot?.querySelector('#main-menu'); - let menuButton: HTMLElement | undefined | null = this.shadowRoot?.querySelector('.sidebar-button'); - if (menu) { - menu.style.width = `0px`; - menu.style.display = `flex`; - // @ts-ignore - menu.style.zIndex = 0; - } - if (menuButton) { - menuButton.style.width = `48px`; - importConfigDiv!.style.left = '45px'; - closeKeyPath!.style.left = '65px'; - } - }; + private initElementsAttr(): void { + this.mainMenu!.setAttribute('main_menu', '1'); + this.chartFilter!.setAttribute('mode', ''); + this.chartFilter!.setAttribute('hidden', ''); + this.customColor!.setAttribute('mode', ''); + this.customColor!.setAttribute('hidden', ''); + this.childComponent = [ + this.spSystemTrace, + this.spRecordTrace, + this.spWelcomePage, + this.spMetrics, + this.spQuerySQL, + this.spSchedulingAnalysis, + this.spInfoAndStats, + this.spHelp, + this.spRecordTemplate, + this.spFlags, + this.spKeyboard, + ]; + } - function showContent(showNode: HTMLElement) { - if (showNode === spSystemTrace) { - menu!.style.pointerEvents = 'auto'; - sidebarButton!.style.pointerEvents = 'auto'; - that.search = true; - litRecordSearch.style.display = 'none'; - litSearch.style.display = 'block'; - window.publish(window.SmartEvent.UI.KeyboardEnable, { - enable: true, - }); - filterConfig.style.visibility = 'visible'; - } else { - that.removeAttribute('custom-color'); - customColor!.setAttribute('hidden', ''); - customColor.cancelOperate(); - menu!.style.pointerEvents = 'none'; - sidebarButton!.style.pointerEvents = 'none'; - that.search = litSearch.isLoading; - if (!that.search) { - litSearch.style.display = 'none'; - litRecordSearch.style.display = 'block'; - } - window.publish(window.SmartEvent.UI.KeyboardEnable, { - enable: false, - }); - filterConfig.style.visibility = 'hidden'; + private openLongTraceFile(ev: any, isRecordTrace: boolean = false) { + this.openFileInit(); + let detail = (ev as any).detail; + let initRes = this.longTraceFileInit(isRecordTrace, detail); + if (!isRecordTrace && initRes) { + let that = this; + let readSize = 0; + let timStamp = new Date().getTime(); + const { traceTypePage, allFileSize, normalTraceNames, specialTraceNames } = initRes; + if (normalTraceNames.length <= 0) { + return; } - log('show pages' + showNode.id); - childNodes.forEach((node) => { - if (that.hasAttribute('chart_filter')) { - that!.removeAttribute('chart_filter'); - } - if (that!.hasAttribute('custom-color')) { - that!.removeAttribute('custom-color'); - customColor!.setAttribute('hidden', ''); - customColor.cancelOperate(); - } - if (node === showNode) { - showNode.style.visibility = 'visible'; - } else { - node!.style.visibility = 'hidden'; - } + const readFiles = async ( + files: FileList, + traceTypePage: Array, + normalNames: Array, + specialNames: Array + ): Promise => { + const promises = Array.from(files).map((file) => { + if (normalNames.indexOf(file.name.toLowerCase()) >= 0) { + return that.longTraceFileRead(file, true, traceTypePage, readSize, timStamp, allFileSize); + } else if (specialNames.indexOf(file.name.toLowerCase()) >= 0) { + return that.longTraceFileRead(file, false, traceTypePage, readSize, timStamp, allFileSize); + } else { + return; + } + }); + return Promise.all(promises); + }; + this.litSearch!.setPercent('Read in file: ', 1); + readFiles(detail, traceTypePage, normalTraceNames, specialTraceNames).then(() => { + this.litSearch!.setPercent('Cut in file: ', 1); + this.sendCutFileMessage(timStamp); }); } + } - function postLog(filename: string, fileSize: string) { - log('postLog filename is: ' + filename + ' fileSize: ' + fileSize); - fetch(`https://${window.location.host.split(':')[0]}:${window.location.port}/logger`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - fileName: filename, - fileSize: fileSize, - }), - }) - .then((response) => response.json()) - .then((data) => {}) - .catch((error) => {}); - } - - function getTraceOptionMenus( - showFileName: string, - fileSize: string, - fileName: string, - isServer: boolean, - dbName?: string - ) { - let menus = [ - { - title: `${showFileName} (${fileSize}M)`, - icon: 'file-fill', - clickHandler: function () { - that.search = true; - showContent(spSystemTrace!); - }, - }, - { - title: 'Scheduling Analysis', - icon: 'piechart-circle-fil', - clickHandler: function () { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'Scheduling Analysis', - action: 'scheduling_analysis', - }); - showContent(spSchedulingAnalysis!); - spSchedulingAnalysis.init(); - }, - }, - { - title: 'Download File', - icon: 'download', - clickHandler: function () { - that.download(mainMenu, fileName, isServer, dbName); - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'download', - action: 'download', - }); - }, - }, - { - title: 'Download Database', - icon: 'download', - clickHandler: function () { - that.downloadDB(mainMenu, fileName); - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'download_db', - action: 'download', - }); - }, - }, - ]; - if (that.querySql) { - if (spQuerySQL) { - spQuerySQL.reset(); - menus.push({ - title: 'Query (SQL)', - icon: 'filesearch', - clickHandler: () => { - showContent(spQuerySQL); - }, - }); - } - - if (spMetrics) { - spMetrics.reset(); - menus.push({ - title: 'Metrics', - icon: 'metric', - clickHandler: () => { - showContent(spMetrics); - }, + private longTraceFileRead = async ( + file: any, + isNormalType: boolean, + traceTypePage: Array, + readSize: number, + timStamp: number, + allFileSize: number + ): Promise => { + info('reading long trace file ', file.name); + let that = this; + return new Promise((resolve, reject) => { + let fr = new FileReader(); + let message = { fileType: '', startIndex: 0, endIndex: 0, size: 0 }; + info('Parse long trace using wasm mode '); + const { fileType, pageNumber } = this.getFileTypeAndPages(file.name, isNormalType, traceTypePage); + let chunk = 48 * 1024 * 1024; + let offset = 0; + let sliceLen = 0; + let index = 1; + fr.onload = function (): void { + let data = fr.result as ArrayBuffer; + LongTraceDBUtils.getInstance() + .addLongTableData(data, fileType, timStamp, pageNumber, index, offset, sliceLen) + .then(() => { + that.longTraceFileReadMessagePush(index, isNormalType, pageNumber, offset, sliceLen, fileType, data); + offset += sliceLen; + if (offset < file.size) { + index++; + } + continueReading(); }); + }; + function continueReading(): void { + if (offset >= file.size) { + message.endIndex = index; + message.size = file.size; + that.longTraceFileReadMessageHandler(pageNumber, message); + resolve(true); + return; } - - if (spInfoAndStats) { - menus.push({ - title: 'Info and stats', - icon: 'info', - clickHandler: () => { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'info', - action: 'info_stats', - }); - showContent(spInfoAndStats); - }, - }); + if (index === 1) { + message.fileType = fileType; + message.startIndex = index; } + sliceLen = Math.min(file.size - offset, chunk); + let slice = file.slice(offset, offset + sliceLen); + readSize += slice.size; + let percentValue = ((readSize * 100) / allFileSize).toFixed(2); + that.litSearch!.setPercent('Read in file: ', Number(percentValue)); + fr.readAsArrayBuffer(slice); } - if ((window as any).cpuCount === 0 || !FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis')) { - //if cpu count > 1 or SchedulingAnalysis config 'enable' then show Scheduling-Analysis menu else hide it - menus.splice(1, 1); - } - - return menus; - } + continueReading(); + fr.onerror = (): void => reject(false); + info('read over long trace file ', file.name); + }); + }; - function restoreDownLoadIcons() { - let querySelectorAll = mainMenu.shadowRoot?.querySelectorAll('lit-main-menu-group'); - querySelectorAll!.forEach((menuGroup) => { - let attribute = menuGroup.getAttribute('title'); - if (attribute === 'Convert trace') { - let querySelectors = menuGroup.querySelectorAll('lit-main-menu-item'); - querySelectors.forEach((item) => { - if (item.getAttribute('title') === 'Convert to .systrace') { - item!.setAttribute('icon', 'download'); - let querySelector = item!.shadowRoot?.querySelector('.icon') as LitIcon; - querySelector.removeAttribute('spin'); - } - }); - } - }); + getFileTypeAndPages(fileName: string, isNormalType: boolean, traceTypePage: Array): any { + let fileType = 'trace'; + let pageNumber = 0; + let firstLastIndexOf = fileName.lastIndexOf('.'); + let firstText = fileName.slice(0, firstLastIndexOf); + let resultLastIndexOf = firstText.lastIndexOf('_'); + let searchResult = firstText.slice(resultLastIndexOf + 1, firstText.length); + if (isNormalType) { + pageNumber = traceTypePage.lastIndexOf(Number(searchResult)); + } else { + fileType = searchResult; } + return { fileType, pageNumber }; + } - function postConvert(fileName: string): void { - let newFileName = fileName.substring(0, fileName.lastIndexOf('.')) + '.systrace'; - let aElement = document.createElement('a'); - convertPool.submitWithName('getConvertData', (status: boolean, msg: string, results: Blob) => { - aElement.href = URL.createObjectURL(results); - aElement.download = newFileName; - let timeoutId = 0; - aElement.addEventListener('click', (ev) => { - clearTimeout(timeoutId); - timeoutId = window.setTimeout(() => { - restoreDownLoadIcons(); - }, 2000); - }); - aElement.click(); - window.URL.revokeObjectURL(aElement.href); - }); + private longTraceFileInit(isRecordTrace: boolean, detail: any): any { + if (!this.wasm) { + this.progressEL!.loading = false; + return; } - - function pushConvertTrace(fileName: string): Array { - let menus = []; - menus.push({ - title: 'Convert to .systrace', - icon: 'download', - clickHandler: function () { - convertPool.init('convert').then((item) => { - let querySelectorAll = mainMenu.shadowRoot?.querySelectorAll('lit-main-menu-group'); - querySelectorAll!.forEach((menuGroup) => { - let attribute = menuGroup.getAttribute('title'); - if (attribute === 'Convert trace') { - let querySelectors = menuGroup.querySelectorAll('lit-main-menu-item'); - querySelectors.forEach((item) => { - if (item.getAttribute('title') === 'Convert to .systrace') { - item!.setAttribute('icon', 'convert-loading'); - item!.classList.add('pending'); - item!.style.fontKerning = ''; - let querySelector = item!.shadowRoot?.querySelector('.icon') as LitIcon; - querySelector.setAttribute('spin', ''); - } - }); - } - }); - postConvert(fileName); - }); - }, - }); - return menus; + if (this.longTracePage) { + this.longTracePage.style.display = 'none'; + this.litSearch!.style.marginLeft = '0px'; + this.shadowRoot!.querySelector('.page-number-list')!.innerHTML = ''; } - - function setProgress(command: string) { - if (command == 'database ready' && SpApplication.loadingProgress < 50) { - SpApplication.progressStep = 6; - } - if (command == 'process' && SpApplication.loadingProgress < 92) { - SpApplication.loadingProgress = 92 + Math.round(Math.random() * SpApplication.progressStep); - } else { - SpApplication.loadingProgress += Math.round(Math.random() * SpApplication.progressStep + Math.random()); + this.currentPageNum = 1; + if (isRecordTrace) { + this.sendCutFileMessage(detail.timeStamp); + return undefined; + } else { + this.longTraceHeadMessageList = []; + this.longTraceTypeMessageMap = undefined; + this.longTraceDataList = []; + let traceTypePage: Array = []; + let allFileSize = 0; + let normalTraceNames: Array = []; + let specialTraceNames: Array = []; + for (let index = 0; index < detail.length; index++) { + let file = detail[index]; + let fileName = file.name as string; + allFileSize += file.size; + let specialMatch = fileName.match(/_(arkts|ebpf|hiperf)\.htrace$/); + let normalMatch = fileName.match(/_\d{8}_\d{6}_\d+\.htrace$/); + if (normalMatch) { + normalTraceNames.push(fileName); + let fileNameStr = fileName.split('.')[0]; + let pageMatch = fileNameStr.match(/\d+$/); + if (pageMatch) { + traceTypePage.push(Number(pageMatch[0])); + } + } else if (specialMatch) { + specialTraceNames.push(fileName); + } } - if (SpApplication.loadingProgress > 99) { - SpApplication.loadingProgress = 99; + if (normalTraceNames.length <= 0) { + this.traceFileLoadFailedHandler('No large trace files exists in the folder!'); } - info('setPercent :' + command + 'percent :' + SpApplication.loadingProgress); - litSearch.setPercent(command + ' ', SpApplication.loadingProgress); + traceTypePage.sort((leftNum: number, rightNum: number) => leftNum - rightNum); + return { traceTypePage, allFileSize, normalTraceNames, specialTraceNames }; } + } - function sendCutFileMessage(timStamp: number) { - that.pageTimStamp = timStamp; - threadPool.init('wasm').then(() => { - let headUintArray = new Uint8Array(that.longTraceHeadMessageList.length * 1024); - let headOffset = 0; - that.longTraceHeadMessageList = that.longTraceHeadMessageList.sort( - (leftMessage, rightMessage) => leftMessage.pageNum - rightMessage.pageNum - ); - for (let index = 0; index < that.longTraceHeadMessageList.length; index++) { - let currentUintArray = new Uint8Array(that.longTraceHeadMessageList[index].data); - headUintArray.set(currentUintArray, headOffset); - headOffset += currentUintArray.length; - } - threadPool.submit( - 'ts-cut-file', - '', - { - headArray: headUintArray, - timeStamp: timStamp, - splitFileInfo: that.longTraceTypeMessageMap?.get(0), - splitDataList: that.longTraceDataList, - }, - (res: Array) => { - litSearch.setPercent('Cut in file ', 100); - if (that.longTraceHeadMessageList.length > 0) { - getTraceFileByPage(that.currentPageNum); - litSearch.style.marginLeft = '80px'; - longTracePage.style.display = 'flex'; - let pageListDiv = that.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; - let previewButton: HTMLDivElement | null | undefined = - that.shadowRoot?.querySelector('#preview-button'); - let nextButton: HTMLDivElement | null | undefined = - that.shadowRoot?.querySelector('#next-button'); - let pageInput = that.shadowRoot?.querySelector('.page-input'); - pageListDiv.innerHTML = ''; - that.refreshPageList( - pageListDiv, - previewButton!, - nextButton!, - pageInput!, - that.currentPageNum, - that.longTraceHeadMessageList.length - ); - if (previewButton) { - previewButton.addEventListener('click', () => { - if (progressEL.loading || that.currentPageNum === 1) { - return; - } - if (that.currentPageNum > 1) { - that.currentPageNum--; - progressEL.loading = true; - that.refreshPageList( - pageListDiv, - previewButton!, - nextButton!, - pageInput!, - that.currentPageNum, - that.longTraceHeadMessageList.length - ); - getTraceFileByPage(that.currentPageNum); - } - }); - } - nextButton!.addEventListener('click', () => { - if (progressEL.loading || that.currentPageNum === that.longTraceHeadMessageList.length) { - return; - } - if (that.currentPageNum < that.longTraceHeadMessageList.length) { - that.currentPageNum++; - progressEL.loading = true; - that.refreshPageList( - pageListDiv, - previewButton!, - nextButton!, - pageInput!, - that.currentPageNum, - that.longTraceHeadMessageList.length - ); - getTraceFileByPage(that.currentPageNum); - } - }); - let nodeListOf = pageListDiv.querySelectorAll('div'); - nodeListOf.forEach((divEL, index) => { - divEL.addEventListener('click', () => { - if (progressEL.loading) { - return; - } - if (divEL.textContent === '...') { - let freeSize = - Number(nodeListOf[index + 1].textContent) - Number(nodeListOf[index - 1].textContent); - that.currentPageNum = Math.floor(freeSize / 2 + Number(nodeListOf[index - 1].textContent)); - } else { - that.currentPageNum = Number(divEL.textContent); - } - progressEL.loading = true; - that.refreshPageList( - pageListDiv, - previewButton!, - nextButton!, - pageInput!, - that.currentPageNum, - that.longTraceHeadMessageList.length - ); - getTraceFileByPage(that.currentPageNum); - }); - }); - pageInput!.addEventListener('input', () => { - let value = pageInput!.value; - value = value.replace(/\D/g, ''); - if (value) { - value = Math.min(that.longTraceHeadMessageList.length, parseInt(value)).toString(); - } - pageInput!.value = value; - }); - let pageConfirmEl = that.shadowRoot?.querySelector('.confirm-button'); - pageConfirmEl!.addEventListener('click', () => { - if (progressEL.loading) { - return; - } - that.currentPageNum = Number(pageInput!.value); - progressEL.loading = true; - that.refreshPageList( - pageListDiv, - previewButton!, - nextButton!, - pageInput!, - that.currentPageNum, - that.longTraceHeadMessageList.length - ); - getTraceFileByPage(that.currentPageNum); - }); - } else { - progressEL.loading = false; - litSearch.setPercent('The basic trace file in the large-file scenario is missing!', -1); - that.freshMenuDisable(false); - return; - } - }, - 'long_trace' - ); + longTraceFileReadMessagePush( + index: number, + isNormalType: boolean, + pageNumber: number, + offset: number, + sliceLen: number, + fileType: string, + data: ArrayBuffer + ) { + if (index === 1 && isNormalType) { + this.longTraceHeadMessageList.push({ + pageNum: pageNumber, + data: data.slice(offset, 1024), }); } + this.longTraceDataList.push({ + index: index, + fileType: fileType, + pageNum: pageNumber, + startOffsetSize: offset, + endOffsetSize: offset + sliceLen, + }); + } - function getTraceFileByPage(pageNumber: number): void { - openFileInit(); - litSearch.clear(); - showContent(spSystemTrace!); - that.search = true; - progressEL.loading = true; - if (!that.wasm) { - progressEL.loading = false; - return; - } - if (that.pageTimStamp === 0) { - return; + longTraceFileReadMessageHandler(pageNumber: number, message: any): void { + if (this.longTraceTypeMessageMap) { + if (this.longTraceTypeMessageMap?.has(pageNumber)) { + let oldTypeList = this.longTraceTypeMessageMap?.get(pageNumber); + oldTypeList?.push(message); + this.longTraceTypeMessageMap?.set(pageNumber, oldTypeList!); + } else { + this.longTraceTypeMessageMap?.set(pageNumber, [message]); } - let indexedDbPageNum = pageNumber - 1; - let maxTraceFileLength = 400 * 1024 * 1024; - let traceRange = IDBKeyRange.bound( - [that.pageTimStamp, 'trace', indexedDbPageNum], - [that.pageTimStamp, 'trace', indexedDbPageNum], - false, - false - ); - LongTraceDBUtils.getInstance() - .indexedDBHelp.get(LongTraceDBUtils.getInstance().tableName, traceRange, 'QueryFileByPage') - .then((result) => { - let traceData = indexedDataToBufferData(result); - let traceLength = traceData.byteLength; - let ebpfRange = IDBKeyRange.bound( - [that.pageTimStamp, 'ebpf_new', indexedDbPageNum], - [that.pageTimStamp, 'ebpf_new', indexedDbPageNum], - false, - false - ); - let arkTsRange = IDBKeyRange.bound( - [that.pageTimStamp, 'arkts_new', indexedDbPageNum], - [that.pageTimStamp, 'arkts_new', indexedDbPageNum], - false, - false - ); - let hiperfRange = IDBKeyRange.bound( - [that.pageTimStamp, 'hiperf_new', indexedDbPageNum], - [that.pageTimStamp, 'hiperf_new', indexedDbPageNum], - false, - false - ); - Promise.all([ - LongTraceDBUtils.getInstance().indexedDBHelp.get( - LongTraceDBUtils.getInstance().tableName, - ebpfRange, - 'QueryFileByPage' - ), - LongTraceDBUtils.getInstance().indexedDBHelp.get( - LongTraceDBUtils.getInstance().tableName, - arkTsRange, - 'QueryFileByPage' - ), - LongTraceDBUtils.getInstance().indexedDBHelp.get( - LongTraceDBUtils.getInstance().tableName, - hiperfRange, - 'QueryFileByPage' - ), - ]).then((otherResult) => { - let ebpfData = indexedDataToBufferData(otherResult[0]); - let arkTsData = indexedDataToBufferData(otherResult[1]); - let hiperfData = indexedDataToBufferData(otherResult[2]); - let traceArray = new Uint8Array(traceData); - let ebpfArray = new Uint8Array(ebpfData); - let arkTsArray = new Uint8Array(arkTsData); - let hiPerfArray = new Uint8Array(hiperfData); - let allOtherData = [ebpfData, arkTsData, hiperfData]; - let otherDataLength = traceLength + ebpfData.byteLength + arkTsData.byteLength + hiperfData.byteLength; - let fileName = `hiprofiler_long_trace_${indexedDbPageNum}.htrace`; - if (otherDataLength > maxTraceFileLength) { - if (traceLength > maxTraceFileLength) { - litSearch.isLoading = false; - litSearch.setPercent('hitrace file too big!', -1); - progressEL.loading = false; - that.freshMenuDisable(false); - } else { - let freeDataLength = maxTraceFileLength - traceLength; - let freeDataIndex = findFreeSizeAlgorithm( - [ebpfData.byteLength, arkTsData.byteLength, hiperfData.byteLength], - freeDataLength - ); - let finalData = [traceData]; - freeDataIndex.forEach((dataIndex) => { - finalData.push(allOtherData[dataIndex]); - }); - let fileBlob = new Blob(finalData); - const file = new File([fileBlob], fileName); - let fileSize = (file.size / 1048576).toFixed(1); - document.title = `${fileName}(${fileSize})`; - handleWasmMode(file, file.name, `${fileSize}`, fileName); - } - } else { - let fileBlob = new Blob([traceArray, ebpfArray, arkTsArray, hiPerfArray]); - const file = new File([fileBlob], fileName); - let fileSize = (file.size / 1048576).toFixed(1); - document.title = `${fileName}(${fileSize})`; - handleWasmMode(file, file.name, `${fileSize}`, file.name); - } - that.traceFileName = fileName; - }); - }); + } else { + this.longTraceTypeMessageMap = new Map(); + this.longTraceTypeMessageMap.set(pageNumber, [message]); } + } - function indexedDataToBufferData(sourceData: any): ArrayBuffer { - let uintArrayLength = 0; - let uintDataList = sourceData.map((item: any) => { - let currentBufData = new Uint8Array(item.buf); - uintArrayLength += currentBufData.length; - return currentBufData; - }); - let resultArrayBuffer = new ArrayBuffer(uintArrayLength); - let resultUintArray = new Uint8Array(resultArrayBuffer); - let offset = 0; - uintDataList.forEach((currentArray: Uint8Array) => { - resultUintArray.set(currentArray, offset); - offset += currentArray.length; - }); - return resultArrayBuffer; + private openTraceFile(ev: any, isClickHandle?: boolean) { + this.removeAttribute('custom-color'); + this.customColor!.setAttribute('hidden', ''); + this.longTracePage!.style.display = 'none'; + this.litSearch!.style.marginLeft = '0px'; + let pageListDiv = this.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; + pageListDiv.innerHTML = ''; + this.openFileInit(); + if (this.importConfigDiv && this.closeKeyPath) { + this.importConfigDiv.style.display = 'none'; + this.closeKeyPath.style.display = 'none'; } + let fileName = (ev as any).name; + this.traceFileName = fileName; + let showFileName = fileName.lastIndexOf('.') === -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); + TraceRow.rangeSelectObject = undefined; + if (this.sqlite) { + info('Parse trace using sql mode'); + this.handleSqliteMode(ev, showFileName, (ev as any).size, fileName); + } + if (this.wasm) { + info('Parse trace using wasm mode '); + this.handleWasmMode(ev, showFileName, (ev as any).size, fileName); + } + } - function findFreeSizeAlgorithm(numbers: Array, freeSize: number): Array { - let closestSize = 0; - let currentSize = 0; - let finalIndex: Array = []; - let currentSelectIndex: Array = []; - - function reBackFind(index: number): void { - if (index === numbers.length) { - const sumDifference = Math.abs(currentSize - freeSize); - if (currentSize <= freeSize && sumDifference < Math.abs(closestSize - freeSize)) { - closestSize = currentSize; - finalIndex = [...currentSelectIndex]; - } - return; + private openLineFileHandler(urlParams: URLSearchParams): void { + this.openFileInit(); + this.openMenu(false); + let downloadLineFile = urlParams.get('local') ? false : true; + this.setProgress(downloadLineFile ? 'download trace file' : 'open trace file'); + this.downloadOnLineFile( + urlParams.get('trace') as string, + downloadLineFile, + (arrayBuf, fileName, showFileName, fileSize) => { + this.handleWasmMode(new File([arrayBuf], fileName), showFileName, fileSize, fileName); + }, + (localPath) => { + let path = urlParams.get('trace') as string; + let fileName: string = ''; + let showFileName: string = ''; + if (urlParams.get('local')) { + this.openMenu(true); + fileName = urlParams.get('traceName') as string; + } else { + fileName = path.split('/').reverse()[0]; } - currentSize += numbers[index]; - currentSelectIndex.push(index); - reBackFind(index + 1); - currentSize -= numbers[index]; - currentSelectIndex.pop(); - reBackFind(index + 1); + this.traceFileName = fileName; + showFileName = fileName.lastIndexOf('.') === -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); + TraceRow.rangeSelectObject = undefined; + let localUrl = downloadLineFile ? `${window.location.origin}${localPath}` : urlParams.get('trace')!; + fetch(localUrl) + .then((res) => { + res.arrayBuffer().then((arrayBuf) => { + if (urlParams.get('local')) { + URL.revokeObjectURL(localUrl); + } + this.handleWasmMode(new File([arrayBuf], fileName), showFileName, arrayBuf.byteLength, fileName); + }); + }) + .catch((e) => { + if (!downloadLineFile) { + const firstQuestionMarkIndex = window.location.href.indexOf('?'); + location.replace(window.location.href.substring(0, firstQuestionMarkIndex)); + } + }); } + ); + } - reBackFind(0); - return finalIndex; + private openMenu(open: boolean): void { + if (this.mainMenu) { + this.mainMenu.style.width = open ? '248px' : '0px'; + this.mainMenu.style.zIndex = open ? '2000' : '0'; + } + if (this.sidebarButton) { + this.sidebarButton.style.width = open ? '0px' : '48px'; + this.importConfigDiv!.style.left = open ? '5px' : '45px'; + this.closeKeyPath!.style.left = open ? '25px' : '65px'; } + } - function handleWasmMode(ev: any, showFileName: string, fileSize: string, fileName: string) { - litSearch.setPercent('', 1); - threadPool.init('wasm').then((res) => { - let reader: FileReader | null = new FileReader(); - reader.readAsArrayBuffer(ev as any); - reader.onloadend = function (ev) { - info('read file onloadend'); - litSearch.setPercent('ArrayBuffer loaded ', 2); - let wasmUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; - if (that.vs) { - wasmUrl = `http://${window.location.host.split(':')[0]}:${window.location.port}/wasm.json`; - } - SpApplication.loadingProgress = 0; - SpApplication.progressStep = 3; - let data = this.result as ArrayBuffer; - info('initData start Parse Data'); - spSystemTrace!.loadDatabaseArrayBuffer( - data, - wasmUrl, - (command: string, percent: number) => { - setProgress(command); - }, - async (res) => { - let existFtrace = await queryExistFtrace(); - let isAllowTrace = true; - if (DbPool.sharedBuffer) { - let traceHeadData = new Uint8Array(DbPool.sharedBuffer!.slice(0, 10)); - let enc = new TextDecoder(); - let headerStr = enc.decode(traceHeadData); - let rowTraceStr = Array.from(new Uint8Array(DbPool.sharedBuffer!.slice(0, 2))) - .map((byte) => byte.toString(16).padStart(2, '0')) - .join(''); - if (headerStr.indexOf('OHOSPROF') !== 0 && rowTraceStr.indexOf('49df') !== 0) { - isAllowTrace = false; - } - cutTraceFile.style.display = 'block'; - DbPool.sharedBuffer = null; - } - let index = 2; - if (existFtrace.length > 0 && isAllowTrace) { - mainMenu.menus!.splice(2, 1, { - collapsed: false, - title: 'Convert trace', - second: false, - icon: '', - describe: 'Convert to other formats', - children: pushConvertTrace(fileName), - }); - index = 3; - } - mainMenu.menus!.splice(index, 1, { - collapsed: false, - title: 'Support', - second: false, - icon: '', - describe: 'Support', - children: [ - { - title: 'Help Documents', - icon: 'smart-help', - clickHandler: function (item: MenuItem) { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'help_page', - action: 'help_doc', - }); - that.search = false; - that.spHelp!.dark = that.dark; - showContent(that.spHelp!); - }, - }, - { - title: 'Flags', - icon: 'menu', - clickHandler: function (item: MenuItem) { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'flags', - action: 'flags', - }); - that.search = false; - showContent(spFlags); - }, - }, - { - title: 'Keyboard shortcuts', - icon: 'smart-help', - clickHandler: function (item: MenuItem) { - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'Keyboard shortcuts', - action: 'Keyboard shortcuts', - }); - that.search = false; - showContent(SpKeyboard); - }, - }, - ], - }); - if (res.status) { - info('loadDatabaseArrayBuffer success'); - mainMenu.menus!.splice(1, mainMenu.menus!.length > 2 ? 1 : 0, { - collapsed: false, - title: 'Current Trace', - second: false, - icon: '', - describe: 'Actions on the current trace', - children: getTraceOptionMenus(showFileName, fileSize, fileName, false), - }); - if (Utils.SCHED_SLICE_MAP.size > 0) { - importConfigDiv!.style.display = 'block'; - } else { - importConfigDiv!.style.display = 'none'; - } - showContent(spSystemTrace!); - litSearch.setPercent('', 101); - chartFilter!.setAttribute('mode', ''); - progressEL.loading = false; - that.freshMenuDisable(false); - } else { - info('loadDatabaseArrayBuffer failed'); - litSearch.setPercent(res.msg || 'This File is not supported!', -1); - progressEL.loading = false; - that.freshMenuDisable(false); - mainMenu.menus!.splice(1, 1); - mainMenu.menus = mainMenu.menus!; - } - spInfoAndStats.initInfoAndStatsData(); - reader = null; - } - ); - }; - }); - } - - const validateFileCacheLost = () => { - caches.has(DbPool.fileCacheKey).then((exist) => { - if (!exist) { - //todo 缓存文件丢失,则禁止下载文件功能 - mainMenu.menus?.forEach((mg) => { - mg.children.forEach((mi: any) => { - if (mi.title === 'Download File') { - mi.disabled = true; - } - }); - }); - cutTraceFile.style.display = 'none'; - mainMenu.menus = mainMenu.menus; + private initGlobalDropEvents(): void { + let body = document.querySelector('body'); + body!.addEventListener( + 'drop', + (e: any) => { + e.preventDefault(); + e.stopPropagation(); + if (this.rootEL!.classList.contains('filedrag')) { + this.rootEL!.classList.remove('filedrag'); } - }); - }; - - let openFileInit = () => { - this.clearTraceFileCache(); - SpStatisticsHttpUtil.addOrdinaryVisitAction({ - event: 'open_trace', - action: 'open_trace', - }); - info('openTraceFile'); - spSystemTrace!.clearPointPair(); - spSystemTrace!.reset((command: string, percent: number) => { - setProgress(command); - }); - window.publish(window.SmartEvent.UI.MouseEventEnable, { - mouseEnable: false, - }); - window.clearTraceRowComplete(); - that.freshMenuDisable(true); - SpSchedulingAnalysis.resetCpu(); - if (mainMenu.menus!.length > 3) { - mainMenu.menus!.splice(1, 2); - mainMenu.menus = mainMenu.menus!; - } else if (mainMenu.menus!.length > 2) { - mainMenu.menus!.splice(1, 1); - mainMenu.menus = mainMenu.menus!; - } - }; - - function openLongTraceFile(ev: any, isRecordTrace: boolean = false) { - openFileInit(); - litSearch.clear(); - showContent(spSystemTrace!); - that.search = true; - progressEL.loading = true; - if (!that.wasm) { - progressEL.loading = false; - return; - } - if (longTracePage) { - longTracePage.style.display = 'none'; - litSearch.style.marginLeft = '0px'; - let pageListDiv = that.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; - pageListDiv.innerHTML = ''; - } - that.currentPageNum = 1; - if (isRecordTrace) { - let detail = (ev as any).detail; - sendCutFileMessage(detail.timeStamp); - } else { - that.longTraceHeadMessageList = []; - that.longTraceTypeMessageMap = undefined; - that.longTraceDataList = []; - let detail = (ev as any).detail; - let timStamp = new Date().getTime(); - let traceTypePage: Array = []; - let allFileSize = 0; - let readSize = 0; - let normalTraceNames: Array = []; - let specialTraceNames: Array = []; - for (let index = 0; index < detail.length; index++) { - let file = detail[index]; - let fileName = file.name as string; - allFileSize += file.size; - let specialMatch = fileName.match(/_(arkts|ebpf|hiperf)\.htrace$/); - let normalMatch = fileName.match(/_\d{8}_\d{6}_\d+\.htrace$/); - if (normalMatch) { - normalTraceNames.push(fileName); - let fileNameStr = fileName.split('.')[0]; - let pageMatch = fileNameStr.match(/\d+$/); - if (pageMatch) { - traceTypePage.push(Number(pageMatch[0])); - } - } else if (specialMatch) { - specialTraceNames.push(fileName); + if (e.dataTransfer.items !== undefined && e.dataTransfer.items.length > 0) { + let item = e.dataTransfer.items[0]; + if (item.webkitGetAsEntry()?.isFile) { + this.openTraceFile(item.getAsFile()); + } else if (item.webkitGetAsEntry()?.isDirectory) { + this.litSearch!.setPercent('This File is not supported!', -1); + this.progressEL!.loading = false; + this.freshMenuDisable(false); + this.mainMenu!.menus!.splice(1, 1); + this.mainMenu!.menus = this.mainMenu!.menus!; + this.spSystemTrace!.reset(null); } } - if (normalTraceNames.length <= 0) { - progressEL.loading = false; - litSearch.setPercent('No large trace files exists in the folder!', -1); - that.freshMenuDisable(false); - return; + }, + false + ); + } + private initGlobalEvents(): void { + let body = document.querySelector('body'); + body!.addEventListener( + 'dragover', + (e: any) => { + e.preventDefault(); + e.stopPropagation(); + if (e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind === 'file') { + e.dataTransfer.dropEffect = 'copy'; + if (!this.rootEL!.classList.contains('filedrag')) { + this.rootEL!.classList.add('filedrag'); + } } - traceTypePage.sort((leftNum: number, rightNum: number) => leftNum - rightNum); - const readFiles = async (files: FileList, traceTypePage: Array, normalNames: Array, specialNames: Array) => { - const promises = Array.from(files).map((file) => { - if (normalNames.indexOf(file.name.toLowerCase()) >= 0) { - return readFile(file, true, traceTypePage); - } else if (specialNames.indexOf(file.name.toLowerCase()) >= 0) { - return readFile(file, false, traceTypePage); - } else { - return; - } - }); - return Promise.all(promises); - }; - const readFile = async (file: any, isNormalType: boolean, traceTypePage: Array) => { - info('reading long trace file ', file.name); - return new Promise((resolve, reject) => { - let fileName = file.name; - let fr = new FileReader(); - let message = { - fileType: '', - startIndex: 0, - endIndex: 0, - size: 0, - }; - info('Parse long trace using wasm mode '); - let maxSize = 48 * 1024 * 1024; - let fileType = 'trace'; - let pageNumber = 0; - let firstLastIndexOf = fileName.lastIndexOf('.'); - let firstText = fileName.slice(0, firstLastIndexOf); - let resultLastIndexOf = firstText.lastIndexOf('_'); - let searchResult = firstText.slice(resultLastIndexOf + 1, firstText.length) - if (isNormalType) { - pageNumber = traceTypePage.lastIndexOf(Number(searchResult)); - } else { - fileType = searchResult; - } - let chunk = maxSize; - let offset = 0; - let sliceLen = 0; - let index = 1; - fr.onload = function () { - let data = fr.result as ArrayBuffer; - LongTraceDBUtils.getInstance() - .indexedDBHelp.add(LongTraceDBUtils.getInstance().tableName, { - buf: data, - id: `${fileType}_${timStamp}_${pageNumber}_${index}`, - fileType: fileType, - pageNum: pageNumber, - startOffset: offset, - endOffset: offset + sliceLen, - index: index, - timStamp: timStamp, - }) - .then(() => { - if (index === 1 && isNormalType) { - that.longTraceHeadMessageList.push({ - pageNum: pageNumber, - data: data.slice(offset, 1024), - }); - } - that.longTraceDataList.push({ - index: index, - fileType: fileType, - pageNum: pageNumber, - startOffsetSize: offset, - endOffsetSize: offset + sliceLen, - }); - offset += sliceLen; - if (offset < file.size) { - index++; - } - continue_reading(); - }); - }; - - function continue_reading() { - if (offset >= file.size) { - message.endIndex = index; - message.size = file.size; - if (that.longTraceTypeMessageMap) { - if (that.longTraceTypeMessageMap?.has(pageNumber)) { - let oldTypeList = that.longTraceTypeMessageMap?.get(pageNumber); - oldTypeList?.push(message); - that.longTraceTypeMessageMap?.set(pageNumber, oldTypeList!); - } else { - that.longTraceTypeMessageMap?.set(pageNumber, [message]); - } - } else { - that.longTraceTypeMessageMap = new Map(); - that.longTraceTypeMessageMap.set(pageNumber, [message]); - } - resolve(true); - return; - } - if (index === 1) { - message.fileType = fileType; - message.startIndex = index; - } - sliceLen = Math.min(file.size - offset, chunk); - let slice = file.slice(offset, offset + sliceLen); - readSize += slice.size; - let percentValue = ((readSize * 100) / allFileSize).toFixed(2); - litSearch.setPercent('Read in file: ', Number(percentValue)); - fr.readAsArrayBuffer(slice); - } - continue_reading(); - fr.onerror = function () { - reject(false); - }; - info('read over long trace file ', file.name); - }); - }; - litSearch.setPercent('Read in file: ', 1); - readFiles(detail, traceTypePage, normalTraceNames, specialTraceNames).then(() => { - litSearch.setPercent('Cut in file: ', 1); - sendCutFileMessage(timStamp); - }); - } - } + }, + false + ); + body!.addEventListener( + 'dragleave', + (e) => { + e.stopPropagation(); + e.preventDefault(); + if (this.rootEL!.classList.contains('filedrag')) { + this.rootEL!.classList.remove('filedrag'); + } + }, + false + ); + this.initGlobalDropEvents(); + } - function openTraceFile(ev: any, isClickHandle?: boolean) { - that.removeAttribute('custom-color'); - customColor!.setAttribute('hidden', ''); - longTracePage.style.display = 'none'; - litSearch.style.marginLeft = '0px'; - let pageListDiv = that.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; - pageListDiv.innerHTML = ''; - openFileInit(); - if (importConfigDiv && closeKeyPath) { - importConfigDiv.style.display = 'none'; - closeKeyPath.style.display = 'none'; + private initDocumentListener(): void { + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible') { + this.validateFileCacheLost(); + if (window.localStorage.getItem('Theme') === 'dark') { + this.changeTheme(Theme.DARK); + } else { + this.changeTheme(Theme.LIGHT); + } } - if (that.vs && isClickHandle) { - Cmd.openFileDialog().then((res: string) => { - if (res != '') { - litSearch.clear(); - showContent(spSystemTrace!); - that.search = true; - progressEL.loading = true; - let openResult = JSON.parse(res); - let fileName = openResult.fileName; - let fileSize = (openResult.fileSize / 1048576).toFixed(1); - let showFileName = - fileName.lastIndexOf('.') == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); - document.title = `${showFileName} (${fileSize}M)`; - TraceRow.rangeSelectObject = undefined; - if (that.wasm) { - info('Parse trace using wasm mode '); - const vsUpload = new FormData(); - vsUpload.append('convertType', 'vsUpload'); - vsUpload.append('isTransform', ''); - vsUpload.append('filePath', openResult.filePath); - info('openResult.filePath ', openResult.filePath); - litSearch.setPercent('upload file ', 1); - Cmd.uploadFile(vsUpload, (response: Response) => { - if (response.ok) { - response.text().then((traceFile) => { - let traceFilePath = - `http://${window.location.host.split(':')[0]}:${window.location.port}` + traceFile; - fetch(traceFilePath).then((res) => { - res.arrayBuffer().then((arrayBuf) => { - handleWasmMode(new File([arrayBuf], fileName), showFileName, fileSize, fileName); - }); - }); - }); - } - }); - return; - } - } else { - return; + }); + document.addEventListener('keydown', (event) => { + const e = event || window.event; + const ctrlKey = e.ctrlKey || e.metaKey; + if (ctrlKey && (this.keyCodeMap as any)[e.keyCode]) { + e.preventDefault(); + } else if (e.detail) { + // Firefox + event.returnValue = false; + } + }); + document.body.addEventListener( + 'wheel', + (e) => { + if (e.ctrlKey) { + if (e.deltaY < 0) { + e.preventDefault(); + return false; + } + if (e.deltaY > 0) { + e.preventDefault(); + return false; } - }); - } else { - litSearch.clear(); - showContent(spSystemTrace!); - that.search = true; - progressEL.loading = true; - let fileName = (ev as any).name; - that.traceFileName = fileName; - let fileSize = ((ev as any).size / 1048576).toFixed(1); - postLog(fileName, fileSize); - let showFileName = - fileName.lastIndexOf('.') == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); - document.title = `${showFileName} (${fileSize}M)`; - TraceRow.rangeSelectObject = undefined; - if (that.sqlite) { - info('Parse trace using sql mode'); - litSearch.setPercent('', 0); - threadPool.init('sqlite').then((res) => { - let reader = new FileReader(); - reader.readAsArrayBuffer(ev as any); - reader.onloadend = function (ev) { - SpApplication.loadingProgress = 0; - SpApplication.progressStep = 3; - spSystemTrace!.loadDatabaseArrayBuffer( - this.result as ArrayBuffer, - '', - (command: string, percent: number) => { - setProgress(command); - }, - () => { - mainMenu.menus!.splice(1, mainMenu.menus!.length > 2 ? 1 : 0, { - collapsed: false, - title: 'Current Trace', - second: false, - icon: '', - describe: 'Actions on the current trace', - children: getTraceOptionMenus(showFileName, fileSize, fileName, false), - }); - litSearch.setPercent('', 101); - chartFilter!.setAttribute('mode', ''); - progressEL.loading = false; - that.freshMenuDisable(false); - } - ); - }; - }); - return; - } - if (that.wasm) { - info('Parse trace using wasm mode '); - handleWasmMode(ev, showFileName, fileSize, fileName); - return; } - } - } + }, + { passive: false } + ); + } - mainMenu.menus = [ + private initMenus(): void { + this.mainMenu!.menus = [ { collapsed: false, title: 'Navigation', @@ -1466,52 +697,44 @@ export class SpApplication extends BaseElement { { title: 'Open trace file', icon: 'folder', - fileChoose: !that.vs, - fileHandler: function (ev: InputEvent) { - openTraceFile(ev.detail as any); + fileChoose: true, + fileHandler: (ev: InputEvent): void => { + this.openTraceFile(ev.detail as any); }, - clickHandler: function (hand: any) { - openTraceFile(hand, true); + clickHandler: (hand: any) => { + this.openTraceFile(hand, true); }, }, { title: 'Open long trace file', icon: 'folder', - fileChoose: !that.vs, - fileHandler: function (ev: InputEvent) { - openLongTraceFile(ev); + fileChoose: true, + fileHandler: (ev: InputEvent): void => { + this.openLongTraceFile(ev); }, - clickHandler: function (hand: any) { - openLongTraceFile(hand, true); + clickHandler: (hand: any): void => { + this.openLongTraceFile(hand, true); }, }, { title: 'Record new trace', icon: 'copyhovered', - clickHandler: function (item: MenuItem) { - if (that.vs) { - spRecordTrace!.vs = true; - spRecordTrace!.startRefreshDeviceList(); - } - spRecordTrace!.synchronizeDeviceList(); - spRecordTemplate!.record_template = false; - spRecordTrace!.refreshConfig(true); - showContent(spRecordTrace!); + clickHandler: (item: MenuItem): void => { + this.spRecordTrace!.synchronizeDeviceList(); + this.spRecordTemplate!.record_template = false; + this.spRecordTrace!.refreshConfig(true); + this.showContent(this.spRecordTrace!); }, }, { title: 'Record template', icon: 'copyhovered', - clickHandler: function (item: MenuItem) { - if (that.vs) { - spRecordTemplate!.vs = true; - spRecordTemplate!.startRefreshDeviceList(); - } - spRecordTemplate!.refreshHint(); - spRecordTemplate!.record_template = true; - spRecordTemplate!.refreshConfig(false); - spRecordTemplate!.synchronizeDeviceList(); - showContent(spRecordTemplate!); + clickHandler: (item: MenuItem): void => { + this.spRecordTemplate!.refreshHint(); + this.spRecordTemplate!.record_template = true; + this.spRecordTemplate!.refreshConfig(false); + this.spRecordTemplate!.synchronizeDeviceList(); + this.showContent(this.spRecordTemplate!); }, }, ], @@ -1526,10 +749,10 @@ export class SpApplication extends BaseElement { { title: 'Help Documents', icon: 'smart-help', - clickHandler: function (item: MenuItem) { - that.spHelp!.dark = that.dark; - that.search = false; - showContent(that.spHelp!); + clickHandler: (item: MenuItem): void => { + this.spHelp!.dark = this.dark; + this.search = false; + this.showContent(this.spHelp!); SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: 'help_page', action: 'help_doc', @@ -1539,9 +762,9 @@ export class SpApplication extends BaseElement { { title: 'Flags', icon: 'menu', - clickHandler: function (item: MenuItem) { - that.search = false; - showContent(spFlags); + clickHandler: (item: MenuItem): void => { + this.search = false; + this.showContent(this.spFlags!); SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: 'flags', action: 'flags', @@ -1551,9 +774,9 @@ export class SpApplication extends BaseElement { { title: 'Keyboard shortcuts', icon: 'smart-help', - clickHandler: function (item: MenuItem) { - that.search = false; - showContent(SpKeyboard); + clickHandler: (item: MenuItem): void => { + this.search = false; + this.showContent(this.spKeyboard!); SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: 'Keyboard shortcuts', action: 'Keyboard shortcuts', @@ -1563,154 +786,887 @@ export class SpApplication extends BaseElement { ], }, ]; + } - let body = document.querySelector('body'); - body!.addEventListener( - 'dragover', - (e: any) => { - e.preventDefault(); - e.stopPropagation(); - if (e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind === 'file') { - e.dataTransfer.dropEffect = 'copy'; - if (!this.rootEL!.classList.contains('filedrag')) { - this.rootEL!.classList.add('filedrag'); + private handleSqliteMode(ev: any, showFileName: string, fileSize: number, fileName: string): void { + let that = this; + let fileSizeStr = (fileSize / 1048576).toFixed(1); + postLog(fileName, fileSizeStr); + document.title = `${showFileName} (${fileSizeStr}M)`; + this.litSearch!.setPercent('', 0); + threadPool.init('sqlite').then((res) => { + let reader = new FileReader(); + reader.readAsArrayBuffer(ev as any); + reader.onloadend = function (ev): void { + SpApplication.loadingProgress = 0; + SpApplication.progressStep = 3; + that.spSystemTrace!.loadDatabaseArrayBuffer( + this.result as ArrayBuffer, + '', + (command: string, _: number) => { + that.setProgress(command); + }, + () => { + that.mainMenu!.menus!.splice(1, that.mainMenu!.menus!.length > 2 ? 1 : 0, { + collapsed: false, + title: 'Current Trace', + second: false, + icon: '', + describe: 'Actions on the current trace', + children: that.getTraceOptionMenus(showFileName, fileSizeStr, fileName, false), + }); + that.litSearch!.setPercent('', 101); + that.chartFilter!.setAttribute('mode', ''); + that.progressEL!.loading = false; + that.freshMenuDisable(false); + } + ); + }; + }); + } + + private handleWasmMode(ev: any, showFileName: string, fileSize: number, fileName: string): void { + let that = this; + let fileSizeStr = (fileSize / 1048576).toFixed(1); + postLog(fileName, fileSizeStr); + document.title = `${showFileName} (${fileSizeStr}M)`; + info('Parse trace using wasm mode '); + this.litSearch!.setPercent('', 1); + let completeHandler = async (res: any): Promise => { + await this.traceLoadCompleteHandler(res, fileSizeStr, showFileName, fileName); + }; + threadPool.init('wasm').then((res) => { + let reader: FileReader | null = new FileReader(); + reader.readAsArrayBuffer(ev as any); + reader.onloadend = function (ev): void { + info('read file onloadend'); + that.litSearch!.setPercent('ArrayBuffer loaded ', 2); + let wasmUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; + SpApplication.loadingProgress = 0; + SpApplication.progressStep = 3; + let data = this.result as ArrayBuffer; + info('initData start Parse Data'); + that.spSystemTrace!.loadDatabaseArrayBuffer( + data, + wasmUrl, + (command: string, _: number) => that.setProgress(command), + completeHandler + ); + }; + }); + } + + private async traceLoadCompleteHandler( + res: any, + fileSize: string, + showFileName: string, + fileName: string + ): Promise { + let existFtrace = await queryExistFtrace(); + let isAllowTrace = true; + if (DbPool.sharedBuffer) { + let traceHeadData = new Uint8Array(DbPool.sharedBuffer!.slice(0, 10)); + let enc = new TextDecoder(); + let headerStr = enc.decode(traceHeadData); + let rowTraceStr = Array.from(new Uint8Array(DbPool.sharedBuffer!.slice(0, 2))) + .map((byte) => byte.toString(16).padStart(2, '0')) + .join(''); + if (headerStr.indexOf('OHOSPROF') !== 0 && rowTraceStr.indexOf('49df') !== 0) { + isAllowTrace = false; + } + this.cutTraceFile!.style.display = 'block'; + DbPool.sharedBuffer = null; + } + let index = 2; + if (existFtrace.length > 0 && isAllowTrace) { + this.showConvertTraceMenu(fileName); + index = 3; + } + this.loadTraceCompleteMenuHandler(index); + if (res.status) { + info('loadDatabaseArrayBuffer success'); + this.showCurrentTraceMenu(fileSize, showFileName, fileName); + this.importConfigDiv!.style.display = Utils.SCHED_SLICE_MAP.size > 0 ? 'block' : 'none'; + this.showContent(this.spSystemTrace!); + this.litSearch!.setPercent('', 101); + this.chartFilter!.setAttribute('mode', ''); + this.freshMenuDisable(false); + } else { + info('loadDatabaseArrayBuffer failed'); + this.litSearch!.setPercent(res.msg || 'This File is not supported!', -1); + this.freshMenuDisable(false); + this.mainMenu!.menus!.splice(1, 1); + this.mainMenu!.menus = this.mainMenu!.menus!; + } + this.progressEL!.loading = false; + this.spInfoAndStats!.initInfoAndStatsData(); + } + + private showConvertTraceMenu(fileName: string): void { + this.mainMenu!.menus!.splice(2, 1, { + collapsed: false, + title: 'Convert trace', + second: false, + icon: '', + describe: 'Convert to other formats', + children: this.pushConvertTrace(fileName), + }); + } + + private showCurrentTraceMenu(fileSize: string, showFileName: string, fileName: string): void { + this.mainMenu!.menus!.splice(1, this.mainMenu!.menus!.length > 2 ? 1 : 0, { + collapsed: false, + title: 'Current Trace', + second: false, + icon: '', + describe: 'Actions on the current trace', + children: this.getTraceOptionMenus(showFileName, fileSize, fileName, false), + }); + } + + private loadTraceCompleteMenuHandler(index: number): void { + let that = this; + this.mainMenu!.menus!.splice(index, 1, { + collapsed: false, + title: 'Support', + second: false, + icon: '', + describe: 'Support', + children: [ + { + title: 'Help Documents', + icon: 'smart-help', + clickHandler: function (item: MenuItem) { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'help_page', + action: 'help_doc', + }); + that.search = false; + that.spHelp!.dark = that.dark; + that.showContent(that.spHelp!); + }, + }, + { + title: 'Flags', + icon: 'menu', + clickHandler: function (item: MenuItem): void { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'flags', + action: 'flags', + }); + that.search = false; + that.showContent(that.spFlags!); + }, + }, + { + title: 'Keyboard shortcuts', + icon: 'smart-help', + clickHandler: function (item: MenuItem): void { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'Keyboard shortcuts', + action: 'Keyboard shortcuts', + }); + that.search = false; + that.showContent(that.spKeyboard!); + }, + }, + ], + }); + } + + private validateGetTraceFileByPage(): boolean { + if (!this.wasm) { + this.progressEL!.loading = false; + return false; + } + if (this.pageTimStamp === 0) { + return false; + } + return true; + } + + private queryFileByPage( + instance: LongTraceDBUtils, + indexedDbPageNum: number, + maxTraceFileLength: number, + traceRange: IDBKeyRange + ) { + instance.indexedDBHelp.get(instance.tableName, traceRange, 'QueryFileByPage').then((result) => { + let traceData = indexedDataToBufferData(result); + let ebpfRange = this.getIDBKeyRange(indexedDbPageNum, 'ebpf_new'); + let arkTsRange = this.getIDBKeyRange(indexedDbPageNum, 'arkts_new'); + let hiperfRange = this.getIDBKeyRange(indexedDbPageNum, 'hiperf_new'); + Promise.all([ + instance.getByRange(ebpfRange), + instance.getByRange(arkTsRange), + instance.getByRange(hiperfRange), + ]).then((otherResult) => { + let ebpfData = indexedDataToBufferData(otherResult[0]); + let arkTsData = indexedDataToBufferData(otherResult[1]); + let hiperfData = indexedDataToBufferData(otherResult[2]); + let traceArray = new Uint8Array(traceData); + let ebpfArray = new Uint8Array(ebpfData); + let arkTsArray = new Uint8Array(arkTsData); + let hiPerfArray = new Uint8Array(hiperfData); + let allOtherData = [ebpfData, arkTsData, hiperfData]; + let otherDataLength = traceData.byteLength + ebpfData.byteLength + arkTsData.byteLength + hiperfData.byteLength; + this.traceFileName = `hiprofiler_long_trace_${indexedDbPageNum}.htrace`; + if (otherDataLength > maxTraceFileLength) { + if (traceData.byteLength > maxTraceFileLength) { + this.traceFileLoadFailedHandler('hitrace file too big!'); + } else { + let freeDataLength = maxTraceFileLength - traceData.byteLength; + let freeDataIndex = findFreeSizeAlgorithm( + [ebpfData.byteLength, arkTsData.byteLength, hiperfData.byteLength], + freeDataLength + ); + let finalData = [traceData]; + freeDataIndex.forEach((dataIndex) => { + finalData.push(allOtherData[dataIndex]); + }); + const file = new File([new Blob(finalData)], this.traceFileName); + this.handleWasmMode(file, file.name, file.size, this.traceFileName); } + } else { + let fileBlob = new Blob([traceArray, ebpfArray, arkTsArray, hiPerfArray]); + const file = new File([fileBlob], this.traceFileName); + this.handleWasmMode(file, file.name, file.size, file.name); } - }, + }); + }); + } + + private getTraceFileByPage(pageNumber: number): void { + this.openFileInit(); + if (this.validateGetTraceFileByPage()) { + let indexedDbPageNum = pageNumber - 1; + let maxTraceFileLength = 400 * 1024 * 1024; + let traceRange = this.getIDBKeyRange(indexedDbPageNum, 'trace'); + let instance = LongTraceDBUtils.getInstance(); + this.queryFileByPage(instance, indexedDbPageNum, maxTraceFileLength, traceRange); + } + } + + private traceFileLoadFailedHandler(reason: string): void { + this.litSearch!.isLoading = false; + this.litSearch!.setPercent(reason, -1); + this.progressEL!.loading = false; + this.freshMenuDisable(false); + } + + private getIDBKeyRange(indexedDbPageNum: number, key: string): IDBKeyRange { + return IDBKeyRange.bound( + [this.pageTimStamp, key, indexedDbPageNum], + [this.pageTimStamp, key, indexedDbPageNum], + false, false ); - body!.addEventListener( - 'dragleave', - (e) => { - e.stopPropagation(); - e.preventDefault(); - if (this.rootEL!.classList.contains('filedrag')) { - this.rootEL!.classList.remove('filedrag'); - } - }, - false + } + + private refreshPageListHandler( + pageListDiv: HTMLDivElement, + previewButton: HTMLDivElement, + nextButton: HTMLDivElement, + pageInput: HTMLInputElement + ): void { + this.progressEL!.loading = true; + this.refreshPageList( + pageListDiv, + previewButton!, + nextButton!, + pageInput!, + this.currentPageNum, + this.longTraceHeadMessageList.length ); - body!.addEventListener( - 'drop', - (e: any) => { - e.preventDefault(); - e.stopPropagation(); - if (this.rootEL!.classList.contains('filedrag')) { - this.rootEL!.classList.remove('filedrag'); - } - if (e.dataTransfer.items !== undefined && e.dataTransfer.items.length > 0) { - let item = e.dataTransfer.items[0]; - if (item.webkitGetAsEntry()?.isFile) { - openTraceFile(item.getAsFile()); - } else if (item.webkitGetAsEntry()?.isDirectory) { - litSearch.setPercent('This File is not supported!', -1); - progressEL.loading = false; - that.freshMenuDisable(false); - mainMenu.menus!.splice(1, 1); - mainMenu.menus = mainMenu.menus!; - spSystemTrace!.reset(null); + this.getTraceFileByPage(this.currentPageNum); + } + + private sendCutFileMessage(timStamp: number): void { + this.pageTimStamp = timStamp; + threadPool.init('wasm').then(() => { + let headUintArray = new Uint8Array(this.longTraceHeadMessageList.length * 1024); + let headOffset = 0; + this.longTraceHeadMessageList = this.longTraceHeadMessageList.sort( + (leftMessage, rightMessage) => leftMessage.pageNum - rightMessage.pageNum + ); + for (let index = 0; index < this.longTraceHeadMessageList.length; index++) { + let currentUintArray = new Uint8Array(this.longTraceHeadMessageList[index].data); + headUintArray.set(currentUintArray, headOffset); + headOffset += currentUintArray.length; + } + threadPool.submit( + 'ts-cut-file', + '', + { + headArray: headUintArray, + timeStamp: timStamp, + splitFileInfo: this.longTraceTypeMessageMap?.get(0), + splitDataList: this.longTraceDataList, + }, + (res: Array) => { + this.litSearch!.setPercent('Cut in file ', 100); + if (this.longTraceHeadMessageList.length > 0) { + this.getTraceFileByPage(this.currentPageNum); + this.litSearch!.style.marginLeft = '80px'; + this.longTracePage!.style.display = 'flex'; + this.initCutFileEvent(); + } else { + this.progressEL!.loading = false; + this.litSearch!.setPercent('The basic trace file in the large-file scenario is missing!', -1); + this.freshMenuDisable(false); + return; } + }, + 'long_trace' + ); + }); + } + + private initCutFileEvent(): void { + let pageListDiv = this.shadowRoot?.querySelector('.page-number-list') as HTMLDivElement; + let previewButton: HTMLDivElement | null | undefined = + this.shadowRoot?.querySelector('#preview-button'); + let nextButton: HTMLDivElement | null | undefined = this.shadowRoot?.querySelector('#next-button'); + let pageInput = this.shadowRoot?.querySelector('.page-input'); + pageListDiv.innerHTML = ''; + this.refreshPageList( + pageListDiv, + previewButton!, + nextButton!, + pageInput!, + this.currentPageNum, + this.longTraceHeadMessageList.length + ); + this.initCutFileNextOrPreEvents(previewButton!, nextButton!, pageListDiv, pageInput!); + let nodeListOf = pageListDiv.querySelectorAll('div'); + nodeListOf.forEach((divEL, index) => { + divEL.addEventListener('click', () => { + if (this.progressEL!.loading) { + return; } + if (divEL.textContent === '...') { + let freeSize = Number(nodeListOf[index + 1].textContent) - Number(nodeListOf[index - 1].textContent); + this.currentPageNum = Math.floor(freeSize / 2 + Number(nodeListOf[index - 1].textContent)); + } else { + this.currentPageNum = Number(divEL.textContent); + } + this.refreshPageListHandler(pageListDiv, previewButton!, nextButton!, pageInput!); + }); + }); + pageInput!.addEventListener('input', () => { + let value = pageInput!.value; + value = value.replace(/\D/g, ''); + if (value) { + value = Math.min(this.longTraceHeadMessageList.length, parseInt(value)).toString(); + } + pageInput!.value = value; + }); + let pageConfirmEl = this.shadowRoot?.querySelector('.confirm-button'); + pageConfirmEl!.addEventListener('click', () => { + if (this.progressEL!.loading) { + return; + } + this.currentPageNum = Number(pageInput!.value); + this.refreshPageListHandler(pageListDiv, previewButton!, nextButton!, pageInput!); + }); + } + + private initCutFileNextOrPreEvents( + previewButton: HTMLDivElement, + nextButton: HTMLDivElement, + pageListDiv: HTMLDivElement, + pageInput: HTMLInputElement + ): void { + if (previewButton) { + previewButton.addEventListener('click', () => { + if (this.progressEL!.loading || this.currentPageNum === 1) { + return; + } + if (this.currentPageNum > 1) { + this.currentPageNum--; + this.refreshPageListHandler(pageListDiv, previewButton!, nextButton!, pageInput!); + } + }); + } + nextButton!.addEventListener('click', () => { + if (this.progressEL!.loading || this.currentPageNum === this.longTraceHeadMessageList.length) { + return; + } + if (this.currentPageNum < this.longTraceHeadMessageList.length) { + this.currentPageNum++; + this.refreshPageListHandler(pageListDiv, previewButton!, nextButton!, pageInput!); + } + }); + } + + private initCustomColorHandler(): void { + let customColorShow = this.shadowRoot + ?.querySelector('lit-main-menu')! + .shadowRoot!.querySelector('.customColor') as HTMLDivElement; + customColorShow.addEventListener('click', (ev) => { + if (this!.hasAttribute('custom-color')) { + this!.removeAttribute('custom-color'); + this.customColor!.setAttribute('hidden', ''); + this.customColor!.cancelOperate(); + } else { + this!.removeAttribute('chart_filter'); + this.chartFilter!.setAttribute('hidden', ''); + this!.setAttribute('custom-color', ''); + this.customColor!.removeAttribute('hidden'); + } + }); + } + + private openFileInit(): void { + clearTraceFileCache(); + this.litSearch!.clear(); + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'open_trace', + action: 'open_trace', + }); + info('openTraceFile'); + this.spSystemTrace!.clearPointPair(); + this.spSystemTrace!.reset((command: string, percent: number) => { + this.setProgress(command); + }); + window.publish(window.SmartEvent.UI.MouseEventEnable, { + mouseEnable: false, + }); + window.clearTraceRowComplete(); + this.freshMenuDisable(true); + SpSchedulingAnalysis.resetCpu(); + if (this.mainMenu!.menus!.length > 3) { + this.mainMenu!.menus!.splice(1, 2); + this.mainMenu!.menus = this.mainMenu!.menus!; + } else if (this.mainMenu!.menus!.length > 2) { + this.mainMenu!.menus!.splice(1, 1); + this.mainMenu!.menus = this.mainMenu!.menus!; + } + this.showContent(this.spSystemTrace!); + this.progressEL!.loading = true; + } + + private restoreDownLoadIcons() { + let querySelectorAll = this.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-group'); + querySelectorAll!.forEach((menuGroup) => { + let attribute = menuGroup.getAttribute('title'); + if (attribute === 'Convert trace') { + let querySelectors = menuGroup.querySelectorAll('lit-main-menu-item'); + querySelectors.forEach((item) => { + if (item.getAttribute('title') === 'Convert to .systrace') { + item!.setAttribute('icon', 'download'); + let querySelector = item!.shadowRoot?.querySelector('.icon') as LitIcon; + querySelector.removeAttribute('spin'); + } + }); + } + }); + } + + private postConvert(fileName: string): void { + let newFileName = fileName.substring(0, fileName.lastIndexOf('.')) + '.systrace'; + let aElement = document.createElement('a'); + convertPool.submitWithName('getConvertData', (status: boolean, msg: string, results: Blob) => { + aElement.href = URL.createObjectURL(results); + aElement.download = newFileName; + let timeoutId = 0; + aElement.addEventListener('click', (ev) => { + clearTimeout(timeoutId); + timeoutId = window.setTimeout(() => { + this.restoreDownLoadIcons(); + }, 2000); + }); + aElement.click(); + window.URL.revokeObjectURL(aElement.href); + }); + } + + private pushConvertTrace(fileName: string): Array { + let instance = this; + let menus = []; + menus.push({ + title: 'Convert to .systrace', + icon: 'download', + clickHandler: function () { + convertPool.init('convert').then((item) => { + let querySelectorAll = + instance.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-group'); + querySelectorAll!.forEach((menuGroup) => { + let attribute = menuGroup.getAttribute('title'); + if (attribute === 'Convert trace') { + let querySelectors = menuGroup.querySelectorAll('lit-main-menu-item'); + querySelectors.forEach((item) => { + if (item.getAttribute('title') === 'Convert to .systrace') { + item!.setAttribute('icon', 'convert-loading'); + item!.classList.add('pending'); + item!.style.fontKerning = ''; + let querySelector = item!.shadowRoot?.querySelector('.icon') as LitIcon; + querySelector.setAttribute('spin', ''); + } + }); + } + }); + instance.postConvert(fileName); + }); }, - false - ); - document.addEventListener('keydown', (event) => { - const e = event || window.event; - const ctrlKey = e.ctrlKey || e.metaKey; - if (ctrlKey && (this.keyCodeMap as any)[e.keyCode]) { - e.preventDefault(); - } else if (e.detail) { - // Firefox - event.returnValue = false; - } }); - document.body.addEventListener( - 'wheel', - (e) => { - if (e.ctrlKey) { - if (e.deltaY < 0) { - e.preventDefault(); - return false; - } - if (e.deltaY > 0) { - e.preventDefault(); - return false; - } - } + return menus; + } + + private setProgress(command: string): void { + if (command === 'database ready' && SpApplication.loadingProgress < 50) { + SpApplication.progressStep = 6; + } + if (command === 'process' && SpApplication.loadingProgress < 92) { + SpApplication.loadingProgress = 92 + Math.round(Math.random() * SpApplication.progressStep); + } else { + SpApplication.loadingProgress += Math.round(Math.random() * SpApplication.progressStep + Math.random()); + } + if (SpApplication.loadingProgress > 99) { + SpApplication.loadingProgress = 99; + } + info('setPercent :' + command + 'percent :' + SpApplication.loadingProgress); + this.litSearch!.setPercent(command + ' ', SpApplication.loadingProgress); + } + + private getTraceOptionMenus( + showFileName: string, + fileSize: string, + fileName: string, + isServer: boolean, + dbName?: string + ): Array { + let menus = [ + { + title: `${showFileName} (${fileSize}M)`, + icon: 'file-fill', + clickHandler: (): void => { + this.search = true; + this.showContent(this.spSystemTrace!); + }, }, - { passive: false } - ); + { + title: 'Scheduling Analysis', + icon: 'piechart-circle-fil', + clickHandler: (): void => { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'Scheduling Analysis', + action: 'scheduling_analysis', + }); + this.showContent(this.spSchedulingAnalysis!); + this.spSchedulingAnalysis!.init(); + }, + }, + { + title: 'Download File', + icon: 'download', + clickHandler: (): void => { + this.download(this.mainMenu!, fileName, isServer, dbName); + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'download', + action: 'download', + }); + }, + }, + { + title: 'Download Database', + icon: 'download', + clickHandler: (): void => { + this.downloadDB(this.mainMenu!, fileName); + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'download_db', + action: 'download', + }); + }, + }, + ]; + this.getTraceQuerySqlMenus(menus); + if ((window as any).cpuCount === 0 || !FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis')) { + menus.splice(1, 1); + } + return menus; + } + + private getTraceQuerySqlMenus(menus: Array): void { + if (this.querySql) { + if (this.spQuerySQL) { + this.spQuerySQL!.reset(); + menus.push({ + title: 'Query (SQL)', + icon: 'filesearch', + clickHandler: () => { + this.showContent(this.spQuerySQL!); + }, + }); + } + if (this.spMetrics) { + this.spMetrics!.reset(); + menus.push({ + title: 'Metrics', + icon: 'metric', + clickHandler: () => { + this.showContent(this.spMetrics!); + }, + }); + } + if (this.spInfoAndStats) { + menus.push({ + title: 'Info and stats', + icon: 'info', + clickHandler: () => { + SpStatisticsHttpUtil.addOrdinaryVisitAction({ + event: 'info', + action: 'info_stats', + }); + this.showContent(this.spInfoAndStats!); + }, + }); + } + } + } - const openMenu = (open: boolean) => { - if (mainMenu) { - mainMenu.style.width = open ? `248px` : '0px'; - mainMenu.style.zIndex = open ? '2000' : '0'; + private initSlideMenuEvents(): void { + //打开侧边栏 + this.sidebarButton!.onclick = (e): void => { + if (this.mainMenu) { + this.mainMenu.style.width = '248px'; + this.mainMenu.style.zIndex = '2000'; + this.mainMenu.style.display = 'flex'; } - if (sidebarButton) { - sidebarButton.style.width = open ? `0px` : '48px'; - importConfigDiv!.style.left = open ? '5px' : '45px'; - closeKeyPath!.style.left = open ? '25px' : '65px'; + if (this.sidebarButton) { + this.sidebarButton.style.width = '0px'; + this.importConfigDiv!.style.left = '5px'; + this.closeKeyPath!.style.left = '25px'; } }; - let urlParams = new URL(window.location.href).searchParams; - if (urlParams && urlParams.get('trace') && urlParams.get('link')) { - openFileInit(); - openMenu(false); - litSearch.clear(); - showContent(spSystemTrace!); - that.search = true; - progressEL.loading = true; - let downloadLineFile = false; - if (urlParams.get('local')) { - downloadLineFile = false; - } else { - downloadLineFile = true; + let icon: HTMLDivElement | undefined | null = this.mainMenu?.shadowRoot?.querySelector('div.header > div'); + icon!.style.pointerEvents = 'none'; + icon!.onclick = (e): void => { + if (this.mainMenu) { + this.mainMenu.style.width = '0px'; + this.mainMenu.style.display = 'flex'; + this.mainMenu.style.zIndex = '0'; } - setProgress(downloadLineFile ? 'download trace file' : 'open trace file'); - this.downloadOnLineFile( - urlParams.get('trace') as string, - downloadLineFile, - (arrayBuf, fileName, showFileName, fileSize) => { - handleWasmMode(new File([arrayBuf], fileName), showFileName, fileSize, fileName); - }, - (localPath) => { - let path = urlParams.get('trace') as string; - let fileName: string = ''; - let showFileName: string = ''; - if (urlParams.get('local')) { - openMenu(true); - fileName = urlParams.get('traceName') as string; + if (this.sidebarButton) { + this.sidebarButton.style.width = '48px'; + this.importConfigDiv!.style.left = '45px'; + this.closeKeyPath!.style.left = '65px'; + } + }; + } + + private initImportConfigEvent(): void { + this.importFileBt?.addEventListener('change', (): void => { + let files = this.importFileBt!.files; + if (files && files.length === 1) { + const reader = new FileReader(); + reader.readAsText(files[0], 'UTF-8'); + reader.onload = (e): void => { + if (e.target?.result) { + try { + const result = parseKeyPathJson(e.target.result as string); + window.publish(window.SmartEvent.UI.KeyPath, result); + this.closeKeyPath!.style.display = 'block'; + } catch { + error('json Parse Failed'); + this.litSearch!.setPercent('Json Parse Failed!', -1); + window.setTimeout(() => { + this.litSearch!.setPercent('Json Parse Failed!', 101); + }, 1000); + } } else { - fileName = path.split('/').reverse()[0]; + window.publish(window.SmartEvent.UI.KeyPath, []); + this.closeKeyPath!.style.display = 'none'; } - that.traceFileName = fileName; - showFileName = fileName.lastIndexOf('.') == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); - TraceRow.rangeSelectObject = undefined; - let localUrl = downloadLineFile ? `${window.location.origin}${localPath}` : urlParams.get('trace')!; - fetch(localUrl) - .then((res) => { - res.arrayBuffer().then((arrayBuf) => { - if (urlParams.get('local')) { - URL.revokeObjectURL(localUrl); - } - let fileSize = (arrayBuf.byteLength / 1048576).toFixed(1); - postLog(fileName, fileSize); - document.title = `${showFileName} (${fileSize}M)`; - info('Parse trace using wasm mode '); - handleWasmMode(new File([arrayBuf], fileName), showFileName, fileSize, fileName); - }); - }) - .catch((e) => { - if (!downloadLineFile) { - const firstQuestionMarkIndex = window.location.href.indexOf('?'); - location.replace(window.location.href.substring(0, firstQuestionMarkIndex)); - } - }); - } + }; + } + this.importFileBt!.files = null; + this.importFileBt!.value = ''; + }); + if (this.closeKeyPath) { + this.closeKeyPath.addEventListener('click', (): void => { + window.publish(window.SmartEvent.UI.KeyPath, []); + this.closeKeyPath!.style.display = 'none'; + }); + } + } + + private initCustomEvents(): void { + window.subscribe(window.SmartEvent.UI.MenuTrace, () => this.showContent(this.spSystemTrace!)); + window.subscribe(window.SmartEvent.UI.Error, (err) => { + this.litSearch!.setPercent(err, -1); + this.progressEL!.loading = false; + this.freshMenuDisable(false); + }); + window.subscribe(window.SmartEvent.UI.Loading, (arg: { loading: boolean; text?: string }) => { + if (arg.text) { + this.litSearch!.setPercent(arg.text || '', arg.loading ? -1 : 101); + } + window.publish(window.SmartEvent.UI.MouseEventEnable, { + mouseEnable: !arg.loading, + }); + this.progressEL!.loading = arg.loading; + }); + } + + private initEvents(): void { + this.addEventListener('copy', function (event) { + let clipdata = event.clipboardData; + let value = clipdata!.getData('text/plain'); + let searchValue = value.toString().trim(); + clipdata!.setData('text/plain', searchValue); + }); + this.initSearchEvents(); + this.initSystemTraceEvents(); + this.filterConfig!.addEventListener('click', (ev) => { + if (this!.hasAttribute('chart_filter')) { + this!.removeAttribute('chart_filter'); + this.chartFilter!.setAttribute('hidden', ''); + } else { + this!.removeAttribute('custom-color'); + this.customColor!.setAttribute('hidden', ''); + this.customColor!.cancelOperate(); + this!.setAttribute('chart_filter', ''); + this.chartFilter!.removeAttribute('hidden'); + } + }); + this.configClose!.addEventListener('click', (ev) => { + if (this.hasAttribute('chart_filter')) { + this!.removeAttribute('chart_filter'); + } + }); + this.cutTraceFile!.addEventListener('click', () => { + this.croppingFile(this.progressEL!, this.litSearch!); + }); + } + + private initSearchChangeEvents(): void { + this.litSearch!.valueChangeHandler = (value: string): void => { + this.litSearch!.isClearValue = false; + if (value.length > 0) { + let list: any[] = []; + this.progressEL!.loading = true; + this.spSystemTrace!.searchCPU(value).then((cpus) => { + list = cpus; + this.spSystemTrace!.searchFunction(list, value).then((mixedResults) => { + if (this.litSearch!.searchValue !== '') { + this.litSearch!.list = this.spSystemTrace!.searchSdk(mixedResults, value); + this.litSearch!.index = this.spSystemTrace!.showStruct(false, -1, this.litSearch!.list); + } + this.progressEL!.loading = false; + }); + }); + } else { + let indexEL = this.litSearch!.shadowRoot!.querySelector('#index'); + indexEL!.textContent = '0'; + this.litSearch!.list = []; + this.spSystemTrace?.visibleRows.forEach((it) => { + it.highlight = false; + it.draw(); + }); + this.spSystemTrace?.timerShaftEL?.removeTriangle('inverted'); + } + }; + } + private initSearchEvents(): void { + this.litSearch!.addEventListener('focus', () => { + window.publish(window.SmartEvent.UI.KeyboardEnable, { + enable: false, + }); + }); + this.litSearch!.addEventListener('blur', () => { + window.publish(window.SmartEvent.UI.KeyboardEnable, { + enable: true, + }); + }); + this.litSearch!.addEventListener('previous-data', (ev: any) => { + this.litSearch!.index = this.spSystemTrace!.showStruct(true, this.litSearch!.index, this.litSearch!.list); + this.litSearch!.blur(); + }); + this.litSearch!.addEventListener('next-data', (ev: any) => { + this.litSearch!.index = this.spSystemTrace!.showStruct(false, this.litSearch!.index, this.litSearch!.list); + this.litSearch!.blur(); + }); + // 翻页事件 + this.litSearch!.addEventListener('retarget-data', (ev: any) => { + this.litSearch!.index = this.spSystemTrace!.showStruct( + true, + ev.detail.value, + this.litSearch!.list, + ev.detail.value ); + this.litSearch!.blur(); + }); + this.initSearchChangeEvents(); + } + + private initSystemTraceEvents(): void { + this.spSystemTrace?.addEventListener('trace-previous-data', (ev: any) => { + this.litSearch!.index = this.spSystemTrace!.showStruct(true, this.litSearch!.index, this.litSearch!.list); + }); + this.spSystemTrace?.addEventListener('trace-next-data', (ev: any) => { + this.litSearch!.index = this.spSystemTrace!.showStruct(false, this.litSearch!.index, this.litSearch!.list); + }); + } + + private showContent(showNode: HTMLElement): void { + if (showNode === this.spSystemTrace) { + this.menu!.style.pointerEvents = 'auto'; + this.sidebarButton!.style.pointerEvents = 'auto'; + this.search = true; + this.litRecordSearch!.style.display = 'none'; + this.litSearch!.style.display = 'block'; + window.publish(window.SmartEvent.UI.KeyboardEnable, { + enable: true, + }); + this.filterConfig!.style.visibility = 'visible'; } else { - openMenu(true); + this.removeAttribute('custom-color'); + this.customColor!.setAttribute('hidden', ''); + this.customColor!.cancelOperate(); + this.menu!.style.pointerEvents = 'none'; + this.sidebarButton!.style.pointerEvents = 'none'; + this.search = this.litSearch!.isLoading; + if (!this.search) { + this.litSearch!.style.display = 'none'; + this.litRecordSearch!.style.display = 'block'; + } + window.publish(window.SmartEvent.UI.KeyboardEnable, { + enable: false, + }); + this.filterConfig!.style.visibility = 'hidden'; } + this.childComponent!.forEach((node) => { + if (this.hasAttribute('chart_filter')) { + this.removeAttribute('chart_filter'); + } + if (this.hasAttribute('custom-color')) { + this.removeAttribute('custom-color'); + this.customColor!.setAttribute('hidden', ''); + this.customColor!.cancelOperate(); + } + if (node === showNode) { + showNode.style.visibility = 'visible'; + } else { + (node! as HTMLElement).style.visibility = 'hidden'; + } + }); + } + + private validateFileCacheLost(): void { + caches.has(DbPool.fileCacheKey).then((exist) => { + if (!exist) { + this.mainMenu!.menus?.forEach((mg) => { + mg.children.forEach((mi: any) => { + if (mi.title === 'Download File') { + mi.disabled = true; + } + }); + }); + this.cutTraceFile!.style.display = 'none'; + this.mainMenu!.menus = this.mainMenu!.menus; + } + }); } private refreshPageList( @@ -1727,51 +1683,28 @@ export class SpApplication extends BaseElement { } let pageText: string[] = []; if (maxPageNumber > 7) { - switch (currentPageNum) { - case 1: - case 2: - case 3: - case 4: - case 5: - pageText = ['1', '2', '3', '4', '5', '...', maxPageNumber.toString()]; - break; - case maxPageNumber: - case maxPageNumber - 1: - case maxPageNumber - 2: - case maxPageNumber - 3: - case maxPageNumber - 4: - pageText = [ - '1', - '...', - (maxPageNumber - 4).toString(), - (maxPageNumber - 3).toString(), - (maxPageNumber - 2).toString(), - (maxPageNumber - 1).toString(), - maxPageNumber.toString(), - ]; - break; - default: - nextButton.style.pointerEvents = 'auto'; - previewButton!.style.pointerEvents = 'auto'; - nextButton.style.opacity = '1'; - previewButton!.style.opacity = '1'; - pageText = [ - '1', - '...', - (currentPageNum - 1).toString(), - currentPageNum.toString(), - (currentPageNum + 1).toString(), - '...', - maxPageNumber.toString(), - ]; - break; - } + pageText = this.largePageHandler(currentPageNum, maxPageNumber, previewButton, nextButton); } else { pageText = []; for (let index = 0; index < maxPageNumber; index++) { pageText.push((index + 1).toString()); } } + this.pageNodeHandler(pageListDiv, pageText, currentPageNum); + nextButton.style.pointerEvents = 'auto'; + nextButton.style.opacity = '1'; + previewButton.style.pointerEvents = 'auto'; + previewButton.style.opacity = '1'; + if (currentPageNum === 1) { + previewButton.style.pointerEvents = 'none'; + previewButton.style.opacity = '0.7'; + } else if (currentPageNum === maxPageNumber) { + nextButton.style.pointerEvents = 'none'; + nextButton.style.opacity = '0.7'; + } + } + + private pageNodeHandler(pageListDiv: HTMLDivElement, pageText: Array, currentPageNum: number): void { let pageNodeList = pageListDiv.querySelectorAll('div'); if (pageNodeList.length > 0) { pageNodeList.forEach((page, index) => { @@ -1798,16 +1731,49 @@ export class SpApplication extends BaseElement { pageListDiv.appendChild(element); }); } - nextButton.style.pointerEvents = 'auto'; - nextButton.style.opacity = '1'; - previewButton.style.pointerEvents = 'auto'; - previewButton.style.opacity = '1'; - if (currentPageNum === 1) { - previewButton.style.pointerEvents = 'none'; - previewButton.style.opacity = '0.7'; - } else if (currentPageNum === maxPageNumber) { - nextButton.style.pointerEvents = 'none'; - nextButton.style.opacity = '0.7'; + } + + private largePageHandler( + currentPageNum: number, + maxPageNumber: number, + previewButton: HTMLDivElement, + nextButton: HTMLDivElement + ): Array { + switch (currentPageNum) { + case 1: + case 2: + case 3: + case 4: + case 5: + return ['1', '2', '3', '4', '5', '...', maxPageNumber.toString()]; + case maxPageNumber: + case maxPageNumber - 1: + case maxPageNumber - 2: + case maxPageNumber - 3: + case maxPageNumber - 4: + return [ + '1', + '...', + (maxPageNumber - 4).toString(), + (maxPageNumber - 3).toString(), + (maxPageNumber - 2).toString(), + (maxPageNumber - 1).toString(), + maxPageNumber.toString(), + ]; + default: + nextButton.style.pointerEvents = 'auto'; + previewButton!.style.pointerEvents = 'auto'; + nextButton.style.opacity = '1'; + previewButton!.style.opacity = '1'; + return [ + '1', + '...', + (currentPageNum - 1).toString(), + currentPageNum.toString(), + (currentPageNum + 1).toString(), + '...', + maxPageNumber.toString(), + ]; } } @@ -1816,94 +1782,96 @@ export class SpApplication extends BaseElement { * @param theme 当前主题(深色和浅色) * @param colorsArray 预览的情况下传入 */ - changeTheme(theme: Theme, colorsArray?: Array) { - let systemTrace = this.shadowRoot!.querySelector('#sp-system-trace'); - let menu: HTMLDivElement | undefined | null = this.shadowRoot?.querySelector('#main-menu'); - let menuGroup = menu!.shadowRoot?.querySelectorAll('lit-main-menu-group'); - let menuItem = menu!.shadowRoot?.querySelectorAll('lit-main-menu-item'); - let customColor = this.shadowRoot?.querySelector('.custom-color') as CustomThemeColor; + changeTheme(theme: Theme, colorsArray?: Array): void { if (!colorsArray) { - customColor.setRadioChecked(theme); + this.customColor!.setRadioChecked(theme); } if (theme === Theme.DARK) { - menu!.style.backgroundColor = '#262f3c'; - menu!.style.transition = '1s'; - menuGroup!.forEach((item) => { - let groupName = item!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; - let groupDescribe = item!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; - groupName.style.color = 'white'; - groupDescribe.style.color = 'white'; - }); - menuItem!.forEach((item) => { - item.style.color = 'white'; - }); - if ( - !colorsArray && - window.localStorage.getItem('DarkThemeColors') && - ColorUtils.FUNC_COLOR_B !== JSON.parse(window.localStorage.getItem('DarkThemeColors')!) - ) { - ColorUtils.MD_PALETTE = JSON.parse(window.localStorage.getItem('DarkThemeColors')!); - ColorUtils.FUNC_COLOR = JSON.parse(window.localStorage.getItem('DarkThemeColors')!); - } else if (colorsArray) { - ColorUtils.MD_PALETTE = colorsArray; - ColorUtils.FUNC_COLOR = colorsArray; - } else { - ColorUtils.MD_PALETTE = ColorUtils.FUNC_COLOR_B; - ColorUtils.FUNC_COLOR = ColorUtils.FUNC_COLOR_B; - } + this.changeDarkTheme(colorsArray); } else { - menu!.style.backgroundColor = 'white'; - menu!.style.transition = '1s'; - menuGroup!.forEach((item) => { - let groupName = item!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; - let groupDescribe = item!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; - groupName.style.color = 'black'; - groupDescribe.style.color = '#92959b'; - }); - menuItem!.forEach((item) => { - item.style.color = 'black'; - }); - if ( - !colorsArray && - window.localStorage.getItem('LightThemeColors') && - ColorUtils.FUNC_COLOR_A !== JSON.parse(window.localStorage.getItem('LightThemeColors')!) - ) { - ColorUtils.MD_PALETTE = JSON.parse(window.localStorage.getItem('LightThemeColors')!); - ColorUtils.FUNC_COLOR = JSON.parse(window.localStorage.getItem('LightThemeColors')!); - } else if (colorsArray) { - ColorUtils.MD_PALETTE = colorsArray; - ColorUtils.FUNC_COLOR = colorsArray; - } else { - ColorUtils.MD_PALETTE = ColorUtils.FUNC_COLOR_A; - ColorUtils.FUNC_COLOR = ColorUtils.FUNC_COLOR_A; - } + this.changeLightTheme(colorsArray); } - systemTrace!.timerShaftEL!.rangeRuler!.draw(); + this.spSystemTrace!.timerShaftEL!.rangeRuler!.draw(); if (this.colorTransiton) { clearTimeout(this.colorTransiton); } - this.colorTransiton = setTimeout(() => { - menu!.style.transition = '0s'; - }, 1000); + this.colorTransiton = setTimeout(() => (this.mainMenu!.style.transition = '0s'), 1000); + } + + private changeDarkTheme(colorsArray?: Array): void { + let menuGroup = this.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-group'); + let menuItem = this.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-item'); + this.mainMenu!.style.backgroundColor = '#262f3c'; + this.mainMenu!.style.transition = '1s'; + menuGroup!.forEach((item) => { + let groupName = item!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; + let groupDescribe = item!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; + groupName.style.color = 'white'; + groupDescribe.style.color = 'white'; + }); + menuItem!.forEach((item) => { + item.style.color = 'white'; + }); + if ( + !colorsArray && + window.localStorage.getItem('DarkThemeColors') && + ColorUtils.FUNC_COLOR_B !== JSON.parse(window.localStorage.getItem('DarkThemeColors')!) + ) { + ColorUtils.MD_PALETTE = JSON.parse(window.localStorage.getItem('DarkThemeColors')!); + ColorUtils.FUNC_COLOR = JSON.parse(window.localStorage.getItem('DarkThemeColors')!); + } else if (colorsArray) { + ColorUtils.MD_PALETTE = colorsArray; + ColorUtils.FUNC_COLOR = colorsArray; + } else { + ColorUtils.MD_PALETTE = ColorUtils.FUNC_COLOR_B; + ColorUtils.FUNC_COLOR = ColorUtils.FUNC_COLOR_B; + } + } + + private changeLightTheme(colorsArray?: Array): void { + let menuGroup = this.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-group'); + let menuItem = this.mainMenu!.shadowRoot?.querySelectorAll('lit-main-menu-item'); + this.mainMenu!.style.backgroundColor = 'white'; + this.mainMenu!.style.transition = '1s'; + menuGroup!.forEach((item) => { + let groupName = item!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; + let groupDescribe = item!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; + groupName.style.color = 'black'; + groupDescribe.style.color = '#92959b'; + }); + menuItem!.forEach((item) => { + item.style.color = 'black'; + }); + if ( + !colorsArray && + window.localStorage.getItem('LightThemeColors') && + ColorUtils.FUNC_COLOR_A !== JSON.parse(window.localStorage.getItem('LightThemeColors')!) + ) { + ColorUtils.MD_PALETTE = JSON.parse(window.localStorage.getItem('LightThemeColors')!); + ColorUtils.FUNC_COLOR = JSON.parse(window.localStorage.getItem('LightThemeColors')!); + } else if (colorsArray) { + ColorUtils.MD_PALETTE = colorsArray; + ColorUtils.FUNC_COLOR = colorsArray; + } else { + ColorUtils.MD_PALETTE = ColorUtils.FUNC_COLOR_A; + ColorUtils.FUNC_COLOR = ColorUtils.FUNC_COLOR_A; + } } private downloadOnLineFile( url: string, download: boolean, - openUrl: (buffer: ArrayBuffer, fileName: string, showFileName: string, fileSize: string) => void, + openUrl: (buffer: ArrayBuffer, fileName: string, showFileName: string, fileSize: number) => void, openFileHandler: (path: string) => void - ) { + ): void { if (download) { fetch(url) .then((res) => { res.arrayBuffer().then((arrayBuf) => { - let fileSize = (arrayBuf.byteLength / 1048576).toFixed(1); let fileName = url.split('/').reverse()[0]; - document.title = `${fileName} (${fileSize}M)`; - info('Parse trace using wasm mode '); let showFileName = - fileName.lastIndexOf('.') == -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); - openUrl(arrayBuf, fileName, showFileName, fileSize); + fileName.lastIndexOf('.') === -1 ? fileName : fileName.substring(0, fileName.lastIndexOf('.')); + openUrl(arrayBuf, fileName, showFileName, arrayBuf.byteLength); }); }) .catch((e) => { @@ -1932,7 +1900,7 @@ export class SpApplication extends BaseElement { } } - private croppingFile(progressEL: LitProgressBar, litSearch: LitSearch) { + private croppingFile(progressEL: LitProgressBar, litSearch: LitSearch): void { let cutLeftNs = TraceRow.rangeSelectObject?.startNS || 0; let cutRightNs = TraceRow.rangeSelectObject?.endNS || 0; if (cutRightNs === cutLeftNs) { @@ -1957,7 +1925,7 @@ export class SpApplication extends BaseElement { let cutIndex = traceFileName.indexOf('_cut_'); let fileType = traceFileName.substring(traceFileName.lastIndexOf('.')); let traceName = document.title.replace(/\s*\([^)]*\)/g, '').trim(); - if (cutIndex != -1) { + if (cutIndex !== -1) { traceName = traceName.substring(0, cutIndex); } let blobUrl = URL.createObjectURL(new Blob([cutBuffer!])); @@ -1975,8 +1943,8 @@ export class SpApplication extends BaseElement { }); } - private downloadDB(mainMenu: LitMainMenu, fileDbName: string) { - let fileName = fileDbName?.substring(0, fileDbName?.lastIndexOf('.')) + '.db'; + private downloadDB(mainMenu: LitMainMenu, fileDbName: string): void { + let fileName = `${fileDbName?.substring(0, fileDbName?.lastIndexOf('.'))}.db`; threadPool.submit( 'download-db', '', @@ -1997,52 +1965,17 @@ export class SpApplication extends BaseElement { ); } - readTraceFileBuffer(): Promise { - return new Promise((resolve) => { - caches.match(DbPool.fileCacheKey).then((res) => { - if (res) { - res.arrayBuffer().then((buffer) => { - resolve(buffer); - }); - } else { - resolve(undefined); - } - }); - }); - } - - clearTraceFileCache(): void { - caches.keys().then((keys) => { - keys.forEach((key) => { - if (key === DbPool.fileCacheKey) { - caches.delete(key).then(); - } else if (key.includes('/') && key.includes('-')) { - let splits = key.split('/'); - let keyStr = splits[splits.length - 1]; - let time = keyStr.split('-')[0]; - let fileDate = new Date(parseInt(time)); - if (fileDate.toLocaleDateString() !== new Date().toLocaleDateString()) { - //如果不是当天的缓存则删去缓存文件 - caches.delete(key).then(); - } - } else { - caches.delete(key).then(); - } - }); - }); - } - - private async download(mainMenu: LitMainMenu, fileName: string, isServer: boolean, dbName?: string) { + private async download(mainMenu: LitMainMenu, fileName: string, isServer: boolean, dbName?: string): Promise { let a = document.createElement('a'); if (isServer) { - if (dbName != '') { + if (dbName !== '') { let file = dbName?.substring(0, dbName?.lastIndexOf('.')) + fileName.substring(fileName.lastIndexOf('.')); - a.href = `https://${window.location.host.split(':')[0]}:${window.location.port}` + file; + a.href = `https://${window.location.host.split(':')[0]}:${window.location.port}${file}`; } else { return; } } else { - let buffer = await this.readTraceFileBuffer(); + let buffer = await readTraceFileBuffer(); if (buffer) { a.href = URL.createObjectURL(new Blob([buffer])); } @@ -2058,7 +1991,7 @@ export class SpApplication extends BaseElement { }, 4000); } - private itemIconLoading(mainMenu: LitMainMenu, groupName: string, itemName: string, start: boolean) { + private itemIconLoading(mainMenu: LitMainMenu, groupName: string, itemName: string, start: boolean): void { let currentTraceGroup = mainMenu.shadowRoot?.querySelector( `lit-main-menu-group[title='${groupName}']` ); @@ -2073,22 +2006,16 @@ export class SpApplication extends BaseElement { } } - freshMenuDisable(disable: boolean) { - let mainMenu = this.shadowRoot?.querySelector('#main-menu') as LitMainMenu; + freshMenuDisable(disable: boolean): void { // @ts-ignore - mainMenu.menus[0].children[0].disabled = disable; + this.mainMenu!.menus[0].children[0].disabled = disable; // @ts-ignore - mainMenu.menus[0].children[1].disabled = disable; - if (mainMenu.menus!.length > 2) { + this.mainMenu!.menus[0].children[1].disabled = disable; + if (this.mainMenu!.menus!.length > 2) { // @ts-ignore - mainMenu.menus[1].children.map((it) => (it.disabled = disable)); - } - mainMenu.menus = mainMenu.menus; - let litIcon = this.shadowRoot?.querySelector('.filter-config') as LitIcon; - if (disable) { - litIcon.style.visibility = 'hidden'; - } else { - litIcon.style.visibility = 'visible'; + this.mainMenu!.menus[1].children.map((it) => (it.disabled = disable)); } + this.mainMenu!.menus = this.mainMenu!.menus; + this.filterConfig!.style.visibility = disable ? 'hidden' : 'visible'; } } diff --git a/ide/src/trace/SpApplication.html.ts b/ide/src/trace/SpApplicationPublicFunc.ts similarity index 82% rename from ide/src/trace/SpApplication.html.ts rename to ide/src/trace/SpApplicationPublicFunc.ts index 892b0d28086715bd7e512e27154f2e919eef4a67..87946f84076dd7e0fd1b075c81adc39cbf4e7c4e 100644 --- a/ide/src/trace/SpApplication.html.ts +++ b/ide/src/trace/SpApplicationPublicFunc.ts @@ -12,7 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export const SpApplicationHtml = ` + +import {DbPool} from "./database/SqlLite"; +import {log} from "../log/Log"; + +export const applicationHtml: string = ` +
+
+
CPU 大小核分类
+
Upload
+
+
+
+
+ + `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts b/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts index f9b1a5450c7b1ac07e1c99ea7c64688d553425d0..06ac2b892d65e20d0b62709341393e059159af2a 100644 --- a/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts +++ b/ide/src/trace/component/schedulingAnalysis/CheckCpuSetting.ts @@ -18,6 +18,7 @@ import { LitCheckBox } from '../../../base-ui/checkbox/LitCheckBox'; import '../../../base-ui/checkbox/LitCheckBox'; import { SpSchedulingAnalysis } from './SpSchedulingAnalysis'; import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; +import { CheckCpuSettingHtml } from './CheckCpuSetting.html'; export class CpuSetting { cpu: number = 0; @@ -150,63 +151,6 @@ export class CheckCpuSetting extends BaseElement { } initHtml(): string { - return ` - -
-
-
CPU 大小核分类
-
Upload
-
-
-
-
- - `; + return CheckCpuSettingHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.html.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..8877f47e47eb6156d02dc18123495e163162c3a6 --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.html.ts @@ -0,0 +1,85 @@ +/* + * 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. + */ +export const TabCpuAnalysisHtml = ` + +
+ +
+
+
CPU Statistics By Duration
+ + CPU Idle + CPU Frequency + CPU Irq + +
+
+
+ + + + `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts index 9937fa665a2beaa05af43f70737a8f0505141089..56008c3cdeca9c933e651f8e632ef65f0a763f1b 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuAnalysis.ts @@ -27,6 +27,7 @@ import '../../../base-ui/progress-bar/LitProgressBar'; import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData'; import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; +import { TabCpuAnalysisHtml } from './TabCpuAnalysis.html'; @element('tab-cpu-analysis') export class TabCpuAnalysis extends BaseElement { @@ -185,76 +186,6 @@ export class TabCpuAnalysis extends BaseElement { } initHtml(): string { - return ` - -
- -
-
-
CPU Statistics By Duration
- - CPU Idle - CPU Frequency - CPU Irq - -
-
-
- - - - `; + return TabCpuAnalysisHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.html.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..b54c839b0be37aacf2b9db27091b64803ece0d25 --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.html.ts @@ -0,0 +1,69 @@ +/* + * 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. + */ +export const TabCpuDetailsFrequencyHtml = ` + + +
+
+
Statistics By Duration
+ +
+
+ + + + + + + + + + + +
+
+ + `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts index 296828ea660862891ae42befb0da0718f6e2179b..d9162f63718c73f6bc5c905e8fc3549248452022 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsFrequency.ts @@ -26,6 +26,7 @@ import '../../../base-ui/progress-bar/LitProgressBar'; import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; import './TableNoData'; import { TableNoData } from './TableNoData'; +import { TabCpuDetailsFrequencyHtml } from './TabCpuDetailsFrequency.html'; @element('tab-cpu-details-frequency') export class TabCpuDetailsFrequency extends BaseElement { @@ -224,60 +225,6 @@ export class TabCpuDetailsFrequency extends BaseElement { } initHtml(): string { - return ` - - -
-
-
Statistics By Duration
- -
-
- - - - - - - - - - - -
-
- - `; + return TabCpuDetailsFrequencyHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.html.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..30fa26dfd026b8d6078ad458e7dab7329f4d3fbf --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.html.ts @@ -0,0 +1,65 @@ +/* + * 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. + */ +export const TabCpuDetailsIdleHtml = ` + + +
+
+
Statistics By Duration
+ +
+
+ + + + + + + + + + + +
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts index 1135a125bf58f90df099e484933152b9386f203a..6cf911db0515cdec90bc7c1f5d873e6cd8dc7886 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIdle.ts @@ -25,6 +25,7 @@ import { getDataNo } from './utils/Utils'; import './TableNoData'; import { TableNoData } from './TableNoData'; import { pieChartColors } from '../../../base-ui/chart/pie/LitChartPieData'; +import { TabCpuDetailsIdleHtml } from './TabCpuDetailsIdle.html'; @element('tab-cpu-details-idle') export class TabCpuDetailsIdle extends BaseElement { @@ -211,56 +212,6 @@ export class TabCpuDetailsIdle extends BaseElement { } initHtml(): string { - return ` - - -
-
-
Statistics By Duration
- -
-
- - - - - - - - - - - -
-
- `; + return TabCpuDetailsIdleHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.html.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..3c080cef952cd9212c42c665b8729ed709a2f9df --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.html.ts @@ -0,0 +1,66 @@ +/* + * 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. + */ +export const TabCpuDetailsIrqHtml = ` + + +
+
+
Statistics By Duration
+ +
+
+ + + + + + + + + + + + + +
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts index b1053bda1b64e5d65fe991cd2ad37a4037b8fc9c..68af2c9e7b1d8067ed624ddc6119502431e4aed2 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsIrq.ts @@ -24,6 +24,7 @@ import { LitProgressBar } from '../../../base-ui/progress-bar/LitProgressBar'; import { getDataNo } from './utils/Utils'; import './TableNoData'; import { TableNoData } from './TableNoData'; +import { TabCpuDetailsIrqHtml } from './TabCpuDetailsIrq.html'; @element('tab-cpu-details-irq') export class TabCpuDetailsIrq extends BaseElement { @@ -205,57 +206,6 @@ export class TabCpuDetailsIrq extends BaseElement { } initHtml(): string { - return ` - - -
-
-
Statistics By Duration
- -
-
- - - - - - - - - - - - - -
-
- `; + return TabCpuDetailsIrqHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.html.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..54309260e6316e785eb31026cd6a0b61888a6fc6 --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.html.ts @@ -0,0 +1,91 @@ +/* + * 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. + */ +export const TabCpuDetailsThreadsHtml = ` + + +
+
+
+
+ +
+ +
Threads in Freq
+
+
Statistics By Duration
+ +
+
+ + + + + + + + + + + +
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts index c3fab01344531788992a64179efeef9007c9e2a5..e510e3b9041795558806560bd1b3862ce6034cdc 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabCpuDetailsThreads.ts @@ -22,6 +22,7 @@ import '../../../base-ui/progress-bar/LitProgressBar'; import { getDataNo } from './utils/Utils'; import './TableNoData'; import { TableNoData } from './TableNoData'; +import { TabCpuDetailsThreadsHtml } from './TabCpuDetailsThreads.html'; @element('tab-cpu-details-threads') export class TabCpuDetailsThreads extends BaseElement { @@ -194,82 +195,6 @@ export class TabCpuDetailsThreads extends BaseElement { } initHtml(): string { - return ` - - -
-
-
-
- -
- -
Threads in Freq
-
-
Statistics By Duration
- -
-
- - - - - - - - - - - -
-
- `; + return TabCpuDetailsThreadsHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.html.ts b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..f57b118f9131f61ab00ecb2ba2be2db7f11a4138 --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.html.ts @@ -0,0 +1,64 @@ +/* + * 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. + */ +export const TabThreadAnalysisHtml = ` + +
+
Top20线程大中小核占用率
+
单个线程频点分布
+
Top20单次运行超长线程
+
Top20进程线程数
+
Top20切换次数线程
+
+
+ + + + + +
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts index f92022a7d3e0cbcbf83bf748bf3aa529a1e01acc..cbd6f13372e159f6599eebcde08b2d5981fa08e0 100644 --- a/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts +++ b/ide/src/trace/component/schedulingAnalysis/TabThreadAnalysis.ts @@ -25,6 +25,7 @@ import { Top20ProcessThreadCount } from './Top20ProcessThreadCount'; import { Top20ProcessSwitchCount } from './Top20ProcessSwitchCount'; import { Top20FrequencyThread } from './Top20FrequencyThread'; import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; +import { TabThreadAnalysisHtml } from './TabThreadAnalysis.html'; @element('tab-thread-analysis') export class TabThreadAnalysis extends BaseElement { @@ -111,7 +112,7 @@ export class TabThreadAnalysis extends BaseElement { let event = showContent.id .replace(/_/g, ' ') .toLowerCase() - .replace(/( |^)[a-z]/g, (L) => L.toUpperCase()); + .replace(/( |^)[a-z]/g, (L: string) => L.toUpperCase()); SpStatisticsHttpUtil.addOrdinaryVisitAction({ event: event, action: 'scheduling_analysis', @@ -136,55 +137,6 @@ export class TabThreadAnalysis extends BaseElement { } initHtml(): string { - return ` - -
-
Top20线程大中小核占用率
-
单个线程频点分布
-
Top20单次运行超长线程
-
Top20进程线程数
-
Top20切换次数线程
-
-
- - - - - -
- `; + return TabThreadAnalysisHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.html.ts b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..7bb8b4f6cd15ce4bf86d79b8a8625d89e72f93fe --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.html.ts @@ -0,0 +1,70 @@ +/* + * 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. + */ +export const Top20FrequencyThreadHtml = ` + + +
+ Thread Search + +
+ +
+
+
Statistics By Duration
+ +
+
+
+
+ + + + + + + +
+
+
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts index ca417a2c85d8166d27c910c121f32177a5099dc6..3087644b30dbae208d14cd6d0a3693e0e4b96142 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20FrequencyThread.ts @@ -27,6 +27,7 @@ import './TableNoData'; import { TableNoData } from './TableNoData'; import { getProbablyTime } from '../../database/logic-worker/ProcedureLogicWorkerCommon'; import {queryThreads} from "../../database/sql/ProcessThread.sql"; +import { Top20FrequencyThreadHtml } from './Top20FrequencyThread.html'; @element('top20-frequency-thread') export class Top20FrequencyThread extends BaseElement { @@ -245,61 +246,6 @@ export class Top20FrequencyThread extends BaseElement { } initHtml(): string { - return ` - - -
- Thread Search - -
- -
-
-
Statistics By Duration
- -
-
-
-
- - - - - - - -
-
-
-
- `; + return Top20FrequencyThreadHtml; } } diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.html.ts b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd0507e9dfb01cdfb9e411baf9aad9a353de737d --- /dev/null +++ b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.html.ts @@ -0,0 +1,129 @@ +/* + * 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. + */ +export const Top20ThreadCpuUsageHtml = ` + + + + +
+
+
+ CPU Setting + + +
+
+ +
+
+
Top20线程大中小核占用率
+ +
+
big
+
mid
+
small
+
+
+
+ +
+
+
+
+
Top20线程小核占用率
+ +
+
small
+
+
+
+ +
+
+
+
+
Top20线程中核占用率
+ +
+
mid
+
+
+
+ +
+
+
+
+
Top20线程大核占用率
+ +
+
big
+
+
+
+ +
+
+
+
+ + `; \ No newline at end of file diff --git a/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts index 0e1b72cf582c82592ec38dafe075ed53df2c8883..deb8a101d3bc6c4761de718b891edc4b7aac365c 100644 --- a/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts +++ b/ide/src/trace/component/schedulingAnalysis/Top20ThreadCpuUsage.ts @@ -28,6 +28,7 @@ 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 { @@ -446,120 +447,6 @@ export class Top20ThreadCpuUsage extends BaseElement { } initHtml(): string { - return ` - - - - -
-
-
- CPU Setting - - -
-
- -
-
-
Top20线程大中小核占用率
- -
-
big
-
mid
-
small
-
-
-
- -
-
-
-
-
Top20线程小核占用率
- -
-
small
-
-
-
- -
-
-
-
-
Top20线程中核占用率
- -
-
mid
-
-
-
- -
-
-
-
-
Top20线程大核占用率
- -
-
big
-
-
-
- -
-
-
-
- - `; + return Top20ThreadCpuUsageHtml; } } diff --git a/ide/src/trace/component/setting/SpRecordPerf.ts b/ide/src/trace/component/setting/SpRecordPerf.ts index 86c95802288fbc96679118d51fef9637cc987a64..6a6448d9cc2f8bf395f48c06485b6e5b2d46a7e6 100644 --- a/ide/src/trace/component/setting/SpRecordPerf.ts +++ b/ide/src/trace/component/setting/SpRecordPerf.ts @@ -35,6 +35,7 @@ import { SpRecordPerfHtml } from './SpRecordPerf.html'; export class SpRecordPerf extends BaseElement { private addOptionButton: HTMLButtonElement | undefined | null; private processSelect: LitSelectV | undefined | null; + private processInput: HTMLInputElement | undefined | null; private cpuSelect: LitSelectV | undefined | null; private eventSelect: LitSelectV | undefined | null; @@ -42,7 +43,12 @@ export class SpRecordPerf extends BaseElement { private recordProcessInput: HTMLInputElement | undefined | null; private offCPUSwitch: LitSwitch | undefined | null; private callSelect: LitSelect | undefined | null; - private perfConfigList: Array = []; + private sp: SpApplication | undefined; + private recordPerfSearch: LitSearch | undefined; + private inputCpu: HTMLInputElement | undefined; + private inputEvent: HTMLInputElement | undefined; + private cpuData: Array = []; + private eventData: Array = []; get show(): boolean { return this.hasAttribute('show'); @@ -87,85 +93,59 @@ export class SpRecordPerf extends BaseElement { clockType: 'monotonic', }; recordPerfConfigVal!.forEach((value) => { - switch (value.title) { - case 'Process': - let processSelect = value as LitSelectV; - if (processSelect.all) { - perfConfig.process = 'ALL'; - break; - } - perfConfig = this.perfConfigByProcess(processSelect, perfConfig); - break; - case 'CPU': - let selectV = value as LitSelectV; - if (selectV.value.length > 0) { - perfConfig.cpu = selectV.value; - } - break; - case 'Event List': - let selectList = value as LitSelectV; - if (selectList.value.length > 0) { - perfConfig.eventList = selectList.value.replace(/\s/g, ','); - } - break; - case 'CPU Percent': - let parEle = value.parentElement; - if (parEle!.hasAttribute('percent')) { - let percent = parEle!.getAttribute('percent'); - perfConfig.cpuPercent = Number(percent); - } - break; - case 'Frequency': - let input = value as HTMLInputElement; - if (input.value !== '') { - perfConfig.frequency = Number(input.value); - } - break; - case 'Period': - let periodInput = value as HTMLInputElement; - if (periodInput.value !== '') { - perfConfig.period = Number(periodInput.value); - } - break; - case 'Off CPU': - let cpuImage = value as LitSwitch; - perfConfig.isOffCpu = cpuImage.checked; - break; - case 'No Inherit': - let InheritImage = value as LitSwitch; - perfConfig.noInherit = InheritImage.checked; - break; - case 'Call Stack': - let callStack = value as LitSelect; - if (callStack.value !== '') { - perfConfig.callStack = callStack.value; - } - break; - case 'Branch': - let branch = value as LitSelect; - if (branch.value !== '') { - perfConfig.branch = branch.value; - } - break; - case 'Mmap Pages': - let parent = value.parentElement; - if (parent!.hasAttribute('percent')) { - let pagesPercent = parent!.getAttribute('percent'); - perfConfig.mmap = Math.pow(2, Number(pagesPercent)); - } - break; - case 'Clock Type': - let clock = value as LitSelect; - if (clock.value !== '') { - perfConfig.clockType = clock.value; - } - break; - } + perfConfig = this.getPerfConfigData(value, perfConfig); }); info('perfConfig is : ', perfConfig); return perfConfig; } + private getPerfConfigData(value: HTMLElement, perfConfig: PerfConfig): PerfConfig { + switch (value.title) { + case 'Process': + let processSelect = value as LitSelectV; + if (processSelect.all) { + perfConfig.process = 'ALL'; + break; + } + perfConfig = this.perfConfigByProcess(processSelect, perfConfig); + break; + case 'CPU': + perfConfig = this.perfConfigByCPU(perfConfig, value as LitSelectV); + break; + case 'Event List': + perfConfig = this.perfConfigByEventList(perfConfig, value as LitSelectV); + break; + case 'CPU Percent': + perfConfig = this.perfConfigCpuPercent(perfConfig, value.parentElement!); + break; + case 'Frequency': + perfConfig = this.perfConfigByFrequency(perfConfig, value as HTMLInputElement); + break; + case 'Period': + perfConfig = this.perfConfigByPeriod(perfConfig, value as HTMLInputElement); + break; + case 'Off CPU': + perfConfig.isOffCpu = (value as LitSwitch).checked; + break; + case 'No Inherit': + perfConfig.noInherit = (value as LitSwitch).checked; + break; + case 'Call Stack': + perfConfig = this.perfConfigByCallStack(perfConfig, value as LitSelect); + break; + case 'Branch': + perfConfig = this.perfConfigByBranch(perfConfig, value as LitSelect); + break; + case 'Mmap Pages': + perfConfig = this.perfConfigByMmapPages(perfConfig, value.parentElement!); + break; + case 'Clock Type': + perfConfig = this.perfConfigByClockType(perfConfig, value as LitSelect); + break; + } + return perfConfig; + } + private perfConfigByProcess(processSelect: LitSelectV, perfConfig: PerfConfig): PerfConfig { if (processSelect.value.length > 0) { let result = processSelect.value.match(/\((.+?)\)/g); @@ -178,12 +158,75 @@ export class SpRecordPerf extends BaseElement { return perfConfig; } - initElements(): void { - let that = this; - this.initConfigList(); + private perfConfigByCPU(perfConfig: PerfConfig, selectValue: LitSelectV): PerfConfig { + if (selectValue.value.length > 0) { + perfConfig.cpu = selectValue.value; + } + return perfConfig; + } + + private perfConfigByEventList(perfConfig: PerfConfig, selectValue: LitSelectV): PerfConfig { + if (selectValue.value.length > 0) { + perfConfig.eventList = selectValue.value.replace(/\s/g, ','); + } + return perfConfig; + } + + private perfConfigCpuPercent(perfConfig: PerfConfig, parEle: HTMLElement): PerfConfig { + if (parEle!.hasAttribute('percent')) { + let percent = parEle!.getAttribute('percent'); + perfConfig.cpuPercent = Number(percent); + } + return perfConfig; + } + + private perfConfigByFrequency(perfConfig: PerfConfig, elValue: HTMLInputElement): PerfConfig { + if (elValue.value !== '') { + perfConfig.frequency = Number(elValue.value); + } + return perfConfig; + } + + private perfConfigByPeriod(perfConfig: PerfConfig, elValue: HTMLInputElement): PerfConfig { + if (elValue.value !== '') { + perfConfig.period = Number(elValue.value); + } + return perfConfig; + } + + private perfConfigByCallStack(perfConfig: PerfConfig, callStack: LitSelect): PerfConfig { + if (callStack.value !== '') { + perfConfig.callStack = callStack.value; + } + return perfConfig; + } + + private perfConfigByBranch(perfConfig: PerfConfig, branch: LitSelect): PerfConfig { + if (branch.value !== '') { + perfConfig.branch = branch.value; + } + return perfConfig; + } + + private perfConfigByMmapPages(perfConfig: PerfConfig, parent: HTMLElement): PerfConfig { + if (parent!.hasAttribute('percent')) { + let pagesPercent = parent!.getAttribute('percent'); + perfConfig.mmap = Math.pow(2, Number(pagesPercent)); + } + return perfConfig; + } + + private perfConfigByClockType(perfConfig: PerfConfig, clock: LitSelect): PerfConfig { + if (clock.value !== '') { + perfConfig.clockType = clock.value; + } + return perfConfig; + } + + private initRecordPerfConfig(): void { let recordPerfConfigList = this.shadowRoot?.querySelector('.configList'); this.addOptionButton = this.shadowRoot?.querySelector('#addOptions'); - this.perfConfigList.forEach((config) => { + perfConfigList.forEach((config) => { let recordPerfDiv = document.createElement('div'); if (config.hidden) { recordPerfDiv.className = 'record-perf-config-div hidden'; @@ -202,254 +245,164 @@ export class SpRecordPerf extends BaseElement { recordPerfHeadDiv.appendChild(recordPerfDes); switch (config.type) { case 'select-multiple': - let html = ''; - let placeholder = config.selectArray[0]; - if (config.title === 'Event List') { - placeholder = 'NONE'; - } - html += ``; - config.selectArray.forEach((value: string) => { - html += `${value}`; - }); - html += ''; - recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + html; + this.configTypeBySelectMultiple(config, recordPerfDiv); break; case 'lit-slider': - let silder = ` -
-
`; - recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + silder; - let litSlider = recordPerfDiv.querySelector('.silderclass'); - litSlider!.percent = config.litSliderStyle.defaultValue; - let sliderBody = recordPerfDiv.querySelector('.sliderBody'); - let bufferInput = recordPerfDiv?.querySelector('.sliderInput') as HTMLInputElement; - litSlider!.addEventListener('input', () => { - bufferInput.value = sliderBody!.getAttribute('percent') + config.litSliderStyle.resultUnit; - }); - litSlider!.sliderStyle = config.litSliderStyle; + this.configTypeByLitSlider(config, recordPerfDiv); break; case 'Mmap-lit-slider': - let defaultValue = Math.pow(2, config.litSliderStyle.defaultValue); - let mapsilder = ` -
`; - recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + mapsilder; - let maplitSlider = recordPerfDiv.querySelector('.silderclass'); - maplitSlider!.percent = config.litSliderStyle.defaultValue; - let mapsliderBody = recordPerfDiv.querySelector('.sliderBody'); - let mapbufferInput = recordPerfDiv?.querySelector('.sliderInput') as HTMLInputElement; - maplitSlider!.addEventListener('input', () => { - let percnet = mapsliderBody!.getAttribute('percent'); - if (percnet !== null) { - mapbufferInput.value = Math.pow(2, Number(percnet)) + config.litSliderStyle.resultUnit; - } - }); - maplitSlider!.sliderStyle = config.litSliderStyle; + this.configTypeByMmapLitSlider(config, recordPerfDiv); break; case 'input': - let recordPerfInput = document.createElement('input'); - recordPerfInput.className = 'record-perf-input config'; - recordPerfInput.textContent = config.value; - recordPerfInput.value = config.value; - recordPerfInput.title = config.title; - recordPerfInput.oninput = (): void => { - recordPerfInput.value = recordPerfInput.value.replace(/\D/g, ''); - }; - recordPerfDiv.appendChild(recordPerfInput); + this.configTypeByInput(config, recordPerfDiv); break; case 'select': - let recordPerfSelect = ''; - recordPerfSelect += ``; - config.selectArray.forEach((value: string) => { - recordPerfSelect += `${value}`; - }); - recordPerfSelect += ''; - recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + recordPerfSelect; + this.configTypeBySelect(config, recordPerfDiv); break; case 'switch': - let recordPerfSwitch = document.createElement('lit-switch') as LitSwitch; - recordPerfSwitch.className = 'config'; - recordPerfSwitch.title = config.title; - recordPerfSwitch.checked = !!config.value; - if (config.title === 'Start Hiperf Sampling') { - recordPerfSwitch.addEventListener('change', (event: CustomEventInit) => { - let detail = event.detail; - if (detail!.checked) { - this.startSamp = true; - this.unDisable(); - this.dispatchEvent(new CustomEvent('addProbe', {})); - } else { - this.startSamp = false; - this.addOptionButton!.style.display = 'unset'; - this.disable(); - this.show = false; - } - }); - } - recordPerfHeadDiv.appendChild(recordPerfSwitch); + this.configTypeBySwitch(config, recordPerfHeadDiv); break; default: break; } recordPerfConfigList!.appendChild(recordPerfDiv); }); - let sp = document.querySelector('sp-application') as SpApplication; - let recordPerfSearch = sp?.shadowRoot?.querySelector('#lit-record-search') as LitSearch; - this.processSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'Process\']'); - this.recordProcessInput = this.processSelect?.shadowRoot?.querySelector('input'); - let querySelector = this.processSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; - querySelector.addEventListener('mousedown', () => { - if (SpRecordTrace.serialNumber === '') { - this.processSelect!.dataSource([], 'ALL-Process'); - } else { - if (sp.search) { - sp.search = false; - recordPerfSearch.clear(); - } - Cmd.getProcess().then( - (processList) => { - this.processSelect?.dataSource(processList, 'ALL-Process'); - }, - () => { - sp.search = true; - recordPerfSearch.clear(); - recordPerfSearch.setPercent('please kill other hdc-server !', -2); - } - ); - } - }); + } - this.cpuSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'CPU\']'); - let inputCpu = this.cpuSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; - let cpuData: Array = []; - inputCpu.addEventListener('mousedown', () => { - if (SpRecordTrace.serialNumber === '') { - this.cpuSelect!.dataSource([], 'ALL-CPU'); + processSelectMousedownHandler = (): void => { + if (SpRecordTrace.serialNumber === '') { + this.processSelect!.dataSource([], 'ALL-Process'); + } else { + if (this.sp!.search) { + this.sp!.search = false; + this.recordPerfSearch!.clear(); } - }); - inputCpu!.addEventListener('mouseup', () => { - if (SpRecordTrace.serialNumber === '') { - this.cpuSelect?.dataSource([], ''); - } else { - if (sp.search) { - sp.search = false; - recordPerfSearch.clear(); - } - if (SpRecordTrace.isVscode) { - let cmd = Cmd.formatString(CmdConstant.CMD_GET_CPU_COUNT_DEVICES, [SpRecordTrace.serialNumber]); - Cmd.execHdcCmd(cmd, (res: string) => { - cpuData = []; - let cpuCount = res!.trim(); - let cpus = Number(cpuCount); - for (let index = 0; index < cpus; index++) { - cpuData.push(String(index)); - } - this.cpuSelect?.dataSource(cpuData, 'ALL-CPU'); - }); - } else { - HdcDeviceManager.connect(SpRecordTrace.serialNumber).then((conn) => { - cpuData = []; - if (conn) { - HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_CPU_COUNT, false).then((res) => { - let cpuCount = res!.trim(); - let cpus = Number(cpuCount); - for (let index = 0; index < cpus; index++) { - cpuData.push(String(index)); - } - this.cpuSelect?.dataSource(cpuData, 'ALL-CPU'); - }); - } else { - recordPerfSearch.clear(); - sp.search = true; - recordPerfSearch.setPercent('please kill other hdc-server !', -2); - } - }); + Cmd.getProcess().then( + (processList) => { + this.processSelect?.dataSource(processList, 'ALL-Process'); + }, + () => { + this.sp!.search = true; + this.recordPerfSearch!.clear(); + this.recordPerfSearch!.setPercent('please kill other hdc-server !', -2); } + ); + } + }; + + cpuSelectMouseDownHandler = (): void => { + if (SpRecordTrace.serialNumber === '') { + this.cpuSelect!.dataSource([], 'ALL-CPU'); + } + }; + + cpuSelectMouseUpHandler = (): void => { + if (SpRecordTrace.serialNumber === '') { + this.cpuSelect?.dataSource([], ''); + } else { + if (this.sp!.search) { + this.sp!.search = false; + this.recordPerfSearch!.clear(); } - }); - this.eventSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'Event List\']'); - let inputEvent = this.eventSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; - let eventData: Array = []; - inputEvent.addEventListener('mousedown', () => { - if (SpRecordTrace.serialNumber === '') { - this.eventSelect!.dataSource([], ''); - } - }); - inputEvent!.addEventListener('click', () => { - if (SpRecordTrace.serialNumber === '') { - this.eventSelect?.dataSource( - [ - 'hw-cpu-cycles', - 'hw-instructions', - 'hw-cache-references', - 'hw-cache-misses', - 'hw-branch-instructions', - 'hw-branch-misses', - 'hw-bus-cycles', - 'hw-stalled-cycles-backend', - 'hw-stalled-cycles-frontend', - 'sw-cpu-clock', - 'sw-task-clock', - 'sw-page-faults', - 'sw-context-switches', - 'sw-cpu-migrations', - 'sw-page-faults-min', - 'sw-page-faults-maj', - 'sw-alignment-faults', - 'sw-emulation-faults', - 'sw-dummy', - 'sw-bpf-output', - ], - '' - ); + if (SpRecordTrace.isVscode) { + let cmd = Cmd.formatString(CmdConstant.CMD_GET_CPU_COUNT_DEVICES, [SpRecordTrace.serialNumber]); + Cmd.execHdcCmd(cmd, (res: string) => { + this.cpuData = []; + let cpuCount = res!.trim(); + let cpus = Number(cpuCount); + for (let index = 0; index < cpus; index++) { + this.cpuData.push(String(index)); + } + this.cpuSelect?.dataSource(this.cpuData, 'ALL-CPU'); + }); } else { - if (sp.search) { - sp.search = false; - recordPerfSearch.clear(); - } - if (SpRecordTrace.isVscode) { - let cmd = Cmd.formatString(CmdConstant.CMD_GET_HIPERF_EVENTS_DEVICES, [SpRecordTrace.serialNumber]); - Cmd.execHdcCmd(cmd, (res: string) => { - let eventMap = that.parseEvent(res); - let eventList = that.getSoftHardWareEvents(eventMap); - if (eventList) { - for (let eventListElement of eventList) { - eventData.push(eventListElement.trim()); + HdcDeviceManager.connect(SpRecordTrace.serialNumber).then((conn) => { + this.cpuData = []; + if (conn) { + HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_CPU_COUNT, false).then((res) => { + let cpuCount = res!.trim(); + let cpus = Number(cpuCount); + for (let index = 0; index < cpus; index++) { + this.cpuData.push(String(index)); } + this.cpuSelect?.dataSource(this.cpuData, 'ALL-CPU'); + }); + } else { + this.recordPerfSearch!.clear(); + this.sp!.search = true; + this.recordPerfSearch!.setPercent('please kill other hdc-server !', -2); + } + }); + } + } + }; + + eventSelectMousedownHandler = (): void => { + if (SpRecordTrace.serialNumber === '') { + this.eventSelect!.dataSource([], ''); + } + }; + + eventSelectClickHandler = (): void => { + let that = this; + if (SpRecordTrace.serialNumber === '') { + this.eventSelect?.dataSource(eventSelect,''); + } else { + if (this.sp!.search) { + this.sp!.search = false; + this.recordPerfSearch!.clear(); + } + if (SpRecordTrace.isVscode) { + let cmd = Cmd.formatString(CmdConstant.CMD_GET_HIPERF_EVENTS_DEVICES, [SpRecordTrace.serialNumber]); + Cmd.execHdcCmd(cmd, (res: string) => { + let eventMap = that.parseEvent(res); + let eventList = that.getSoftHardWareEvents(eventMap); + if (eventList) { + for (let eventListElement of eventList) { + this.eventData.push(eventListElement.trim()); } - this.eventSelect!.dataSource(eventData, ''); - }); - } else { - HdcDeviceManager.connect(SpRecordTrace.serialNumber).then((conn) => { - eventData = []; - if (conn) { - HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_HIPERF_EVENTS, false).then((res) => { - if (res) { - let eventMap = that.parseEvent(res); - let eventList = that.getSoftHardWareEvents(eventMap); - if (eventList) { - for (let eventListElement of eventList) { - eventData.push(eventListElement.trim()); - } + } + this.eventSelect!.dataSource(this.eventData, ''); + }); + } else { + HdcDeviceManager.connect(SpRecordTrace.serialNumber).then((conn) => { + this.eventData = []; + if (conn) { + HdcDeviceManager.shellResultAsString(CmdConstant.CMD_GET_HIPERF_EVENTS, false).then((res) => { + if (res) { + let eventMap = that.parseEvent(res); + let eventList = that.getSoftHardWareEvents(eventMap); + if (eventList) { + for (let eventListElement of eventList) { + this.eventData.push(eventListElement.trim()); } - this.eventSelect!.dataSource(eventData, ''); } - }); - } else { - sp.search = true; - recordPerfSearch.clear(); - recordPerfSearch.setPercent('please kill other hdc-server !', -2); - } - }); - } + this.eventSelect!.dataSource(this.eventData, ''); + } + }); + } else { + this.sp!.search = true; + this.recordPerfSearch!.clear(); + this.recordPerfSearch!.setPercent('please kill other hdc-server !', -2); + } + }); } - }); + } + }; + initElements(): void { + this.cpuData = []; + this.eventData = []; + this.initRecordPerfConfig(); + this.sp = document.querySelector('sp-application') as SpApplication; + this.recordPerfSearch = this.sp?.shadowRoot?.querySelector('#lit-record-search') as LitSearch; + this.processSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'Process\']'); + this.recordProcessInput = this.processSelect?.shadowRoot?.querySelector('input'); + this.processInput = this.processSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; + this.cpuSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'CPU\']'); + this.inputCpu = this.cpuSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; + this.eventSelect = this.shadowRoot?.querySelector('lit-select-v[title=\'Event List\']'); + this.inputEvent = this.eventSelect!.shadowRoot?.querySelector('input') as HTMLInputElement; this.frequencySetInput = this.shadowRoot?.querySelector('input[title=\'Frequency\']'); this.frequencySetInput!.onkeydown = (ev): void => { // @ts-ignore @@ -469,6 +422,104 @@ placement="bottom" title="${config.title}" placeholder="${config.selectArray[0] this.disable(); } + private configTypeBySwitch(config: any, recordPerfHeadDiv: HTMLDivElement): void { + let recordPerfSwitch = document.createElement('lit-switch') as LitSwitch; + recordPerfSwitch.className = 'config'; + recordPerfSwitch.title = config.title; + recordPerfSwitch.checked = !!config.value; + if (config.title === 'Start Hiperf Sampling') { + recordPerfSwitch.addEventListener('change', (event: CustomEventInit) => { + let detail = event.detail; + if (detail!.checked) { + this.startSamp = true; + this.unDisable(); + this.dispatchEvent(new CustomEvent('addProbe', {})); + } else { + this.startSamp = false; + this.addOptionButton!.style.display = 'unset'; + this.disable(); + this.show = false; + } + }); + } + recordPerfHeadDiv.appendChild(recordPerfSwitch); + } + + private configTypeBySelect(config: any, recordPerfDiv: HTMLDivElement): void { + let recordPerfSelect = ''; + recordPerfSelect += ``; + config.selectArray.forEach((value: string) => { + recordPerfSelect += `${value}`; + }); + recordPerfSelect += ''; + recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + recordPerfSelect; + } + + private configTypeByInput(config: any, recordPerfDiv: HTMLDivElement): void { + let recordPerfInput = document.createElement('input'); + recordPerfInput.className = 'record-perf-input config'; + recordPerfInput.textContent = config.value; + recordPerfInput.value = config.value; + recordPerfInput.title = config.title; + recordPerfInput.oninput = (): void => { + recordPerfInput.value = recordPerfInput.value.replace(/\D/g, ''); + }; + recordPerfDiv.appendChild(recordPerfInput); + } + + private configTypeByMmapLitSlider(config: any, recordPerfDiv: HTMLDivElement): void { + let defaultValue = Math.pow(2, config.litSliderStyle.defaultValue); + let mapsilder = ` +
`; + recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + mapsilder; + let maplitSlider = recordPerfDiv.querySelector('.silderclass'); + maplitSlider!.percent = config.litSliderStyle.defaultValue; + let mapsliderBody = recordPerfDiv.querySelector('.sliderBody'); + let mapbufferInput = recordPerfDiv?.querySelector('.sliderInput') as HTMLInputElement; + maplitSlider!.addEventListener('input', () => { + let percnet = mapsliderBody!.getAttribute('percent'); + if (percnet !== null) { + mapbufferInput.value = Math.pow(2, Number(percnet)) + config.litSliderStyle.resultUnit; + } + }); + maplitSlider!.sliderStyle = config.litSliderStyle; + } + + private configTypeByLitSlider(config: any, recordPerfDiv: HTMLDivElement): void{ + let sliderEl = ` +
+
`; + recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + sliderEl; + let litSlider = recordPerfDiv.querySelector('.silderclass'); + litSlider!.percent = config.litSliderStyle.defaultValue; + let sliderBody = recordPerfDiv.querySelector('.sliderBody'); + let bufferInput = recordPerfDiv?.querySelector('.sliderInput') as HTMLInputElement; + litSlider!.addEventListener('input', () => { + bufferInput.value = sliderBody!.getAttribute('percent') + config.litSliderStyle.resultUnit; + }); + litSlider!.sliderStyle = config.litSliderStyle; + } + + private configTypeBySelectMultiple(config: any, recordPerfDiv: HTMLDivElement): void { + let html = ''; + let placeholder = config.selectArray[0]; + if (config.title === 'Event List') { + placeholder = 'NONE'; + } + html += ``; + config.selectArray.forEach((value: string) => { + html += `${value}`; + }); + html += ''; + recordPerfDiv.innerHTML = recordPerfDiv.innerHTML + html; + } + getSoftHardWareEvents(eventListResult: Map): string[] { let shEvents = []; let hardwareEvents = eventListResult.get('hardware'); @@ -547,118 +598,6 @@ placement="bottom" title="${config.title}" placeholder="${config.selectArray[0] } } - initConfigList(): void { - this.perfConfigList = [ - { - title: 'Start Hiperf Sampling', - des: '', - hidden: false, - type: 'switch', - value: false, - }, - { - type: 'select-multiple', - title: 'Process', - des: 'Record process', - hidden: false, - selectArray: [''], - }, - { - title: 'CPU', - des: 'Record assign cpu num such as 0,1,2', - hidden: true, - type: 'select-multiple', - selectArray: [''], - }, - { - title: 'Event List', - des: 'Event type Default is cpu cycles', - hidden: true, - type: 'select-multiple', - selectArray: [''], - }, - { - title: 'CPU Percent', - des: 'Set the max percent of cpu time used for recording', - hidden: true, - type: 'lit-slider', - litSliderStyle: { - minRange: 0, - maxRange: 100, - defaultValue: '100', - resultUnit: '%', - stepSize: 1, - lineColor: 'var(--dark-color3,#a88888)', - buttonColor: '#a88888', - }, - }, - { - title: 'Frequency', - des: 'Set event sampling frequency', - hidden: false, - type: 'input', - value: '1000', - }, - { - title: 'Period', - des: 'Set event sampling period for trace point events2', - hidden: true, - type: 'input', - value: '1', - }, - { - title: 'Off CPU', - des: 'Trace when threads are scheduled off cpu', - hidden: false, - type: 'switch', - value: true, - }, - { - title: 'No Inherit', - des: 'Don\'t trace child processes', - hidden: true, - type: 'switch', - value: false, - }, - { - title: 'Call Stack', - des: 'Setup and enable call stack recording', - hidden: false, - type: 'select', - selectArray: ['dwarf', 'fp', 'none'], - }, - { - title: 'Branch', - des: 'Taken branch stack sampling', - hidden: true, - type: 'select', - selectArray: ['none', 'any', 'any_call', 'any_ret', 'ind_call', 'call', 'user', 'kernel'], - }, - { - title: 'Mmap Pages', - des: 'Used to receiving record data from kernel', - hidden: true, - type: 'Mmap-lit-slider', - litSliderStyle: { - minRange: 1, - maxRange: 10, - defaultValue: '8', - resultUnit: 'MB', - stepSize: 1, - lineColor: 'var(--dark-color3,#46B1E3)', - buttonColor: '#999999', - }, - }, - { - title: 'Clock Type', - des: 'Set the clock id to use for the various time fields in the perf_event_type records', - hidden: true, - type: 'select', - selectArray: ['monotonic', 'realtime', 'monotonic_raw', 'boottime', 'perf'], - }, - ]; - } - connectedCallback(): void { let traceMode = this.shadowRoot!.querySelector('#traceMode') as HTMLDivElement; let isLongTrace = SpApplication.isLongTrace; @@ -667,6 +606,20 @@ placement="bottom" title="${config.title}" placeholder="${config.selectArray[0] } else { traceMode!.style.display = 'none'; } + this.processInput?.addEventListener('mousedown', this.processSelectMousedownHandler); + this.inputCpu?.addEventListener('mousedown', this.cpuSelectMouseDownHandler); + this.inputCpu?.addEventListener('mouseup', this.cpuSelectMouseUpHandler); + this.inputEvent?.addEventListener('mousedown', this.eventSelectMousedownHandler); + this.inputEvent?.addEventListener('click', this.eventSelectClickHandler); + } + + disconnectedCallback(): void { + super.disconnectedCallback(); + this.processInput?.removeEventListener('mousedown', this.processSelectMousedownHandler); + this.inputCpu?.removeEventListener('mousedown', this.cpuSelectMouseDownHandler); + this.inputCpu?.removeEventListener('mouseup', this.cpuSelectMouseUpHandler); + this.inputEvent?.removeEventListener('mousedown', this.eventSelectMousedownHandler); + this.inputEvent?.removeEventListener('click', this.eventSelectClickHandler); } initHtml(): string { @@ -688,3 +641,136 @@ export interface PerfConfig { mmap: number; clockType: string; } + +const eventSelect = [ + 'hw-cpu-cycles', + 'hw-instructions', + 'hw-cache-references', + 'hw-cache-misses', + 'hw-branch-instructions', + 'hw-branch-misses', + 'hw-bus-cycles', + 'hw-stalled-cycles-backend', + 'hw-stalled-cycles-frontend', + 'sw-cpu-clock', + 'sw-task-clock', + 'sw-page-faults', + 'sw-context-switches', + 'sw-cpu-migrations', + 'sw-page-faults-min', + 'sw-page-faults-maj', + 'sw-alignment-faults', + 'sw-emulation-faults', + 'sw-dummy', + 'sw-bpf-output', +]; + +const perfConfigList = [ + { + title: 'Start Hiperf Sampling', + des: '', + hidden: false, + type: 'switch', + value: false, + }, + { + type: 'select-multiple', + title: 'Process', + des: 'Record process', + hidden: false, + selectArray: [''], + }, + { + title: 'CPU', + des: 'Record assign cpu num such as 0,1,2', + hidden: true, + type: 'select-multiple', + selectArray: [''], + }, + { + title: 'Event List', + des: 'Event type Default is cpu cycles', + hidden: true, + type: 'select-multiple', + selectArray: [''], + }, + { + title: 'CPU Percent', + des: 'Set the max percent of cpu time used for recording', + hidden: true, + type: 'lit-slider', + litSliderStyle: { + minRange: 0, + maxRange: 100, + defaultValue: '100', + resultUnit: '%', + stepSize: 1, + lineColor: 'var(--dark-color3,#a88888)', + buttonColor: '#a88888', + }, + }, + { + title: 'Frequency', + des: 'Set event sampling frequency', + hidden: false, + type: 'input', + value: '1000', + }, + { + title: 'Period', + des: 'Set event sampling period for trace point events2', + hidden: true, + type: 'input', + value: '1', + }, + { + title: 'Off CPU', + des: 'Trace when threads are scheduled off cpu', + hidden: false, + type: 'switch', + value: true, + }, + { + title: 'No Inherit', + des: 'Don\'t trace child processes', + hidden: true, + type: 'switch', + value: false, + }, + { + title: 'Call Stack', + des: 'Setup and enable call stack recording', + hidden: false, + type: 'select', + selectArray: ['dwarf', 'fp', 'none'], + }, + { + title: 'Branch', + des: 'Taken branch stack sampling', + hidden: true, + type: 'select', + selectArray: ['none', 'any', 'any_call', 'any_ret', 'ind_call', 'call', 'user', 'kernel'], + }, + { + title: 'Mmap Pages', + des: 'Used to receiving record data from kernel', + hidden: true, + type: 'Mmap-lit-slider', + litSliderStyle: { + minRange: 1, + maxRange: 10, + defaultValue: '8', + resultUnit: 'MB', + stepSize: 1, + lineColor: 'var(--dark-color3,#46B1E3)', + buttonColor: '#999999', + }, + }, + { + title: 'Clock Type', + des: 'Set the clock id to use for the various time fields in the perf_event_type records', + hidden: true, + type: 'select', + selectArray: ['monotonic', 'realtime', 'monotonic_raw', 'boottime', 'perf'], + }, +]; diff --git a/ide/src/trace/component/setting/SpRecordSetting.html.ts b/ide/src/trace/component/setting/SpRecordSetting.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..68a7939f42a5fd3a5cc49903548b0897ebfd8f2e --- /dev/null +++ b/ide/src/trace/component/setting/SpRecordSetting.html.ts @@ -0,0 +1,219 @@ +/* + * 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. + */ + +export const SpRecordSettingHtml = ` + +
+
+ Record mode +
+ Normal Mode + Long Trace Mode +
+
+
+ output file path +
+ /data/local/tmp/ + +
+
+
+
+ In-memory buffer size + (max memory buffer size is 512 MB) +
+ + +
+ + MB +
+
+
+
+ Max duration + (max duration value is 01:00:00) +
+ + +
+ + h:m:s +
+ +
+
+`; diff --git a/ide/src/trace/component/setting/SpRecordSetting.ts b/ide/src/trace/component/setting/SpRecordSetting.ts index 7edad02579d3eb55142cc749fbdf1214c2c179fa..b47d10ba1126ff1fec9f3abe30f6cf9d37cf9f32 100644 --- a/ide/src/trace/component/setting/SpRecordSetting.ts +++ b/ide/src/trace/component/setting/SpRecordSetting.ts @@ -21,6 +21,8 @@ import { LitSlider } from '../../../base-ui/slider/LitSlider'; import '../../../base-ui/popover/LitPopover'; import { info } from '../../../log/Log'; import { SpApplication } from '../../SpApplication'; +import { NUM_200, NUM_30, NUM_3600, NUM_60, NUM_64 } from '../../bean/NumBean'; +import { SpRecordSettingHtml } from './SpRecordSetting.html'; @element('record-setting') export class SpRecordSetting extends BaseElement { @@ -33,6 +35,7 @@ export class SpRecordSetting extends BaseElement { private outputPath: HTMLInputElement | undefined; private lastMemoryValue: string | undefined; private lastDurationValue: string | undefined; + private maxSizeInput: HTMLInputElement | undefined; isRecordTemplate: boolean = false; get longTraceSingleFileMaxSize(): number { @@ -40,7 +43,7 @@ export class SpRecordSetting extends BaseElement { if (maxFileSizeEl) { return Number(maxFileSizeEl.value); } - return 200; + return NUM_200; } get recordMod(): boolean { @@ -76,7 +79,7 @@ export class SpRecordSetting extends BaseElement { info('bufferSize is : ', this.bufferNumber!.getAttribute('percent')); return Number(this.bufferNumber!.getAttribute('percent')); } - return 64; + return NUM_64; } get maxDur(): number { @@ -84,13 +87,13 @@ export class SpRecordSetting extends BaseElement { info('maxDur is : ', this.durationNumber!.getAttribute('percent')); return Number(this.durationNumber!.getAttribute('percent')); } - return 30; + return NUM_30; } resetValue(): void { let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; let parentElement = this.memoryBufferSlider!.parentNode as Element; - if (bufferInput.style.color != 'var(--dark-color1,#000000)' && this.lastMemoryValue) { + if (bufferInput.style.color !== 'var(--dark-color1,#000000)' && this.lastMemoryValue) { bufferInput.value = `${this.lastMemoryValue}`; this.memoryBufferSlider!.percent = `${this.lastMemoryValue}`; this.memoryBufferSlider!.sliderStyle = { @@ -109,11 +112,11 @@ export class SpRecordSetting extends BaseElement { let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; let durationEl = this.maxDurationSliders!.parentNode as Element; - if (durationInput.style.color != 'var(--dark-color1,#000000)' && this.lastDurationValue) { + if (durationInput.style.color !== 'var(--dark-color1,#000000)' && this.lastDurationValue) { durationInput.style.color = 'var(--dark-color1,#000000)'; let durationList = this.lastDurationValue.split(':'); - let resultDuration = Number(durationList[0]) * 3600 + Number(durationList[1]) * 60 + Number(durationList[2]); - + let resultDuration = Number(durationList[0]) * NUM_3600 + + Number(durationList[1]) * NUM_60 + Number(durationList[2]); durationInput.value = this.lastDurationValue; this.maxDurationSliders!.sliderStyle = { minRange: 10, @@ -140,13 +143,11 @@ export class SpRecordSetting extends BaseElement { } }); }); - let bu = this.shadowRoot?.querySelector('.record') as HTMLDivElement; this.shadowRoot?.querySelectorAll('.MenuButton').forEach((button) => { - button!.addEventListener('mouseenter', (e) => { + button!.addEventListener('mouseenter', () => { button.style.backgroundColor = '#EFEFEF'; }); - - button!.addEventListener('mouseout', (e) => { + button!.addEventListener('mouseout', () => { button.style.backgroundColor = '#E4E3E9'; }); }); @@ -155,12 +156,8 @@ export class SpRecordSetting extends BaseElement { this.initLitSlider(); } - private addLongTraceConfig() { - this.longTraceRadio = this.shadowRoot?.querySelector('#longTraceRadio') as LitRadioBox; - this.outputPath = this.shadowRoot?.querySelector('#trace_path') as HTMLInputElement; - let rootEl = this.shadowRoot?.querySelector('.root') as HTMLDivElement; - let longTraceMaxSlide = document.createElement('div'); - longTraceMaxSlide.innerHTML = `
+ private getLongTraceSlideHTML(): string { + return `
Single file max size (single file size after cutting is 200MB - 300MB) @@ -168,15 +165,31 @@ export class SpRecordSetting extends BaseElement {
- + MB
`; + } + private addLongTraceConfig(): void { + this.longTraceRadio = this.shadowRoot?.querySelector('#longTraceRadio') as LitRadioBox; + this.outputPath = this.shadowRoot?.querySelector('#trace_path') as HTMLInputElement; + let rootEl = this.shadowRoot?.querySelector('.root') as HTMLDivElement; + let longTraceMaxSlide = document.createElement('div'); + longTraceMaxSlide.innerHTML = this.getLongTraceSlideHTML(); let maxSingleFileEl = longTraceMaxSlide.querySelector('.max-single-file-size'); let maxSizeSliders = longTraceMaxSlide.querySelector('#max-size') as LitSlider; - let maxSizeInput = longTraceMaxSlide.querySelector('.max_size_result') as HTMLInputElement; - maxSizeInput!.onkeydown = (ev): void => { + this.maxSizeInput = longTraceMaxSlide.querySelector('.max_size_result') as HTMLInputElement; + this.maxSizeInput.onkeydown = (ev): void => { // @ts-ignore if (ev.key === '0' && ev.target.value.length === 1 && ev.target.value === '0') { ev.preventDefault(); @@ -194,45 +207,56 @@ export class SpRecordSetting extends BaseElement { }; maxSizeSliders.addEventListener('input', () => { if (maxSingleFileEl?.hasAttribute('percent')) { - maxSizeInput.value = `${maxSingleFileEl?.getAttribute('percent')}`; + this.maxSizeInput!.value = `${maxSingleFileEl?.getAttribute('percent')}`; } else { - maxSizeInput.value = maxSizeSliders.sliderStyle.defaultValue; + this.maxSizeInput!.value = maxSizeSliders.sliderStyle.defaultValue; } }); - maxSizeInput.value = maxSizeSliders.sliderStyle.defaultValue; + this.maxSizeInput.value = maxSizeSliders.sliderStyle.defaultValue; maxSizeParentElement.setAttribute('percent', '50'); - maxSizeInput.style.color = 'var(--dark-color1,#000000)'; - maxSizeInput.addEventListener('input', (ev) => { - maxSizeSliders!.percent = maxSizeInput.value; - let htmlInputElement = maxSizeSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; - htmlInputElement.value = maxSizeInput.value; - maxSizeSliders!.sliderStyle = { - minRange: 200, - maxRange: 300, - defaultValue: maxSizeInput.value, - resultUnit: 'MB', - stepSize: 2, - lineColor: 'var(--dark-color3,#46B1E3)', - buttonColor: '#999999', - }; - maxSizeParentElement.setAttribute('percent', maxSizeInput.value); + this.maxSizeInput.style.color = 'var(--dark-color1,#000000)'; + this.maxSizeInput.addEventListener('input', () => { + this.maxSizeInputHandler(maxSizeSliders, maxSizeParentElement); }); - this.radioBox!.addEventListener('click', () => { - SpApplication.isLongTrace = false; - if (rootEl.lastChild === longTraceMaxSlide) { - rootEl.removeChild(longTraceMaxSlide); - } - this.outputPath!.value = 'hiprofiler_data.htrace'; + this.normalModelRadioHandler(rootEl, longTraceMaxSlide); }); this.longTraceRadio.addEventListener('click', () => { - SpApplication.isLongTrace = true; - rootEl.appendChild(longTraceMaxSlide); - this.outputPath!.value = 'long_trace'; + this.longTraceModelRadioHandler(rootEl, longTraceMaxSlide); }); } - initLitSlider() { + private normalModelRadioHandler(rootEl: HTMLDivElement, longTraceMaxSlide: HTMLDivElement): void { + SpApplication.isLongTrace = false; + if (rootEl.lastChild === longTraceMaxSlide) { + rootEl.removeChild(longTraceMaxSlide); + } + this.outputPath!.value = 'hiprofiler_data.htrace'; + } + + private longTraceModelRadioHandler(rootEl: HTMLDivElement, longTraceMaxSlide: HTMLDivElement): void { + SpApplication.isLongTrace = true; + rootEl.appendChild(longTraceMaxSlide); + this.outputPath!.value = 'long_trace'; + } + + private maxSizeInputHandler(maxSizeSliders: LitSlider, maxSizeParentElement: Element): void { + maxSizeSliders!.percent = this.maxSizeInput!.value; + let htmlInputElement = maxSizeSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; + htmlInputElement.value = this.maxSizeInput!.value; + maxSizeSliders!.sliderStyle = { + minRange: 200, + maxRange: 300, + defaultValue: this.maxSizeInput!.value, + resultUnit: 'MB', + stepSize: 2, + lineColor: 'var(--dark-color3,#46B1E3)', + buttonColor: '#999999', + }; + maxSizeParentElement.setAttribute('percent', this.maxSizeInput!.value); + } + + initLitSlider(): void { this.memoryBufferSlider = this.shadowRoot?.querySelector('#memory-buffer') as LitSlider; this.memoryBufferSlider.sliderStyle = { minRange: 4, @@ -244,60 +268,7 @@ export class SpRecordSetting extends BaseElement { buttonColor: '#999999', }; this.lastMemoryValue = '64'; - let parentElement = this.memoryBufferSlider!.parentNode as Element; - let bufferInput = this.shadowRoot?.querySelector('.memory_buffer_result') as HTMLInputElement; - bufferInput.value = this.memoryBufferSlider.sliderStyle.defaultValue; - this.memoryBufferSlider.addEventListener('input', (evt) => { - bufferInput.value = this.bufferSize.toString(); - }); - parentElement.setAttribute('percent', '64'); - bufferInput.style.color = 'var(--dark-color1,#000000)'; - bufferInput.addEventListener('input', (ev) => { - if (this.bufferNumber!.hasAttribute('percent')) { - this.bufferNumber!.removeAttribute('percent'); - } - bufferInput.style.color = 'var(--dark-color1,#000000)'; - bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - if (bufferInput.value.trim() == '') { - bufferInput.style.color = 'red'; - parentElement.setAttribute('percent', '64'); - return; - } - let memorySize = Number(bufferInput.value); - if ( - !memorySize || - memorySize < this.memoryBufferSlider!.sliderStyle.minRange || - memorySize > this.memoryBufferSlider!.sliderStyle.maxRange - ) { - bufferInput.style.color = 'red'; - parentElement.setAttribute('percent', '64'); - } else { - this.memoryBufferSlider!.percent = bufferInput.value; - let htmlInputElement = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; - htmlInputElement.value = bufferInput.value; - this.memoryBufferSlider!.sliderStyle = { - minRange: 4, - maxRange: 512, - defaultValue: bufferInput.value, - resultUnit: 'MB', - stepSize: 2, - lineColor: 'var(--dark-color3,#46B1E3)', - buttonColor: '#999999', - }; - parentElement.setAttribute('percent', bufferInput.value); - this.lastMemoryValue = bufferInput.value; - } - }); - - let memoryBufferInput = this.memoryBufferSlider!.shadowRoot?.querySelector('#slider') as HTMLInputElement; - - memoryBufferInput.addEventListener('input', (ev) => { - bufferInput.style.color = 'var(--dark-color1,#000000)'; - bufferInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - bufferInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - }); - + this.initMemoryBufferEl(); this.maxDurationSliders = this.shadowRoot?.querySelector('#max-duration') as LitSlider; this.maxDurationSliders.sliderStyle = { minRange: 10, @@ -312,267 +283,131 @@ export class SpRecordSetting extends BaseElement { let durationParentElement = this.maxDurationSliders!.parentNode as Element; let durationInput = this.shadowRoot?.querySelector('.max_duration_result') as HTMLInputElement; durationInput.value = this.maxDurationSliders.sliderStyle.defaultValue; - this.maxDurationSliders.addEventListener('input', (evt) => { + this.maxDurationSliders.addEventListener('input', () => { durationInput.value = this.maxDurationSliders!.formatSeconds(this.maxDur.toString()); }); - durationInput.style.color = 'var(--dark-color1,#000000)'; - durationInput.addEventListener('input', (ev) => { - if (this.durationNumber!.hasAttribute('percent')) { - this.durationNumber!.removeAttribute('percent'); - } - durationInput.style.color = 'var(--dark-color1,#000000)'; - durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - let regExpMatchArray = durationInput.value.trim(); - if (regExpMatchArray == '') { - durationInput.style.color = 'red'; - durationParentElement.setAttribute('percent', '30'); - return; - } - let regExpMatch = durationInput.value.trim().match('^\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}$'); - if (regExpMatch) { - let durationList = regExpMatchArray.split(':'); - let resultDuration = Number(durationList[0]) * 3600 + Number(durationList[1]) * 60 + Number(durationList[2]); - if ( - Number(durationList[0]) > 60 || - Number(durationList[1]) > 60 || - Number(durationList[2]) > 60 || - resultDuration > this.maxDurationSliders!.sliderStyle.maxRange || - resultDuration < this.maxDurationSliders!.sliderStyle.minRange - ) { - durationInput.style.color = 'red'; - durationParentElement.setAttribute('percent', '30'); - } else { - durationInput.style.color = 'var(--dark-color1,#000000)'; - durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; - let htmlInputElement = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; - htmlInputElement.value = `${resultDuration}`; - this.maxDurationSliders!.sliderStyle = { - minRange: 10, - maxRange: 3600, - defaultValue: `${Number(durationList[0])}:${Number(durationList[1])}:${Number(durationList[2])}`, - resultUnit: 'h:m:s', - stepSize: 1, - lineColor: 'var(--dark-color4,#61CFBE)', - buttonColor: '#999999', - }; - durationParentElement.setAttribute('percent', resultDuration.toString()); - this.lastDurationValue = regExpMatchArray; - } - } else { - durationInput.style.color = 'red'; - durationParentElement.setAttribute('percent', '30'); - } + durationInput.addEventListener('input', () => { + this.maxDurationInputHandler(durationInput, durationParentElement); }); - let maxDurationInput = this.maxDurationSliders!.shadowRoot?.querySelector('#slider') as HTMLInputElement; - maxDurationInput.addEventListener('input', (ev) => { + maxDurationInput.addEventListener('input', () => { durationInput.style.color = 'var(--dark-color1,#000000)'; durationInput.parentElement!.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; durationInput.style.backgroundColor = 'var(--dark-background5,#F2F2F2)'; }); } - initHtml(): string { - return ` - -
-
- Record mode -
- Normal Mode - Long Trace Mode -
-
-
- output file path -
- /data/local/tmp/ - -
-
-
-
- In-memory buffer size - (max memory buffer size is 512 MB) -
- - -
- - MB -
-
-
-
- Max duration - (max duration value is 01:00:00) -
- - -
- - h:m:s -
- -
-
- `; + initHtml(): string { + return SpRecordSettingHtml; } } diff --git a/ide/src/trace/component/setting/SpRecordTemplate.html.ts b/ide/src/trace/component/setting/SpRecordTemplate.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..caa1919a2686dccd56d37725dedbc3141dc5e88b --- /dev/null +++ b/ide/src/trace/component/setting/SpRecordTemplate.html.ts @@ -0,0 +1,88 @@ +/* + * 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. + */ + +export const SpRecordTemplateHtml = ` + +
+
+
+ FrameTimeline + +
+
+
+
+ SchedulingAnalysis + +
+
+
+
+ AppStartup + +
+
+
+
+ TaskPool + +
+
+
+
+ AnimationAnalysis + +
+
+
+`; diff --git a/ide/src/trace/component/setting/SpRecordTemplate.ts b/ide/src/trace/component/setting/SpRecordTemplate.ts index ea64abc864a756a71f22c2e7d3f8d5be522a8bda..ce5fba5375a400bfdb4733ca40e1af46ac9ef5ff 100644 --- a/ide/src/trace/component/setting/SpRecordTemplate.ts +++ b/ide/src/trace/component/setting/SpRecordTemplate.ts @@ -16,7 +16,7 @@ import { BaseElement, element } from '../../../base-ui/BaseElement'; import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; import { HiperfPluginConfig, ProfilerPluginConfig, TracePluginConfig } from './bean/ProfilerServiceTypes'; -import { SpRecordTrace } from '../SpRecordTrace'; +import { SpRecordTemplateHtml } from './SpRecordTemplate.html'; @element('sp-record-template') export class SpRecordTemplate extends BaseElement { @@ -100,7 +100,7 @@ export class SpRecordTemplate extends BaseElement { ); } - addProbeListener(...elements: HTMLElement[]) { + addProbeListener(...elements: HTMLElement[]): void { elements.forEach((element) => { element.addEventListener('change', (event: CustomEventInit) => { let detail = event.detail; @@ -112,20 +112,21 @@ export class SpRecordTemplate extends BaseElement { }); }); } + getTemplateConfig(): Array> { let config: Array> = []; - let traceEventSet = new Array(); - let hitraceCategories = new Array(); + let traceEventSet: string[] = []; + let hiTraceCategories: string[] = []; let useFtracePlugin: boolean = false; if (this.frameTimeline?.checked || this.appStartup?.checked || this.dynamicEffectEl?.checked) { useFtracePlugin = true; SpRecordTemplate.FRAME_TIMELINE_CATEGORIES_EVENT.forEach((categories) => { - if (hitraceCategories.indexOf(categories) == -1) { - hitraceCategories.push(categories); + if (hiTraceCategories.indexOf(categories) === -1) { + hiTraceCategories.push(categories); } }); if (this.appStartup?.checked) { - hitraceCategories.push('musl'); + hiTraceCategories.push('musl'); config.push(this.createHiperfDefaultConfig()); } SpRecordTemplate.FRAME_TIMELINE_EVENTS.forEach((ev) => { @@ -134,22 +135,12 @@ export class SpRecordTemplate extends BaseElement { } }); } - if (this.schedulingAnalysis?.checked) { - useFtracePlugin = true; - SpRecordTemplate.SCHEDULING_ANALYSIS_EVENT.forEach((event) => { - if (traceEventSet.indexOf(event) < 0) { - traceEventSet.push(event); - } - }); - } - if (this.taskPoolEl!.checked) { - useFtracePlugin = true; - hitraceCategories.push('commonlibrary'); - } + useFtracePlugin = this.schedulingAnalysisConfig(useFtracePlugin, traceEventSet); + useFtracePlugin = this.taskPoolElConfig(useFtracePlugin, hiTraceCategories); if (useFtracePlugin) { let tracePluginConfig: TracePluginConfig = { ftraceEvents: traceEventSet, - hitraceCategories: hitraceCategories, + hitraceCategories: hiTraceCategories, flushIntervalMs: 1000, hitraceApps: [], bufferSizeKb: 2048, @@ -171,93 +162,40 @@ export class SpRecordTemplate extends BaseElement { return config; } + private schedulingAnalysisConfig(useFtracePlugin: boolean, traceEventSet: string[]): boolean { + if (this.schedulingAnalysis?.checked) { + useFtracePlugin = true; + SpRecordTemplate.SCHEDULING_ANALYSIS_EVENT.forEach((event) => { + if (traceEventSet.indexOf(event) < 0) { + traceEventSet.push(event); + } + }); + } + return useFtracePlugin; + } + + private taskPoolElConfig(useFtracePlugin: boolean, hitraceCategories: string[]): boolean { + if (this.taskPoolEl!.checked) { + useFtracePlugin = true; + hitraceCategories.push('commonlibrary'); + } + return useFtracePlugin; + } + private createHiperfDefaultConfig(): ProfilerPluginConfig { let hiPerf: HiperfPluginConfig = { isRoot: false, outfileName: '/data/local/tmp/perf.data', recordArgs: SpRecordTemplate.HIPERF_DEFAULT_RECORD_ARGS, }; - let htraceProfilerPluginConfig: ProfilerPluginConfig = { + return { pluginName: 'hiperf-plugin', sampleInterval: 5000, configData: hiPerf, }; - return htraceProfilerPluginConfig; } initHtml(): string { - return ` - -
-
-
- FrameTimeline - -
-
-
-
- SchedulingAnalysis - -
-
-
-
- AppStartup - -
-
-
-
- TaskPool - -
-
-
-
- AnimationAnalysis - -
-
-
- `; + return SpRecordTemplateHtml; } } diff --git a/ide/src/trace/component/setting/SpSdkConfig.html.ts b/ide/src/trace/component/setting/SpSdkConfig.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..14ec945bf90b33cb4d247773225b1c39f79ea580 --- /dev/null +++ b/ide/src/trace/component/setting/SpSdkConfig.html.ts @@ -0,0 +1,125 @@ +/* + * 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. + */ + +export const SpSdkConfigHtml = ` + +
+
+
+ Start Custom Config + +
+
+
+ +
+
+
+
+`; diff --git a/ide/src/trace/component/setting/SpSdkConfig.ts b/ide/src/trace/component/setting/SpSdkConfig.ts index 61476821eb7155117ec3ede69d2a5ee1ba8a8141..cf1a825bba82bae30ee33e38ce935145f1235bef 100644 --- a/ide/src/trace/component/setting/SpSdkConfig.ts +++ b/ide/src/trace/component/setting/SpSdkConfig.ts @@ -21,6 +21,7 @@ import '../../../base-ui/switch/lit-switch'; import LitSwitch, { LitSwitchChangeEvent } from '../../../base-ui/switch/lit-switch'; import { LitSelectV } from '../../../base-ui/select/LitSelectV'; import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; +import { SpSdkConfigHtml } from './SpSdkConfig.html'; @element('sp-sdk-config') export class SpSdkConfig extends BaseElement { @@ -32,7 +33,7 @@ export class SpSdkConfig extends BaseElement { private pluginName: string = ''; private sampleInterval: number = 5000; - static get observedAttributes() { + static get observedAttributes(): string[] { return ['configName', 'value', 'type']; } @@ -61,7 +62,7 @@ export class SpSdkConfig extends BaseElement { } set configName(configName: string) { - if (configName != '') { + if (configName !== '') { this.setAttribute('configName', configName); } else { this.removeAttribute('configName'); @@ -77,7 +78,7 @@ export class SpSdkConfig extends BaseElement { } set type(type: string) { - if (type != '') { + if (type !== '') { this.setAttribute('type', type); } else { this.removeAttribute('type'); @@ -87,7 +88,7 @@ export class SpSdkConfig extends BaseElement { private wasmMap: Map = new Map(); private wasmList: Array = []; - private changGpu(gpuName: string) { + private changGpu(gpuName: string): void { let config = this.wasmMap.get(gpuName); this.pluginName = config?.pluginName; this.sampleInterval = config?.sampleInterval; @@ -98,7 +99,7 @@ export class SpSdkConfig extends BaseElement { WasmName: config.wasmName, }; this.worker!.postMessage(pam); - this.worker!.onmessage = (event: MessageEvent) => { + this.worker!.onmessage = (event: MessageEvent): void => { let results = event.data.results; this.sdkConfigList = results.settingConfig; this.initConfig(); @@ -140,7 +141,7 @@ export class SpSdkConfig extends BaseElement { return gpuConfig; } - initElements(): void { + private initSdkWasm(): void { try { let spApplication = document.querySelector('sp-application'); let wasmJsonUrl = `https://${window.location.host.split(':')[0]}:${window.location.port}/application/wasm.json`; @@ -162,8 +163,8 @@ export class SpSdkConfig extends BaseElement { }); } }) - .catch((err) => {}); - if (this.worker == null) { + ['catch'](() => {}); + if (this.worker === null) { // @ts-ignore if (window.useWb) { return; @@ -171,6 +172,10 @@ export class SpSdkConfig extends BaseElement { this.worker = new Worker(new URL('../../database/ConfigWorker', import.meta.url)); } } catch (e) {} + } + + initElements(): void { + this.initSdkWasm(); this.customConfig = this.shadowRoot?.querySelector('.configList'); let switchButton = this.shadowRoot?.querySelector('.config_switch') as LitSwitch; switchButton.addEventListener('change', (event: CustomEventInit) => { @@ -191,7 +196,7 @@ export class SpSdkConfig extends BaseElement { this.selectConfig!.processData = this.wasmList; this.selectConfig!.initData(); }); - inputDiv.addEventListener('valuable', (ev) => { + inputDiv.addEventListener('valuable', () => { this.changGpu(input!.value); }); } @@ -200,13 +205,83 @@ export class SpSdkConfig extends BaseElement { this.isAbleShowConfig(true); } - initConfig() { + + private sdkConfigByBooleanType(key: string, sdkConfigSwitch: LitSwitch, sdkConfigHeadDiv: HTMLDivElement): void { + sdkConfigSwitch.className = 'switch1 config'; + sdkConfigSwitch.setAttribute('configName', key); + sdkConfigSwitch.setAttribute('type', this.sdkConfigList.configuration[key].type); + if (this.sdkConfigList.configuration[key]['default'] == 'true') { + sdkConfigSwitch.setAttribute('checked', ''); + sdkConfigSwitch.setAttribute('value', 'true'); + } else { + sdkConfigSwitch.removeAttribute('checked'); + sdkConfigSwitch.setAttribute('value', 'false'); + } + sdkConfigHeadDiv.appendChild(sdkConfigSwitch); + this.list!.push(sdkConfigSwitch); + } + + private sdkConfigByIntegerType(key: string, sdkConfigDiv: HTMLDivElement, sdkConfigTitle: HTMLSpanElement): void { + let input = document.createElement('input'); + input.className = 'sdk-config-input config'; + if (this.sdkConfigList.configuration[key]['default']) { + input.value = this.sdkConfigList.configuration[key]['default']; + } + input.setAttribute('configName', key); + input.setAttribute('type', this.sdkConfigList.configuration[key].type); + input.oninput = (): void => { + input.value = this.checkIntegerInput(input.value); + sdkConfigTitle.setAttribute('value', input.value); + }; + sdkConfigDiv.appendChild(input); + this.list!.push(input); + } + + private sdkConfigByNumberType(key: string, sdkConfigDiv: HTMLDivElement): void { + let numberInput = document.createElement('input'); + numberInput.className = 'sdk-config-input config'; + if (this.sdkConfigList.configuration[key]['default']) { + numberInput.value = this.sdkConfigList.configuration[key]['default']; + } + numberInput.setAttribute('configName', key); + numberInput.setAttribute('type', 'num'); + numberInput.oninput = (): void => { + numberInput.value = this.checkFloatInput(numberInput.value); + }; + sdkConfigDiv.appendChild(numberInput); + this.list!.push(numberInput); + } + + private sdkConfigByStringType(key: string, sdkConfigDiv: HTMLDivElement): void { + let html = ''; + if (this.sdkConfigList.configuration[key]['enum']) { + let placeholder = ''; + if (this.sdkConfigList.configuration[key]['default']) { + placeholder = this.sdkConfigList.configuration[key]['default']; + } + html += ``; + sdkConfigDiv.innerHTML = sdkConfigDiv.innerHTML + html; + } else { + let inputElement = document.createElement('input'); + inputElement.className = 'sdk-config-input config'; + if (this.sdkConfigList.configuration[key]['default']) { + inputElement.value = this.sdkConfigList.configuration[key]['default']; + } + inputElement.setAttribute('configName', key); + inputElement.setAttribute('type', this.sdkConfigList.configuration[key].type); + sdkConfigDiv.appendChild(inputElement); + this.list!.push(inputElement); + } + } + + initConfig(): void { this.customConfig!.innerHTML = ''; this.list = []; this.list.push(this.selectConfig!); let sdkConfigSwitch = document.createElement('lit-switch') as LitSwitch; for (let key in this.sdkConfigList.configuration) { - let html = ''; let sdkConfigDiv = document.createElement('div'); sdkConfigDiv.className = 'sdk-config-div'; let sdkConfigHeadDiv = document.createElement('div'); @@ -221,77 +296,24 @@ export class SpSdkConfig extends BaseElement { sdkConfigHeadDiv.appendChild(sdkConfigDes); switch (this.sdkConfigList.configuration[key].type) { case 'string': - if (this.sdkConfigList.configuration[key].enum) { - let placeholder = ''; - if (this.sdkConfigList.configuration[key].default) { - placeholder = this.sdkConfigList.configuration[key].default; - } - html += ``; - sdkConfigDiv.innerHTML = sdkConfigDiv.innerHTML + html; - } else { - let inputElement = document.createElement('input'); - inputElement.className = 'sdk-config-input config'; - if (this.sdkConfigList.configuration[key].default) { - inputElement.value = this.sdkConfigList.configuration[key].default; - } - inputElement.setAttribute('configName', key); - inputElement.setAttribute('type', this.sdkConfigList.configuration[key].type); - sdkConfigDiv.appendChild(inputElement); - this.list.push(inputElement); - } + this.sdkConfigByStringType(key, sdkConfigDiv); break; case 'number': - let numberInput = document.createElement('input'); - numberInput.className = 'sdk-config-input config'; - if (this.sdkConfigList.configuration[key].default) { - numberInput.value = this.sdkConfigList.configuration[key].default; - } - numberInput.setAttribute('configName', key); - numberInput.setAttribute('type', 'num'); - numberInput.oninput = (ev) => { - let inputValue = this.checkFloatInput(numberInput.value); - numberInput.value = inputValue; - }; - sdkConfigDiv.appendChild(numberInput); - this.list.push(numberInput); + this.sdkConfigByNumberType(key, sdkConfigDiv); break; case 'integer': - let input = document.createElement('input'); - input.className = 'sdk-config-input config'; - if (this.sdkConfigList.configuration[key].default) { - input.value = this.sdkConfigList.configuration[key].default; - } - input.setAttribute('configName', key); - input.setAttribute('type', this.sdkConfigList.configuration[key].type); - input.oninput = (ev) => { - let inputValue = this.checkIntegerInput(input.value); - input.value = inputValue; - sdkConfigTitle.setAttribute('value', input.value); - }; - sdkConfigDiv.appendChild(input); - this.list.push(input); + this.sdkConfigByIntegerType(key, sdkConfigDiv, sdkConfigTitle); break; case 'boolean': - sdkConfigSwitch.className = 'switch1 config'; - sdkConfigSwitch.setAttribute('configName', key); - sdkConfigSwitch.setAttribute('type', this.sdkConfigList.configuration[key].type); - if (this.sdkConfigList.configuration[key].default == 'true') { - sdkConfigSwitch.setAttribute('checked', ''); - sdkConfigSwitch.setAttribute('value', 'true'); - } else { - sdkConfigSwitch.removeAttribute('checked'); - sdkConfigSwitch.setAttribute('value', 'false'); - } - sdkConfigHeadDiv.appendChild(sdkConfigSwitch); - this.list.push(sdkConfigSwitch); + this.sdkConfigByBooleanType(key, sdkConfigSwitch, sdkConfigHeadDiv); break; } this.customConfig!.appendChild(sdkConfigDiv); - if (this.sdkConfigList.configuration[key].enum) { + if (this.sdkConfigList.configuration[key]['enum']) { let select = this.shadowRoot!.querySelector(`#${key}`); select!.setAttribute('type', 'enum'); - select!.setAttribute('value', this.sdkConfigList.configuration[key].default); - select!.dataSource(this.sdkConfigList.configuration[key].enum, ''); + select!.setAttribute('value', this.sdkConfigList.configuration[key]['default']); + select!.dataSource(this.sdkConfigList.configuration[key]['enum'], ''); this.list.push(select!); select!.addEventListener('click', () => { select!.setAttribute('value', select!.value); @@ -299,11 +321,7 @@ export class SpSdkConfig extends BaseElement { } } sdkConfigSwitch.addEventListener('change', () => { - if (sdkConfigSwitch.hasAttribute('checked')) { - sdkConfigSwitch.setAttribute('value', 'true'); - } else { - sdkConfigSwitch.setAttribute('value', 'false'); - } + sdkConfigSwitch.setAttribute('value', `${sdkConfigSwitch.hasAttribute('checked')}`); }); } @@ -324,7 +342,7 @@ export class SpSdkConfig extends BaseElement { return inputValue.replace(/\.{2,}|-(0){2,}|(-)0+(\d+)/g, '.'); } - isAbleShowConfig(isAbleShow: boolean) { + isAbleShowConfig(isAbleShow: boolean): void { if (this.list!) { if (isAbleShow) { this.list!.forEach((item) => { @@ -339,114 +357,6 @@ export class SpSdkConfig extends BaseElement { } initHtml(): string { - return ` - -
-
-
- Start Custom Config - -
-
-
- -
-
-
-
- `; + return SpSdkConfigHtml; } } diff --git a/ide/src/trace/component/setting/SpTraceCommand.html.ts b/ide/src/trace/component/setting/SpTraceCommand.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..af2dffb937da3872ddb91f7524f8ddd51b1f184e --- /dev/null +++ b/ide/src/trace/component/setting/SpTraceCommand.html.ts @@ -0,0 +1,104 @@ +/* + * 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. + */ + +export const SpTraceCommandHtml = ` + +
+ + +
+`; diff --git a/ide/src/trace/component/setting/SpTraceCommand.ts b/ide/src/trace/component/setting/SpTraceCommand.ts index 03cb8d6019573c7093ac7c9753076c00ef613d95..f3aff15bfe1db2e07854a759ab68296b6517639f 100644 --- a/ide/src/trace/component/setting/SpTraceCommand.ts +++ b/ide/src/trace/component/setting/SpTraceCommand.ts @@ -17,15 +17,15 @@ import { BaseElement, element } from '../../../base-ui/BaseElement'; import { info } from '../../../log/Log'; import { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; import { PluginConvertUtils } from './utils/PluginConvertUtils'; +import { SpTraceCommandHtml } from './SpTraceCommand.html'; @element('trace-command') export class SpTraceCommand extends BaseElement { private codeHl: HTMLTextAreaElement | undefined | null; private copyEl: HTMLElement | undefined | null; - private codeCopyText: HTMLInputElement | undefined; get hdcCommon(): string { - return this.codeHl!.textContent + ''; + return `${this.codeHl!.textContent}`; } set hdcCommon(value: string) { @@ -70,94 +70,6 @@ export class SpTraceCommand extends BaseElement { } initHtml(): string { - return ` - -
- - -
- `; + return SpTraceCommandHtml; } } diff --git a/ide/src/trace/component/setting/SpVmTracker.html.ts b/ide/src/trace/component/setting/SpVmTracker.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..56cb4f171a1dbe9bc3fb08111d341b948607d6c5 --- /dev/null +++ b/ide/src/trace/component/setting/SpVmTracker.html.ts @@ -0,0 +1,118 @@ +/* + * 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. + */ + +export const SpVmTrackerHtml = ` + +
+
+
+ Start VM Tracker Record + +
+
+
+
+ Process + Record process +
+ +
+
+`; diff --git a/ide/src/trace/component/setting/SpVmTracker.ts b/ide/src/trace/component/setting/SpVmTracker.ts index 02020beaf1e5c9eea4e8a8a504a406f57a32f9c9..e62ab9d14a543c1ca944c501f6b8128aa4ff713e 100644 --- a/ide/src/trace/component/setting/SpVmTracker.ts +++ b/ide/src/trace/component/setting/SpVmTracker.ts @@ -21,6 +21,7 @@ import '../../../base-ui/switch/lit-switch'; import { LitAllocationSelect } from '../../../base-ui/select/LitAllocationSelect'; import { SpRecordTrace } from '../SpRecordTrace'; import { Cmd } from '../../../command/Cmd'; +import { SpVmTrackerHtml } from './SpVmTracker.html'; @element('sp-vm-tracker') export class SpVmTracker extends BaseElement { @@ -66,7 +67,7 @@ export class SpVmTracker extends BaseElement { }); this.vmTrackerProcessInput = this.shadowRoot?.querySelector('lit-allocation-select'); let vmTrackerMul = this.vmTrackerProcessInput?.shadowRoot?.querySelector('.multipleSelect') as HTMLDivElement; - vmTrackerMul!.addEventListener('mousedown', (ev) => { + vmTrackerMul!.addEventListener('mousedown', () => { if (SpRecordTrace.serialNumber === '') { this.vmTrackerProcessInput!.processData = []; this.vmTrackerProcessInput!.initData(); @@ -103,108 +104,6 @@ export class SpVmTracker extends BaseElement { } initHtml(): string { - return ` - -
-
-
- Start VM Tracker Record - -
-
-
-
- Process - Record process -
- -
-
- `; + return SpVmTrackerHtml; } } diff --git a/ide/src/trace/component/setting/SpWebHdcShell.ts b/ide/src/trace/component/setting/SpWebHdcShell.ts index 55e89d8d8414af7cf62d816cbf7623d403508599..60e19a09070a7457d37f31584c7fe50e613b1b59 100644 --- a/ide/src/trace/component/setting/SpWebHdcShell.ts +++ b/ide/src/trace/component/setting/SpWebHdcShell.ts @@ -85,11 +85,11 @@ export class SpWebHdcShell extends BaseElement { this.hdcShellFocus(); } }); - window.subscribe(window.SmartEvent.UI.DeviceDisConnect, (deviceName: string) => { + window.subscribe(window.SmartEvent.UI.DeviceDisConnect, () => { this.clear(); }); let that = this; - this.shellCanvas!.addEventListener('blur', function (event) { + this.shellCanvas!.addEventListener('blur', function () { if (that.intervalId) { window.clearInterval(that.intervalId); } @@ -315,6 +315,51 @@ export class SpWebHdcShell extends BaseElement { private finalArr: Array = []; + private drawShellPage(resultStrArr: string[]): void { + let maxWidth = this.shellCanvas!.width; + let foundationWidth = Math.ceil(this.shellCanvasCtx!.measureText(' ').width); + for (let index = 0; index < resultStrArr.length - 1; index++) { + let shellStr = resultStrArr[index]; + let strWidth = this.shellCanvasCtx!.measureText(shellStr).width; + if (strWidth > maxWidth) { + let lines = this.singleLineToMultiLine(shellStr, foundationWidth, maxWidth - SpWebHdcShell.LEFT_OFFSET); + this.finalArr.push(...lines); + } else { + this.finalArr.push(shellStr); + } + } + if (this.finalArr.length > SpWebHdcShell.MAX_DISPLAY_ROWS) { + this.finalArr.splice(0, this.finalArr.length - SpWebHdcShell.MAX_DISPLAY_ROWS + 1); + } + this.shellCanvasCtx!.fillStyle = '#fff'; + this.shellCanvasCtx!.font = '16px serif'; + this.textY = SpWebHdcShell.TOP_OFFSET; + this.finalArr.push(this.cursorRow); + for (let index: number = 0; index < this.finalArr.length; index++) { + let shellStr: string = this.finalArr[index]; + this.textY = SpWebHdcShell.TOP_OFFSET + index * 16; + this.shellCanvasCtx!.fillText(shellStr, SpWebHdcShell.LEFT_OFFSET, this.textY); + } + } + + private drawCursorStyle(): void { + if (this.intervalId) { + window.clearInterval(this.intervalId); + } + let needClear = false; + this.intervalId = window.setInterval(() => { + if (needClear) { + needClear = false; + this.shellCanvasCtx!.fillStyle = '#000'; + this.shellCanvasCtx!.fillRect(this.shellStrLength, this.textY, 12, 3); + } else { + needClear = true; + this.shellCanvasCtx!.fillStyle = '#fff'; + this.shellCanvasCtx!.fillRect(this.shellStrLength, this.textY, 12, 3); + } + }, 500); + } + refreshShellPage(scroller: boolean): void { try { if (this.resultStr.length === 0 && this.cursorRow.length === 0) { @@ -329,56 +374,16 @@ export class SpWebHdcShell extends BaseElement { } this.finalArr = []; if (this.shellCanvas!.width > 0) { - let maxWidth = this.shellCanvas!.width; - let foundationWidth = Math.ceil(this.shellCanvasCtx!.measureText(' ').width); - for (let i = 0; i < resultStrArr.length - 1; i++) { - let shellStr = resultStrArr[i]; - let strWidth = this.shellCanvasCtx!.measureText(shellStr).width; - if (strWidth > maxWidth) { - let lines = this.singleLineToMultiLine(shellStr, foundationWidth, maxWidth - SpWebHdcShell.LEFT_OFFSET); - this.finalArr.push(...lines); - } else { - this.finalArr.push(shellStr); - } - } - if (this.finalArr.length > SpWebHdcShell.MAX_DISPLAY_ROWS) { - this.finalArr.splice(0, this.finalArr.length - SpWebHdcShell.MAX_DISPLAY_ROWS + 1); - } - let unitWidth: number = this.shellCanvasCtx!.measureText(' ').width; - this.shellCanvasCtx!.fillStyle = '#fff'; - this.shellCanvasCtx!.font = '16px serif'; - this.textY = SpWebHdcShell.TOP_OFFSET; - this.finalArr.push(this.cursorRow); - for (let index: number = 0; index < this.finalArr.length; index++) { - let shellStr: string = this.finalArr[index]; - this.textY = SpWebHdcShell.TOP_OFFSET + index * 16; - this.shellCanvasCtx!.fillText(shellStr, SpWebHdcShell.LEFT_OFFSET, this.textY); - } + this.drawShellPage(resultStrArr); this.shellStrLength = this.shellCanvasCtx!.measureText(this.cursorRow.slice(0, this.cursorIndex)).width + SpWebHdcShell.LEFT_OFFSET; // 记录前一次滚动条的位置 this.prevTextY = this.shellDiv!.scrollTop + this.shellDiv!.clientHeight - 3; - if (scroller) { - if (this.textY > this.shellDiv!.clientHeight && this.textY > this.prevTextY) { - this.shellDiv!.scrollTop = this.textY - this.shellDiv!.clientHeight + 3; - this.currentScreenRemain = this.shellDiv!.scrollTop; - } - } - if (this.intervalId) { - window.clearInterval(this.intervalId); + if (scroller && this.textY > this.shellDiv!.clientHeight && this.textY > this.prevTextY) { + this.shellDiv!.scrollTop = this.textY - this.shellDiv!.clientHeight + 3; + this.currentScreenRemain = this.shellDiv!.scrollTop; } - let needClear = false; - this.intervalId = window.setInterval(() => { - if (needClear) { - needClear = false; - this.shellCanvasCtx!.fillStyle = '#000'; - this.shellCanvasCtx!.fillRect(this.shellStrLength, this.textY, 12, 3); - } else { - needClear = true; - this.shellCanvasCtx!.fillStyle = '#fff'; - this.shellCanvasCtx!.fillRect(this.shellStrLength, this.textY, 12, 3); - } - }, 500); + this.drawCursorStyle(); } } catch (e) {} } @@ -471,22 +476,7 @@ export class SpWebHdcShell extends BaseElement { } const arrayA = new Uint8Array(resData); if (arrayA[0] === 13 && arrayA[1] !== 10 && arrayA[1] !== 13) { - const index = this.resultStr.lastIndexOf('\n'); - const resultStrLength = this.resultStr.length; - if (index > -1 && resultStrLength > index) { - this.resultStr = - this.resultStr.substring(0, index + 1) + this.textDecoder.decode(arrayA.slice(1, arrayA.length)); - } else { - if (this.resultStr.split('\n').length === 1) { - const index = this.cursorRow.lastIndexOf('\n'); - this.cursorRow = - this.cursorRow.substring(0, index + 1) + this.textDecoder.decode(arrayA.slice(1, arrayA.length)); - this.resultStr = this.cursorRow; - } else { - this.resultStr += result.getDataToString(); - } - } - this.realTimeResult = ''; + this.hdcRecvEnterAndBracket(arrayA, result); } else if (this.isStartWidthArrayBuffer(arrayA, this.startRealTimeFlag)) { let lastIndex = this.getLastRestorationIndex(arrayA, this.endRealTimeFlag); this.realTimeResult = this.removeTextAndColorSequenceStr( @@ -503,27 +493,7 @@ export class SpWebHdcShell extends BaseElement { this.resultStr += this.realTimeResult; this.startRealTime = false; } - if (this.startRealTime) { - if (result.getDataToString().includes(SpWebHdcShell.MULTI_LINE_FLAG)) { - this.realTimeResult += result.getDataToString().substring(result.getDataToString().indexOf('\r')); - } else { - this.realTimeResult += result.getDataToString(); - } - this.realTimeResult = this.removeTextAndColorSequenceStr(this.realTimeResult!); - } else { - this.realTimeResult = ''; - if (result.getDataToString().includes(SpWebHdcShell.MULTI_LINE_FLAG)) { - // 获取所有内容,不包括最后一行数据 - this.resultStr = this.resultStr.substring( - 0, - this.resultStr.lastIndexOf('\r\n') + SpWebHdcShell.LINE_BREAK_LENGTH - ); - // 多行情况不能直接拼接返回数据 - this.resultStr += result.getDataToString().substring(result.getDataToString().indexOf('\r')); - } else { - this.resultStr += result.getDataToString(); - } - } + this.hdcRecvRealMessage(result); } } this.resultStr = this.removeTextAndColorSequenceStr(this.resultStr); @@ -532,6 +502,49 @@ export class SpWebHdcShell extends BaseElement { } } + private hdcRecvEnterAndBracket(arrayA: Uint8Array, result: DataMessage): void { + const index = this.resultStr.lastIndexOf('\n'); + const resultStrLength = this.resultStr.length; + if (index > -1 && resultStrLength > index) { + this.resultStr = + this.resultStr.substring(0, index + 1) + this.textDecoder.decode(arrayA.slice(1, arrayA.length)); + } else { + if (this.resultStr.split('\n').length === 1) { + const index = this.cursorRow.lastIndexOf('\n'); + this.cursorRow = + this.cursorRow.substring(0, index + 1) + this.textDecoder.decode(arrayA.slice(1, arrayA.length)); + this.resultStr = this.cursorRow; + } else { + this.resultStr += result.getDataToString(); + } + } + this.realTimeResult = ''; + } + + private hdcRecvRealMessage(result: DataMessage): void { + if (this.startRealTime) { + if (result.getDataToString().includes(SpWebHdcShell.MULTI_LINE_FLAG)) { + this.realTimeResult += result.getDataToString().substring(result.getDataToString().indexOf('\r')); + } else { + this.realTimeResult += result.getDataToString(); + } + this.realTimeResult = this.removeTextAndColorSequenceStr(this.realTimeResult!); + } else { + this.realTimeResult = ''; + if (result.getDataToString().includes(SpWebHdcShell.MULTI_LINE_FLAG)) { + // 获取所有内容,不包括最后一行数据 + this.resultStr = this.resultStr.substring( + 0, + this.resultStr.lastIndexOf('\r\n') + SpWebHdcShell.LINE_BREAK_LENGTH + ); + // 多行情况不能直接拼接返回数据 + this.resultStr += result.getDataToString().substring(result.getDataToString().indexOf('\r')); + } else { + this.resultStr += result.getDataToString(); + } + } + } + private removeTextAndColorSequenceStr(currentStr: string): string { return currentStr.replace(new RegExp(/\x1B\[[0-9;]*[a-zA-Z]/g), ''); } diff --git a/ide/src/trace/component/setting/bean/ProfilerServiceTypes.ts b/ide/src/trace/component/setting/bean/ProfilerServiceTypes.ts index a4709f49205d1a764d8a9ad9bf91bbf5273ac59d..309bf042570eb87711eba7b234ef4888ed70c073 100644 --- a/ide/src/trace/component/setting/bean/ProfilerServiceTypes.ts +++ b/ide/src/trace/component/setting/bean/ProfilerServiceTypes.ts @@ -124,7 +124,7 @@ export interface MemoryConfig { reportGpuDumpInfo?: boolean; } -export function sysVMeminfoTypeFromJSON(object: any): SysVMeminfoType { +const switchCase = (object: any): SysVMeminfoType => { switch (object) { case 0: case 'VMEMINFO_UNSPECIFIED': @@ -518,6 +518,10 @@ export function sysVMeminfoTypeFromJSON(object: any): SysVMeminfoType { default: return SysVMeminfoType.UNRECOGNIZED; } +}; + +export function sysVMeminfoTypeFromJSON(object: any): SysVMeminfoType { + return switchCase(object); } export enum SysVMeminfoType { @@ -695,7 +699,7 @@ export enum SysMeminfoType { UNRECOGNIZED = 'UNRECOGNIZED', } -export function sysMeminfoTypeFromJSON(object: any): SysMeminfoType { +const sysMeminfoCase = (object: any): SysMeminfoType => { switch (object) { case 0: case 'MEMINFO_UNSPECIFIED': @@ -816,6 +820,10 @@ export function sysMeminfoTypeFromJSON(object: any): SysMeminfoType { default: return SysMeminfoType.UNRECOGNIZED; } +}; + +export function sysMeminfoTypeFromJSON(object: any): SysMeminfoType { + return sysMeminfoCase(object); } export enum Type { @@ -915,7 +923,8 @@ export interface DiskioConfig { reportIoStats: string; } -export interface NetworkConfig {} +export interface NetworkConfig { +} export interface HiperfPluginConfig { isRoot: boolean; diff --git a/ide/src/trace/component/trace/base/CustomThemeColor.html.ts b/ide/src/trace/component/trace/base/CustomThemeColor.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..25c685e6e91a84da1dc186cadd9cc0ac3e12f936 --- /dev/null +++ b/ide/src/trace/component/trace/base/CustomThemeColor.html.ts @@ -0,0 +1,177 @@ +/* + * 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. + */ + +export const CustomThemeColorHtml = ` + +
+
+ Color Setting + +
+
+
+ Appearance + light + dark +
+
+ Color Customization + Please customize colors according to your preferences +
+
+
+
+
+ + + +
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/base/CustomThemeColor.ts b/ide/src/trace/component/trace/base/CustomThemeColor.ts index 010704ae9789ab2312619ed551daced22642f22b..814e00975c09a329a5aa4158dfa85df17965a517 100644 --- a/ide/src/trace/component/trace/base/CustomThemeColor.ts +++ b/ide/src/trace/component/trace/base/CustomThemeColor.ts @@ -18,6 +18,7 @@ import { ColorUtils } from './ColorUtils'; import { LitRadioBox } from '../../../../base-ui/radiobox/LitRadioBox'; import { SpApplication } from '../../../SpApplication'; import { SpSystemTrace } from '../../SpSystemTrace'; +import { CustomThemeColorHtml } from './CustomThemeColor.html'; @element('custom-theme-color') export class CustomThemeColor extends BaseElement { @@ -179,7 +180,7 @@ export class CustomThemeColor extends BaseElement { this.setRadioChecked(this.theme); } - cancelOperate() { + cancelOperate(): void { if (window.localStorage.getItem('Theme') === 'light' || !window.localStorage.getItem('Theme')) { this.theme = Theme.LIGHT; this.colorsArray = @@ -201,168 +202,7 @@ export class CustomThemeColor extends BaseElement { connectedCallback(): void {} initHtml(): string { - return ` - -
-
- Color Setting - -
-
-
- Appearance - ${Theme.LIGHT} - ${Theme.DARK} -
-
- Color Customization - Please customize colors according to your preferences -
-
-
-
-
- - - -
-
- `; + return CustomThemeColorHtml; } attributeChangedCallback(name: string, oldValue: string, newValue: string): void { diff --git a/ide/src/trace/component/trace/base/TraceRow.html.ts b/ide/src/trace/component/trace/base/TraceRow.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ef5ba458bdb6be6b0af300f38bfce969aa952b2 --- /dev/null +++ b/ide/src/trace/component/trace/base/TraceRow.html.ts @@ -0,0 +1,274 @@ +/* + * 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. + */ +export const TraceRowHtml = ` + +
+
+ + + +
+
+ `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/base/TraceRow.ts b/ide/src/trace/component/trace/base/TraceRow.ts index 453191b79c6ffec5b01baa4f56cb5624377b13c6..aea7575819bc1f4298a9cdd87f01a533d45e2a68 100644 --- a/ide/src/trace/component/trace/base/TraceRow.ts +++ b/ide/src/trace/component/trace/base/TraceRow.ts @@ -31,6 +31,7 @@ import { drawSelectionRange, isFrameContainPoint } from '../../../database/ui-wo import { TraceRowConfig } from './TraceRowConfig'; import { type TreeItemData, LitTree } from '../../../../base-ui/tree/LitTree'; import { SpSystemTrace } from '../../SpSystemTrace'; +import { TraceRowHtml } from './TraceRow.html'; export class RangeSelectStruct { startX: number | undefined; @@ -1339,265 +1340,6 @@ export class TraceRow extends HTMLElement { } initHtml(): string { - return ` - -
-
- - - -
-
- `; + return TraceRowHtml; } } diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.html.ts b/ide/src/trace/component/trace/base/TraceRowConfig.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..9ce24012981da630cc9f4bc96558ace1b0696ab4 --- /dev/null +++ b/ide/src/trace/component/trace/base/TraceRowConfig.html.ts @@ -0,0 +1,203 @@ +/* + * 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. + */ +export const TraceRowConfigHtml = ` + +
+ Display Template + + +
+
+
+ +
Template Select
+
+
+
+
+
+
+ +
Timeline Details
+
+
+
+
+ +
+ +
+
+ + + + +
+
+
+
+
+
+`; diff --git a/ide/src/trace/component/trace/base/TraceRowConfig.ts b/ide/src/trace/component/trace/base/TraceRowConfig.ts index 0675806b12803144a47928150747aaacdef8065b..1f35fa2d94346212366df9d5643e0a9859bbbc5f 100644 --- a/ide/src/trace/component/trace/base/TraceRowConfig.ts +++ b/ide/src/trace/component/trace/base/TraceRowConfig.ts @@ -23,6 +23,7 @@ import { TraceSheet } from './TraceSheet'; import { CpuStruct } from '../../../database/ui-worker/cpu/ProcedureWorkerCPU'; import { type BaseStruct } from '../../../bean/BaseStruct'; import { LitIcon } from '../../../../base-ui/icon/LitIcon'; +import { TraceRowConfigHtml } from './TraceRowConfig.html'; const LOCAL_STORAGE_JSON = 'subsystem_config'; @@ -706,6 +707,17 @@ export class TraceRowConfig extends BaseElement { let configCheckBox: LitCheckBox = new LitCheckBox(); configCheckBox.className = 'scene-check-box temp-chart-item'; configCheckBox.setAttribute('search_text', subsystemNode.nodeName!); + this.buildCheckBox(configCheckBox, subsystemNode); + subsystemDiv.appendChild(configCheckBox); + this.chartTable?.appendChild(subsystemDiv); + if (subsystemNode.children && this.expandedNodeList.has(subsystemNode.id)) { + subsystemNode.children.forEach((item) => { + this.buildSubsystem(item); + }); + } + } + + private buildCheckBox(configCheckBox: LitCheckBox, subsystemNode: SubsystemNode): void { if (subsystemNode.scene) { configCheckBox.title = subsystemNode.scene.toString(); } @@ -718,16 +730,16 @@ export class TraceRowConfig extends BaseElement { this.refreshTable(); this.displayRow(subsystemNode, configCheckBox); // 收藏后的泳道的展示或者隐藏 - this.spSystemTrace?.collectRows.forEach((favoriteRow) => { + this.spSystemTrace?.collectRows.forEach((subsystemFavorite) => { let isShowRow: boolean = false; let favoriteName = ''; if (this.subsystemSelectList!.length === 0) { - favoriteRow.removeAttribute('scene'); - favoriteRow.rowHidden = true; + subsystemFavorite.removeAttribute('scene'); + subsystemFavorite.rowHidden = true; } else { - if (favoriteRow.parentRowEl) { - favoriteRow.parentRowEl.expansion = false; - favoriteName = favoriteRow.parentRowEl!.name; + if (subsystemFavorite.parentRowEl) { + subsystemFavorite.parentRowEl.expansion = false; + favoriteName = subsystemFavorite.parentRowEl!.name; for (let i = 0; i < this.subsystemSelectList!.length; i++) { if (this.subsystemSelectList![i].nodeName === favoriteName) { isShowRow = true; @@ -735,7 +747,7 @@ export class TraceRowConfig extends BaseElement { } } } else { - favoriteName = favoriteRow.name; + favoriteName = subsystemFavorite.name; for (let i = 0; i < this.subsystemSelectList!.length; i++) { if (this.subsystemSelectList![i].nodeName === favoriteName) { isShowRow = true; @@ -744,23 +756,16 @@ export class TraceRowConfig extends BaseElement { } } if (isShowRow) { - favoriteRow.rowHidden = false; - favoriteRow.setAttribute('scene', ''); + subsystemFavorite.rowHidden = false; + subsystemFavorite.setAttribute('scene', ''); } else { - favoriteRow.removeAttribute('scene'); - favoriteRow.rowHidden = true; + subsystemFavorite.removeAttribute('scene'); + subsystemFavorite.rowHidden = true; } } }); this.refreshSystemPanel(); }); - subsystemDiv.appendChild(configCheckBox); - this.chartTable?.appendChild(subsystemDiv); - if (subsystemNode.children && this.expandedNodeList.has(subsystemNode.id)) { - subsystemNode.children.forEach((item) => { - this.buildSubsystem(item); - }); - } } private buildTempOtherList(id: number): void { @@ -857,195 +862,7 @@ export class TraceRowConfig extends BaseElement { } initHtml(): string { - return ` - -
- Display Template - - -
-
-
- -
Template Select
-
-
-
-
-
-
- -
Timeline Details
-
-
-
-
- -
- -
-
- - - - -
-
-
-
-
-
-`; + return TraceRowConfigHtml; } attributeChangedCallback(name: string, oldValue: string, newValue: string): void { diff --git a/ide/src/trace/component/trace/base/TraceRowObject.ts b/ide/src/trace/component/trace/base/TraceRowObject.ts index bb51910fa26593a1d2cbec578b58749f8b3d34e7..aa55e8f7ae742ed4307f9b5481dc1c3ae69147dd 100644 --- a/ide/src/trace/component/trace/base/TraceRowObject.ts +++ b/ide/src/trace/component/trace/base/TraceRowObject.ts @@ -55,9 +55,7 @@ export class TraceRowObject { | WebGL2RenderingContext | null | undefined - ) => void) - | undefined - | null; + ) => void) | undefined | null; public top: number = 0; public rowIndex: number = 0; public preObject: TraceRowObject | undefined | null; diff --git a/ide/src/trace/component/trace/base/TraceSheet.ts b/ide/src/trace/component/trace/base/TraceSheet.ts index 8a19e11f2f100b30fe2edad32e230e803cfc6ebe..ad608a40a6150792bea7fd8caa215c854ab6d799 100644 --- a/ide/src/trace/component/trace/base/TraceSheet.ts +++ b/ide/src/trace/component/trace/base/TraceSheet.ts @@ -92,6 +92,12 @@ export class TraceSheet extends BaseElement { private importDiv: HTMLDivElement | undefined | null; private exportBt: LitIcon | undefined | null; private nav: HTMLDivElement | undefined | null; + private tabs: HTMLDivElement | undefined | null; + private navRoot: HTMLDivElement | null | undefined; + private search: HTMLDivElement | undefined | null; + private timerShaft: HTMLDivElement | undefined | null; + private spacer: HTMLDivElement | undefined | null; + private rowsPaneEL: HTMLDivElement | undefined | null; private selection: SelectionParam | undefined | null; private currentPaneID: string = 'current-selection'; private fragment: DocumentFragment | undefined; @@ -159,39 +165,19 @@ export class TraceSheet extends BaseElement { this.updateRangeSelect(selectIPid); this.lastSelectIPid = selectIPid; }; - this.buildTabs(this.litTabs); this.litTabs!.onTabClick = (e: any): void => this.loadTabPaneData(e.detail.key); - this.litTabs!.addEventListener('close-handler', () => { - Reflect.ownKeys(tabConfig) - .reverse() - .forEach((id) => { - let element = tabConfig[id]; - let pane = this.shadowRoot!.querySelector(`#${id as string}`); - if (element.require) { - pane!.hidden = !element.require(this.selection); - } else { - pane!.hidden = true; - } - }); - this.litTabs?.activeByKey(`${this.getPaneByID(this.currentPaneID).key}`); - }); + this.tableCloseHandler(); + this.rowClickEvent(); + } + private rowClickEvent(): void { this.getComponentByID('box-spt')?.addEventListener('row-click', this.rowClickHandler.bind(this)); this.getComponentByID('box-pts')?.addEventListener('row-click', this.rowClickHandler.bind(this)); this.getComponentByID('box-perf-analysis')?.addEventListener('row-click', (evt: MouseEvent) => { - // @ts-ignore - if (evt.detail.button === 2) { - let pane = this.getPaneByID('box-perf-profile'); - this.litTabs!.activeByKey(pane.key); - } + this.perfAnalysisListener(evt); }); this.getComponentByID('box-native-statistic-analysis')?.addEventListener('row-click', (e: MouseEvent) => { - //@ts-ignore - if (e.detail.button === 2) { - let pane = this.getPaneByID('box-native-calltree'); - pane.hidden = false; - this.litTabs!.activeByKey(pane.key); - } + this.nativeAnalysisListener(e); }); this.getComponentByID('box-io-tier-statistics-analysis')?.addEventListener('row-click', (evt: MouseEvent) => { // @ts-ignore @@ -221,149 +207,132 @@ export class TraceSheet extends BaseElement { } ); this.getComponentByID('box-native-statstics')?.addEventListener('row-click', (e: any) => { - if(e.detail.button === 0){ - this.selection!.statisticsSelectData = e.detail; - let pane = this.getPaneByID('box-native-memory'); - this.litTabs?.activeByKey(pane.key); - (pane.children.item(0) as any)!.fromStastics(this.selection); - } + this.nativeStatsticsListener(e); }); this.getComponentByID('box-virtual-memory-statistics')?.addEventListener('row-click', (e: any) => { - if(e.detail.button === 0){ - this.selection!.fileSystemVMData = { path: e.detail.path }; - let pane = this.getPaneByID('box-vm-events'); - this.litTabs?.activeByKey(pane.key); - if (e.detail.path) { - (pane.children.item(0) as any)!.fromStastics(this.selection); - } - } + this.virtualMemoryListener(e); }); this.getComponentByID('box-io-tier-statistics')?.addEventListener('row-click', (e: any) => { - if(e.detail.button === 0){ - this.selection!.fileSystemIoData = { path: e.detail.path }; - let pane = this.getPaneByID('box-io-events'); - this.litTabs?.activeByKey(pane.key); - if (e.detail.path) { - (pane.children.item(0) as any)!.fromStastics(this.selection); - } - } + this.ioTierListener(e); }); this.getComponentByID('box-file-system-statistics')?.addEventListener('row-click', (e: any) => { - if(e.detail.button === 0){ - this.selection!.fileSystemFsData = e.detail.data; - let pane = this.getPaneByID('box-file-system-event'); - this.litTabs?.activeByKey(pane.key); - if (e.detail.data) { - (pane.children.item(0) as any)!.fromStastics(this.selection); - } + this.fileSystemListener(e); + }); + } + + private perfAnalysisListener(evt: MouseEvent): void { + // @ts-ignore + if (evt.detail.button === 2) { + let pane = this.getPaneByID('box-perf-profile'); + this.litTabs!.activeByKey(pane.key); + } + } + + private nativeAnalysisListener(e: MouseEvent):void { + //@ts-ignore + if (e.detail.button === 2) { + let pane = this.getPaneByID('box-native-calltree'); + pane.hidden = false; + this.litTabs!.activeByKey(pane.key); + } + } + + private nativeStatsticsListener(e: any): void { + if (e.detail.button === 0) { + this.selection!.statisticsSelectData = e.detail; + let pane = this.getPaneByID('box-native-memory'); + this.litTabs?.activeByKey(pane.key); + (pane.children.item(0) as any)!.fromStastics(this.selection); + } + } + + private virtualMemoryListener(e: any): void { + if (e.detail.button === 0) { + this.selection!.fileSystemVMData = {path: e.detail.path}; + let pane = this.getPaneByID('box-vm-events'); + this.litTabs?.activeByKey(pane.key); + if (e.detail.path) { + (pane.children.item(0) as any)!.fromStastics(this.selection); + } + } + } + + private ioTierListener(e: any):void { + if (e.detail.button === 0) { + this.selection!.fileSystemIoData = {path: e.detail.path}; + let pane = this.getPaneByID('box-io-events'); + this.litTabs?.activeByKey(pane.key); + if (e.detail.path) { + (pane.children.item(0) as any)!.fromStastics(this.selection); } + } + } + + private fileSystemListener(e: any): void { + if (e.detail.button === 0) { + this.selection!.fileSystemFsData = e.detail.data; + let pane = this.getPaneByID('box-file-system-event'); + this.litTabs?.activeByKey(pane.key); + if (e.detail.data) { + (pane.children.item(0) as any)!.fromStastics(this.selection); + } + } + } + + private tableCloseHandler(): void { + this.litTabs!.addEventListener('close-handler', () => { + Reflect.ownKeys(tabConfig) + .reverse() + .forEach((id) => { + let element = tabConfig[id]; + let pane = this.shadowRoot!.querySelector(`#${id as string}`); + if (element.require) { + pane!.hidden = !element.require(this.selection); + } else { + pane!.hidden = true; + } + }); + this.litTabs?.activeByKey(`${this.getPaneByID(this.currentPaneID).key}`); }); } connectedCallback(): void { this.nav = this.shadowRoot?.querySelector('#tabs')?.shadowRoot?.querySelector('.tab-nav-vessel'); - let tabs: HTMLDivElement | undefined | null = this.shadowRoot?.querySelector('#tabs'); - let navRoot: HTMLDivElement | null | undefined = this.shadowRoot - ?.querySelector('#tabs') - ?.shadowRoot?.querySelector('.nav-root'); - let search: HTMLDivElement | undefined | null = document - .querySelector('body > sp-application') + this.tabs = this.shadowRoot?.querySelector('#tabs'); + this.navRoot = this.shadowRoot?.querySelector('#tabs')?.shadowRoot?.querySelector('.nav-root'); + this.search = document.querySelector('body > sp-application') ?.shadowRoot?.querySelector('div > div.search-vessel'); - let timerShaft: HTMLDivElement | undefined | null = this.parentElement?.querySelector('.timer-shaft'); - let spacer: HTMLDivElement | undefined | null = this.parentElement?.querySelector('.spacer'); - let rowsPaneEL: HTMLDivElement | undefined | null = this.parentElement?.querySelector('.rows-pane'); - - let borderTop: number = 1; - let initialHeight = { tabs: `calc(30vh + 39px)`, node: '30vh' }; - this.nav!.onmousedown = (event): void => { - (window as any).isSheetMove = true; - let litTabpane: NodeListOf | undefined | null = - this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); - let preY = event.pageY; - let preHeight = tabs!.offsetHeight; - document.onmousemove = function (event): void { - let moveY: number = preHeight - (event.pageY - preY); - litTabpane!.forEach((node: HTMLDivElement) => { - if (spacer!.offsetHeight > rowsPaneEL!.offsetHeight) { - tabs!.style.height = moveY + 'px'; - node!.style.height = moveY - navRoot!.offsetHeight + 'px'; - tabsPackUp!.name = 'down'; - } else if ( - navRoot!.offsetHeight <= moveY && - search!.offsetHeight + timerShaft!.offsetHeight + borderTop + spacer!.offsetHeight <= - window.innerHeight - moveY - ) { - tabs!.style.height = moveY + 'px'; - node!.style.height = moveY - navRoot!.offsetHeight + 'px'; - tabsPackUp!.name = 'down'; - } else if (navRoot!.offsetHeight >= moveY) { - tabs!.style.height = navRoot!.offsetHeight + 'px'; - node!.style.height = '0px'; - tabsPackUp!.name = 'up'; - } else if ( - search!.offsetHeight + timerShaft!.offsetHeight + borderTop + spacer!.offsetHeight >= - window.innerHeight - moveY - ) { - tabs!.style.height = - window.innerHeight - - search!.offsetHeight - - timerShaft!.offsetHeight - - borderTop - - spacer!.offsetHeight + - 'px'; - node!.style.height = - window.innerHeight - - search!.offsetHeight - - timerShaft!.offsetHeight - - navRoot!.offsetHeight - - borderTop - - spacer!.offsetHeight + - 'px'; - tabsPackUp!.name = 'down'; - } - }); - }; - document.onmouseup = function (): void { - setTimeout(() => { - (window as any).isSheetMove = false; - }, 100); - litTabpane!.forEach((node: HTMLDivElement): void => { - if (node!.style.height !== '0px' && tabs!.style.height !== '') { - initialHeight.node = node!.style.height; - initialHeight.tabs = tabs!.style.height; - } - }); - this.onmousemove = null; - this.onmouseup = null; - }; - }; + this.timerShaft = this.parentElement?.querySelector('.timer-shaft'); + this.spacer = this.parentElement?.querySelector('.spacer'); + this.rowsPaneEL = this.parentElement?.querySelector('.rows-pane'); let tabsOpenUp: LitIcon | undefined | null = this.shadowRoot?.querySelector('#max-btn'); let tabsPackUp: LitIcon | undefined | null = this.shadowRoot?.querySelector('#min-btn'); - let importFileBt: HTMLInputElement | undefined | null = - this.shadowRoot?.querySelector('#import-file'); + let borderTop: number = 1; + let initialHeight = { tabs: `calc(30vh + 39px)`, node: '30vh' }; + this.initNavElements(tabsPackUp!, borderTop, initialHeight); this.exportBt = this.shadowRoot?.querySelector('#export-btn'); tabsOpenUp!.onclick = (): void => { - tabs!.style.height = window.innerHeight - search!.offsetHeight - timerShaft!.offsetHeight - borderTop + 'px'; + this.tabs!.style.height = window.innerHeight - this.search!.offsetHeight - this.timerShaft!.offsetHeight - borderTop + 'px'; let litTabpane: NodeListOf | undefined | null = this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); litTabpane!.forEach((node: HTMLDivElement): void => { node!.style.height = window.innerHeight - - search!.offsetHeight - - timerShaft!.offsetHeight - - navRoot!.offsetHeight - + this.search!.offsetHeight - + this.timerShaft!.offsetHeight - + this.navRoot!.offsetHeight - borderTop + 'px'; initialHeight.node = node!.style.height; }); - initialHeight.tabs = tabs!.style.height; + initialHeight.tabs = this.tabs!.style.height; tabsPackUp!.name = 'down'; }; tabsPackUp!.onclick = (): void => { let litTabpane: NodeListOf | undefined | null = this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); if (tabsPackUp!.name == 'down') { - tabs!.style.height = navRoot!.offsetHeight + 'px'; + this.tabs!.style.height = this.navRoot!.offsetHeight + 'px'; litTabpane!.forEach((node: HTMLDivElement) => (node!.style.height = '0px')); tabsPackUp!.name = 'up'; tabsPackUp!.title = 'Reset Tab'; @@ -371,10 +340,88 @@ export class TraceSheet extends BaseElement { } else { tabsPackUp!.name = 'down'; tabsPackUp!.title = 'Minimize Tab'; - tabs!.style.height = initialHeight.tabs; + this.tabs!.style.height = initialHeight.tabs; litTabpane!.forEach((node: HTMLDivElement) => (node!.style.height = initialHeight.node)); } }; + this.importClickEvent(); + this.exportClickEvent(); + } + + private initNavElements(tabsPackUp: LitIcon, borderTop: number, initialHeight: { node: string; tabs: string }): void { + let that = this; + this.nav!.onmousedown = (event): void => { + (window as any).isSheetMove = true; + let litTabpane: NodeListOf | undefined | null = + this.shadowRoot?.querySelectorAll('#tabs > lit-tabpane'); + this.navMouseMove(event, litTabpane!, that, tabsPackUp, borderTop); + document.onmouseup = function (): void { + setTimeout(() => { + (window as any).isSheetMove = false; + }, 100); + litTabpane!.forEach((node: HTMLDivElement): void => { + if (node!.style.height !== '0px' && that.tabs!.style.height !== '') { + initialHeight.node = node!.style.height; + initialHeight.tabs = that.tabs!.style.height; + } + }); + this.onmousemove = null; + this.onmouseup = null; + }; + }; + } + + private navMouseMove(event: MouseEvent, litTabpane: NodeListOf, + that: this, tabsPackUp: LitIcon, borderTop: number): void { + let preY = event.pageY; + let preHeight = this.tabs!.offsetHeight; + document.onmousemove = function (event): void { + let moveY: number = preHeight - (event.pageY - preY); + litTabpane!.forEach((node: HTMLDivElement) => { + if (that.spacer!.offsetHeight > that.rowsPaneEL!.offsetHeight) { + that.tabs!.style.height = moveY + 'px'; + node!.style.height = moveY - that.navRoot!.offsetHeight + 'px'; + tabsPackUp!.name = 'down'; + } else if ( + that.navRoot!.offsetHeight <= moveY && + that.search!.offsetHeight + that.timerShaft!.offsetHeight + borderTop + that.spacer!.offsetHeight <= + window.innerHeight - moveY + ) { + that.tabs!.style.height = moveY + 'px'; + node!.style.height = moveY - that.navRoot!.offsetHeight + 'px'; + tabsPackUp!.name = 'down'; + } else if (that.navRoot!.offsetHeight >= moveY) { + that.tabs!.style.height = that.navRoot!.offsetHeight + 'px'; + node!.style.height = '0px'; + tabsPackUp!.name = 'up'; + } else if ( + that.search!.offsetHeight + that.timerShaft!.offsetHeight + borderTop + that.spacer!.offsetHeight >= + window.innerHeight - moveY + ) { + that.tabs!.style.height = + window.innerHeight - + that.search!.offsetHeight - + that.timerShaft!.offsetHeight - + borderTop - + that.spacer!.offsetHeight + + 'px'; + node!.style.height = + window.innerHeight - + that.search!.offsetHeight - + that.timerShaft!.offsetHeight - + that.navRoot!.offsetHeight - + borderTop - + that.spacer!.offsetHeight + + 'px'; + tabsPackUp!.name = 'down'; + } + }); + }; + } + + private importClickEvent(): void { + let importFileBt: HTMLInputElement | undefined | null = + this.shadowRoot?.querySelector('#import-file'); importFileBt!.addEventListener('change', (event): void => { let files = importFileBt?.files; if (files) { @@ -407,6 +454,9 @@ export class TraceSheet extends BaseElement { importFileBt!.files = null; importFileBt!.value = ''; }); + } + + private exportClickEvent(): void { this.exportBt!.onclick = (): void => { let currentTab = this.getTabpaneByKey(this.litTabs?.activekey!); if (currentTab) { diff --git a/ide/src/trace/component/trace/base/TraceSheetConfig.ts b/ide/src/trace/component/trace/base/TraceSheetConfig.ts index 17cd6dea9cc8725543bb957ce5f65e9f248dc5b2..d4e76e6507fadd9451579fd079a1b5c897e47217 100644 --- a/ide/src/trace/component/trace/base/TraceSheetConfig.ts +++ b/ide/src/trace/component/trace/base/TraceSheetConfig.ts @@ -119,14 +119,8 @@ import { TabPaneSchedPriority } from '../sheet/cpu/TabPaneSchedPriority'; import { TabPaneGpuResourceVmTracker } from '../sheet/vmtracker/TabPaneGpuResourceVmTracker'; import { TabPaneGpuGraph } from '../sheet/gpu/TabPaneGraph'; import { TabPaneFreqUsage } from '../sheet/frequsage/TabPaneFreqUsage'; -import { TabPaneFreqDataCut } from '../sheet/frequsage/TabPaneFreqDataCut'; import { TabPaneHisysEvents } from '../sheet/hisysevent/TabPaneHisysEvents'; import { TabPaneHiSysEventSummary } from '../sheet/hisysevent/TabPaneHiSysEventSummary'; -import { TabPaneSchedSwitch } from '../sheet/schedswitch/TabPaneSchedSwitch'; -import { TabPaneBinderDataCut } from '../sheet/binder/TabPaneBinderDataCut'; -import { TabPaneBinders } from '../sheet/binder/TabPaneBinders'; -import { TabPaneGpufreq } from '../sheet/gpufreq/tabPaneGpufreqUsage'; -import { TabPaneGpufreqDataCut } from '../sheet/gpufreq/tabPaneGpufreqDataCut'; export let tabConfig: any = { 'current-selection': { @@ -640,11 +634,6 @@ export let tabConfig: any = { type: TabPaneFreqUsage, require: (param: SelectionParam) => param.threadIds.length > 0, }, - 'tabpane-freqdatacut': { - title: 'Freq DataCut', - type: TabPaneFreqDataCut, - require: (param: SelectionParam) => param.threadIds.length > 0, - }, 'tab-hisysevents': { title: 'HiSysevents', type: TabPaneHisysEvents, @@ -655,29 +644,4 @@ export let tabConfig: any = { type: TabPaneHiSysEventSummary, require: (param: SelectionParam) => param.hiSysEvents.length > 0, }, - 'tabpane-schedswitch': { - title: 'Sched Switch', - type: TabPaneSchedSwitch, - require: (param: SelectionParam) => param.threadIds.length > 0, - }, - 'tabpane-binders': { - title: 'Thread Binders', - type: TabPaneBinders, - require: (param: SelectionParam) => param.threadIds.length > 0, - }, - 'tabpane-binder-datacut': { - title: 'Binder DataCut', - type: TabPaneBinderDataCut, - require: (param: SelectionParam) => param.threadIds.length > 0, - }, - 'tabpane-gpufreq': { - title: 'Gpufreq Usage', - type: TabPaneGpufreq, - require: (param: SelectionParam) => param.clockMapData.size > 0 && param.clockMapData.size < 2, - }, - 'tabpane-freqDataCut': { - title: 'Gpufreq DataCut', - type: TabPaneGpufreqDataCut, - require: (param: SelectionParam) => param.clockMapData.size > 0 && param.clockMapData.size < 2, - }, }; diff --git a/ide/src/trace/component/trace/base/Utils.ts b/ide/src/trace/component/trace/base/Utils.ts index f54e1bf14ae365c923a761c327081c18a344c54f..d085a0a6f9450f3280c65028db2dcbfe5e3848ad 100644 --- a/ide/src/trace/component/trace/base/Utils.ts +++ b/ide/src/trace/component/trace/base/Utils.ts @@ -90,15 +90,15 @@ export class Utils { ); } - public static transferPTSTitle(value: any) { - if (value.startsWith('S-')) { - return Utils.getEndState(value.replace('S-', '')); - } else if (value.startsWith('P-')) { - let pid = value.replace('P-', ''); + public static transferPTSTitle(ptsValue: any) { + if (ptsValue.startsWith('S-')) { + return Utils.getEndState(ptsValue.replace('S-', '')); + } else if (ptsValue.startsWith('P-')) { + let pid = ptsValue.replace('P-', ''); let process = Utils.PROCESS_MAP.get(parseInt(pid)) || 'Process'; return `${process} [${pid}]`; - } else if (value.startsWith('T-')) { - let tid = value.replace('T-', ''); + } else if (ptsValue.startsWith('T-')) { + let tid = ptsValue.replace('T-', ''); let thread = Utils.THREAD_MAP.get(parseInt(tid)) || 'Thread'; return `${thread} [${tid}]`; } else { diff --git a/ide/src/trace/component/trace/search/Search.html.ts b/ide/src/trace/component/trace/search/Search.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..1af33f8aef37682b2c7254ec3517b987f016c46c --- /dev/null +++ b/ide/src/trace/component/trace/search/Search.html.ts @@ -0,0 +1,154 @@ +/* + * 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. + */ +export const SearchHtml = ` + + + +
+
    +
    + `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/search/Search.ts b/ide/src/trace/component/trace/search/Search.ts index 50e79c94ce7be9eb5f24e813a7e4a12d89d605d7..5a2a8e6e6e089aa03b014048346ebe6faee3ad80 100644 --- a/ide/src/trace/component/trace/search/Search.ts +++ b/ide/src/trace/component/trace/search/Search.ts @@ -15,6 +15,7 @@ import { BaseElement, element } from '../../../../base-ui/BaseElement'; import { LitIcon } from '../../../../base-ui/icon/LitIcon'; +import { SearchHtml } from './Search.html'; const LOCAL_STORAGE_SEARCH_KEY = 'search_key'; @@ -312,146 +313,7 @@ export class LitSearch extends BaseElement { } initHtml(): string { - return ` - - - -
    -
      -
      - `; + return SearchHtml; } showSearchHistoryList() { diff --git a/ide/src/trace/component/trace/sheet/SheetUtils.ts b/ide/src/trace/component/trace/sheet/SheetUtils.ts index b0c8b12804cb92de596fba8554a6bddcc20f18f5..122082252684f8a5db82eedd4128cdc85ba60bb7 100644 --- a/ide/src/trace/component/trace/sheet/SheetUtils.ts +++ b/ide/src/trace/component/trace/sheet/SheetUtils.ts @@ -25,9 +25,11 @@ export function resizeObserver( ): void { new ResizeObserver((entries) => { if (parentEl.clientHeight !== 0) { - // @ts-ignore - tableEl?.shadowRoot.querySelector('.table').style.height = parentEl.clientHeight - tblOffsetHeight + 'px'; - tableEl?.reMeauseHeight(); + if (tableEl) { + // @ts-ignore + tableEl.shadowRoot.querySelector('.table').style.height = parentEl.clientHeight - tblOffsetHeight + 'px'; + tableEl.reMeauseHeight(); + } if (loadingPage) { loadingPage.style.height = parentEl.clientHeight - loadingPageOffsetHeight + 'px'; } @@ -44,9 +46,11 @@ export function resizeObserverFromMemory( new ResizeObserver((entries) => { let filterHeight = 0; if (parentElement.clientHeight !== 0) { - // @ts-ignore - tableEl?.shadowRoot.querySelector('.table').style.height = parentElement.clientHeight - tblOffsetHeight + 'px'; - tableEl?.reMeauseHeight(); + if (tableEl) { + // @ts-ignore + tableEl.shadowRoot.querySelector('.table').style.height = parentElement.clientHeight - tblOffsetHeight + 'px'; + tableEl.reMeauseHeight(); + } } if (filterEl!.clientHeight > 0) { filterHeight = filterEl!.clientHeight; diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrent.html.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrent.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..3aae22cbdd887dd41cbb9833259adba2d57737f4 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrent.html.ts @@ -0,0 +1,65 @@ +/* + * 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. + */ +export const TabPaneCurrentHtml = ` + + + + + + + + + + + + + + + + + `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts index 0d637915b9c82b610ee54eb262c83fb338266b11..d5775e8250bcdb80e7006fcacfbdfcee5537538e 100644 --- a/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts +++ b/ide/src/trace/component/trace/sheet/TabPaneCurrent.ts @@ -19,6 +19,7 @@ import { MarkStruct } from '../../../bean/MarkStruct'; import { SpSystemTrace } from '../../SpSystemTrace'; import { SlicesTime, StType } from '../timer-shaft/SportRuler'; import { getTimeString } from './TabPaneCurrentSelection'; +import { TabPaneCurrentHtml } from './TabPaneCurrent.html'; @element('tabpane-current') export class TabPaneCurrent extends BaseElement { @@ -61,6 +62,11 @@ export class TabPaneCurrent extends BaseElement { }); }); this.panelTable = this.shadowRoot!.querySelector('.notes-editor-panel'); + this.rowClickListener(); + this.mouseOutListener(); + } + + private rowClickListener(): void { this.panelTable!.addEventListener('row-click', (evt: any) => { if (evt.detail.data.startTime === undefined) { return; @@ -80,6 +86,9 @@ export class TabPaneCurrent extends BaseElement { this.systemTrace?.timerShaftEL!.sportRuler!.draw(); }); }); + } + + private mouseOutListener(): void { // 当鼠标移出panel时重新加载备注信息 this.systemTrace?.shadowRoot?.querySelector('trace-sheet')?.addEventListener( 'mouseout', @@ -94,7 +103,7 @@ export class TabPaneCurrent extends BaseElement { } event.stopPropagation(); }, - { capture: true } + {capture: true} ); } @@ -176,54 +185,15 @@ export class TabPaneCurrent extends BaseElement { private eventHandler(): void { let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; tr[0].querySelector('#text-input')!.disabled = true; - tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { - this.systemTrace!.slicesList = []; - let slicesTimeList = [...this.slicesTimeList]; - for (let i = 0; i < slicesTimeList.length; i++) { - slicesTimeList[i].hidden = true; - document.dispatchEvent(new CustomEvent('slices-change', { detail: slicesTimeList[i] })); - } - this.slicesTimeList = []; - return; - }); - - // 更新备注信息 - this.panelTable!.addEventListener('click', (event: any) => { - if (this.slicesTimeList.length === 0) { - return; - } - for (let i = 1; i < tr.length; i++) { - let inputValue = tr[i].querySelector('#text-input')!.value; - if ( - this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && - this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime - ) { - this.slicesTimeList[i - 1].text = inputValue; - document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); - // 旗子颜色改变时,重绘泳道图 - this.systemTrace?.refreshCanvas(true); - } - } - }); + this.trClickEvent(tr); + this.panelTableClick(tr); // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.slicesTimeList数组的第一个对应……,所以i从1开始,在this.slicesTimeList数组中取值时用i-1 for (let i = 1; i < tr.length; i++) { // 修改颜色 tr[i].querySelector('#color-input')!.value = this.slicesTimeList[i - 1].color; // 点击色块修改颜色 - tr[i].querySelector('#color-input')?.addEventListener('change', (event: any) => { - if ( - this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && - this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime - ) { - this.systemTrace!.slicesList = this.slicesTimeList || []; - this.slicesTimeList[i - 1].color = event?.target.value; - document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); - // 卡尺颜色改变时,重绘泳道图 - this.systemTrace?.refreshCanvas(true); - } - event.stopPropagation(); - }); + this.trChangeEvent(tr, i); // 修改备注 tr[i].querySelector('#text-input')!.value = this.slicesTimeList[i - 1].text; @@ -262,34 +232,90 @@ export class TabPaneCurrent extends BaseElement { } event.stopPropagation(); }); + this.trFocusEvent(tr, i); + this.removeButtonClickEvent(tr, i); + } + } - tr[i].querySelector('#text-input')?.addEventListener('focus', (event: any) => { - (window as any).flagInputFocus = true; - window.publish(window.SmartEvent.UI.KeyboardEnable, { - enable: false, - }); - let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; - // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1 - for (let i = 1; i < tr.length; i++) { - tr[i].querySelector('#text-input')!.value = this.slicesTimeList[i - 1].text; - } + private trChangeEvent(tr: NodeListOf, i: number): void { + tr[i].querySelector('#color-input')?.addEventListener('change', (event: any) => { + if ( + this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && + this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime + ) { + this.systemTrace!.slicesList = this.slicesTimeList || []; + this.slicesTimeList[i - 1].color = event?.target.value; + document.dispatchEvent(new CustomEvent('slices-change', {detail: this.slicesTimeList[i - 1]})); + // 卡尺颜色改变时,重绘泳道图 + this.systemTrace?.refreshCanvas(true); + } + event.stopPropagation(); + }); + } + + private trFocusEvent(tr: NodeListOf, i: number): void { + tr[i].querySelector('#text-input')?.addEventListener('focus', (event: any) => { + (window as any).flagInputFocus = true; + window.publish(window.SmartEvent.UI.KeyboardEnable, { + enable: false, }); + let tr = this.panelTable!.shadowRoot!.querySelectorAll('.tr') as NodeListOf; + // 第一个tr是移除全部,所以跳过,从第二个tr开始,和this.flagList数组的第一个对应……,所以i从1开始,在this.flagList数组中取值时用i-1 + for (let i = 1; i < tr.length; i++) { + tr[i].querySelector('#text-input')!.value = this.slicesTimeList[i - 1].text; + } + }); + } + + private trClickEvent(tr: NodeListOf): void { + tr[0].querySelector('.removeAll')!.addEventListener('click', (evt: any) => { + this.systemTrace!.slicesList = []; + let slicesTimeList = [...this.slicesTimeList]; + for (let i = 0; i < slicesTimeList.length; i++) { + slicesTimeList[i].hidden = true; + document.dispatchEvent(new CustomEvent('slices-change', {detail: slicesTimeList[i]})); + } + this.slicesTimeList = []; + return; + }); + } + + private removeButtonClickEvent(tr: NodeListOf, i: number): void { + // 点击remove按钮移除 + tr[i]!.querySelector('.remove')?.addEventListener('click', (event: any) => { + if ( + this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && + this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime + ) { + this.slicesTimeList[i - 1].hidden = true; + this.systemTrace!.slicesList = this.slicesTimeList || []; + document.dispatchEvent(new CustomEvent('slices-change', {detail: this.slicesTimeList[i - 1]})); + // 移除时更新表格内容 + this.setTableData(); + } + event.stopPropagation(); + }); + } - // 点击remove按钮移除 - tr[i]!.querySelector('.remove')?.addEventListener('click', (event: any) => { + private panelTableClick(tr: NodeListOf): void { + // 更新备注信息 + this.panelTable!.addEventListener('click', (event: any) => { + if (this.slicesTimeList.length === 0) { + return; + } + for (let i = 1; i < tr.length; i++) { + let inputValue = tr[i].querySelector('#text-input')!.value; if ( this.tableDataSource[i].startTime === this.slicesTimeList[i - 1].startTime && this.tableDataSource[i].endTime === this.slicesTimeList[i - 1].endTime ) { - this.slicesTimeList[i - 1].hidden = true; - this.systemTrace!.slicesList = this.slicesTimeList || []; - document.dispatchEvent(new CustomEvent('slices-change', { detail: this.slicesTimeList[i - 1] })); - // 移除时更新表格内容 - this.setTableData(); + this.slicesTimeList[i - 1].text = inputValue; + document.dispatchEvent(new CustomEvent('slices-change', {detail: this.slicesTimeList[i - 1]})); + // 旗子颜色改变时,重绘泳道图 + this.systemTrace?.refreshCanvas(true); } - event.stopPropagation(); - }); - } + } + }); } /** @@ -303,56 +329,6 @@ export class TabPaneCurrent extends BaseElement { } initHtml(): string { - return ` - - - - - - - - - - - - - - - - - `; + return TabPaneCurrentHtml; } } diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts index 8673dadeaabdac5c3fb8ca35495f0849992d15fd..95c769efcbe1df86e7f4b8373b7fb19af2fd026a 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneCpuAbility.ts @@ -22,6 +22,7 @@ import { ColorUtils } from '../../base/ColorUtils'; import { log } from '../../../../../log/Log'; import { resizeObserver } from '../SheetUtils'; import { getTabCpuAbilityData } from '../../../../database/sql/Ability.sql'; +import { NUM_2 } from '../../../../bean/NumBean'; @element('tabpane-cpu-ability') export class TabPaneCpuAbility extends BaseElement { @@ -30,9 +31,11 @@ export class TabPaneCpuAbility extends BaseElement { private queryCpuResult: Array = []; private search: HTMLInputElement | undefined | null; - set data(cpuAbilityValue: SelectionParam | any) { - // @ts-ignore - this.cpuAbilityTbl?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + set data(cpuAbilityValue: SelectionParam) { + if (this.cpuAbilityTbl) { + // @ts-ignore + this.cpuAbilityTbl.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + } this.queryDataByDB(cpuAbilityValue); } @@ -44,12 +47,12 @@ export class TabPaneCpuAbility extends BaseElement { }); } - connectedCallback() { + connectedCallback(): void { super.connectedCallback(); resizeObserver(this.parentElement!, this.cpuAbilityTbl!); } - filterData() { + filterData(): void { if (this.queryCpuResult.length > 0) { let filterCpu = this.queryCpuResult.filter((item) => { let array = this.toCpuAbilityArray(item); @@ -66,7 +69,7 @@ export class TabPaneCpuAbility extends BaseElement { } } - toCpuAbilityArray(systemCpuSummary: SystemCpuSummary): any[] { + toCpuAbilityArray(systemCpuSummary: SystemCpuSummary): string[] { let array: Array = []; array.push(systemCpuSummary.startTimeStr); array.push(systemCpuSummary.durationStr); @@ -77,20 +80,20 @@ export class TabPaneCpuAbility extends BaseElement { return array; } - queryDataByDB(val: SelectionParam | any) { + queryDataByDB(val: SelectionParam): void { getTabCpuAbilityData(val.leftNs, val.rightNs).then((result) => { log('getTabCpuAbilityData size :' + result.length); - if (result.length != null && result.length > 0) { + if (result.length !== null && result.length > 0) { for (const systemCpuSummary of result) { - if (systemCpuSummary.startTime == 0) { + if (systemCpuSummary.startTime === 0) { systemCpuSummary.startTimeStr = '0:000.000.000'; } else { systemCpuSummary.startTimeStr = Utils.getTimeStampHMS(systemCpuSummary.startTime); } systemCpuSummary.durationStr = Utils.getDurString(systemCpuSummary.duration); - systemCpuSummary.totalLoadStr = systemCpuSummary.totalLoad.toFixed(2) + '%'; - systemCpuSummary.userLoadStr = systemCpuSummary.userLoad.toFixed(2) + '%'; - systemCpuSummary.systemLoadStr = systemCpuSummary.systemLoad.toFixed(2) + '%'; + systemCpuSummary.totalLoadStr = systemCpuSummary.totalLoad.toFixed(NUM_2) + '%'; + systemCpuSummary.userLoadStr = systemCpuSummary.userLoad.toFixed(NUM_2) + '%'; + systemCpuSummary.systemLoadStr = systemCpuSummary.systemLoad.toFixed(NUM_2) + '%'; systemCpuSummary.threadsStr = ColorUtils.formatNumberComma(systemCpuSummary.threads); } this.cpuAbilitySource = result; @@ -117,17 +120,23 @@ export class TabPaneCpuAbility extends BaseElement { } - + - + - + - + - + - + `; @@ -153,24 +162,25 @@ export class TabPaneCpuAbility extends BaseElement { }; compareFunction = (sort: number, getProperty: (data: SystemCpuSummary) => number | string) => - (cpuAbilityLeftData: SystemCpuSummary, cpuAbilityRightData: SystemCpuSummary) => { - let leftValue = getProperty(cpuAbilityLeftData); - let rightValue = getProperty(cpuAbilityRightData); - let result = 0; - if (leftValue > rightValue) { - result = sort === 2 ? -1 : 1; - } else if (leftValue < rightValue) { - result = sort === 2 ? 1 : -1; - } - return result; - }; + (cpuAbilityLeftData: SystemCpuSummary, cpuAbilityRightData: SystemCpuSummary): number => { + let leftValue = getProperty(cpuAbilityLeftData); + let rightValue = getProperty(cpuAbilityRightData); + let result = 0; + if (leftValue > rightValue) { + result = sort === 2 ? -1 : 1; + } else if (leftValue < rightValue) { + result = sort === 2 ? 1 : -1; + } + return result; + }; - compare = (property: string, sort: number, type: string) => { + compare = (property: string, sort: number, type: string): + (cpuAbilityLeftData: SystemCpuSummary, cpuAbilityRightData: SystemCpuSummary) => number => { let getProperty = this.getPropertyByType(property, type); return this.compareFunction(sort, getProperty); }; - sortByColumn(detail: any) { + sortByColumn(detail: any): void { let typeMaping: { [key: string]: string } = { startTime: 'string', durationStr: 'durationStr', diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts index 108143055482a6558bd0833f5c882708f4e5d510..f0ea4d9f64d18123d7f3c844c6c943d01bb9a9b0 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDiskAbility.ts @@ -21,7 +21,7 @@ import { Utils } from '../../base/Utils'; import { ColorUtils } from '../../base/ColorUtils'; import { log } from '../../../../../log/Log'; import { resizeObserver } from '../SheetUtils'; -import {getTabDiskAbilityData} from "../../../../database/sql/Ability.sql"; +import { getTabDiskAbilityData } from '../../../../database/sql/Ability.sql'; @element('tabpane-disk-ability') export class TabPaneDiskAbility extends BaseElement { @@ -30,9 +30,11 @@ export class TabPaneDiskAbility extends BaseElement { private queryDiskResult: Array = []; private search: HTMLInputElement | undefined | null; - set data(diskAbilityValue: SelectionParam | any) { - // @ts-ignore - this.diskAbilityTbl?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + set data(diskAbilityValue: SelectionParam) { + if (this.diskAbilityTbl) { + // @ts-ignore + this.diskAbilityTbl.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + } this.queryDataByDB(diskAbilityValue); } @@ -44,12 +46,12 @@ export class TabPaneDiskAbility extends BaseElement { }); } - connectedCallback() { + connectedCallback(): void { super.connectedCallback(); resizeObserver(this.parentElement!, this.diskAbilityTbl!); } - filterData() { + filterData(): void { if (this.queryDiskResult.length > 0) { let filterDisk = this.queryDiskResult.filter((item) => { let array = this.toDiskAbilityArray(item); @@ -66,7 +68,7 @@ export class TabPaneDiskAbility extends BaseElement { } } - toDiskAbilityArray(systemDiskIOSummary: SystemDiskIOSummary): any[] { + toDiskAbilityArray(systemDiskIOSummary: SystemDiskIOSummary): string[] { let array: Array = []; array.push(systemDiskIOSummary.startTimeStr); array.push(systemDiskIOSummary.durationStr); @@ -80,10 +82,10 @@ export class TabPaneDiskAbility extends BaseElement { return array; } - queryDataByDB(val: SelectionParam | any) { + queryDataByDB(val: SelectionParam): void { getTabDiskAbilityData(val.leftNs, val.rightNs).then((result) => { log('getTabDiskAbilityData result size : ' + result.length); - if (result.length != null && result.length > 0) { + if (result.length !== null && result.length > 0) { for (const systemDiskIOSummary of result) { if (systemDiskIOSummary.startTime <= 0) { systemDiskIOSummary.startTimeStr = '0:000.000.000'; @@ -124,25 +126,35 @@ export class TabPaneDiskAbility extends BaseElement { } - + - + - + - + - + - + - + - + - + - + `; @@ -167,7 +179,7 @@ export class TabPaneDiskAbility extends BaseElement { }; compareFunction = (sort: number, getProperty: (data: SystemDiskIOSummary) => number | string) => - (diskAbilityLeftData: SystemDiskIOSummary, diskAbilityRightData: SystemDiskIOSummary) => { + (diskAbilityLeftData: SystemDiskIOSummary, diskAbilityRightData: SystemDiskIOSummary): number => { let leftValue = getProperty(diskAbilityLeftData); let rightValue = getProperty(diskAbilityRightData); let result = 0; @@ -179,12 +191,13 @@ export class TabPaneDiskAbility extends BaseElement { return result; }; - compareDisk(property: string, sort: number, type: string) { + compareDisk(property: string, sort: number, type: string): + (diskAbilityLeftData: SystemDiskIOSummary, diskAbilityRightData: SystemDiskIOSummary) => number { let getProperty = this.getPropertyByType(property, type); return this.compareFunction(sort, getProperty); } - sortByColumn(detail: any) { + sortByColumn(detail: any): void { let typeMapping = { startTime: 'string', durationStr: 'durationStr', diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts index 803eeee4ed46a16e01a529479802403237451f1a..7c64c9fbe7fbd2b160d502dc9626c2bd08ae0cc3 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbility.ts @@ -20,7 +20,8 @@ import { Dma } from '../../../../bean/AbilityMonitor'; import { resizeObserver } from '../SheetUtils'; import { MemoryConfig } from '../../../../bean/MemoryConfig'; import { Utils } from '../../base/Utils'; -import {getTabDmaAbilityData} from "../../../../database/sql/Dma.sql"; +import { getTabDmaAbilityData } from '../../../../database/sql/Dma.sql'; +import { NUM_5, NUM_MILLON } from '../../../../bean/NumBean'; @element('tabpane-dma-ability') export class TabPaneDmaAbility extends BaseElement { @@ -30,11 +31,11 @@ export class TabPaneDmaAbility extends BaseElement { private dmaTimeRange: HTMLLabelElement | null | undefined; private total: Dma = new Dma(); - set data(dmaAbilityValue: SelectionParam | any) { + set data(dmaAbilityValue: SelectionParam) { if (dmaAbilityValue.dmaAbilityData.length > 0) { this.init(); this.dmaTimeRange!.textContent = - 'Selected range: ' + ((dmaAbilityValue.rightNs - dmaAbilityValue.leftNs) / 1000000.0).toFixed(5) + ' ms'; + 'Selected range: ' + ((dmaAbilityValue.rightNs - dmaAbilityValue.leftNs) / NUM_MILLON).toFixed(NUM_5) + ' ms'; this.dmaTbl!.loading = true; this.queryDataByDB(dmaAbilityValue); } @@ -68,8 +69,9 @@ export class TabPaneDmaAbility extends BaseElement { } } - queryDataByDB(val: SelectionParam | any): void { - getTabDmaAbilityData(val.leftNs, val.rightNs, (MemoryConfig.getInstance().interval * 1000000) / 5).then((data) => { + queryDataByDB(val: SelectionParam): void { + getTabDmaAbilityData(val.leftNs, val.rightNs, + (MemoryConfig.getInstance().interval * NUM_MILLON) / NUM_5).then((data) => { this.dmaSource = data; this.dmaTbl!.loading = false; if (data.length !== null && data.length > 0) { @@ -123,9 +125,11 @@ export class TabPaneDmaAbility extends BaseElement { padding: 10px 10px; } -
      +
      - +
      diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts index f2520ac75da763e8028742c29900067841268f3d..26187963d9be489ce5032d199822e4bf9e113a09 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaAbilityComparison.ts @@ -23,7 +23,7 @@ import { Utils } from '../../base/Utils'; import { compare, resizeObserverFromMemory } from '../SheetUtils'; import '../TabPaneJsMemoryFilter'; import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; -import {getTabDmaAbilityComparisonData} from "../../../../database/sql/Dma.sql"; +import { getTabDmaAbilityComparisonData } from '../../../../database/sql/Dma.sql'; @element('tabpane-dma-ability-comparison') export class TabPaneDmaAbilityComparison extends BaseElement { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts index 06be9f0d172370ff27f1421b409031f606f410e5..f6f4d97bda71463688e80a507c688f196c578913 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneDmaSelectAbility.ts @@ -19,7 +19,7 @@ import { type Dma } from '../../../../bean/AbilityMonitor'; import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; import { SpSystemTrace } from '../../../SpSystemTrace'; import { Utils } from '../../base/Utils'; -import {getTabDmaAbilityClickData} from "../../../../database/sql/Dma.sql"; +import { getTabDmaAbilityClickData } from '../../../../database/sql/Dma.sql'; @element('tabpane-dma-selection-ability') export class TabPaneDmaSelectAbility extends BaseElement { @@ -53,9 +53,9 @@ export class TabPaneDmaSelectAbility extends BaseElement { connectedCallback(): void { super.connectedCallback(); new ResizeObserver(() => { - if (this.parentElement?.clientHeight !== 0) { + if (this.parentElement?.clientHeight !== 0 && this.damClickTable) { // @ts-ignore - this.damClickTable?.shadowRoot?.querySelector('.table').style.height = + this.damClickTable.shadowRoot.querySelector('.table').style.height = this.parentElement!.clientHeight - 18 + 'px'; this.parentElement!.style.overflow = 'hidden'; this.damClickTable?.reMeauseHeight(); diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts index 765245497202e5654532cecc2aef36849553b6eb..0d4de4a4fb8e812e2020e9ef6a59d1abb11c33f2 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneHistoryProcesses.ts @@ -30,9 +30,11 @@ export class TabPaneHistoryProcesses extends BaseElement { private search: HTMLInputElement | undefined | null; set data(historyProcessValue: SelectionParam | any) { - // @ts-ignore - this.historyProcessTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 45 + 'px'; + if (this.historyProcessTbl) { + // @ts-ignore + this.historyProcessTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 45 + 'px'; + } this.queryDataByDB(historyProcessValue); } diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts index c737b0ee21734500785dc85a83842c36df0b5203..b83f12562cf4f57598409a7d475f8e67e145fe5d 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneLiveProcesses.ts @@ -30,11 +30,12 @@ export class TabPaneLiveProcesses extends BaseElement { private search: HTMLInputElement | undefined | null; set data(liveProcessValue: SelectionParam | any) { - // @ts-ignore - this.liveProcessTbl?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + if (this.liveProcessTbl) { + // @ts-ignore + this.liveProcessTbl.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 45 + 'px'; + } this.queryDataByDB(liveProcessValue); } - initElements(): void { this.liveProcessTbl = this.shadowRoot?.querySelector('#tb-live-processes'); this.liveProcessTbl!.addEventListener('column-click', (evt) => { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts index 6a80d70b300f03b0ccf92e66e2afa2bf619e0f44..66551491598046c79a8fe10b6f8cad706206c898 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneMemoryAbility.ts @@ -20,8 +20,8 @@ import { SystemMemorySummary } from '../../../../bean/AbilityMonitor'; import { Utils } from '../../base/Utils'; import { log } from '../../../../../log/Log'; import { resizeObserver } from '../SheetUtils'; -import {queryStartTime} from "../../../../database/sql/SqlLite.sql"; -import {getTabMemoryAbilityData} from "../../../../database/sql/Ability.sql"; +import { queryStartTime } from '../../../../database/sql/SqlLite.sql'; +import { getTabMemoryAbilityData } from '../../../../database/sql/Ability.sql'; @element('tabpane-memory-ability') export class TabPaneMemoryAbility extends BaseElement { @@ -31,9 +31,11 @@ export class TabPaneMemoryAbility extends BaseElement { private search: HTMLInputElement | undefined | null; set data(memoryAbilityValue: SelectionParam | any) { - // @ts-ignore - this.memoryAbilityTbl?.shadowRoot?.querySelector('.table').style.height = - this.parentElement!.clientHeight - 45 + 'px'; + if (this.memoryAbilityTbl) { + // @ts-ignore + this.memoryAbilityTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 45 + 'px'; + } this.queryDataByDB(memoryAbilityValue); } diff --git a/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts index b0810ceb77c58ef4278e1028220f8119ccf538aa..0e7c7de9e37676f0dca92d96da7c55907e6aa680 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPaneNetworkAbility.ts @@ -21,7 +21,7 @@ import { Utils } from '../../base/Utils'; import { ColorUtils } from '../../base/ColorUtils'; import { log } from '../../../../../log/Log'; import { resizeObserver } from '../SheetUtils'; -import {getTabNetworkAbilityData} from "../../../../database/sql/Ability.sql"; +import { getTabNetworkAbilityData } from '../../../../database/sql/Ability.sql'; @element('tabpane-network-ability') export class TabPaneNetworkAbility extends BaseElement { @@ -32,9 +32,11 @@ export class TabPaneNetworkAbility extends BaseElement { private search: HTMLInputElement | undefined | null; set data(networkAbilityValue: SelectionParam | any) { - // @ts-ignore - this.networkAbilityTbl?.shadowRoot?.querySelector('.table').style.height = - this.parentElement!.clientHeight - 45 + 'px'; + if (this.networkAbilityTbl) { + // @ts-ignore + this.networkAbilityTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 45 + 'px'; + } this.queryDataByDB(networkAbilityValue); } diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts index a762e0115b7af0a983816e431eb5c1ce05668f18..13ad5b68d84e7bd308b40b7a303349d877fbe1e1 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPin.ts @@ -20,8 +20,8 @@ import { MemoryConfig } from '../../../../bean/MemoryConfig'; import { Utils } from '../../base/Utils'; import { resizeObserver } from '../SheetUtils'; import { PurgeableTabStruct } from './TabPanePurgTotal'; -import {querySysPurgeableTab} from "../../../../database/sql/Ability.sql"; -import {queryProcessPurgeableTab} from "../../../../database/sql/ProcessThread.sql"; +import { querySysPurgeableTab } from '../../../../database/sql/Ability.sql'; +import { queryProcessPurgeableTab } from '../../../../database/sql/ProcessThread.sql'; @element('tabpane-purg-pin') export class TabPanePurgPin extends BaseElement { @@ -33,10 +33,12 @@ export class TabPanePurgPin extends BaseElement { private sortType = 2; set data(selection: SelectionParam) { - //@ts-ignore - this.purgeablePinTable?.shadowRoot?.querySelector('.table')?.style?.height = `${ - this.parentElement!.clientHeight - 45 - }px`; + if (this.purgeablePinTable) { + //@ts-ignore + this.purgeablePinTable.shadowRoot.querySelector('.table').style.height = `${ + this.parentElement!.clientHeight - 45 + }px`; + } this.init(); this.purgPinTimeRange!.textContent = 'Selected range: ' + ((selection.rightNs - selection.leftNs) / 1000000.0).toFixed(5) + ' ms'; @@ -51,7 +53,7 @@ export class TabPanePurgPin extends BaseElement { true ).then((purgePinResults) => { this.purgeablePinTable!.loading = false; - this.getDataSource(purgePinResults) + this.getDataSource(purgePinResults); }); } else if (selection.purgeablePinVM.length > 0) { this.purgeablePinSource = []; @@ -63,19 +65,19 @@ export class TabPanePurgPin extends BaseElement { true ).then((results) => { this.purgeablePinTable!.loading = false; - this.getDataSource(results) + this.getDataSource(results); }); } } - getDataSource(res: any): void{ + getDataSource(res: any): void { if (res.length > 0) { for (let i = 0; i < res.length; i++) { this.purgeablePinSource.push( this.toTabStruct(res[i].name, res[i].maxSize, res[i].minSize, res[i].avgSize) ); } - this.sortByColumn({ key: this.sortKey, sort: this.sortType }); + this.sortByColumn({key: this.sortKey, sort: this.sortType}); let total = this.totalData(this.purgeablePinSource); this.purgeablePinSource.unshift(total); this.purgeablePinTable!.recycleDataSource = this.purgeablePinSource; @@ -157,6 +159,7 @@ export class TabPanePurgPin extends BaseElement { } }; } + if (detail.key === 'type') { this.purgeablePinSource.sort(compare(detail.key, detail.sort, 'string')); } else { diff --git a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts index 9478dec86a3077a52521e63c7031d64d1bb81041..91d72107e667333bc3ad2a9cd2cc57211ad564ad 100644 --- a/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts +++ b/ide/src/trace/component/trace/sheet/ability/TabPanePurgPinComparisonAbility.ts @@ -20,7 +20,8 @@ import { type SelectionParam } from '../../../../bean/BoxSelection'; import { Utils } from '../../base/Utils'; import { CompareStruct, compare, resizeObserverFromMemory } from '../SheetUtils'; import { type TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; -import {querySysPurgeableSelectionTab} from "../../../../database/sql/Ability.sql"; +import { querySysPurgeableSelectionTab } from '../../../../database/sql/Ability.sql'; + @element('tabpane-purgeable-pin-comparison-ability') export class TabPanePurgPinComparisonAbility extends BaseElement { private purgeablePinTable: LitTable | null | undefined; @@ -33,11 +34,14 @@ export class TabPanePurgPinComparisonAbility extends BaseElement { this.filterEl = this.shadowRoot!.querySelector('#filter'); this.selectEl = this.filterEl?.shadowRoot?.querySelector('lit-select'); } + public totalData(purgePinComParam: SelectionParam | any, dataList: any): void { - //@ts-ignore - this.purgeablePinTable?.shadowRoot?.querySelector('.table')?.style?.height = `${ - this.parentElement!.clientHeight - 45 - }px`; + if (this.purgeablePinTable) { + //@ts-ignore + this.purgeablePinTable.shadowRoot.querySelector('.table').style.height = `${ + this.parentElement!.clientHeight - 45 + }px`; + } this.purgeablePinSource = []; let fileArr: any[] = []; for (let file of dataList) { @@ -49,6 +53,7 @@ export class TabPanePurgPinComparisonAbility extends BaseElement { this.initSelect(purgePinComParam.startNs, fileArr); this.updateComparisonData(purgePinComParam.startNs, fileArr[0].startNs); } + private initSelect(fileStartNs: number, purgePinComFileArr: Array): void { let that = this; let input = this.selectEl!.shadowRoot?.querySelector('input') as HTMLInputElement; @@ -74,6 +79,7 @@ export class TabPanePurgPinComparisonAbility extends BaseElement { }); }); } + private async updateComparisonData(baseTime: number, targetTime: number): Promise { this.purgeablePinSource = []; let tableData = await this.queryTableData(baseTime, targetTime); @@ -84,6 +90,7 @@ export class TabPanePurgPinComparisonAbility extends BaseElement { this.purgeablePinTable!.recycleDataSource = []; } } + private async queryTableData(baseTime: number, targetTime: number): Promise { let delta = { purgPinedDelta: '0Bytes', @@ -118,6 +125,7 @@ export class TabPanePurgPinComparisonAbility extends BaseElement { super.connectedCallback(); resizeObserverFromMemory(this.parentElement!, this.purgeablePinTable!, this.filterEl!); } + public initHtml(): string { return ` +
      + + +
      + + + + + + + + + + + + + + + + +
      + +
      +
      + Retainers + + + + + + + + + + + + + +
      +
      + +
      +
      + + +
      +
      +`; diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts index 9eb5016a32526b71335ff750725b34f498bd8a33..b065fcc115f6947c3eeb1b1785e80cc49f9b9cc8 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneComparison.ts @@ -16,14 +16,18 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { LitTable } from '../../../../../base-ui/table/lit-table'; import { HeapDataInterface } from '../../../../../js-heap/HeapDataInterface'; -import { ConstructorComparison, ConstructorItem, ConstructorType } from '../../../../../js-heap/model/UiStruct'; -import { LitTableColumn } from '../../../../../base-ui/table/lit-table-column'; +import { + ConstructorComparison, + ConstructorItem, + ConstructorType +} from '../../../../../js-heap/model/UiStruct'; import '../../../../../base-ui/table/lit-table-column'; import { TabPaneJsMemoryFilter } from '../TabPaneJsMemoryFilter'; import '../TabPaneJsMemoryFilter'; import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; import { LitSelectOption } from '../../../../../base-ui/select/LitSelectOption'; import { LitSelect } from '../../../../../base-ui/select/LitSelect'; +import { TabPaneComparisonHtml } from './TabPaneComparison.html'; @element('tabpane-comparison') export class TabPaneComparison extends BaseElement { @@ -54,214 +58,10 @@ export class TabPaneComparison extends BaseElement { this.rightTheadTable = this.retainerTableEl!.shadowRoot?.querySelector('.thead') as HTMLDivElement; this.leftTheadTable = this.comparisonTableEl!.shadowRoot?.querySelector('.thead') as HTMLDivElement; this.comparisonTable = this.comparisonTableEl.shadowRoot?.querySelector('.table') as HTMLDivElement; - this.comparisonTableEl!.addEventListener('icon-click', (e) => { - // @ts-ignore - let clickRow = e.detail.data; - if (clickRow.status) { - clickRow.targetFileId = this.targetFileId; - let next = HeapDataInterface.getInstance().getNextForComparison(clickRow); - clickRow.children = next; - if (clickRow.children.length > 0) { - for (let item of clickRow.children) { - let nodeName = item.nodeName + ` @${item.id}`; - item.nodeId = ` @${item.id}`; - if (item.isString()) { - item.objectName = '"' + item.nodeName + '"' + ` @${item.id}`; - } else { - item.objectName = nodeName; - } - item.deltaCount = '-'; - item.deltaSize = '-'; - if (item.edgeName !== '') { - item.objectName = item.edgeName + '\xa0' + '::' + '\xa0' + nodeName; - } else { - if (item.fileId == this.baseFileId) { - item.addedCount = '•'; - item.addedSize = item.shallowSize; - item.removedCount = '-'; - item.removedSize = '-'; - } else if (item.fileId) { - item.removedCount = '•'; - item.removedSize = item.shallowSize; - item.addedCount = '-'; - item.addedSize = '-'; - } - } - if (item.type == ConstructorType.FiledType) { - item.removedCount = '-'; - item.removedSize = '-'; - item.addedCount = '-'; - item.addedSize = '-'; - } - } - } else { - this.comparisonTableEl!.snapshotDataSource = []; - } - } else { - clickRow.status = true; - } - if (this.search!.value !== '') { - if (this.leftTheadTable!.hasAttribute('sort')) { - this.comparisonTableEl!.snapshotDataSource = this.leftArray; - } else { - this.comparisonTableEl!.snapshotDataSource = this.comparisonFilter; - } - } else { - if (this.leftTheadTable!.hasAttribute('sort')) { - this.comparisonTableEl!.snapshotDataSource = this.leftArray; - } else { - this.comparisonTableEl!.snapshotDataSource = this.comparisonsData; - } - } - new ResizeObserver(() => { - this.comparisonTableEl!.style.height = '100%'; - this.comparisonTableEl!.reMeauseHeight(); - }).observe(this.parentElement!); - }); - this.retainerTableEl!.addEventListener('icon-click', (e) => { - // @ts-ignore - let retainerNext = e.detail.data as ConstructorItem; - if (retainerNext) { - if (this.retainsData.length > 0) { - if (retainerNext.status) { - retainerNext.getChildren(); - let i = 0; - let that = this; - let retainsTable = () => { - const getList = (comList: Array): void => { - comList.forEach((row) => { - let shallow = Math.round((row.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((row.retainedSize / this.fileSize) * 100) + '%'; - row.shallowPercent = shallow; - row.retainedPercent = retained; - let nodeId = row.nodeName + ` @${row.id}`; - row.objectName = row.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - if (row.distance >= 100000000 || row.distance === -5) { - // @ts-ignore - row.distance = '-'; - } - i++; - // @ts-ignore - if (i < that.retainsData[0].distance - 1 && comList[0].distance !== '-') { - comList[0].getChildren(); - comList[0].expanded = false; - if (row.hasNext) { - getList(row.children); - } - } else { - return; - } - }); - }; - getList(retainerNext.children); - }; - retainsTable(); - } else { - retainerNext.status = true; - } - if (this.rightTheadTable!.hasAttribute('sort')) { - this.retainerTableEl!.snapshotDataSource = this.rightArray; - } else { - this.retainerTableEl!.snapshotDataSource = this.retainsData; - } - } else { - this.retainerTableEl!.snapshotDataSource = []; - } - new ResizeObserver(() => { - this.retainerTableEl!.style.height = 'calc(100% - 21px)'; - this.retainerTableEl!.reMeauseHeight(); - }).observe(this.parentElement!); - } - }); - this.comparisonTableEl!.addEventListener('column-click', (e) => { - // @ts-ignore - this.sortComprisonByColumn(e.detail.key, e.detail.sort); - this.comparisonTableEl!.reMeauseHeight(); - }); - this.retainerTableEl!.addEventListener('column-click', (e) => { - // @ts-ignore - this.sortRetainerByColumn(e.detail.key, e.detail.sort); - this.retainerTableEl!.reMeauseHeight(); - }); - this.comparisonTableEl!.addEventListener('row-click', (e) => { - this.rightTheadTable!.removeAttribute('sort'); - // @ts-ignore - let item = e.detail.data as ConstructorItem; - (item as any).isSelected = true; - this.retainsData = HeapDataInterface.getInstance().getRetains(item); - if (this.retainsData && this.retainsData.length > 0) { - this.retainsData.forEach((comparisonRetainEl) => { - let shallow = Math.round((comparisonRetainEl.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((comparisonRetainEl.retainedSize / this.fileSize) * 100) + '%'; - comparisonRetainEl.shallowPercent = shallow; - comparisonRetainEl.retainedPercent = retained; - if (comparisonRetainEl.distance >= 100000000 || comparisonRetainEl.distance === -5) { - // @ts-ignore - comparisonRetainEl.distance = '-'; - } - let nodeId = comparisonRetainEl.nodeName + ` @${comparisonRetainEl.id}`; - comparisonRetainEl.objectName = comparisonRetainEl.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - }); - let i = 0; - let that = this; - if (this.retainsData[0].distance > 1) { - this.retainsData[0].getChildren(); - this.retainsData[0].expanded = false; - } - let retainsTable = () => { - const getList = (list: Array) => { - list.forEach((structRow) => { - let shallow = Math.round((structRow.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((structRow.retainedSize / this.fileSize) * 100) + '%'; - structRow.shallowPercent = shallow; - structRow.retainedPercent = retained; - let nodeId = structRow.nodeName + ` @${structRow.id}`; - structRow.objectName = structRow.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - if (structRow.distance >= 100000000 || structRow.distance === -5) { - // @ts-ignore - structRow.distance = '-'; - } - i++; - // @ts-ignore - if (i < that.retainsData[0].distance - 1 && list[0].distance !== '-') { - list[0].getChildren(); - list[0].expanded = false; - if (structRow.hasNext) { - getList(structRow.children); - } - } else { - return; - } - }); - }; - getList(that.retainsData[0].children); - }; - retainsTable(); - this.retainerTableEl!.snapshotDataSource = this.retainsData; - } else { - this.retainerTableEl!.snapshotDataSource = []; - } - new ResizeObserver(() => { - this.retainerTableEl!.style.height = 'calc(100% - 21px)'; - this.retainerTableEl!.reMeauseHeight(); - }).observe(this.parentElement!); - // @ts-ignore - if ((e.detail as any).callBack) { - // @ts-ignore - (e.detail as any).callBack(true); - } - }); - this.retainerTableEl!.addEventListener('row-click', (evt: any) => { - let data = evt.detail.data as ConstructorItem; - (data as any).isSelected = true; - if ((evt.detail as any).callBack) { - (evt.detail as any).callBack(true); - } - }); this.classFilter(); } - initComparison(data: HeapSnapshotStruct, dataListCache: Array) { + initComparison(data: HeapSnapshotStruct, dataListCache: Array): void { this.clear(); this.retainerTableEl!.snapshotDataSource = []; let fileArr: HeapSnapshotStruct[] = []; @@ -283,7 +83,7 @@ export class TabPaneComparison extends BaseElement { }).observe(this.parentElement!); } - updateComparisonData(baseFileId: number, targetFileId: number) { + updateComparisonData(baseFileId: number, targetFileId: number): void { this.comparisonsData = HeapDataInterface.getInstance().getClassListForComparison(baseFileId, targetFileId); this.comparisonsData.forEach((dataList) => { dataList.objectName = dataList.nodeName; @@ -340,45 +140,49 @@ export class TabPaneComparison extends BaseElement { } else { this.leftArray = [...this.comparisonFilter]; } - switch (column) { - case 'addedCount': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.addedCount - b.addedCount : b.addedCount - a.addedCount; - }); - break; - case 'removedCount': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.removedCount - b.removedCount : b.removedCount - a.removedCount; - }); - break; - case 'deltaCount': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.deltaCount - b.deltaCount : b.deltaCount - a.deltaCount; - }); - break; - case 'objectName': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 - ? (a.objectName + '').localeCompare(b.objectName + '') - : (b.objectName + '').localeCompare(a.objectName + ''); - }); - break; - case 'addedSize': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.addedSize - b.addedSize : b.addedSize - a.addedSize; - }); - break; - case 'removedSize': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.removedSize - b.removedSize : b.removedSize - a.removedSize; - }); - break; - case 'deltaSize': - this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { - return sort === 1 ? a.deltaSize - b.deltaSize : b.deltaSize - a.deltaSize; - }); - break; - } + this.sortComprisonByColumnExtend(column, sort); + break; + } + } + + private sortComprisonByColumnExtend(column: string, sort: number): void{ + switch (column) { + case 'addedCount': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.addedCount - b.addedCount : b.addedCount - a.addedCount; + }); + break; + case 'removedCount': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.removedCount - b.removedCount : b.removedCount - a.removedCount; + }); + break; + case 'deltaCount': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.deltaCount - b.deltaCount : b.deltaCount - a.deltaCount; + }); + break; + case 'objectName': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? + (`${a.objectName }`).localeCompare(`${b.objectName }`) : + (`${b.objectName }`).localeCompare(`${a.objectName }`); + }); + break; + case 'addedSize': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.addedSize - b.addedSize : b.addedSize - a.addedSize; + }); + break; + case 'removedSize': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.removedSize - b.removedSize : b.removedSize - a.removedSize; + }); + break; + case 'deltaSize': + this.comparisonTableEl!.snapshotDataSource = this.leftArray.sort((a, b) => { + return sort === 1 ? a.deltaSize - b.deltaSize : b.deltaSize - a.deltaSize; + }); break; } } @@ -392,114 +196,130 @@ export class TabPaneComparison extends BaseElement { this.rightArray = [...this.retainsData]; switch (column) { case 'distance': - this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((a, b) => { - return sort === 1 ? a.distance - b.distance : b.distance - a.distance; - }); - this.rightArray.forEach((list) => { - let retainsTable = function () { - const getList = function (currentList: Array) { - currentList.sort((a, b) => { - return sort === 1 ? a.distance - b.distance : b.distance - a.distance; - }); - currentList.forEach(function (currentRow) { - if (currentRow.children.length > 0) { - getList(currentRow.children); - } - }); - }; - getList(list.children); - }; - retainsTable(); - }); - this.retainerTableEl!.snapshotDataSource = this.rightArray; + this.sortRetainerByDistanceType(sort); break; case 'shallowSize': - this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { - return sort === 1 - ? rightArrA.shallowSize - rightArrB.shallowSize - : rightArrB.shallowSize - rightArrA.shallowSize; - }); - this.rightArray.forEach((list) => { - let retainsTable = function () { - const getList = function (listArr: Array) { - listArr.sort((listArrA, listArrB) => { - return sort === 1 - ? listArrA.shallowSize - listArrB.shallowSize - : listArrB.shallowSize - listArrA.shallowSize; - }); - listArr.forEach(function (rowEl) { - if (rowEl.children.length > 0) { - getList(rowEl.children); - } - }); - }; - getList(list.children); - }; - retainsTable(); - }); - this.retainerTableEl!.snapshotDataSource = this.rightArray; + this.sortRetainerByShallowSizeType(sort); break; case 'retainedSize': - this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { - return sort === 1 - ? rightArrA.retainedSize - rightArrB.retainedSize - : rightArrB.retainedSize - rightArrA.retainedSize; - }); - this.rightArray.forEach((list) => { - let retainsTable = function () { - const getList = function (listArr: Array) { - listArr.sort((listArrA, listArrB) => { - return sort === 1 - ? listArrA.retainedSize - listArrB.retainedSize - : listArrB.retainedSize - listArrA.retainedSize; - }); - listArr.forEach(function (row) { - if (row.children.length > 0) { - getList(row.children); - } - }); - }; - getList(list.children); - }; - retainsTable(); - }); - this.retainerTableEl!.snapshotDataSource = this.rightArray; + this.sortRetainerByRetainedSizeType(sort); break; case 'objectName': - this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { - return sort === 1 - ? (rightArrA.objectName + '').localeCompare(rightArrB.objectName + '') - : (rightArrB.objectName + '').localeCompare(rightArrA.objectName + ''); - }); - this.rightArray.forEach((list) => { - let retainsTable = function () { - const getList = function (listArr: Array) { - listArr.sort((listArrA, listArrB) => { - return sort === 1 - ? (listArrA.objectName + '').localeCompare(listArrB.objectName + '') - : (listArrB.objectName + '').localeCompare(listArrA.objectName + ''); - }); - listArr.forEach(function (currentRow) { - if (currentRow.children.length > 0) { - getList(currentRow.children); - } - }); - }; - getList(list.children); - }; - retainsTable(); - }); - this.retainerTableEl!.snapshotDataSource = this.rightArray; + this.sortRetainerByObjectNameType(sort); break; } break; } } + private sortRetainerByObjectNameType(sort: number): void { + this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { + return sort === 1 ? + (`${rightArrA.objectName }`).localeCompare(`${rightArrB.objectName }`) : + (`${rightArrB.objectName }`).localeCompare(`${rightArrA.objectName }`); + }); + this.rightArray.forEach((list) => { + let retainsTable = (): void => { + const getList = (listArr: Array): void => { + listArr.sort((listArrA, listArrB) => { + return sort === 1 ? + (`${listArrA.objectName }`).localeCompare(`${listArrB.objectName }`) : + (`${listArrB.objectName }`).localeCompare(`${listArrA.objectName }`); + }); + listArr.forEach(function (currentRow) { + if (currentRow.children.length > 0) { + getList(currentRow.children); + } + }); + }; + getList(list.children); + }; + retainsTable(); + }); + this.retainerTableEl!.snapshotDataSource = this.rightArray; + } + + private sortRetainerByRetainedSizeType(sort: number): void { + this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { + return sort === 1 ? + rightArrA.retainedSize - rightArrB.retainedSize : + rightArrB.retainedSize - rightArrA.retainedSize; + }); + this.rightArray.forEach((list) => { + let retainsTable = (): void => { + const getList = (listArr: Array): void => { + listArr.sort((listArrA, listArrB) => { + return sort === 1 ? + listArrA.retainedSize - listArrB.retainedSize : + listArrB.retainedSize - listArrA.retainedSize; + }); + listArr.forEach(function (row) { + if (row.children.length > 0) { + getList(row.children); + } + }); + }; + getList(list.children); + }; + retainsTable(); + }); + this.retainerTableEl!.snapshotDataSource = this.rightArray; + } + + private sortRetainerByShallowSizeType(sort: number): void { + this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((rightArrA, rightArrB) => { + return sort === 1 ? + rightArrA.shallowSize - rightArrB.shallowSize : + rightArrB.shallowSize - rightArrA.shallowSize; + }); + this.rightArray.forEach((list) => { + let retainsTable = (): void => { + const getList = (listArr: Array): void => { + listArr.sort((listArrA, listArrB) => { + return sort === 1 ? + listArrA.shallowSize - listArrB.shallowSize : + listArrB.shallowSize - listArrA.shallowSize; + }); + listArr.forEach(function (rowEl) { + if (rowEl.children.length > 0) { + getList(rowEl.children); + } + }); + }; + getList(list.children); + }; + retainsTable(); + }); + this.retainerTableEl!.snapshotDataSource = this.rightArray; + } + + private sortRetainerByDistanceType(sort: number): void { + this.retainerTableEl!.snapshotDataSource = this.rightArray.sort((a, b) => { + return sort === 1 ? a.distance - b.distance : b.distance - a.distance; + }); + this.rightArray.forEach((list) => { + let retainsTable = (): void => { + const getList = (currentList: Array): void => { + currentList.sort((a, b) => { + return sort === 1 ? a.distance - b.distance : b.distance - a.distance; + }); + currentList.forEach(function (currentRow) { + if (currentRow.children.length > 0) { + getList(currentRow.children); + } + }); + }; + getList(list.children); + }; + retainsTable(); + }); + this.retainerTableEl!.snapshotDataSource = this.rightArray; + } + classFilter(): void { this.search!.addEventListener('keyup', () => { this.comparisonFilter = []; - this.comparisonData.forEach((a: any, key: number) => { + this.comparisonData.forEach((a: any) => { if (a.objectName.toLowerCase().includes(this.search!.value.toLowerCase())) { this.comparisonFilter.push(a); } else { @@ -522,104 +342,255 @@ export class TabPaneComparison extends BaseElement { connectedCallback(): void { super.connectedCallback(); let filterHeight = 0; - new ResizeObserver((entries) => { + new ResizeObserver(() => { let comparisonPanelFilter = this.shadowRoot!.querySelector('#filter') as HTMLElement; - if (comparisonPanelFilter.clientHeight > 0) filterHeight = comparisonPanelFilter.clientHeight; + if (comparisonPanelFilter.clientHeight > 0) {filterHeight = comparisonPanelFilter.clientHeight} if (this.parentElement!.clientHeight > filterHeight) { comparisonPanelFilter.style.display = 'flex'; } else { comparisonPanelFilter.style.display = 'none'; } }).observe(this.parentElement!); + this.comparisonTableEl!.addEventListener('icon-click', this.comparisonTblIconClickHandler); + this.retainerTableEl!.addEventListener('icon-click', this.retainerTblIconClickHandler); + this.comparisonTableEl!.addEventListener('column-click', this.comparisonTblColumnClickHandler); + this.retainerTableEl!.addEventListener('column-click', this.retainerTblColumnClickHandler); + this.comparisonTableEl!.addEventListener('row-click', this.comparisonTblRowClickHandler); + this.retainerTableEl!.addEventListener('row-click', this.retainerTblRowClickHandler); } - initHtml(): string { - return ` - -
      - - -
      - - - - - - - - - - - - - - - - -
      - -
      -
      - Retainers - - - - - - - - - - - - - -
      -
      - -
      -
      - - -
      -
      - `; + } else { + this.comparisonTableEl!.snapshotDataSource = []; + } + } else { + clickRow.status = true; + } + this.comparisonTblIconClickData(); + }; + + private comparisonTblIconClickData(): void{ + if (this.search!.value !== '') { + if (this.leftTheadTable!.hasAttribute('sort')) { + this.comparisonTableEl!.snapshotDataSource = this.leftArray; + } else { + this.comparisonTableEl!.snapshotDataSource = this.comparisonFilter; + } + } else { + if (this.leftTheadTable!.hasAttribute('sort')) { + this.comparisonTableEl!.snapshotDataSource = this.leftArray; + } else { + this.comparisonTableEl!.snapshotDataSource = this.comparisonsData; + } + } + new ResizeObserver(() => { + this.comparisonTableEl!.style.height = '100%'; + this.comparisonTableEl!.reMeauseHeight(); + }).observe(this.parentElement!); + } + + initHtml(): string { + return TabPaneComparisonHtml; } } diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.html.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..738fd446751819ab65167658eeb71b83f5a3de77 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.html.ts @@ -0,0 +1,71 @@ +/* + * 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. + */ + +export const TabPaneJsCpuHtml = ` + +
      + + +
      + + + + + + + +
      + +
      +
      + Heaviest Stack + + + + + +
      +
      +
      +
      + + +
      + `; diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts index f0bd7d84fe7c9b2213e60353b51376a6349e226d..95bc5a305c4384153085916f6504187a2e523eee 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpu.ts @@ -20,8 +20,9 @@ import { type JsCpuProfilerChartFrame, JsCpuProfilerTabStruct } from '../../../. import { procedurePool } from '../../../../database/Procedure'; import { findSearchNode, ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; import { SpSystemTrace } from '../../../SpSystemTrace'; -import { type FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { TabPaneFilter } from '../TabPaneFilter'; import '../TabPaneFilter'; +import { TabPaneJsCpuHtml } from './TabPaneJsCpu.html'; export class TabPaneJsCpuCallTree extends BaseElement { protected TYPE_TOP_DOWN = 0; @@ -51,7 +52,7 @@ export class TabPaneJsCpuCallTree extends BaseElement { return; } this.currentSelection = data; - let chartData = []; + let chartData; chartData = data.jsCpuProfilerData; this.totalNs = chartData.reduce((acc, struct) => acc + struct.totalTime, 0); if (data.rightNs && data.leftNs) { @@ -88,7 +89,7 @@ export class TabPaneJsCpuCallTree extends BaseElement { private setCallTreeTableData(results: Array): void { this.clearTab(); const callTreeMap = new Map(); - const setTabData = (data: Array) => { + const setTabData = (data: Array): void => { data.forEach((item) => { if (item.children && item.children.length > 0) { item.children.forEach((it) => { @@ -100,10 +101,10 @@ export class TabPaneJsCpuCallTree extends BaseElement { if (item.scriptName === 'unknown') { item.symbolName = item.name; } else { - item.symbolName = item.name + ` ${item.scriptName}`; + item.symbolName = `${item.name } ${item.scriptName}`; } - item.totalTimePercent = ((item.totalTime / this.totalNs) * 100).toFixed(1) + '%'; - item.selfTimePercent = ((item.selfTime / this.totalNs) * 100).toFixed(1) + '%'; + item.totalTimePercent = `${((item.totalTime / this.totalNs) * 100).toFixed(1) }%`; + item.selfTimePercent = `${((item.selfTime / this.totalNs) * 100).toFixed(1) }%`; item.selfTimeStr = ns2s(item.selfTime); item.totalTimeStr = ns2s(item.totalTime); item.parent = callTreeMap.get(item.parentId!); @@ -115,53 +116,53 @@ export class TabPaneJsCpuCallTree extends BaseElement { this.callTreeTable!.recycleDataSource = this.callTreeSource; } + private callTreeRowClickHandler(evt: Event): void { + const heaviestStack: JsCpuProfilerTabStruct[] = []; + const getHeaviestChildren = (children: Array): void => { + if (children.length === 0) { + return; + } + const heaviestChild = children.reduce( + (max, struct): JsCpuProfilerTabStruct => + Math.max(max.totalTime, struct.totalTime) === max.totalTime ? max : struct + ); + heaviestStack?.push(heaviestChild); + getHeaviestChildren(heaviestChild.children); + }; + const getParent = (list: JsCpuProfilerTabStruct): void => { + if (list.parent) { + heaviestStack.push(list.parent!); + getParent(list.parent!); + } + }; + //@ts-ignore + const data = evt.detail.data as JsCpuProfilerTabStruct; + heaviestStack!.push(data); + if (data.parent) { + heaviestStack.push(data.parent!); + getParent(data.parent!); + } + heaviestStack.reverse(); + getHeaviestChildren(data.children); + this.stackTable!.recycleDataSource = heaviestStack; + data.isSelected = true; + this.stackTable?.clearAllSelection(data); + this.stackTable?.setCurrentSelection(data); + // @ts-ignore + if (evt.detail.callBack) { + // @ts-ignore + evt.detail.callBack(true); + } + } + public initElements(): void { this.callTreeTable = this.shadowRoot?.querySelector('#callTreeTable') as LitTable; this.stackTable = this.shadowRoot?.querySelector('#stackTable') as LitTable; this.treeTable = this.callTreeTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement; this.profilerFilter = this.shadowRoot?.querySelector('#filter') as TabPaneFilter; this.callTreeTable!.addEventListener('row-click', (evt): void => { - const heaviestStack = new Array(); - - const getHeaviestChildren = (children: Array): void => { - if (children.length === 0) { - return; - } - const heaviestChild = children.reduce( - (max, struct): JsCpuProfilerTabStruct => - Math.max(max.totalTime, struct.totalTime) === max.totalTime ? max : struct - ); - heaviestStack?.push(heaviestChild); - getHeaviestChildren(heaviestChild.children); - }; - - const getParent = (list: JsCpuProfilerTabStruct): void => { - if (list.parent) { - heaviestStack.push(list.parent!); - getParent(list.parent!); - } - }; - - //@ts-ignore - const data = evt.detail.data as JsCpuProfilerTabStruct; - heaviestStack!.push(data); - if (data.parent) { - heaviestStack.push(data.parent!); - getParent(data.parent!); - } - heaviestStack.reverse(); - getHeaviestChildren(data.children); - this.stackTable!.recycleDataSource = heaviestStack; - data.isSelected = true; - this.stackTable?.clearAllSelection(data); - this.stackTable?.setCurrentSelection(data); - // @ts-ignore - if (evt.detail.callBack) { - // @ts-ignore - evt.detail.callBack(true); - } + this.callTreeRowClickHandler(evt); }); - this.stackTable!.addEventListener('row-click', (evt) => { //@ts-ignore const data = evt.detail.data as JsCpuProfilerTabStruct; @@ -181,7 +182,7 @@ export class TabPaneJsCpuCallTree extends BaseElement { this.sortType = evt.detail.sort; this.setCallTreeTableData(this.callTreeSource); }); - this.profilerFilter!.getFilterData((data: FilterData): void => { + this.profilerFilter!.getFilterData((): void => { if (this.searchValue !== this.profilerFilter!.filterValue) { this.searchValue = this.profilerFilter!.filterValue; findSearchNode(this.callTreeSource, this.searchValue, false); @@ -195,18 +196,19 @@ export class TabPaneJsCpuCallTree extends BaseElement { super.connectedCallback(); new ResizeObserver(() => { // @ts-ignore - this.callTreeTable?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 32 + 'px'; + this.callTreeTable?.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 32 }px`; this.callTreeTable?.reMeauseHeight(); // @ts-ignore this.stackTable?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 32 - 22 + 'px'; + `${this.parentElement!.clientHeight - 32 - 22 }px`; this.stackTable?.reMeauseHeight(); }).observe(this.parentElement!); } private sortTree(arr: Array): Array { const that = this; - function defaultSort(callTreeLeftData: JsCpuProfilerTabStruct, callTreeRightData: JsCpuProfilerTabStruct) { + function defaultSort(callTreeLeftData: JsCpuProfilerTabStruct, callTreeRightData: JsCpuProfilerTabStruct): number { if (that.currentType === that.TYPE_TOP_DOWN) { return callTreeRightData.totalTime - callTreeLeftData.totalTime; } else { @@ -226,9 +228,9 @@ export class TabPaneJsCpuCallTree extends BaseElement { if (this.sortType === 0) { return defaultSort(callTreeLeftData, callTreeRightData); } else if (this.sortType === 1) { - return (callTreeLeftData.symbolName + '').localeCompare(callTreeRightData.symbolName + ''); + return (`${callTreeLeftData.symbolName }`).localeCompare(`${callTreeRightData.symbolName }`); } else { - return (callTreeRightData.symbolName + '').localeCompare(callTreeLeftData.symbolName + ''); + return (`${callTreeRightData.symbolName }`).localeCompare(`${callTreeLeftData.symbolName }`); } } else { if (this.sortType === 0) { @@ -253,53 +255,6 @@ export class TabPaneJsCpuCallTree extends BaseElement { } public initHtml(): string { - return ` - -
      - - -
      - - - - - - - -
      - -
      -
      - Heaviest Stack - - - - - -
      -
      -
      -
      - - -
      - `; + return TabPaneJsCpuHtml; } } diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.html.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..b436592cf92832e4ff358a3f6bdcedc08e1e01d1 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.html.ts @@ -0,0 +1,66 @@ +/* + * 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. + */ + +export const TabPaneJsCpuStatisticsHtml = ` + + +
      +
      +
      Statistics By Total
      + +
      +
      + + + + + +
      +
      +`; diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts index 7a069b9c76fe6f10480ccb0594dde27cf0e19d64..8c3ea96c53ce8ece24e1e45b36b5d3f9712f1161 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneJsCpuStatistics.ts @@ -22,8 +22,8 @@ import { type JsCpuProfilerChartFrame, JsCpuProfilerStatisticsStruct } from '../ import { procedurePool } from '../../../../database/Procedure'; import { type SampleType } from '../../../../database/logic-worker/ProcedureLogicWorkerJsCpuProfiler'; import { ns2s } from '../../../../database/ui-worker/ProcedureWorkerCommon'; -import { SpSystemTrace } from '../../../SpSystemTrace'; import { resizeObserver } from '../SheetUtils'; +import { TabPaneJsCpuStatisticsHtml } from './TabPaneJsCpuStatistics.html'; @element('tabpane-js-cpu-statistics') export class TabPaneJsCpuStatistics extends BaseElement { @@ -71,7 +71,7 @@ export class TabPaneJsCpuStatistics extends BaseElement { } private getDataByWorker(data: SelectionParam | Array, handler: Function): void { - let params = undefined; + let params; if (data instanceof SelectionParam) { params = { data: data.jsCpuProfilerData, @@ -151,8 +151,7 @@ export class TabPaneJsCpuStatistics extends BaseElement { for (let item of source) { totalTime += item.time; } - let totalData = this.toStatisticsStruct('', totalTime, totalTime); - return totalData; + return this.toStatisticsStruct('', totalTime, totalTime); } private clearData(): void { @@ -177,13 +176,12 @@ export class TabPaneJsCpuStatistics extends BaseElement { time: number, percentage: number ): JsCpuProfilerStatisticsStruct { - const statisticsStruct = new JsCpuProfilerStatisticsStruct( + return new JsCpuProfilerStatisticsStruct( type, time, ns2s(time), ((time / percentage || 0) * 100).toFixed(1) ); - return statisticsStruct; } private sortByColumn(detail: any): void { @@ -241,53 +239,6 @@ export class TabPaneJsCpuStatistics extends BaseElement { } public initHtml(): string { - return ` - - -
      -
      -
      Statistics By Total
      - -
      -
      - - - - - -
      -
      - `; + return TabPaneJsCpuStatisticsHtml; } } diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.html.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..dd8f5b79fbe00f49027b5b443f5ed9b96b293aeb --- /dev/null +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.html.ts @@ -0,0 +1,177 @@ +/* + * 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. + */ + +export const TabPaneSummaryHtml = ` + +
      + + +
      + + + + + + + + + + + + + + +
      + +
      +
      +
      +
        +
      • Retainers
      • + +
      +
      + + + + + + + + + + + + + + + + +
      +
      +
      +
      + + +
      +`; diff --git a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts index 9fdc62867d584c1f3990007e5dedf972fdb4af82..b6ec743a20ab5cbf88dbdc79ed8119bd49e21ccd 100644 --- a/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts +++ b/ide/src/trace/component/trace/sheet/ark-ts/TabPaneSummary.ts @@ -26,6 +26,7 @@ import '../../../../../base-ui/progress-bar/LitProgressBar'; import '../../../../../base-ui/slicer/lit-slicer'; import { HeapSnapshotStruct } from '../../../../database/ui-worker/ProcedureWorkerHeapSnapshot'; import { HeapTraceFunctionInfo } from '../../../../../js-heap/model/DatabaseStruct'; +import { TabPaneSummaryHtml } from './TabPaneSummary.html'; @element('tabpane-summary') export class TabPaneSummary extends BaseElement { @@ -68,228 +69,6 @@ export class TabPaneSummary extends BaseElement { this.leftTheadTable = this.tblSummary!.shadowRoot?.querySelector('.thead') as HTMLDivElement; this.tbsTable = this.tbs!.shadowRoot?.querySelector('.table') as HTMLDivElement; this.leftTable = this.shadowRoot?.querySelector('#summary_left_table') as HTMLDivElement; - this.tblSummary!.addEventListener('row-click', (evt) => { - this.rightTheadTable!.removeAttribute('sort'); - this.tbsTable!.scrollTop = 0; - //@ts-ignore - let data = evt.detail.data as ConstructorItem; - (data as any).isSelected = true; - this.retainsData = []; - this.retainsData = HeapDataInterface.getInstance().getRetains(data); - this.retainsData.forEach((element) => { - let shallow = Math.round((element.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((element.retainedSize / this.fileSize) * 100) + '%'; - element.shallowPercent = shallow; - element.retainedPercent = retained; - if (element.distance >= 100000000 || element.distance === -5) { - //@ts-ignore - element.distance = '-'; - } - let nodeId = element.nodeName + ` @${element.id}`; - element.objectName = element.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - }); - if (this.retainsData.length > 0) { - if (this.retainsData[0].distance > 1) { - this.retainsData[0].getChildren(); - this.retainsData[0].expanded = false; - } - let i = 0; - let that = this; - let retainsTable = () => { - const getList = (list: Array) => { - list.forEach((row: ConstructorItem) => { - let shallow = Math.round((row.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((row.retainedSize / this.fileSize) * 100) + '%'; - row.shallowPercent = shallow; - row.retainedPercent = retained; - let nodeId = row.nodeName + ` @${row.id}`; - row.objectName = row.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - if (row.distance >= 100000000 || row.distance === -5) { - //@ts-ignore - row.distance = '-'; - } - i++; - //@ts-ignore - if (i < that.retainsData[0].distance - 1 && list[0].distance != '-') { - list[0].getChildren(); - list[0].expanded = false; - if (row.hasNext) { - getList(row.children); - } - } else { - return; - } - }); - }; - getList(that.retainsData[0].children); - }; - retainsTable(); - this.tbs!.snapshotDataSource = this.retainsData; - } else { - this.tbs!.snapshotDataSource = []; - } - if (this.file!.name.includes('Timeline')) { - this.stackData = HeapDataInterface.getInstance().getAllocationStackData(data); - if (this.stackData.length > 0) { - this.stackTable!.recycleDataSource = this.stackData; - this.stackText!.textContent = ''; - this.stackText!.style.display = 'none'; - if (this.stack!.className == 'active') { - this.stackTable!.style.display = 'grid'; - this.tbs!.style.display = 'none'; - } - } else { - this.stackText!.style.display = 'flex'; - this.stackTable!.recycleDataSource = []; - this.stackTable!.style.display = 'none'; - if (this.retainers!.className == 'active') { - this.stackText!.style.display = 'none'; - } - if (this.retainsData === undefined || this.retainsData.length === 0) { - this.stackText!.textContent = ''; - } else { - this.stackText!.textContent = - 'Stack was not recorded for this object because it had been allocated before this profile recording started.'; - } - } - } - new ResizeObserver(() => { - this.tbs!.style.height = 'calc(100% - 30px)'; - this.tbs!.reMeauseHeight(); - this.stackTable!.style.height = 'calc(100% - 30px)'; - this.stackTable!.reMeauseHeight(); - }).observe(this.parentElement!); - // @ts-ignore - if ((evt.detail as any).callBack) { - // @ts-ignore - (evt.detail as any).callBack(true); - } - }); - - this.tbs!.addEventListener('row-click', (summanyRowEvent: any) => { - let data = summanyRowEvent.detail.data as ConstructorItem; - (data as any).isSelected = true; - if ((summanyRowEvent.detail as any).callBack) { - // @ts-ignore - (summanyRowEvent.detail as any).callBack(true); - } - }); - - this.tblSummary!.addEventListener('icon-click', (evt) => { - // @ts-ignore - let data = evt.detail.data; - if (data.status) { - data.getChildren(); - if (data.children.length > 0) { - data.children.sort(function (a: ConstructorItem, b: ConstructorItem) { - return b.retainedSize - a.retainedSize; - }); - data.children.forEach((summaryDataEl: any) => { - let shallow = Math.round((summaryDataEl.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((summaryDataEl.retainedSize / this.fileSize) * 100) + '%'; - summaryDataEl.shallowPercent = shallow; - summaryDataEl.retainedPercent = retained; - if (summaryDataEl.distance >= 100000000 || summaryDataEl.distance === -5) { - summaryDataEl.distance = '-'; - } - let nodeId = summaryDataEl.nodeName + ` @${summaryDataEl.id}`; - summaryDataEl.nodeId = ` @${summaryDataEl.id}`; - if (data.isString()) { - summaryDataEl.objectName = '"' + summaryDataEl.nodeName + '"' + ` @${summaryDataEl.id}`; - } else { - summaryDataEl.objectName = nodeId; - } - if (summaryDataEl.edgeName != '') { - summaryDataEl.objectName = summaryDataEl.edgeName + '\xa0' + '::' + '\xa0' + nodeId; - } - }); - } else { - this.tblSummary!.snapshotDataSource = []; - } - } else { - data.status = true; - } - if (this.search!.value != '') { - if (this.leftTheadTable!.hasAttribute('sort')) { - this.tblSummary!.snapshotDataSource = this.leftArray; - } else { - this.tblSummary!.snapshotDataSource = this.summaryFilter; - } - } else { - if (this.leftTheadTable!.hasAttribute('sort')) { - this.tblSummary!.snapshotDataSource = this.leftArray; - } else { - this.tblSummary!.snapshotDataSource = this.summary; - } - } - new ResizeObserver(() => { - if (this.parentElement?.clientHeight !== 0) { - this.tblSummary!.style.height = '100%'; - this.tblSummary!.reMeauseHeight(); - } - }).observe(this.parentElement!); - }); - this.tbs!.addEventListener('icon-click', (evt) => { - // @ts-ignore - let data = evt.detail.data; - if (data.status) { - data.getChildren(); - let i = 0; - let retainsTable = () => { - const getList = (list: Array) => { - list.forEach((currentRow: ConstructorItem) => { - let shallow = Math.round((currentRow.shallowSize / this.fileSize) * 100) + '%'; - let retained = Math.round((currentRow.retainedSize / this.fileSize) * 100) + '%'; - currentRow.shallowPercent = shallow; - currentRow.retainedPercent = retained; - let nodeId = currentRow.nodeName + ` @${currentRow.id}`; - currentRow.objectName = currentRow.edgeName + '\xa0' + 'in' + '\xa0' + nodeId; - if (currentRow.distance >= 100000000 || currentRow.distance === -5) { - // @ts-ignore - currentRow.distance = '-'; - } - i++; - // @ts-ignore - if (i < evt.detail.data.distance - 1 && list[0].distance != '-') { - list[0].getChildren(); - list[0].expanded = false; - if (currentRow.hasNext) { - getList(currentRow.children); - } - } else { - return; - } - }); - }; - getList(data.children); - }; - retainsTable(); - } else { - data.status = true; - } - if (this.rightTheadTable!.hasAttribute('sort')) { - this.tbs!.snapshotDataSource = this.rightArray; - } else { - this.tbs!.snapshotDataSource = this.retainsData; - } - new ResizeObserver(() => { - if (this.parentElement?.clientHeight !== 0) { - this.tbs!.style.height = 'calc(100% - 30px)'; - this.tbs!.reMeauseHeight(); - } - }).observe(this.parentElement!); - }); - - this.tblSummary!.addEventListener('column-click', (evt) => { - // @ts-ignore - this.sortByLeftTable(evt.detail.key, evt.detail.sort); - this.tblSummary!.reMeauseHeight(); - }); - this.tbs!.addEventListener('column-click', (evt) => { - // @ts-ignore - this.sortByRightTable(evt.detail.key, evt.detail.sort); - this.tbs!.reMeauseHeight(); - }); this.classFilter(); } @@ -297,7 +76,7 @@ export class TabPaneSummary extends BaseElement { data: HeapSnapshotStruct, dataListCache: Array, scrollCallback: ((d: HeapSnapshotStruct, ds: Array) => void) | undefined - ) { + ): void { if (scrollCallback) { scrollCallback(data, dataListCache); } @@ -314,14 +93,14 @@ export class TabPaneSummary extends BaseElement { this.fileSize = file.size; this.summary.forEach((summaryEl: any) => { if (summaryEl.childCount > 1) { - let count = summaryEl.nodeName + ` ×${summaryEl.childCount}`; + let count = `${summaryEl.nodeName } ×${summaryEl.childCount}`; summaryEl.objectName = count; summaryEl.count = ` ×${summaryEl.childCount}`; } else { summaryEl.objectName = summaryEl.nodeName; } - let shallow = Math.round((summaryEl.shallowSize / file.size) * 100) + '%'; - let retained = Math.round((summaryEl.retainedSize / file.size) * 100) + '%'; + let shallow = `${Math.round((summaryEl.shallowSize / file.size) * 100) }%`; + let retained = `${Math.round((summaryEl.retainedSize / file.size) * 100) }%`; summaryEl.shallowPercent = shallow; summaryEl.retainedPercent = retained; if (summaryEl.distance >= 100000000 || summaryEl.distance === -5) { @@ -399,9 +178,9 @@ export class TabPaneSummary extends BaseElement { private retainsTableByObjectName(currentLeftItem: ConstructorItem, sort: number): void { const getList = function (list: Array): void { list.sort((leftA, rightB) => { - return sort === 1 - ? (leftA.objectName + '').localeCompare(rightB.objectName + '') - : (rightB.objectName + '').localeCompare(leftA.objectName + ''); + return sort === 1 ? + (`${leftA.objectName }`).localeCompare(`${rightB.objectName }`) : + (`${rightB.objectName }`).localeCompare(`${leftA.objectName }`); }); list.forEach(function (row) { if (row.children.length > 0) { @@ -412,7 +191,7 @@ export class TabPaneSummary extends BaseElement { getList(currentLeftItem.children); } - sortByLeftTable(column: string, sort: number) { + sortByLeftTable(column: string, sort: number): void { switch (sort) { case 0: if (this.search!.value === '') { @@ -429,53 +208,68 @@ export class TabPaneSummary extends BaseElement { } switch (column) { case 'distance': - this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { - return sort === 1 ? leftData.distance - rightData.distance : rightData.distance - leftData.distance; - }); - this.leftArray.forEach((currentLeftItem) => { - this.retainsTableByDistance(currentLeftItem, sort); - }); - this.tblSummary!.snapshotDataSource = this.leftArray; + this.sortLeftByDistanceColum(sort); break; case 'shallowSize': - this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { - return sort === 1 - ? leftData.shallowSize - rightData.shallowSize - : rightData.shallowSize - leftData.shallowSize; - }); - this.leftArray.forEach((currentLeftItem) => { - this.retainsTableByShallowSize(currentLeftItem, sort); - }); - this.tblSummary!.snapshotDataSource = this.leftArray; + this.sortLeftByShallowSizeColum(sort); break; case 'retainedSize': - this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { - return sort === 1 - ? leftData.retainedSize - rightData.retainedSize - : rightData.retainedSize - leftData.retainedSize; - }); - this.leftArray.forEach((currentLeftItem) => { - this.retainsTableByRetainedSize(currentLeftItem, sort); - }); - this.tblSummary!.snapshotDataSource = this.leftArray; + this.sortLeftByRetainedSizeColum(sort); break; case 'objectName': - this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { - return sort === 1 - ? (leftData.objectName + '').localeCompare(rightData.objectName + '') - : (rightData.objectName + '').localeCompare(leftData.objectName + ''); - }); - this.leftArray.forEach((currentLeftItem) => { - this.retainsTableByObjectName(currentLeftItem, sort); - }); - this.tblSummary!.snapshotDataSource = this.leftArray; + this.sortLeftByObjectNameColum(sort); break; } break; } } + private sortLeftByObjectNameColum(sort: number): void { + this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { + return sort === 1 ? + (`${leftData.objectName }`).localeCompare(`${rightData.objectName }`) : + (`${rightData.objectName }`).localeCompare(`${leftData.objectName }`); + }); + this.leftArray.forEach((currentLeftItem) => { + this.retainsTableByObjectName(currentLeftItem, sort); + }); + this.tblSummary!.snapshotDataSource = this.leftArray; + } + + private sortLeftByRetainedSizeColum(sort: number): void { + this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { + return sort === 1 ? + leftData.retainedSize - rightData.retainedSize : + rightData.retainedSize - leftData.retainedSize; + }); + this.leftArray.forEach((currentLeftItem) => { + this.retainsTableByRetainedSize(currentLeftItem, sort); + }); + this.tblSummary!.snapshotDataSource = this.leftArray; + } + + private sortLeftByShallowSizeColum(sort: number): void { + this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { + return sort === 1 ? + leftData.shallowSize - rightData.shallowSize : + rightData.shallowSize - leftData.shallowSize; + }); + this.leftArray.forEach((currentLeftItem) => { + this.retainsTableByShallowSize(currentLeftItem, sort); + }); + this.tblSummary!.snapshotDataSource = this.leftArray; + } + + private sortLeftByDistanceColum(sort: number): void { + this.tblSummary!.snapshotDataSource = this.leftArray.sort((leftData, rightData) => { + return sort === 1 ? leftData.distance - rightData.distance : rightData.distance - leftData.distance; + }); + this.leftArray.forEach((currentLeftItem) => { + this.retainsTableByDistance(currentLeftItem, sort); + }); + this.tblSummary!.snapshotDataSource = this.leftArray; + } - sortByRightTable(column: string, sort: number) { + sortByRightTable(column: string, sort: number): void { switch (sort) { case 0: this.tbs!.snapshotDataSource = this.retainsData; @@ -512,9 +306,9 @@ export class TabPaneSummary extends BaseElement { break; case 'objectName': this.tbs!.snapshotDataSource = this.rightArray.sort((a, b) => { - return sort === 1 - ? (a.objectName + '').localeCompare(b.objectName + '') - : (b.objectName + '').localeCompare(a.objectName + ''); + return sort === 1 ? + (`${a.objectName }`).localeCompare(`${b.objectName }`) : + (`${b.objectName }`).localeCompare(`${a.objectName }`); }); this.rightArray.forEach((list) => { this.retainsTableByObjectName(list, sort); @@ -526,13 +320,13 @@ export class TabPaneSummary extends BaseElement { } } - clickToggleTable() { - let lis = this.shadowRoot?.querySelectorAll('li') as any; + clickToggleTable(): void { + let lis = this.shadowRoot?.querySelectorAll('li'); let that = this; - lis.forEach((li: any, i: any) => { - lis[i].onclick = function () { - for (let i = 0; i < lis.length; i++) { - lis[i].className = ''; + lis!.forEach((li: HTMLElement, i: number) => { + lis![i].onclick = function (): void { + for (let i = 0; i < lis!.length; i++) { + lis![i].className = ''; } switch (li.textContent) { case 'Retainers': @@ -552,18 +346,20 @@ export class TabPaneSummary extends BaseElement { that.stackText!.textContent = ''; } else { that.stackText!.textContent = - 'Stack was not recorded for this object because it had been allocated before this profile recording started.'; + 'Stack was not recorded for this object because it had been allocated before ' + + 'this profile recording started.'; } } that.tbs!.style.display = 'none'; break; } + // @ts-ignore this.className = 'active'; }; }); } - classFilter() { + classFilter(): void { this.search!.addEventListener('keyup', () => { this.summaryFilter = []; this.summaryData.forEach((a) => { @@ -579,7 +375,7 @@ export class TabPaneSummary extends BaseElement { }); } - clear() { + clear(): void { this.tbs!.snapshotDataSource = []; this.stackTable!.recycleDataSource = []; this.retainsData = []; @@ -594,184 +390,294 @@ export class TabPaneSummary extends BaseElement { this.leftTheadTable!.removeAttribute('sort'); } - connectedCallback() { + connectedCallback(): void { super.connectedCallback(); let filterHeight = 0; - let parentWidth = this.parentElement!.clientWidth + 'px'; + let parentWidth = `${this.parentElement!.clientWidth }px`; let system = document .querySelector('body > sp-application') ?.shadowRoot?.querySelector('#app-content > sp-system-trace'); new ResizeObserver(() => { let summaryPaneFilter = this.shadowRoot!.querySelector('#filter') as HTMLElement; - if (summaryPaneFilter.clientHeight > 0) filterHeight = summaryPaneFilter.clientHeight; + if (summaryPaneFilter.clientHeight > 0) {filterHeight = summaryPaneFilter.clientHeight} if (this.parentElement!.clientHeight > filterHeight) { summaryPaneFilter.style.display = 'flex'; } else { summaryPaneFilter.style.display = 'none'; } - parentWidth = this.parentElement!.clientWidth + 'px'; + parentWidth = `${this.parentElement!.clientWidth }px`; this.tbs!.style.height = 'calc(100% - 30px)'; this.tbsTable!.style.width = `calc(${parentWidth} - ${this.leftTable!.style.width} - 5px)`; this.tbs!.reMeauseHeight(); this.tblSummary!.reMeauseHeight(); }).observe(this.parentElement!); new ResizeObserver(() => { - this.parentElement!.style.width = system!.clientWidth + 'px'; - this.style.width = system!.clientWidth + 'px'; + this.parentElement!.style.width = `${system!.clientWidth }px`; + this.style.width = `${system!.clientWidth }px`; }).observe(system!); new ResizeObserver(() => { this.tbsTable!.style.width = `calc(${parentWidth} - ${this.leftTable!.style.width} - 5px)`; }).observe(this.leftTable!); + + this.tblSummary!.addEventListener('row-click', this.tblSummaryRowClick); + this.tbs!.addEventListener('row-click', this.tbsRowClick); + this.tblSummary!.addEventListener('icon-click', this.tblSummaryIconClick); + this.tbs!.addEventListener('icon-click', this.tbsIconClick); + this.tblSummary!.addEventListener('column-click', this.tblSummaryColumnClick); + this.tbs!.addEventListener('column-click', this.tblColumnClick); } - initHtml(): string { - return ` - -
      - - -
      - - - - - - - - - - - - - - -
      - -
      -
      -
      -
        -
      • Retainers
      • - -
      -
      - - - - - - - - - - - - - - - - -
      -
      -
      -
      - - -
      - `; + } + } + new ResizeObserver(() => { + this.tbs!.style.height = 'calc(100% - 30px)'; + this.tbs!.reMeauseHeight(); + this.stackTable!.style.height = 'calc(100% - 30px)'; + this.stackTable!.reMeauseHeight(); + }).observe(this.parentElement!); + // @ts-ignore + if ((evt.detail as any).callBack) { + // @ts-ignore + (evt.detail as any).callBack(true); + } + } + + initHtml(): string { + return TabPaneSummaryHtml; } } diff --git a/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts b/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts deleted file mode 100644 index 10050fa7f9a49613c7cb52b4a92b0604df1f99f9..0000000000000000000000000000000000000000 --- a/ide/src/trace/component/trace/sheet/binder/TabPaneBinderDataCut.ts +++ /dev/null @@ -1,803 +0,0 @@ -/* - * 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 { type LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; -import { Utils } from '../../base/Utils'; -import { type SelectionParam } from '../../../../bean/BoxSelection'; -import { - type BinderItem, - type BinderGroup, - type DataSource, - type FuncNameCycle, - type BinderDataStruct, -} from '../../../../bean/BinderProcessThread'; -import { querySingleFuncNameCycle, queryLoopFuncNameCycle } from '../../../../../trace/database/sql/Func.sql'; -import { queryBinderByThreadId } from '../../../../../trace/database/sql/ProcessThread.sql'; -import { resizeObserver } from '../SheetUtils'; -import { type LitChartColumn } from '../../../../../base-ui/chart/column/LitChartColumn'; -import '../../../../../base-ui/chart/column/LitChartColumn'; - -@element('tabpane-binder-datacut') -export class TabPaneBinderDataCut extends BaseElement { - private threadBindersCutTbl: LitTable | null | undefined; - private currentSelectionParam: SelectionParam | any; - private threadStatesDIV: Element | null | undefined; - private cycleARangeArr: BinderGroup[] | undefined; - private cycleBRangeArr: BinderGroup[] | undefined; - private cycleAStartRangeDIV: HTMLInputElement | null | undefined; - private cycleAEndRangeDIV: HTMLInputElement | null | undefined; - private cycleBStartRangeDIV: HTMLInputElement | null | undefined; - private cycleBEndRangeDIV: HTMLInputElement | null | undefined; - private chartTotal: LitChartColumn | null | undefined; - private dataSource: DataSource[] | undefined; - private rowCycleData: BinderGroup[] | undefined; - private funcNameCycleArr: FuncNameCycle[] | undefined; - private cacheBinderArr: BinderGroup[] | undefined; - private currentThreadId: string | undefined; - - set data(threadStatesParam: SelectionParam | any) { - let threadIdDIV = this.shadowRoot!.querySelector('.thread-id-input') as HTMLElement; - threadIdDIV.style.border = '1px solid rgb(151,151,151)'; - let cycleNameDIV = this.shadowRoot!.querySelector('.cycle-name-input') as HTMLElement; - cycleNameDIV.style.border = '1px solid rgb(151,151,151)'; - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.dispalyQueryArea(true); - this.clickLoop(false); - this.clickSingle(false); - this.currentSelectionParam = threadStatesParam; - this.threadBindersCutTbl!.recycleDataSource = []; - this.tHeadClick(this.threadBindersCutTbl!.recycleDataSource); - } - - dispalyQueryArea(b: boolean): void { - if (b) { - this.setAttribute('dispalyQueryArea', ''); - } else { - this.removeAttribute('dispalyQueryArea'); - } - } - - clickSingle(b: boolean): void { - if (b) { - this.setAttribute('clickSingle', ''); - } else { - this.removeAttribute('clickSingle'); - } - } - - clickLoop(b: boolean): void { - if (b) { - this.setAttribute('clickLoop', ''); - } else { - this.removeAttribute('clickLoop'); - } - } - - async dataLoopCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement): Promise { - this.threadBindersCutTbl!.loading = true; - this.currentThreadId = ''; - let threadIds: number[] = this.currentSelectionParam.threadIds; - //@ts-ignore - let processIds: number[] = [...new Set(this.currentSelectionParam.processIds)]; - let threadIdValue: string = threadId.value.trim(); - let threadFuncName: string = threadFunc.value.trim(); - let leftNS: number = this.currentSelectionParam.leftNs; - let rightNS: number = this.currentSelectionParam.rightNs; - if (threadIdValue !== '' && threadFuncName !== '') { - this.clickLoop(true); - this.clickSingle(false); - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - this.funcNameCycleArr = await queryLoopFuncNameCycle(threadFuncName, threadIdValue, leftNS, rightNS); - let binderItemArr: BinderItem[] = await queryBinderByThreadId(processIds, threadIds, leftNS, rightNS); - if (this.funcNameCycleArr.length !== 0) { - let binderCutArr: BinderItem[] = []; - for (let j: number = 0; j < this.funcNameCycleArr.length - 1; j++) { - this.funcNameCycleArr[j].cycleDur = - this.funcNameCycleArr[j + 1].cycleStartTime - this.funcNameCycleArr[j].cycleStartTime; - for (let i: number = 0; i < binderItemArr.length; i++) { - if ( - binderItemArr[i].ts > this.funcNameCycleArr[j].cycleStartTime && - binderItemArr[i].ts + binderItemArr[i].dur < this.funcNameCycleArr[j + 1].cycleStartTime - ) { - // calculate cycle duration - binderItemArr[i].cycleDur = - this.funcNameCycleArr[j + 1].cycleStartTime - this.funcNameCycleArr[j].cycleStartTime; - binderItemArr[i].cycleStartTime = this.funcNameCycleArr[j].cycleStartTime; - binderItemArr[i].funcName = this.funcNameCycleArr[j].funcName; - binderItemArr[i].id = this.funcNameCycleArr[j].id; - binderItemArr[i].thread = Utils.THREAD_MAP.get(binderItemArr[i].tid) || 'Thread'; - binderItemArr[i].process = Utils.PROCESS_MAP.get(binderItemArr[i].pid) || 'Process'; - binderCutArr.push(binderItemArr[i]); - } - } - } - let finalBinderCutArr: BinderItem[] = this.completionCycleName(binderCutArr, 'loop'); - this.threadBindersCutTbl!.recycleDataSource = this.transferToTreeData(finalBinderCutArr); - this.threadBindersCutTbl!.loading = false; - this.tHeadClick(this.threadBindersCutTbl!.recycleDataSource); - } else { - this.clearTableData(); - } - } else { - this.verifyInputIsEmpty(threadIdValue, threadFuncName, threadId, threadFunc); - } - } - - async dataSingleCut(threadId: HTMLInputElement, threadFunc: HTMLInputElement): Promise { - this.threadBindersCutTbl!.loading = true; - this.currentThreadId = ''; - let threadIds: number[] = this.currentSelectionParam.threadIds; - //@ts-ignore - let processIds: number[] = [...new Set(this.currentSelectionParam.processIds)]; - let threadIdValue: string = threadId.value.trim(); - let threadFuncName: string = threadFunc.value.trim(); - let leftNS: number = this.currentSelectionParam.leftNs; - let rightNS: number = this.currentSelectionParam.rightNs; - if (threadIdValue !== '' && threadFuncName !== '') { - this.clickLoop(false); - this.clickSingle(true); - threadId.style.border = '1px solid rgb(151,151,151)'; - threadFunc.style.border = '1px solid rgb(151,151,151)'; - this.funcNameCycleArr = await querySingleFuncNameCycle(threadFuncName, threadIdValue, leftNS, rightNS); - let binderItemArr: BinderItem[] = await queryBinderByThreadId(processIds, threadIds, leftNS, rightNS); - if (this.funcNameCycleArr.length !== 0) { - let binderCutArr: BinderItem[] = []; - for (let j: number = 0; j < this.funcNameCycleArr.length; j++) { - for (let i: number = 0; i < binderItemArr.length; i++) { - if ( - binderItemArr[i].ts > this.funcNameCycleArr[j].cycleStartTime && - binderItemArr[i].ts + binderItemArr[i].dur < - this.funcNameCycleArr[j].cycleStartTime + this.funcNameCycleArr[j]!.cycleDur - ) { - binderItemArr[i].cycleDur = this.funcNameCycleArr[j].cycleDur; - binderItemArr[i].cycleStartTime = this.funcNameCycleArr[j].cycleStartTime; - binderItemArr[i].funcName = this.funcNameCycleArr[j].funcName; - binderItemArr[i].id = this.funcNameCycleArr[j].id; - binderItemArr[i].thread = Utils.THREAD_MAP.get(binderItemArr[i].tid) || 'Thread'; - binderItemArr[i].process = Utils.PROCESS_MAP.get(binderItemArr[i].pid) || 'Process'; - binderItemArr[i].count = 1; - binderCutArr.push(binderItemArr[i]); - } - } - } - let finalBinderCutArr: BinderItem[] = this.completionCycleName(binderCutArr, 'single'); - this.threadBindersCutTbl!.recycleDataSource = this.transferToTreeData(finalBinderCutArr); - this.threadBindersCutTbl!.loading = false; - this.tHeadClick(this.threadBindersCutTbl!.recycleDataSource); - } else { - this.clearTableData(); - } - } else { - this.verifyInputIsEmpty(threadIdValue, threadFuncName, threadId, threadFunc); - } - } - - clearTableData(): void { - this.threadBindersCutTbl!.recycleDataSource = []; - this.threadBindersCutTbl!.loading = false; - this.tHeadClick(this.threadBindersCutTbl!.recycleDataSource); - } - - verifyInputIsEmpty( - threadIdValue: string, - threadFuncName: string, - threadId: HTMLInputElement, - threadFunc: HTMLInputElement - ): void { - if (threadIdValue === '') { - threadId.style.border = '1px solid rgb(255,0,0)'; - threadId.setAttribute('placeholder', 'Please input thread id'); - this.clearTableData(); - } else { - threadId.style.border = '1px solid rgb(151,151,151)'; - } - - if (threadFuncName === '') { - threadFunc.style.border = '1px solid rgb(255,0,0)'; - threadFunc.setAttribute('placeholder', 'Please input function name'); - this.clearTableData(); - } else { - threadFunc.style.border = '1px solid rgb(151,151,151)'; - } - } - - completionCycleName(binderCutArr: BinderItem[], type: string): BinderItem[] { - let threadIds: number[] = this.currentSelectionParam.threadIds; - let threadBinderCutArr: BinderItem[][] = []; - let childThreadbinderCutArr: BinderItem[] = []; - threadIds.forEach((tid: number) => { - childThreadbinderCutArr = []; - binderCutArr.forEach((binder: BinderItem) => { - if (binder.tid === tid) { - childThreadbinderCutArr.push(binder); - } - }); - if (childThreadbinderCutArr.length > 0) { - threadBinderCutArr.push(childThreadbinderCutArr); - } - }); - // loop data cut need delete last function Name cycle data - if (type === 'loop') { - this.funcNameCycleArr?.pop(); - } - let cloneThreadBinderCutArr: BinderItem[][] = JSON.parse(JSON.stringify(threadBinderCutArr)); - let threadBinderContainsFuncIdArr: number[] = []; - threadBinderCutArr.forEach((binderArr: BinderItem[], idx: number) => { - binderArr.forEach((binder: BinderItem) => { - if (!threadBinderContainsFuncIdArr.includes(binder.id!)) { - threadBinderContainsFuncIdArr.push(binder.id!); - } - }); - // When the cycle data is incomplete - if (this.funcNameCycleArr!.length !== threadBinderContainsFuncIdArr.length) { - this.completionAllFname(threadBinderContainsFuncIdArr, idx, cloneThreadBinderCutArr); - } - threadBinderContainsFuncIdArr = []; - }); - cloneThreadBinderCutArr.forEach((arr: BinderItem[]) => arr.sort(this.compare('id'))); - return cloneThreadBinderCutArr.flat(); - } - - completionAllFname(binderContainsFuncIdArr: number[], idx: number, cloneThreadBinderCutArr: BinderItem[][]): void { - this.funcNameCycleArr!.forEach((it: FuncNameCycle) => { - if (!binderContainsFuncIdArr.includes(it.id)) { - let itemData = cloneThreadBinderCutArr[idx][0]; - let item: BinderItem = { - title: '', - count: 0, - totalCount: 0, - cycleDur: it.cycleDur, - cycleStartTime: it.cycleStartTime, - id: it.id, - name: '', - pid: itemData.pid, - process: itemData.process!, - thread: itemData.thread!, - tid: itemData.tid, - idx: 0, - ts: 0, - dur: 0, - startTime: 0, - endTime: 0, - }; - cloneThreadBinderCutArr[idx].push(item); - } - }); - } - - compare(prop: string) { - return function (obj1: any, obj2: any) { - let val1 = obj1[prop]; - let val2 = obj2[prop]; - if (val1 < val2) { - return -1; - } else if (val1 > val2) { - return 1; - } else { - return 0; - } - }; - } - - transferToTreeData(binderList: Array): Array { - let group: any = {}; - binderList.forEach((it: BinderItem) => { - let cycleItem = { - title: it.thread + ' ' + '[' + it.tid + ']' + '[' + it.id + ']', - totalCount: it.count, - binderTransactionCount: it.name === 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name === 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name === 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name === 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid, - thread: it.thread, - cycleDur: it.cycleDur || 0, - cycleStartTime: it.cycleStartTime, - type: 'cycle', - }; - if (group[`${it.pid}`]) { - let process = group[`${it.pid}`]; - process.totalCount += it.count; - let thread = process.children.find((child: BinderGroup) => child.title === it.thread + ' ' + '[' + it.tid + ']'); - if (thread) { - thread.totalCount += it.count; - let cycle = thread.children.find((child: BinderGroup) => child.title === it.thread + ' ' + '[' + it.tid + ']' + '[' + it.id + ']'); - if (cycle) { - cycle.totalCount += it.count; - cycle.binderTransactionCount += it.name === 'binder transaction' ? it.count : 0; - cycle.binderAsyncRcvCount += it.name === 'binder async rcv' ? it.count : 0; - cycle.binderReplyCount += it.name === 'binder reply' ? it.count : 0; - cycle.binderTransactionAsyncCount += it.name === 'binder transaction async' ? it.count : 0; - } else { - thread.children.push(cycleItem); - } - } else { - process.children.push({ - title: it.thread + ' ' + '[' + it.tid + ']', - totalCount: it.count, - tid: it.tid, - pid: it.pid, - type: 'thread', - children: [cycleItem], - }); - } - } else { - group[`${it.pid}`] = { - title: it.process + ' ' + '[' + it.pid + ']', - totalCount: it.count, - type: 'process', - children: [ - { - title: it.thread + ' ' + '[' + it.tid + ']', - totalCount: it.count, - tid: it.tid, - pid: it.pid, - type: 'thread', - children: [cycleItem], - }, - ], - }; - } - }); - this.cacheBinderArr = JSON.parse(JSON.stringify(this.addCycleNumber(Object.values(group)))); - let groupArr: Array = this.timeUnitConversion(Object.values(group)); - return groupArr; - } - - addCycleNumber(groupArr: Array): Array { - for (let i = 0; i < groupArr.length; i++) { - if (groupArr[i].type === 'cycle') { - - groupArr[i].title = 'cycle ' + (i + 1) + '_' + groupArr[i].thread; - groupArr[i].idx = i + 1; - } else { - this.addCycleNumber(groupArr[i].children!); - } - } - return groupArr; - } - - timeUnitConversion(groupArr: Array): Array { - for (let i = 0; i < groupArr.length; i++) { - if (groupArr[i].type === 'cycle') { - groupArr[i].cycleDur = Number((groupArr[i].cycleDur / 1000000).toFixed(3)); - groupArr[i].cycleStartTime = Number((groupArr[i].cycleStartTime / 1000000).toFixed(3)); - } else { - this.timeUnitConversion(groupArr[i].children!); - } - } - return groupArr; - } - - private tHeadClick(data: Array): void { - let labels = this.threadBindersCutTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process')) { - this.threadBindersCutTbl!.setStatus(data, false); - this.threadBindersCutTbl!.recycleDs = this.threadBindersCutTbl!.meauseTreeRowElement( - data, - RedrawTreeForm.Retract - ); - } else if (label.includes('Thread')) { - for (let item of data) { - item.status = true; - if (item.children != undefined && item.children.length > 0) { - this.threadBindersCutTbl!.setStatus(item.children, false); - } - } - this.threadBindersCutTbl!.recycleDs = this.threadBindersCutTbl!.meauseTreeRowElement( - data, - RedrawTreeForm.Retract - ); - } else if (label.includes('Cycle')) { - this.threadBindersCutTbl!.setStatus(data, true); - this.threadBindersCutTbl!.recycleDs = this.threadBindersCutTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } - } - } - - binderWithCountList(rowCycleData: BinderGroup[]): Array { - let binderWithCountList: Array = []; - rowCycleData.forEach((it) => { - if (it.totalCount !== 0) { - let cycleDataArr: BinderDataStruct[] = []; - if (it.binderTransactionCount !== 0) { - cycleDataArr.push({ - name: 'binder transaction', - count: it.binderTransactionCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx, - }); - } - if (it.binderTransactionAsyncCount !== 0) { - cycleDataArr.push({ - name: 'binder transaction async', - count: it.binderTransactionAsyncCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx, - }); - } - if (it.binderReplyCount !== 0) { - cycleDataArr.push({ - name: 'binder reply', - count: it.binderReplyCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx, - }); - } - if (it.binderAsyncRcvCount !== 0) { - cycleDataArr.push({ - name: 'binder async rcv', - count: it.binderAsyncRcvCount!, - dur: it.cycleDur, - startNS: it.cycleStartTime, - idx: it.idx, - }); - } - binderWithCountList.push(cycleDataArr); - } - }); - return binderWithCountList; - } - - findThreadByThreadId(groupArr: Array, threadId: number): BinderGroup[] { - let currentSelectThread: BinderGroup[] = []; - groupArr.forEach((p: BinderGroup) => { - p.children?.forEach((th: BinderGroup) => { - if (th.tid === threadId) { - currentSelectThread = th.children!; - } - }); - }); - return currentSelectThread; - } - - rowClickFunc(): void { - this.threadBindersCutTbl!.addEventListener('row-click', (evt: any) => { - let currentData: BinderGroup = evt.detail.data; - if (currentData.type === 'thread') { - this.currentThreadId = currentData.tid + '' + currentData.pid; - this.clearCycleRange(); - currentData.isSelected = true; - this.threadBindersCutTbl!.clearAllSelection(currentData); - this.threadBindersCutTbl!.setCurrentSelection(currentData); - this.rowCycleData = currentData.children; - this.dispalyQueryArea(false); - let totalCount = currentData.totalCount; - this.dataSource = []; - this.dataSource.push({ - xName: 'Total', - yAverage: totalCount > 0 ? Math.ceil(totalCount / this.rowCycleData!.length) : 0, - }); - if (this.dataSource!.length > 0) { - this.drawColumn(); - } - } - - if (currentData.type === 'cycle' && currentData.tid + '' + currentData.pid === this.currentThreadId) { - currentData.isSelected = true; - this.threadBindersCutTbl!.clearAllSelection(currentData); - this.threadBindersCutTbl!.setCurrentSelection(currentData); - } - }); - } - - queryBtnFunc(): void { - this.shadowRoot?.querySelector('#query-btn')?.addEventListener('click', () => { - this.cycleARangeArr = this.rowCycleData?.filter((it: BinderGroup) => { - return ( - it.cycleDur >= Number(this.cycleAStartRangeDIV!.value) && it.cycleDur < Number(this.cycleAEndRangeDIV!.value) - ); - }); - this.cycleBRangeArr = this.rowCycleData?.filter((it: BinderGroup) => { - return ( - it.cycleDur >= Number(this.cycleBStartRangeDIV!.value) && it.cycleDur < Number(this.cycleBEndRangeDIV!.value) - ); - }); - let cycleACount: number = 0; - this.cycleARangeArr?.forEach((it: BinderGroup) => { - cycleACount += it.totalCount; - }); - let cycleBCount: number = 0; - this.cycleBRangeArr?.forEach((it: BinderGroup) => { - cycleBCount += it.totalCount; - }); - this.dataSource!.length > 1 && this.dataSource?.splice(1); - this.dataSource!.push({ - xName: 'cycleA', - yAverage: cycleACount !== 0 ? Math.ceil(cycleACount / this.cycleARangeArr!.length) : 0, - }); - this.dataSource!.push({ - xName: 'cycleB', - yAverage: cycleBCount !== 0 ? Math.ceil(cycleBCount / this.cycleBRangeArr!.length) : 0, - }); - if (this.dataSource!.length !== 0) { - this.drawColumn(); - } - }); - } - - initElements(): void { - this.threadBindersCutTbl = this.shadowRoot?.querySelector('#tb-binder-count'); - this.chartTotal = this.shadowRoot!.querySelector('#chart_cycle'); - this.cycleAStartRangeDIV = this.shadowRoot?.querySelector('#cycle-a-start-range'); - this.cycleAEndRangeDIV = this.shadowRoot?.querySelector('#cycle-a-end-range'); - this.cycleBStartRangeDIV = this.shadowRoot?.querySelector('#cycle-b-start-range'); - this.cycleBEndRangeDIV = this.shadowRoot?.querySelector('#cycle-b-end-range'); - - this.threadStatesDIV = this.shadowRoot!.querySelector('#dataCut'); - this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { - this.dispalyQueryArea(true); - this.dataSource = []; - // @ts-ignore - this.dataSingleCut(this.threadStatesDIV!.children[0], this.threadStatesDIV?.children[1]); - }); - this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { - this.dispalyQueryArea(true); - this.dataSource = []; - // @ts-ignore - this.dataLoopCut(this.threadStatesDIV?.children[0], this.threadStatesDIV?.children[1]); - }); - this.rowClickFunc(); - this.queryBtnFunc(); - } - - clearCycleRange(): void { - this.cycleAStartRangeDIV!.value = ''; - this.cycleAEndRangeDIV!.value = ''; - this.cycleBStartRangeDIV!.value = ''; - this.cycleBEndRangeDIV!.value = ''; - } - - drawColumn(): void { - this.chartTotal!.dataSource = this.dataSource!; - this.chartTotal!.config = { - data: this.dataSource!, - appendPadding: 10, - xField: 'xName', - yField: 'yAverage', - seriesField: '', - removeUnit: true, - notSort: true, - color: (a) => { - if (a.xName === 'Total') { - return '#2f72f8'; - } else if (a.xName === 'cycleA') { - return '#ffab67'; - } else if (a.xName === 'cycleB') { - return '#a285d2'; - } else { - return '#0a59f7'; - } - }, - tip: (a) => { - if (a && a[0]) { - let tip: string = ''; - tip = `
      -
      Average count: ${a[0].obj.yAverage}
      -
      `; - return tip; - } else { - return ''; - } - }, - label: null, - }; - } - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadBindersCutTbl!); - } - - initHtml(): string { - return ` - -
      - - -
      - - -
      -
      -
      - -
      - - - - - - - - - - - - - - - - - - -
      - -
      -
      -
      - Cycle A: - - ~ - -
      -
      -
      - Cycle B: - - ~ - -
      -
      - -
      -
      -
      -
      -
      Average Binder Count
      - -
      -
      Total
      -
      CycleA
      -
      CycleB
      -
      -
      -
      -
      -
      - `; - } -} diff --git a/ide/src/trace/component/trace/sheet/binder/TabPaneBinders.ts b/ide/src/trace/component/trace/sheet/binder/TabPaneBinders.ts deleted file mode 100644 index aee1c856f38e83c6b19cbb595998f0bc4cd46b17..0000000000000000000000000000000000000000 --- a/ide/src/trace/component/trace/sheet/binder/TabPaneBinders.ts +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2023 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, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; -import { SelectionData, SelectionParam } from '../../../../bean/BoxSelection'; -import '../../../StackBar'; -import { queryBinderByThreadId } from '../../../../database/sql/ProcessThread.sql'; -import { Utils } from '../../base/Utils'; -import { resizeObserver } from '../SheetUtils'; -import { BinderGroup, BinderItem } from '../../../../bean/BinderProcessThread'; - -@element('tabpane-binders') -export class TabPaneBinders extends BaseElement { - private threadBindersTbl: LitTable | null | undefined; - private threadBindersTblSource: Array = []; - private currentSelectionParam: Selection | undefined; - - set data(threadStatesParam: SelectionParam | any) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.threadBindersTbl!.loading = true; - this.currentSelectionParam = threadStatesParam; - this.threadBindersTblSource = []; - this.threadBindersTbl!.recycleDataSource = []; - this.initBinderData(threadStatesParam); - } - - initBinderData(threadStatesParam: SelectionParam): void { - this.threadBindersTbl!.recycleDataSource = []; - let binderList: BinderItem[] = []; - let threadIds = threadStatesParam.threadIds; - let processIds: number[] = [...new Set(threadStatesParam.processIds)]; - queryBinderByThreadId(processIds, threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs).then((result) => { - if (result !== null && result.length > 0) { - binderList = result; - } - if (binderList.length > 0) { - this.threadBindersTbl!.recycleDataSource = this.transferToTreeData(binderList); - this.threadBindersTblSource = this.threadBindersTbl!.recycleDataSource; - this.threadBindersTbl!.loading = false; - this.threadBinderHeadClick(this.threadBindersTbl!.recycleDataSource); - } else if (binderList.length === 0) { - this.threadBindersTbl!.recycleDataSource = []; - this.threadBindersTblSource = []; - this.threadBindersTbl!.loading = false; - this.threadBinderHeadClick(this.threadBindersTbl!.recycleDataSource); - } - }); - } - - initElements(): void { - this.threadBindersTbl = this.shadowRoot?.querySelector('#tb-binder-count'); - this.threadBindersTbl!.itemTextHandleMap.set('title', Utils.transferBinderTitle); - } - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadBindersTbl!); - } - - transferToTreeData(binderList: BinderItem[]): BinderGroup[] { - let group: any = {}; - binderList.forEach((it: BinderItem) => { - if (group[`${it.pid}`]) { - let process = group[`${it.pid}`]; - process.totalCount += it.count; - let thread = process.children.find((child: BinderGroup) => child.title === `T-${it.tid}`); - if (thread) { - thread.totalCount += it.count; - thread.binderTransactionCount += it.name === 'binder transaction' ? it.count : 0; - thread.binderAsyncRcvCount += it.name === 'binder async rcv' ? it.count : 0; - thread.binderReplyCount += it.name === 'binder reply' ? it.count : 0; - thread.binderTransactionAsyncCount += it.name === 'binder transaction async' ? it.count : 0; - } else { - process.children.push({ - title: `T-${it.tid}`, - totalCount: it.count, - binderTransactionCount: it.name === 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name === 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name === 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name === 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid, - }); - } - } else { - group[`${it.pid}`] = { - title: `P-${it.pid}`, - totalCount: it.count, - tid: it.tid, - pid: it.pid, - children: [ - { - title: `T-${it.tid}`, - totalCount: it.count, - binderTransactionCount: it.name === 'binder transaction' ? it.count : 0, - binderAsyncRcvCount: it.name === 'binder async rcv' ? it.count : 0, - binderReplyCount: it.name === 'binder reply' ? it.count : 0, - binderTransactionAsyncCount: it.name === 'binder transaction async' ? it.count : 0, - tid: it.tid, - pid: it.pid, - }, - ], - }; - } - }); - return Object.values(group); - } - - private threadBinderHeadClick(data: Array): void { - let labels = this.threadBindersTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Process')) { - this.threadBindersTbl!.setStatus(data, false); - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement( - data, - RedrawTreeForm.Retract - ); - } else if (label.includes('Thread')) { - for (let item of data) { - item.status = true; - if (item.children !== undefined && item.children.length > 0) { - this.threadBindersTbl!.setStatus(item.children, false); - } - } - this.threadBindersTbl!.recycleDs = this.threadBindersTbl!.meauseTreeRowElement( - data, - RedrawTreeForm.Retract - ); - } - }); - } - } - } - - initHtml(): string { - return ` - - - - - - - - - - - - - - - - `; - } -} diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts index d666acc50dbb6a00b277890bff7aff8862977c35..1f10c3c5b79c9852f08eab80760fd00d59874379 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneBoxChild.ts @@ -28,8 +28,10 @@ export class TabPaneBoxChild extends BaseElement { private boxChildSource: Array = []; set data(boxChildValue: BoxJumpParam) { - // @ts-ignore - this.boxChildTbl?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 45 + 'px'; + if (this.boxChildTbl) { + // @ts-ignore + this.boxChildTbl.shadowRoot.querySelector('.table').style.height = this.parentElement!.clientHeight - 45 + 'px'; + } this.boxChildRange!.textContent = 'Selected range: ' + parseFloat(((boxChildValue.rightNs - boxChildValue.leftNs) / 1000000.0).toFixed(5)) + ' ms'; this.boxChildTbl!.recycleDataSource = []; @@ -67,12 +69,16 @@ export class TabPaneBoxChild extends BaseElement { e.note = '-'; }); this.boxChildSource = result; - // @ts-ignore - this.boxChildTbl?.recycleDataSource = result; + if (this.boxChildTbl) { + // @ts-ignore + this.boxChildTbl.recycleDataSource = result; + } } else { this.boxChildSource = []; - // @ts-ignore - this.boxChildTbl?.recycleDataSource = []; + if (this.boxChildTbl) { + // @ts-ignore + this.boxChildTbl.recycleDataSource = []; + } } }); } diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts index e7bec32f002ed7e29a2a4a73654c44fd0a9850e6..fa4d260d8b33b2d4a829ec3c2585cfeeb78bd712 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCounterSample.ts @@ -49,9 +49,11 @@ export class TabPaneCounterSample extends BaseElement { this.sampleProgressEL!.loading = true; this.counterLoadingPage.style.visibility = 'visible'; this.selectionParam = counterSampleValue; - // @ts-ignore - this.counterSampleTbl!.shadowRoot?.querySelector('.table').style.height = - this.parentElement!.clientHeight - 25 + 'px'; + if (this.counterSampleTbl) { + // @ts-ignore + this.counterSampleTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 25 + 'px'; + } this.queryDataByDB(counterSampleValue); } diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts index 491773edee0b966a7b819e601c517fba3a055b83..7e29ecad9f1f1523a89afaed4dfd53f2f681ca29 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByProcess.ts @@ -37,9 +37,11 @@ export class TabPaneCpuByProcess extends BaseElement { 'Selected range: ' + parseFloat(((cpuByProcessValue.rightNs - cpuByProcessValue.leftNs) / 1000000.0).toFixed(5)) + ' ms'; - // @ts-ignore - this.cpuByProcessTbl!.shadowRoot!.querySelector('.table')?.style?.height = - this.parentElement!.clientHeight - 50 + 'px'; + if (this.cpuByProcessTbl) { + // @ts-ignore + this.cpuByProcessTbl.shadowRoot!.querySelector('.table').style.height = + this.parentElement!.clientHeight - 50 + 'px'; + } this.cpuByProcessTbl!.recycleDataSource = []; this.cpuByProcessTbl!.loading = true; getTabCpuByProcess(cpuByProcessValue.cpus, cpuByProcessValue.leftNs, cpuByProcessValue.rightNs).then((result) => { diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts index d3bcce68b33511d63354d426a90969444e1ff806..8815f242cbd9bba3a2bf3e732036f04841e4b8df 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuByThread.ts @@ -57,64 +57,15 @@ export class TabPaneCpuByThread extends BaseElement { parseFloat(((cpuByThreadValue.rightNs - cpuByThreadValue.leftNs) / 1000000.0).toFixed(5)) + ' ms'; this.cpuByThreadTbl!.loading = true; + this.handleAsyncRequest(cpuByThreadValue); + } + + private handleAsyncRequest(cpuByThreadValue: any): void { getTabCpuByThread(cpuByThreadValue.cpus, cpuByThreadValue.leftNs, cpuByThreadValue.rightNs).then((result) => { this.cpuByThreadTbl!.loading = false; if (result != null && result.length > 0) { log('getTabCpuByThread size :' + result.length); - let sumWall = 0.0; - let sumOcc = 0; - let map: Map = new Map(); - for (let e of result) { - sumWall += e.wallDuration; - sumOcc += e.occurrences; - if (map.has(`${e.tid}`)) { - let thread = map.get(`${e.tid}`)!; - thread.wallDuration += e.wallDuration; - thread.occurrences += e.occurrences; - thread[`cpu${e.cpu}`] = e.wallDuration || 0; - thread[`cpu${e.cpu}TimeStr`] = getProbablyTime(e.wallDuration || 0); - thread[`cpu${e.cpu}Ratio`] = ( - (100.0 * (e.wallDuration || 0)) / - (cpuByThreadValue.rightNs - cpuByThreadValue.leftNs) - ).toFixed(2); - } else { - let process = Utils.PROCESS_MAP.get(e.pid); - let thread = Utils.THREAD_MAP.get(e.tid); - let cpuByThreadObject: any = { - tid: e.tid, - pid: e.pid, - thread: thread == null || thread.length == 0 ? '[NULL]' : thread, - process: process == null || process.length == 0 ? '[NULL]' : process, - wallDuration: e.wallDuration || 0, - occurrences: e.occurrences || 0, - avgDuration: 0, - }; - for (let i of cpuByThreadValue.cpus) { - cpuByThreadObject[`cpu${i}`] = 0; - cpuByThreadObject[`cpu${i}TimeStr`] = '0'; - cpuByThreadObject[`cpu${i}Ratio`] = '0'; - } - cpuByThreadObject[`cpu${e.cpu}`] = e.wallDuration || 0; - cpuByThreadObject[`cpu${e.cpu}TimeStr`] = getProbablyTime(e.wallDuration || 0); - cpuByThreadObject[`cpu${e.cpu}Ratio`] = ( - (100.0 * (e.wallDuration || 0)) / - (cpuByThreadValue.rightNs - cpuByThreadValue.leftNs) - ).toFixed(2); - map.set(`${e.tid}`, cpuByThreadObject); - } - } - let arr = Array.from(map.values()).sort((a, b) => b.wallDuration - a.wallDuration); - for (let e of arr) { - e.avgDuration = (e.wallDuration / (e.occurrences || 1.0) / 1000000.0).toFixed(5); - e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5)); - } - let count: any = {}; - count.process = ' '; - count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(7)); - count.occurrences = sumOcc; - arr.splice(0, 0, count); - this.cpuByThreadSource = arr; - this.cpuByThreadTbl!.recycleDataSource = arr; + this.processResult(result, cpuByThreadValue); } else { this.cpuByThreadSource = []; this.cpuByThreadTbl!.recycleDataSource = this.cpuByThreadSource; @@ -122,6 +73,67 @@ export class TabPaneCpuByThread extends BaseElement { }); } + private processResult(result: Array, cpuByThreadValue: any): void { + let sumWall = 0.0; + let sumOcc = 0; + let map: Map = new Map(); + for (let e of result) { + sumWall += e.wallDuration; + sumOcc += e.occurrences; + if (map.has(`${e.tid}`)) { + let thread = map.get(`${e.tid}`)!; + thread.wallDuration += e.wallDuration; + thread.occurrences += e.occurrences; + thread[`cpu${e.cpu}`] = e.wallDuration || 0; + thread[`cpu${e.cpu}TimeStr`] = getProbablyTime(e.wallDuration || 0); + thread[`cpu${e.cpu}Ratio`] = ( + (100.0 * (e.wallDuration || 0)) / + (cpuByThreadValue.rightNs - cpuByThreadValue.leftNs) + ).toFixed(2); + } else { + let process = Utils.PROCESS_MAP.get(e.pid); + let thread = Utils.THREAD_MAP.get(e.tid); + let cpuByThreadObject: any = { + tid: e.tid, + pid: e.pid, + thread: thread == null || thread.length == 0 ? '[NULL]' : thread, + process: process == null || process.length == 0 ? '[NULL]' : process, + wallDuration: e.wallDuration || 0, + occurrences: e.occurrences || 0, + avgDuration: 0, + }; + for (let i of cpuByThreadValue.cpus) { + cpuByThreadObject[`cpu${i}`] = 0; + cpuByThreadObject[`cpu${i}TimeStr`] = '0'; + cpuByThreadObject[`cpu${i}Ratio`] = '0'; + } + cpuByThreadObject[`cpu${e.cpu}`] = e.wallDuration || 0; + cpuByThreadObject[`cpu${e.cpu}TimeStr`] = getProbablyTime(e.wallDuration || 0); + cpuByThreadObject[`cpu${e.cpu}Ratio`] = ( + (100.0 * (e.wallDuration || 0)) / + (cpuByThreadValue.rightNs - cpuByThreadValue.leftNs) + ).toFixed(2); + map.set(`${e.tid}`, cpuByThreadObject); + } + } + this.calculateCount(map, sumWall, sumOcc); + } + + private calculateCount(map: Map, sumWall: number, sumOcc: number): void { + let arr = Array.from(map.values()).sort((a, b) => b.wallDuration - a.wallDuration); + for (let e of arr) { + e.avgDuration = (e.wallDuration / (e.occurrences || 1.0) / 1000000.0).toFixed(5); + e.wallDuration = parseFloat((e.wallDuration / 1000000.0).toFixed(5)); + } + let count: any = {}; + count.process = ' '; + count.wallDuration = parseFloat((sumWall / 1000000.0).toFixed(7)); + count.occurrences = sumOcc; + arr.splice(0, 0, count); + this.cpuByThreadSource = arr; + this.cpuByThreadTbl!.recycleDataSource = arr; + } + getTableColumns(cpus: Array) { let cpuByThreadTblHtml = `${this.pubColumns}`; let cpuByThreadList = cpus.sort((cpuByThreadA, cpuByThreadB) => cpuByThreadA - cpuByThreadB); diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts index 8d0dca7a5e9a8d8e7abd4f5212c19b030c6d8b7f..7dc39f7ad48a85405ea40f13bb3503df5364c892 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneCpuUsage.ts @@ -57,30 +57,7 @@ export class TabPaneCpuUsage extends BaseElement { usage.usage = 1; } usage.usageStr = (usage.usage * 100.0).toFixed(2) + '%'; - let arr = []; - if (freqMap.has(usage.cpu)) { - let freqList = freqMap.get(usage.cpu); - let list = []; - for (let i = 0; i < freqList!.length; i++) { - let freq = freqList![i]; - if (i == freqList!.length - 1) { - freq.dur = cpuUsageValue.rightNs - freq.startNs; - } else { - freq.dur = freqList![i + 1].startNs - freq.startNs; - } - if (freq.startNs + freq.dur > cpuUsageValue.leftNs) { - list.push(freq); - } - } - if (list.length > 0) { - if (list[0].startNs < cpuUsageValue.leftNs) { - list[0].dur = list[0].startNs + list[0].dur - cpuUsageValue.leftNs; - list[0].startNs = cpuUsageValue.leftNs; - } - } - arr = this.sortFreq(list); - this.getFreqTop3(usage, arr[0], arr[1], arr[2], range); - } + this.handleUsage(freqMap, usage, cpuUsageValue, range); data.push(usage); } this.cpuUsageTbl!.recycleDataSource = data; @@ -88,6 +65,33 @@ export class TabPaneCpuUsage extends BaseElement { }); } + private handleUsage(freqMap: Map>, usage: CpuUsage, cpuUsageValue: any, range: number): void { + let arr = []; + if (freqMap.has(usage.cpu)) { + let freqList = freqMap.get(usage.cpu); + let list = []; + for (let i = 0; i < freqList!.length; i++) { + let freq = freqList![i]; + if (i == freqList!.length - 1) { + freq.dur = cpuUsageValue.rightNs - freq.startNs; + } else { + freq.dur = freqList![i + 1].startNs - freq.startNs; + } + if (freq.startNs + freq.dur > cpuUsageValue.leftNs) { + list.push(freq); + } + } + if (list.length > 0) { + if (list[0].startNs < cpuUsageValue.leftNs) { + list[0].dur = list[0].startNs + list[0].dur - cpuUsageValue.leftNs; + list[0].startNs = cpuUsageValue.leftNs; + } + } + arr = this.sortFreq(list); + this.getFreqTop3(usage, arr[0], arr[1], arr[2], range); + } + } + initElements(): void { this.cpuUsageTbl = this.shadowRoot?.querySelector('#tb-cpu-usage'); this.range = this.shadowRoot?.querySelector('#time-range'); diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts index 81391bb5630c1c93c24a69d256f78b8820858948..f12c6c564ea98ebb626ea2495b638d27a7f9aa1f 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneFrequencySample.ts @@ -46,9 +46,11 @@ export class TabPaneFrequencySample extends BaseElement { return; } this.selectionParam = frequencySampleValue; - // @ts-ignore - this.frequencySampleTbl!.shadowRoot?.querySelector('.table').style.height = - this.parentElement!.clientHeight - 25 + 'px'; + if (this.frequencySampleTbl) { + // @ts-ignore + this.frequencySampleTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 25 + 'px'; + } this.queryDataByDB(frequencySampleValue); } @@ -123,19 +125,24 @@ export class TabPaneFrequencySample extends BaseElement { } } } - let s = CpuFreqStruct.maxFreqName; - let textMetrics = context.measureText(s); - context.globalAlpha = 0.8; - context.fillStyle = '#f0f0f0'; - context.fillRect(0, 5, textMetrics.width + 8, 18); - context.globalAlpha = 1; - context.fillStyle = '#333'; - context.textBaseline = 'middle'; - context.fillText(s, 4, 5 + 9); - row.canvasRestore(context, this.systemTrace); + this.metricsText(context, row); } } } + + private metricsText(context: CanvasRenderingContext2D, row: TraceRow): void { + let s = CpuFreqStruct.maxFreqName; + let textMetrics = context.measureText(s); + context.globalAlpha = 0.8; + context.fillStyle = '#f0f0f0'; + context.fillRect(0, 5, textMetrics.width + 8, 18); + context.globalAlpha = 1; + context.fillStyle = '#333'; + context.textBaseline = 'middle'; + context.fillText(s, 4, 5 + 9); + row.canvasRestore(context, this.systemTrace); + } + connectedCallback() { super.connectedCallback(); resizeObserver(this.parentElement!, this.frequencySampleTbl!, 25, this.frequencyLoadingPage, 24); @@ -313,8 +320,8 @@ export class TabPaneFrequencySample extends BaseElement { return ` diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts index 8ac72012d938806eabda9c6adf2e756b85ed1cb3..89530f8331902fdc0408a088fbb4b17c2417dbcd 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneSPT.ts @@ -32,8 +32,10 @@ export class TabPaneSPT extends BaseElement { return; } this.selectionParam = sptValue; - // @ts-ignore - this.sptTbl?.shadowRoot?.querySelector('.table').style.height = this.parentElement!.clientHeight - 45 + 'px'; + if (this.sptTbl) { + // @ts-ignore + this.sptTbl.shadowRoot.querySelector('.table').style.height = this.parentElement!.clientHeight - 45 + 'px'; + } this.range!.textContent = 'Selected range: ' + parseFloat(((sptValue.rightNs - sptValue.leftNs) / 1000000.0).toFixed(5)) + ' ms'; this.getDataBySPT(sptValue.leftNs, sptValue.rightNs, sptValue.cpus); @@ -95,9 +97,9 @@ export class TabPaneSPT extends BaseElement { return ` diff --git a/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts b/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts index 27b43335da57758e590d33b3470e11d5dfa812e1..bee85024041ce9c97e6ca3f508c3d09422fa1bb5 100644 --- a/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts +++ b/ide/src/trace/component/trace/sheet/cpu/TabPaneSchedPriority.ts @@ -34,8 +34,10 @@ export class TabPaneSchedPriority extends BaseElement { return; } this.selectionParam = sptValue; - // @ts-ignore - this.sptTbl?.shadowRoot?.querySelector('.table').style.height = this.parentElement!.clientHeight - 45 + 'px'; + if (this.priorityTbl) { + // @ts-ignore + this.priorityTbl.shadowRoot.querySelector('.table').style.height = this.parentElement!.clientHeight - 45 + 'px'; + } this.range!.textContent = 'Selected range: ' + parseFloat(((sptValue.rightNs - sptValue.leftNs) / 1000000.0).toFixed(5)) + ' ms'; this.queryDataByDB(sptValue); @@ -54,16 +56,9 @@ export class TabPaneSchedPriority extends BaseElement { private async queryDataByDB(sptParam: SelectionParam | any): Promise { this.priorityTbl!.loading = true; const resultData: Array = []; - if (this.strValueMap.size === 0) { - await queryThreadStateArgsByName('next_info').then((value) => { - for (const item of value) { - this.strValueMap.set(item.argset, item.strValue); - } - }); - } + await this.fetchAndProcessData(); const filterList = ['0', '0x0']; //next_info第2字段不为0 || next_info第3字段不为0 - // 通过priority与next_info结合判断优先级等级 function setPriority(item: Priority, strArg: string[]) { if (item.priority >= 0 && item.priority <= 88) { @@ -95,41 +90,74 @@ export class TabPaneSchedPriority extends BaseElement { if (item.cpu === null || !sptParam.cpus.includes(item.cpu)) { continue; } - - let strArg: string[] = []; - const args = this.strValueMap.get(item.argSetID); - if (args) { - strArg = args!.split(','); - } - - const slice = Utils.SCHED_SLICE_MAP.get(`${item.itId}-${item.startTs}`); - if (slice) { - const runningPriority = new Priority(); - runningPriority.priority = slice.priority; - runningPriority.state = 'Running'; - runningPriority.dur = item.dur; - setPriority(runningPriority, strArg); - resultData.push(runningPriority); - - const runnableItem = runnableMap.get(`${item.itId}_${item.startTs}`); - if (runnableItem) { - const runnablePriority = new Priority(); - runnablePriority.priority = slice.priority; - runnablePriority.state = 'Runnable'; - runnablePriority.dur = runnableItem.dur; - setPriority(runnablePriority, strArg); - resultData.push(runnablePriority); - } - } + this.fetchData(item, setPriority, resultData, runnableMap); } this.getDataByPriority(resultData); } ); } + private fetchData(item: any, setPriority: (item: Priority, strArg: string[]) => void, + resultData: Array, runnableMap: Map) { + let strArg: string[] = []; + const args = this.strValueMap.get(item.argSetID); + if (args) { + strArg = args!.split(','); + } + const slice = Utils.SCHED_SLICE_MAP.get(`${item.itId}-${item.startTs}`); + if (slice) { + const runningPriority = new Priority(); + runningPriority.priority = slice.priority; + runningPriority.state = 'Running'; + runningPriority.dur = item.dur; + setPriority(runningPriority, strArg); + resultData.push(runningPriority); + + const runnableItem = runnableMap.get(`${item.itId}_${item.startTs}`); + if (runnableItem) { + const runnablePriority = new Priority(); + runnablePriority.priority = slice.priority; + runnablePriority.state = 'Runnable'; + runnablePriority.dur = runnableItem.dur; + setPriority(runnablePriority, strArg); + resultData.push(runnablePriority); + } + } + } + + private async fetchAndProcessData() { + if (this.strValueMap.size === 0) { + await queryThreadStateArgsByName('next_info').then((value) => { + for (const item of value) { + this.strValueMap.set(item.argset, item.strValue); + } + }); + } + } + private getDataByPriority(source: Array): void { const priorityMap: Map = new Map(); const stateMap: Map = new Map(); + this.prepareMaps(source, priorityMap, stateMap); + + const priorityArr: Array = []; + for (const key of priorityMap.keys()) { + const ptsValues = priorityMap.get(key); + ptsValues!.children = []; + for (const itemKey of stateMap.keys()) { + if (itemKey.startsWith(key + '_')) { + const sp = stateMap.get(itemKey); + ptsValues!.children.push(sp!); + } + } + priorityArr.push(ptsValues!); + } + this.priorityTbl!.loading = false; + this.priorityTbl!.recycleDataSource = priorityArr; + this.theadClick(priorityArr); + } + + private prepareMaps(source: Array, priorityMap: Map, stateMap: Map) { source.map((priorityItem) => { if (priorityMap.has(priorityItem.priorityType + '')) { const priorityMapObj = priorityMap.get(priorityItem.priorityType + ''); @@ -174,22 +202,6 @@ export class TabPaneSchedPriority extends BaseElement { stateMap.set(priorityItem.priorityType + '_' + priorityItem.state, ptsPtMapObj); } }); - - const priorityArr: Array = []; - for (const key of priorityMap.keys()) { - const ptsValues = priorityMap.get(key); - ptsValues!.children = []; - for (const itemKey of stateMap.keys()) { - if (itemKey.startsWith(key + '_')) { - const sp = stateMap.get(itemKey); - ptsValues!.children.push(sp!); - } - } - priorityArr.push(ptsValues!); - } - this.priorityTbl!.loading = false; - this.priorityTbl!.recycleDataSource = priorityArr; - this.theadClick(priorityArr); } private theadClick(data: Array) { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts b/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts index 014a3eebb2571fd91f99ce5cecc7502fc7f29b75..e695da9cbc59842500e3ec23d5eae4d11f100277 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPaneEnergyAnomaly.ts @@ -20,39 +20,21 @@ import { LitTable } from '../../../../../base-ui/table/lit-table'; import { SelectionParam } from '../../../../bean/BoxSelection'; import { EnergyAnomalyStruct } from '../../../../database/ui-worker/ProcedureWorkerEnergyAnomaly'; import { resizeObserver } from '../SheetUtils'; -import {queryAnomalyDetailedData} from "../../../../database/sql/ProcessThread.sql"; +import { queryAnomalyDetailedData } from '../../../../database/sql/ProcessThread.sql'; @element('tabpane-anomaly-details') export class TabPaneEnergyAnomaly extends BaseElement { private tblAnomaly: LitTable | null | undefined; private static KEY_INDEX: number = 2; private static VALUE_INDEX: number = 3; + set data(selectionAnomaly: SelectionParam) { let div: HTMLElement | null | undefined = this?.shadowRoot?.querySelector('#anomaly-details'); let htmlText = ''; if (selectionAnomaly) { this.queryAnomalyTableData(selectionAnomaly.leftNs, selectionAnomaly.rightNs).then((bean) => { - let filterAppMap = new Map(); - for (let index = 0; index < bean.length; index++) { - let findAppNameIndex = -1; - // @ts-ignore - let values = Object.values(bean[index]); - if (values[TabPaneEnergyAnomaly.VALUE_INDEX]) { - let apps = values[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); - for (let appIndex = 0; appIndex < apps.length; appIndex++) { - if (apps.indexOf(SpHiSysEnergyChart.app_name) !== -1) { - findAppNameIndex = apps.indexOf(SpHiSysEnergyChart.app_name); - filterAppMap.set(values[0] + values[1], findAppNameIndex); - break; - } - } - if (values[TabPaneEnergyAnomaly.KEY_INDEX] == 'APPNAME') { - //ts+eventName : appNameIndex - filterAppMap.set(values[0] + values[1], findAppNameIndex); - } - } - } - let set = new Set(); + let filterAppMap = this.setFilterAppMapByAnomalyData(bean); + let tempSet = new Set(); for (let index = 0; index < bean.length; index++) { // @ts-ignore let values = Object.values(bean[index]); @@ -62,49 +44,30 @@ export class TabPaneEnergyAnomaly extends BaseElement { } else { findAppNameIndex = filterAppMap.get(values[0] + values[1]); } - if (!set.has(values[0])) { - set.add(values[0]); - htmlText += - '
      ' + '' + - values[1] + - ''; + values[1] + ''; } // @ts-ignore - if (set.has(Object.values(bean[index])[0])) { + if (tempSet.has(Object.values(bean[index])[0])) { let appValues = values[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); htmlText += - "" + + '' + values[TabPaneEnergyAnomaly.KEY_INDEX] + - "" + - (findAppNameIndex >= 0 - ? appValues.length > 1 - ? appValues[findAppNameIndex] - : values[TabPaneEnergyAnomaly.VALUE_INDEX] - : values[TabPaneEnergyAnomaly.VALUE_INDEX]) + + '' + + (findAppNameIndex >= 0 ? appValues.length > 1 ? appValues[findAppNameIndex] : + values[TabPaneEnergyAnomaly.VALUE_INDEX] : values[TabPaneEnergyAnomaly.VALUE_INDEX]) + TabPaneEnergyAnomaly.getUnit(values[TabPaneEnergyAnomaly.KEY_INDEX]) + - ""; + ''; } if (index + 1 < bean.length) { // @ts-ignore let nextValues = Object.values(bean[index + 1]); - let appValues = nextValues[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); - if (set.has(nextValues[0])) { - htmlText += - "" + - nextValues[TabPaneEnergyAnomaly.KEY_INDEX] + - "" + - (findAppNameIndex >= 0 - ? appValues.length > 1 - ? appValues[findAppNameIndex] - : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX] - : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX]) + - TabPaneEnergyAnomaly.getUnit(nextValues[TabPaneEnergyAnomaly.KEY_INDEX]) + - ''; - } else { - htmlText += ''; - htmlText += '
      '; + htmlText = this.spliceHtmlText(findAppNameIndex, nextValues, htmlText, tempSet); + if (!tempSet.has(nextValues[0])) { continue; } index++; @@ -115,6 +78,52 @@ export class TabPaneEnergyAnomaly extends BaseElement { } } + private spliceHtmlText(findAppNameIndex: number, nextValues: any[], htmlText: string, tempSet: Set): string{ + let appValues = nextValues[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); + if (tempSet.has(nextValues[0])) { + htmlText += + '' + + nextValues[TabPaneEnergyAnomaly.KEY_INDEX] + + '' + + (findAppNameIndex >= 0 + ? appValues.length > 1 + ? appValues[findAppNameIndex] + : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX] + : nextValues[TabPaneEnergyAnomaly.VALUE_INDEX]) + + TabPaneEnergyAnomaly.getUnit(nextValues[TabPaneEnergyAnomaly.KEY_INDEX]) + + ''; + } else { + htmlText += ''; + htmlText += '
      '; + return htmlText + } + return htmlText + } + + private setFilterAppMapByAnomalyData(bean: EnergyAnomalyStruct[]): Map { + let filterAppMap = new Map(); + for (let index = 0; index < bean.length; index++) { + let findAppNameIndex = -1; + // @ts-ignore + let values = Object.values(bean[index]); + if (values[TabPaneEnergyAnomaly.VALUE_INDEX]) { + let apps = values[TabPaneEnergyAnomaly.VALUE_INDEX].split(','); + for (let appIndex = 0; appIndex < apps.length; appIndex++) { + if (apps.indexOf(SpHiSysEnergyChart.app_name) !== -1) { + findAppNameIndex = apps.indexOf(SpHiSysEnergyChart.app_name); + filterAppMap.set(values[0] + values[1], findAppNameIndex); + break; + } + } + if (values[TabPaneEnergyAnomaly.KEY_INDEX] == 'APPNAME') { + //ts+eventName : appNameIndex + filterAppMap.set(values[0] + values[1], findAppNameIndex); + } + } + } + return filterAppMap; + } + static getUnit(value: any) { if (value == 'DURATION') { return ' ms'; @@ -137,7 +146,8 @@ export class TabPaneEnergyAnomaly extends BaseElement { initElements(): void { this.tblAnomaly = this.shadowRoot?.querySelector('#anomalyselectionTbl'); - this.tblAnomaly?.addEventListener('column-click', (ev: any) => {}); + this.tblAnomaly?.addEventListener('column-click', (ev: any) => { + }); } connectedCallback() { diff --git a/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.html.ts b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..ab6360af0121a159e76a0790334793ff23cbb18d --- /dev/null +++ b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.html.ts @@ -0,0 +1,101 @@ +/* + * 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. + */ + +export const TabPanePowerDetailsHTML = ` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; diff --git a/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts index ce76129ffabdc16ddb22f0f20565d5b8cadea93b..242c8c51337961a24f4bba01e3bd2088200c137d 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPanePowerDetails.ts @@ -20,7 +20,9 @@ import { log } from '../../../../../log/Log'; import { PowerDetailsEnergy } from '../../../../bean/EnergyStruct'; import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; import { resizeObserver } from '../SheetUtils'; -import {getTabPowerDetailsData} from "../../../../database/sql/ProcessThread.sql"; +import { getTabPowerDetailsData } from '../../../../database/sql/ProcessThread.sql'; +import { TabPanePowerDetailsHTML } from './TabPanePowerDetails.html'; +import { NUM_100, NUM_3 } from '../../../../bean/NumBean'; @element('tabpane-power-details') export class TabPanePowerDetails extends BaseElement { @@ -28,16 +30,16 @@ export class TabPanePowerDetails extends BaseElement { private sourcePowerDetails: Array = []; private itemType: any; - set data(valPowerDetails: SelectionParam | any) { + set data(valPowerDetails: SelectionParam) { this.queryDataByDB(valPowerDetails); } - connectedCallback() { + connectedCallback(): void { super.connectedCallback(); resizeObserver(this.parentElement!, this.tblPowerDetails!); } - getTimeTypeValue() { + getTimeTypeValue(): string[] { return [ 'foreground_duration', 'background_duration', @@ -54,7 +56,7 @@ export class TabPanePowerDetails extends BaseElement { ]; } - getDurationTypeValue() { + getDurationTypeValue(): string[] { return [ 'background_time', 'screen_on_time', @@ -72,7 +74,7 @@ export class TabPanePowerDetails extends BaseElement { ]; } - getEnergyTypeValue() { + getEnergyTypeValue(): string[] { return [ 'background_time', 'screen_on_time', @@ -96,7 +98,7 @@ export class TabPanePowerDetails extends BaseElement { ]; } - getCountTypeValue() { + getCountTypeValue(): string[] { return [ 'background_time', 'screen_on_time', @@ -123,11 +125,11 @@ export class TabPanePowerDetails extends BaseElement { }); this.sourcePowerDetails = []; this.itemType = { - time_type:[], - duration_type:[], - energy_type:[], - count_type:[] - } + time_type: [], + duration_type: [], + energy_type: [], + count_type: [] + }; this.itemType.time_type = this.getTimeTypeValue(); this.itemType.duration_type = this.getDurationTypeValue(); this.itemType.energy_type = this.getEnergyTypeValue(); @@ -149,18 +151,18 @@ export class TabPanePowerDetails extends BaseElement { } getTotalEnergy(powerData: any) { - return powerData['POWER_IDE_CPU'].getTotalEnergy(false) + - powerData['POWER_IDE_LOCATION'].getTotalEnergy(false) + - powerData['POWER_IDE_GPU'].getTotalEnergy(true) + - powerData['POWER_IDE_DISPLAY'].getTotalEnergy(true) + - powerData['POWER_IDE_CAMERA'].getTotalEnergy(false) + - powerData['POWER_IDE_BLUETOOTH'].getTotalEnergy(false) + - powerData['POWER_IDE_FLASHLIGHT'].getTotalEnergy(false) + - powerData['POWER_IDE_AUDIO'].getTotalEnergy(false) + - powerData['POWER_IDE_WIFISCAN'].getTotalEnergy(false); + return powerData.POWER_IDE_CPU.getTotalEnergy(false) + + powerData.POWER_IDE_LOCATION.getTotalEnergy(false) + + powerData.POWER_IDE_GPU.getTotalEnergy(true) + + powerData.POWER_IDE_DISPLAY.getTotalEnergy(true) + + powerData.POWER_IDE_CAMERA.getTotalEnergy(false) + + powerData.POWER_IDE_BLUETOOTH.getTotalEnergy(false) + + powerData.POWER_IDE_FLASHLIGHT.getTotalEnergy(false) + + powerData.POWER_IDE_AUDIO.getTotalEnergy(false) + + powerData.POWER_IDE_WIFISCAN.getTotalEnergy(false); } - queryDataByDB(val: SelectionParam | any) { + queryDataByDB(val: SelectionParam | any): void { getTabPowerDetailsData(val.leftNs - val.leftNs, val.rightNs).then((items) => { log('getTabPowerDetailsData size :' + items.length); let detailsData: Array = []; @@ -175,12 +177,12 @@ export class TabPanePowerDetails extends BaseElement { items.forEach((item) => { let powerDatum: any = powerData[item.eventName]; if (item.appKey.toLocaleLowerCase() === 'appname') { - powerDatum['appName'] = SpHiSysEnergyChart.app_name; + powerDatum.appName = SpHiSysEnergyChart.app_name; currentAppIndex = item.eventValue.split(',').indexOf(SpHiSysEnergyChart.app_name!); tsMax = 0; } else if (currentAppIndex > -1 && (set.has(item.appKey) ? item.startNS >= tsMax : true)) { if (set.has(item.appKey)) { - powerDatum[item.appKey.toLocaleLowerCase()] = item.startNS >= tsMax ? (tsMax = item.startNS, item.eventValue) : powerDatum[item.appKey.toLocaleLowerCase()]; + powerDatum[item.appKey.toLocaleLowerCase()] = item.startNS >= tsMax ? (tsMax = item.startNS , item.eventValue) : powerDatum[item.appKey.toLocaleLowerCase()]; } else { powerDatum[item.appKey.toLocaleLowerCase()] = (powerDatum[item.appKey.toLocaleLowerCase()] || 0) + parseInt(item.eventValue.split(',')[currentAppIndex]); } @@ -221,11 +223,11 @@ export class TabPanePowerDetails extends BaseElement { } setEnergyItems(powerData: any, totalEnergy: number, energyName: string, isSimpleEnergy: boolean, type: any): any { - let ratio = (powerData[energyName].getTotalEnergy(isSimpleEnergy) * 100) / totalEnergy; - if (totalEnergy == 0) { + let ratio = (powerData[energyName].getTotalEnergy(isSimpleEnergy) * NUM_100) / totalEnergy; + if (totalEnergy === 0) { powerData[energyName].energyConsumptionRatio = '0.000 %'; } else { - powerData[energyName].energyConsumptionRatio = ratio.toFixed(3) + ' %'; + powerData[energyName].energyConsumptionRatio = ratio.toFixed(NUM_3) + ' %'; } return this.getEnergyStyle(powerData, energyName, type); } @@ -235,13 +237,13 @@ export class TabPanePowerDetails extends BaseElement { powerData[energyName][item] = '-'; }); if (type === 'energy_type') { - if (energyName == 'POWER_IDE_GPU') { + if (energyName === 'POWER_IDE_GPU') { powerData[energyName]['duration'] = '-'; } else { powerData[energyName]['usage'] = '-'; } } else if (type === 'duration_type') { - if (energyName != 'POWER_IDE_CAMERA') { + if (energyName !== 'POWER_IDE_CAMERA') { powerData[energyName]['camera_id'] = '-'; } } @@ -249,93 +251,30 @@ export class TabPanePowerDetails extends BaseElement { } initHtml(): string { - return ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - `; + return TabPanePowerDetailsHTML; } - sortByColumn(detail: any) { + sortByColumn(detail: any): void { // @ts-ignore function compare(property, sort, type) { return function (aPowerDetails: PowerDetailsEnergy, bPowerDetails: PowerDetailsEnergy) { if (type === 'number') { return sort === 2 ? // @ts-ignore - parseFloat(bPowerDetails[property] == '-' ? 0 : bPowerDetails[property]) - + parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]) - // @ts-ignore - parseFloat(aPowerDetails[property] == '-' ? 0 : aPowerDetails[property]) + parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property]) : // @ts-ignore - parseFloat(aPowerDetails[property] == '-' ? 0 : aPowerDetails[property]) - + parseFloat(aPowerDetails[property] === '-' ? 0 : aPowerDetails[property]) - // @ts-ignore - parseFloat(bPowerDetails[property] == '-' ? 0 : bPowerDetails[property]); + parseFloat(bPowerDetails[property] === '-' ? 0 : bPowerDetails[property]); } else { // @ts-ignore if (bPowerDetails[property] > aPowerDetails[property]) { return sort === 2 ? 1 : -1; } else { // @ts-ignore - if (bPowerDetails[property] == aPowerDetails[property]) { + if (bPowerDetails[property] === aPowerDetails[property]) { return 0; } else { return sort === 2 ? -1 : 1; diff --git a/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts b/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts index b6f370080255f238815bdead0a81a6d9fb4b60e6..9f460a56da4f3646c741d913b9a0e0647c647f04 100644 --- a/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts +++ b/ide/src/trace/component/trace/sheet/energy/TabPaneSystemDetails.ts @@ -213,37 +213,7 @@ export class TabPaneSystemDetails extends BaseElement { watchIndex[number] = number + filterData.ts; } } else { - let number = watchIndex.indexOf(filterData.workId); - if (number > -1) { - lifeCycleData[number].rangeData.push(filterData); - let virtualEndData = JSON.parse(JSON.stringify(filterData)); - virtualEndData.ts = rightNs; - virtualEndData.eventName = 'WORK_REMOVE'; - lifeCycleData[number].endData = virtualEndData; - } else { - if (filterData.eventName.indexOf('WORK_START') > -1) { - lifeCycleData.push({ - startData: {}, - endData: {}, - rangeData: [], - }); - watchIndex.push(filterData.workId); - number = watchIndex.indexOf(filterData.workId); - let virtualData = JSON.parse(JSON.stringify(filterData)); - if (filterData.ts > 0) { - virtualData.ts = 0; - } else { - virtualData.ts = filterData.ts - 1; - } - virtualData.eventName = 'WORK_ADD'; - lifeCycleData[number].startData = virtualData; - lifeCycleData[number].rangeData.push(filterData); - let virtualEndData = JSON.parse(JSON.stringify(filterData)); - virtualEndData.ts = rightNs; - virtualEndData.eventName = 'WORK_REMOVE'; - lifeCycleData[number].endData = virtualEndData; - } - } + lifeCycleData = this.getSysDataExtend(rightNs, watchIndex, filterData, lifeCycleData) } } } @@ -265,6 +235,46 @@ export class TabPaneSystemDetails extends BaseElement { return resultData; } + getSysDataExtend( + rightNs: number, + watchIndex: Array, + filterData: any, + lifeCycleData: any[] + ): any[]{ + let number = watchIndex.indexOf(filterData.workId); + if (number > -1) { + lifeCycleData[number].rangeData.push(filterData); + let virtualEndData = JSON.parse(JSON.stringify(filterData)); + virtualEndData.ts = rightNs; + virtualEndData.eventName = 'WORK_REMOVE'; + lifeCycleData[number].endData = virtualEndData; + } else { + if (filterData.eventName.indexOf('WORK_START') > -1) { + lifeCycleData.push({ + startData: {}, + endData: {}, + rangeData: [], + }); + watchIndex.push(filterData.workId); + number = watchIndex.indexOf(filterData.workId); + let virtualData = JSON.parse(JSON.stringify(filterData)); + if (filterData.ts > 0) { + virtualData.ts = 0; + } else { + virtualData.ts = filterData.ts - 1; + } + virtualData.eventName = 'WORK_ADD'; + lifeCycleData[number].startData = virtualData; + lifeCycleData[number].rangeData.push(filterData); + let virtualEndData = JSON.parse(JSON.stringify(filterData)); + virtualEndData.ts = rightNs; + virtualEndData.eventName = 'WORK_REMOVE'; + lifeCycleData[number].endData = virtualEndData; + } + } + return lifeCycleData; + } + private getSystemLocationData(data: Array, leftNs: number) { let values = this.getConvertData(data); let fillMap: Map = new Map(); diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..588cfa522a927a4c135bdb9c4356b55b7615f791 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.html.ts @@ -0,0 +1,86 @@ +/* + * 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. + */ +export const TabPaneCallTreeHtml = ` + +
      + + + +
      + + + + + + +
      + + + Heaviest Stack Trace + + + + + + +
      + + + + + + + +
      +
      `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts index 75ed7c9ffc0bc105c00b9c0118c686b64774d9bf..207b888e6608f4d8ae369e5d743acf1419d7850e 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneCallTree.ts @@ -26,6 +26,8 @@ import { showButtonMenu } from '../SheetUtils'; import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct'; import '../../../../../base-ui/headline/lit-headline'; import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; +import { NUM_3, NUM_4 } from '../../../../bean/NumBean'; +import { TabPaneCallTreeHtml } from './TabPaneCallTree.html'; const InvertOptionIndex: number = 0; const hideEventOptionIndex: number = 2; @@ -39,7 +41,7 @@ export class TabPaneCallTree extends BaseElement { private callTreeTbr: LitTable | null | undefined; private callTreeProgressEL: LitProgressBar | null | undefined; private callTreeRightSource: Array = []; - private callTreeFilter: any; + private callTreeFilter: TabPaneFilter | null | undefined; private callTreeDataSource: any[] = []; private callTreeSortKey: string = 'weight'; private callTreeSortType: number = 0; @@ -62,14 +64,14 @@ export class TabPaneCallTree extends BaseElement { private _currentCallTreeLevel: number = 0; private _rowClickData: any = undefined; private callTreeLevel: CallTreeLevelStruct | undefined | null; - private headLine: LitHeadLine | null | undefined; + private callTreeHeadLine: LitHeadLine | null | undefined; set pieTitle(value: string) { this._pieTitle = value; if (this._pieTitle.length > 0) { - this.headLine!.isShow = true; - this.headLine!.titleTxt = this._pieTitle; - this.headLine!.closeCallback = () => { + this.callTreeHeadLine!.isShow = true; + this.callTreeHeadLine!.titleTxt = this._pieTitle; + this.callTreeHeadLine!.closeCallback = (): void => { this.restore(); }; } @@ -104,7 +106,8 @@ export class TabPaneCallTree extends BaseElement { } else { this.callTreeFilter!.style.display = 'none'; } - procedurePool.submitWithName('logic0', 'fileSystem-reset', [], undefined, () => {}); + procedurePool.submitWithName('logic0', 'fileSystem-reset', [], undefined, () => { + }); this.callTreeFilter!.initializeFilterTree(true, true, true); this.callTreeFilter!.filterValue = ''; this.callTreeProgressEL!.loading = true; @@ -121,7 +124,7 @@ export class TabPaneCallTree extends BaseElement { if (this._rowClickData && this.currentRowClickData !== undefined && this.currentSelection?.isRowClick) { this.getCallTreeDataByPieLevel(); } else { - this.headLine!.isShow = false; + this.callTreeHeadLine!.isShow = false; this.getCallTreeData(callTreeSelection, this.initWidth); } } @@ -135,7 +138,7 @@ export class TabPaneCallTree extends BaseElement { }, { funcName: 'getCurrentDataFromDb', - funcArgs: [{ queryFuncName: this.queryFuncName, ...callTreeSelection }], + funcArgs: [{queryFuncName: this.queryFuncName, ...callTreeSelection}], }, ], (results: any[]) => { @@ -146,7 +149,7 @@ export class TabPaneCallTree extends BaseElement { this.frameChart!.data = this.callTreeDataSource; this.currentCallTreeDataSource = this.callTreeDataSource; this.switchFlameChart(); - this.callTreeFilter.icon = 'block'; + this.callTreeFilter!.icon = 'block'; } ); } @@ -169,13 +172,13 @@ export class TabPaneCallTree extends BaseElement { funcArgs: [this.currentSelection, this.callTreeLevel], }); - if (this._rowClickData && this._rowClickData.libId !== undefined && this._currentCallTreeLevel === 3) { + if (this._rowClickData && this._rowClickData.libId !== undefined && this._currentCallTreeLevel === NUM_3) { this.callTreeLevel.libName = this._rowClickData.tableName; args.push({ funcName: 'showLibLevelData', funcArgs: [this.callTreeLevel.libId, this.callTreeLevel.libName], }); - } else if (this._rowClickData && this._rowClickData.symbolId !== undefined && this._currentCallTreeLevel === 4) { + } else if (this._rowClickData && this._rowClickData.symbolId !== undefined && this._currentCallTreeLevel === NUM_4) { this.callTreeLevel.symbolName = this._rowClickData.tableName; args.push({ funcName: 'showFunLevelData', @@ -193,14 +196,14 @@ export class TabPaneCallTree extends BaseElement { this.frameChart!.data = this.callTreeDataSource; this.currentCallTreeDataSource = this.callTreeDataSource; this.switchFlameChart(); - this.callTreeFilter.icon = 'block'; + this.callTreeFilter!.icon = 'block'; }); } private restore(): void { this.searchValue = ''; this.callTreeFilter!.filterValue = ''; - this.headLine!.isShow = false; + this.callTreeHeadLine!.isShow = false; this._rowClickData = undefined; this.getCallTreeData(this.currentSelection, this.initWidth); } @@ -316,21 +319,25 @@ export class TabPaneCallTree extends BaseElement { this.frameChart?.updateCanvas(false, entries[0].contentRect.width); this.frameChart?.calculateChartData(); } - // @ts-ignore - this.callTreeTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 35 + 'px'; - this.callTreeTbl?.reMeauseHeight(); - // @ts-ignore - this.callTreeTbr?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 45 - 21 + 'px'; - this.callTreeTbr?.reMeauseHeight(); + if (this.callTreeTbl) { + // @ts-ignore + this.callTreeTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 35 + 'px'; + this.callTreeTbl.reMeauseHeight(); + } + if (this.callTreeTbr) { + // @ts-ignore + this.callTreeTbr.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 45 - 21 + 'px'; + this.callTreeTbr.reMeauseHeight(); + } this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; } }).observe(this.parentElement!); } initElements(): void { - this.headLine = this.shadowRoot?.querySelector('.titleBox'); + this.callTreeHeadLine = this.shadowRoot?.querySelector('.titleBox'); this.callTreeTbl = this.shadowRoot?.querySelector('#tb-calltree'); this.callTreeProgressEL = this.shadowRoot?.querySelector('.call-tree-progress') as LitProgressBar; this.frameChart = this.shadowRoot?.querySelector('#framechart'); @@ -542,7 +549,9 @@ export class TabPaneCallTree extends BaseElement { this.getDataByWorker(callTreeArgs, (result: any[]) => { this.setLTableData(result); this.frameChart!.data = this.callTreeDataSource; - if (this.isChartShow) this.frameChart?.calculateChartData(); + if (this.isChartShow) { + this.frameChart?.calculateChartData(); + } }); } }); @@ -721,7 +730,7 @@ export class TabPaneCallTree extends BaseElement { procedurePool.submitWithName( 'logic0', this.procedureAction, - { args, callType: this.queryFuncName }, + {args, callType: this.queryFuncName}, undefined, (callTreeResults: any): void => { handler(callTreeResults); @@ -735,77 +744,6 @@ export class TabPaneCallTree extends BaseElement { } initHtml(): string { - return ` - -
      - - - -
      - - - - - - -
      - - - Heaviest Stack Trace - - - - - - -
      - - - - - - - -
      -
      `; + return TabPaneCallTreeHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..7ba23a150b4aa986b239237efd219637bb7022d3 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.html.ts @@ -0,0 +1,90 @@ +/* + * 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. + */ +export const TabPaneFileSystemCalltreeHtml = ` + +
      + + + +
      + + + + + + + +
      + + + Heaviest Stack Trace + + + + + + +
      + + + + + + + +
      +
      `; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts index 4ef186812dd3b479fc46769ea950efa1e8f81d8b..7870387210aa8124d916e63a9f23edf836780905 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemCalltree.ts @@ -28,6 +28,7 @@ import { showButtonMenu } from '../SheetUtils'; import { CallTreeLevelStruct } from '../../../../bean/EbpfStruct'; import '../../../../../base-ui/headline/lit-headline'; import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; +import { TabPaneFileSystemCalltreeHtml } from './TabPaneFileSystemCalltree.html'; const InvertOptionIndex: number = 0; const hideEventOptionIndex: number = 2; @@ -62,14 +63,14 @@ export class TabpaneFilesystemCalltree extends BaseElement { private _currentFsCallTreeLevel: number = 0; private _fsRowClickData: any = undefined; private FsCallTreeLevel: CallTreeLevelStruct | undefined | null; - private headLine: LitHeadLine | null | undefined; + private fileSystemHeadLine: LitHeadLine | null | undefined; set pieTitle(value: string) { this._pieTitle = value; if (this._pieTitle.length > 0) { - this.headLine!.isShow = true; - this.headLine!.titleTxt = this._pieTitle; - this.headLine!.closeCallback = () => { + this.fileSystemHeadLine!.isShow = true; + this.fileSystemHeadLine!.titleTxt = this._pieTitle; + this.fileSystemHeadLine!.closeCallback = () => { this.restore(); }; } @@ -120,7 +121,7 @@ export class TabpaneFilesystemCalltree extends BaseElement { if (this._fsRowClickData && this.currentRowClickData !== undefined && this.currentSelection?.isRowClick) { this.getFsCallTreeDataByPieLevel(); } else { - this.headLine!.isShow = false; + this.fileSystemHeadLine!.isShow = false; this.getFsCallTreeData(fsCallTreeSelection, this.initWidth); } } @@ -201,7 +202,7 @@ export class TabpaneFilesystemCalltree extends BaseElement { private restore(): void { this.searchValue = ''; this.fsCallTreeFilter.filterValue = ''; - this.headLine!.isShow = false; + this.fileSystemHeadLine!.isShow = false; this._fsRowClickData = undefined; this.getFsCallTreeData(this.currentSelection, this.initWidth); } @@ -273,7 +274,7 @@ export class TabpaneFilesystemCalltree extends BaseElement { } initElements(): void { - this.headLine = this.shadowRoot?.querySelector('.titleBox'); + this.fileSystemHeadLine = this.shadowRoot?.querySelector('.titleBox'); this.fsCallTreeTbl = this.shadowRoot?.querySelector('#tb-filesystem-calltree'); this.fsCallTreeProgressEL = this.shadowRoot?.querySelector('.fs-call-tree-progress') as LitProgressBar; this.frameChart = this.shadowRoot?.querySelector('#framechart'); @@ -591,14 +592,18 @@ export class TabpaneFilesystemCalltree extends BaseElement { this.frameChart?.updateCanvas(false, entries[0].contentRect.width); this.frameChart?.calculateChartData(); } - // @ts-ignore - this.fsCallTreeTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 35 + 'px'; - this.fsCallTreeTbl?.reMeauseHeight(); - // @ts-ignore - this.fsCallTreeTbr?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 45 - 21 + 'px'; - this.fsCallTreeTbr?.reMeauseHeight(); + if (this.fsCallTreeTbl) { + // @ts-ignore + this.fsCallTreeTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 35 + 'px'; + this.fsCallTreeTbl.reMeauseHeight(); + } + if (this.fsCallTreeTbr) { + // @ts-ignore + this.fsCallTreeTbr.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 45 - 21 + 'px'; + this.fsCallTreeTbr.reMeauseHeight(); + } this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; } }).observe(this.parentElement!); @@ -724,81 +729,6 @@ export class TabpaneFilesystemCalltree extends BaseElement { } initHtml(): string { - return ` - -
      - - - -
      - - - - - - - -
      - - - Heaviest Stack Trace - - - - - - -
      - - - - - - - -
      -
      `; + return TabPaneFileSystemCalltreeHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..dff44cc63bf9c42aa16f09dcd42822d2476633ca --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.html.ts @@ -0,0 +1,87 @@ +/* + * 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. + */ +export const TabPaneFileSystemDescHistoryHtml = ` + +
      +
      + +
      + + + + + + + + + + + +
      + + + + + + + + +
      +
      + + +
      +
      +`; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts index f6344b2153cd15db79ce8ada578116f571e4466e..35bc4d469a45f428437fc75461486f7676cf5ee7 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescHistory.ts @@ -21,6 +21,7 @@ import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressB import { FilterData, TabPaneFilter } from '../TabPaneFilter'; import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; import { procedurePool } from '../../../../database/Procedure'; +import { TabPaneFileSystemDescHistoryHtml } from './TabPaneFileSystemDescHistory.html'; @element('tabpane-filesystem-desc-history') export class TabPaneFileSystemDescHistory extends BaseElement { @@ -47,14 +48,18 @@ export class TabPaneFileSystemDescHistory extends BaseElement { return; } this.currentSelection = fsDescHistorySelection; - // @ts-ignore - this.fsDescHistoryTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - // @ts-ignore - this.fsDescHistoryTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - this.fsDescHistoryTbl!.recycleDataSource = []; - this.fsDescHistoryTblData!.recycleDataSource = []; + if (this.fsDescHistoryTbl) { + // @ts-ignore + this.fsDescHistoryTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + this.fsDescHistoryTbl.recycleDataSource = []; + } + if (this.fsDescHistoryTblData) { + // @ts-ignore + this.fsDescHistoryTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + this.fsDescHistoryTblData.recycleDataSource = []; + } if (fsDescHistorySelection) { this.fsDescHistoryLoadingList.push(1); this.fsDescHistoryProgressEL!.loading = true; @@ -184,14 +189,18 @@ export class TabPaneFileSystemDescHistory extends BaseElement { super.connectedCallback(); new ResizeObserver((entries) => { if (this.parentElement?.clientHeight != 0) { - // @ts-ignore - this.fsDescHistoryTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 31 + 'px'; - this.fsDescHistoryTbl?.reMeauseHeight(); - // @ts-ignore - this.fsDescHistoryTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 31 + 'px'; - this.fsDescHistoryTblData?.reMeauseHeight(); + if (this.fsDescHistoryTbl) { + // @ts-ignore + this.fsDescHistoryTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 31 + 'px'; + this.fsDescHistoryTbl.reMeauseHeight(); + } + if (this.fsDescHistoryTblData) { + // @ts-ignore + this.fsDescHistoryTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 31 + 'px'; + this.fsDescHistoryTblData.reMeauseHeight(); + } this.fsDescHistoryLoadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; } }).observe(this.parentElement!); @@ -246,78 +255,6 @@ export class TabPaneFileSystemDescHistory extends BaseElement { } initHtml(): string { - return ` - -
      -
      - -
      - - - - - - - - - - - -
      - - - - - - - - -
      -
      - - -
      -
      -`; + return TabPaneFileSystemDescHistoryHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..a8fccd6610729732af0cea6741c020268b237876 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.html.ts @@ -0,0 +1,86 @@ +/* + * 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. + */ +export const TabPaneFileSystemDescTimeSliceHtml = ` + +
      +
      + +
      + + + + + + + + + + +
      + + + + + + + + +
      +
      + + +
      +
      +`; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts index f20b095c91988f652b528f4d2da067d2b9c42304..24403958dfbfc962fb91a8b9626d279edaacc00f 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemDescTimeSlice.ts @@ -20,6 +20,7 @@ import '../../../../../base-ui/slicer/lit-slicer'; import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; import { procedurePool } from '../../../../database/Procedure'; +import { TabPaneFileSystemDescTimeSliceHtml } from './TabPaneFileSystemDescTimeSlice.html'; @element('tabpane-filesystem-desc-time-slice') export class TabPaneFileSystemDescTimeSlice extends BaseElement { @@ -38,12 +39,16 @@ export class TabPaneFileSystemDescTimeSlice extends BaseElement { return; } this.currentSelection = fsDescTimeSliceSelection; - // @ts-ignore - this.fsDescTimeSliceTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - // @ts-ignore - this.fsDescTimeSliceTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; + if (this.fsDescTimeSliceTbl) { + // @ts-ignore + this.fsDescTimeSliceTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + } + if (this.fsDescTimeSliceTblData) { + // @ts-ignore + this.fsDescTimeSliceTblData.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 20 - 31 }px`; + } this.fsDescTimeSliceTbl!.recycleDataSource = []; this.fsDescTimeSliceTblData!.recycleDataSource = []; if (fsDescTimeSliceSelection) { @@ -116,15 +121,19 @@ export class TabPaneFileSystemDescTimeSlice extends BaseElement { super.connectedCallback(); new ResizeObserver((entries) => { if (this.parentElement?.clientHeight != 0) { - // @ts-ignore - this.fsDescTimeSliceTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 31 + 'px'; - this.fsDescTimeSliceTbl?.reMeauseHeight(); - // @ts-ignore - this.fsDescTimeSliceTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 31 + 'px'; - this.fsDescTimeSliceTblData?.reMeauseHeight(); - this.fsDescTimeSliceLoadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; + if (this.fsDescTimeSliceTbl) { + // @ts-ignore + this.fsDescTimeSliceTbl.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 10 - 31 }px`; + this.fsDescTimeSliceTbl.reMeauseHeight(); + } + if (this.fsDescTimeSliceTblData) { + // @ts-ignore + this.fsDescTimeSliceTblData.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 10 - 31 }px`; + this.fsDescTimeSliceTblData.reMeauseHeight(); + this.fsDescTimeSliceLoadingPage.style.height = `${this.parentElement!.clientHeight - 24 }px`; + } } }).observe(this.parentElement!); } @@ -170,77 +179,6 @@ export class TabPaneFileSystemDescTimeSlice extends BaseElement { } initHtml(): string { - return ` - -
      -
      - -
      - - - - - - - - - - -
      - - - - - - - - -
      -
      - - -
      -
      -`; + return TabPaneFileSystemDescTimeSliceHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..16fd24f67347a2b45f2abbe8b4f1581592ea56be --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.html.ts @@ -0,0 +1,94 @@ +/* + * 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. + */ +export const TabPaneFileSystemEventsHtml = ` + +
      +
      + +
      + + + + + + + + + + + + + + + + + + +
      + + + + + + + + +
      +
      + + +
      +
      +`; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts index a42f941850ec7d3612c2b3beb2d8a803a2f2ec7a..83ac450a25fa582ace85a835d16aad44084ea070 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFileSystemEvents.ts @@ -22,6 +22,7 @@ import { procedurePool } from '../../../../database/Procedure'; import { FileSysEvent } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; import { FilterData, TabPaneFilter } from '../TabPaneFilter'; import '../TabPaneFilter'; +import { TabPaneFileSystemEventsHtml } from './TabPaneFileSystemEvents.html'; @element('tabpane-filesystem-event') export class TabPaneFileSystemEvents extends BaseElement { @@ -48,12 +49,16 @@ export class TabPaneFileSystemEvents extends BaseElement { return; } this.currentSelection = fsSysEventSelection; - // @ts-ignore - this.fsSysEventTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - // @ts-ignore - this.fsSysEventTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; + if (this.fsSysEventTbl) { + // @ts-ignore + this.fsSysEventTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + } + if (this.fsSysEventTblData) { + // @ts-ignore + this.fsSysEventTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + } this.filterEventType = '0'; this.filterProcess = '0'; this.queryData(fsSysEventSelection); @@ -217,14 +222,18 @@ export class TabPaneFileSystemEvents extends BaseElement { super.connectedCallback(); new ResizeObserver((entries) => { if (this.parentElement?.clientHeight != 0) { - // @ts-ignore - this.fsSysEventTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.fsSysEventTbl?.reMeauseHeight(); - // @ts-ignore - this.fsSysEventTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.fsSysEventTblData?.reMeauseHeight(); + if (this.fsSysEventTbl) { + // @ts-ignore + this.fsSysEventTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 33 + 'px'; + this.fsSysEventTbl.reMeauseHeight(); + } + if (this.fsSysEventTblData) { + // @ts-ignore + this.fsSysEventTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 33 + 'px'; + this.fsSysEventTblData.reMeauseHeight(); + } this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; } }).observe(this.parentElement!); @@ -237,55 +246,19 @@ export class TabPaneFileSystemEvents extends BaseElement { let arr = Array.from(this.fsSysEventFilterSource); arr.sort((fsEventA, fsEventB): number => { if (key == 'startTsStr') { - if (type == 1) { - return fsEventA.startTs - fsEventB.startTs; - } else { - return fsEventB.startTs - fsEventA.startTs; - } + return (type === 1) ? (fsEventA.startTs - fsEventB.startTs) : (fsEventB.startTs - fsEventA.startTs); } else if (key == 'durStr') { - if (type == 1) { - return fsEventA.dur - fsEventB.dur; - } else { - return fsEventB.dur - fsEventA.dur; - } + return (type === 1) ? (fsEventA.dur - fsEventB.dur) : (fsEventB.dur - fsEventA.dur); } else if (key == 'process') { - if (fsEventA.process > fsEventB.process) { - return type === 2 ? 1 : -1; - } else if (fsEventA.process == fsEventB.process) { - return 0; - } else { - return type === 2 ? -1 : 1; - } + return this.sortProcessCase(fsEventA, fsEventB, type); } else if (key == 'thread') { - if (fsEventA.thread > fsEventB.thread) { - return type === 2 ? 1 : -1; - } else if (fsEventA.thread == fsEventB.thread) { - return 0; - } else { - return type === 2 ? -1 : 1; - } + return this.sortThreadCase(fsEventA, fsEventB, type); } else if (key == 'typeStr') { - if (fsEventA.typeStr > fsEventB.typeStr) { - return type === 2 ? 1 : -1; - } else if (fsEventA.typeStr == fsEventB.typeStr) { - return 0; - } else { - return type === 2 ? -1 : 1; - } + return this.sortTypeCase(fsEventA, fsEventB, type); } else if (key == 'fd') { - if (type == 1) { - return (fsEventA.fd || 0) - (fsEventB.fd || 0); - } else { - return (fsEventB.fd || 0) - (fsEventA.fd || 0); - } + return (type === 1) ? ((fsEventA.fd || 0) - (fsEventB.fd || 0)) : ((fsEventB.fd || 0) - (fsEventA.fd || 0)); } else if (key == 'path') { - if (fsEventA.path > fsEventB.path) { - return type === 2 ? 1 : -1; - } else if (fsEventA.path == fsEventB.path) { - return 0; - } else { - return type === 2 ? -1 : 1; - } + return this.sortPathCase(fsEventA, fsEventB, type); } else { return 0; } @@ -294,86 +267,47 @@ export class TabPaneFileSystemEvents extends BaseElement { } } + private sortPathCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { + if (fsEventA.path > fsEventB.path) { + return type === 2 ? 1 : -1; + } else if (fsEventA.path == fsEventB.path) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + + private sortTypeCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { + if (fsEventA.typeStr > fsEventB.typeStr) { + return type === 2 ? 1 : -1; + } else if (fsEventA.typeStr == fsEventB.typeStr) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + + private sortThreadCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { + if (fsEventA.thread > fsEventB.thread) { + return type === 2 ? 1 : -1; + } else if (fsEventA.thread == fsEventB.thread) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + + private sortProcessCase(fsEventA: FileSysEvent, fsEventB: FileSysEvent, type: number): number { + if (fsEventA.process > fsEventB.process) { + return type === 2 ? 1 : -1; + } else if (fsEventA.process == fsEventB.process) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + initHtml(): string { - return ` - -
      -
      - -
      - - - - - - - - - - - - - - - - - - -
      - - - - - - - - -
      -
      - - -
      -
      -`; + return TabPaneFileSystemEventsHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts index 7b4416ef01fab88db13769c55676157674e0d8f5..2fa252f902e798fd821bd73749dd36168bc9b042 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatistics.ts @@ -90,7 +90,7 @@ export class TabPaneFileStatistics extends BaseElement { }; } - queryDataByDB(val: SelectionParam | any) { + queryDataByDB(val: SelectionParam | any): void { this.fileStatisticsLoadingList.push(1); this.fileStatisticsProgressEL!.loading = true; this.fileStatisticsLoadingPage.style.visibility = 'visible'; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..8cd91e7ecc7a74803a8a0040ee12b0c36d545af0 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.html.ts @@ -0,0 +1,109 @@ +/* + * 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. + */ +export const TabPaneFilesystemStatisticsAnalysisHtml = ` + + +
      + +
      +
      +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + + + + + + + + + + +
      +
      + +`; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts index 37d9a49a2dc8bf80e6994425d84cf2a7443513d2..66df5e4a71b87f272367aa689eec2a2f55e522da 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneFilesystemStatisticsAnalysis.ts @@ -25,6 +25,8 @@ import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; import { TabPaneFilter } from '../TabPaneFilter'; import { initSort } from '../SheetUtils'; import { TabpaneFilesystemCalltree } from './TabPaneFileSystemCalltree'; +import { NUM_5, NUM_MILLON } from '../../../../bean/NumBean'; +import { TabPaneFilesystemStatisticsAnalysisHtml } from './TabPaneFilesystemStatisticsAnalysis.html'; @element('tabpane-file-statistics-analysis') export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { @@ -58,8 +60,8 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { private threadStatisticsData!: {}; private libStatisticsData!: {}; private functionStatisticsData!: {}; - private titleEl: HTMLDivElement | undefined | null; - private filterEl: TabPaneFilter | undefined | null; + private fileSystemTitleEl: HTMLDivElement | undefined | null; + private fileSystemFilterEl: TabPaneFilter | undefined | null; private hideProcessCheckBox: LitCheckBox | undefined | null; private hideThreadCheckBox: LitCheckBox | undefined | null; private checkBoxs: NodeListOf | undefined | null; @@ -82,10 +84,10 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { this.reset(this.fileStatisticsAnalysisTableProcess!, false); this.hideProcessCheckBox!.checked = false; this.hideThreadCheckBox!.checked = false; - this.titleEl!.textContent = ''; + this.fileSystemTitleEl!.textContent = ''; this.tabName!.textContent = ''; this.fileStatisticsAnalysisRange!.textContent = - 'Selected range: ' + parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) + ' ms'; + 'Selected range: ' + parseFloat(((val.rightNs - val.leftNs) / NUM_MILLON).toFixed(NUM_5)) + ' ms'; this.fileStatisticsAnalysisProgressEL!.loading = true; this.getDataByWorker( [ @@ -115,10 +117,10 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { this.fileStatisticsAnalysisTableType = this.shadowRoot!.querySelector('#tb-type-usage'); this.fileStatisticsAnalysisProgressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; this.goBack(); - this.titleEl = this.shadowRoot!.querySelector('.title'); - this.filterEl = this.shadowRoot?.querySelector('#filter'); - this.filterEl!.setOptionsList(['Hide Process', 'Hide Thread']); - let popover = this.filterEl!.shadowRoot!.querySelector('#check-popover'); + this.fileSystemTitleEl = this.shadowRoot!.querySelector('.title'); + this.fileSystemFilterEl = this.shadowRoot?.querySelector('#filter'); + this.fileSystemFilterEl!.setOptionsList(['Hide Process', 'Hide Thread']); + let popover = this.fileSystemFilterEl!.shadowRoot!.querySelector('#check-popover'); this.hideProcessCheckBox = popover!!.querySelector('div > #hideProcess'); this.hideThreadCheckBox = popover!!.querySelector('div > #hideThread'); this.checkBoxs = popover!.querySelectorAll('.check-wrap > lit-check-box'); @@ -150,7 +152,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { } private checkBoxListener(box: LitCheckBox): void { - box!.addEventListener('change', (event) => { + box!.addEventListener('change', () => { if (this.hideProcessCheckBox!.checked && this.hideThreadCheckBox!.checked) { this.hideThread(); this.fsBack!.style.visibility = 'hidden'; @@ -181,10 +183,10 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { } fsTab!.fsRowClickData = detail.data; let title = ''; - if (this.titleEl?.textContent === '') { + if (this.fileSystemTitleEl?.textContent === '') { title = detail.data.tableName; } else { - title = this.titleEl?.textContent + ' / ' + detail.data.tableName; + title = this.fileSystemTitleEl?.textContent + ' / ' + detail.data.tableName; } fsTab!.pieTitle = title; // 是否是在表格上右键点击跳转到火焰图的 @@ -226,17 +228,17 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { this.fsBack!.style.visibility = 'visible'; } else { this.fsBack!.style.visibility = 'hidden'; - this.titleEl!.textContent = ''; + this.fileSystemTitleEl!.textContent = ''; } if (this.fsTableArray) { - for (let table of this.fsTableArray) { - if (table === showTable) { - initSort(table!, this.fsSortColumn, this.fsSortType); - table.style.display = 'grid'; - table.setAttribute('hideDownload', ''); + for (let fileSystemTable of this.fsTableArray) { + if (fileSystemTable === showTable) { + initSort(fileSystemTable!, this.fsSortColumn, this.fsSortType); + fileSystemTable.style.display = 'grid'; + fileSystemTable.setAttribute('hideDownload', ''); } else { - table!.style.display = 'none'; - table!.removeAttribute('hideDownload'); + fileSystemTable!.style.display = 'none'; + fileSystemTable!.removeAttribute('hideDownload'); } } } @@ -340,7 +342,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = ''; + this.fileSystemTitleEl!.textContent = ''; this.tabName!.textContent = 'Statistic By Process AllDuration'; this.fileStatisticsAnalysisPidData.unshift(this.processStatisticsData); this.fileStatisticsAnalysisTableProcess!.recycleDataSource = this.fileStatisticsAnalysisPidData; @@ -355,7 +357,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { this.getFilesystemType(it); // @ts-ignore this.fsProcessName = it.tableName; - this.titleEl!.textContent = this.fsProcessName; + this.fileSystemTitleEl!.textContent = this.fsProcessName; this.fsPieChart?.hideTip(); } @@ -386,7 +388,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = this.fsProcessName; + this.fileSystemTitleEl!.textContent = this.fsProcessName; this.tabName!.textContent = 'Statistic By type AllDuration'; this.fileStatisticsAnalysisTypeData.unshift(this.typeStatisticsData); this.fileStatisticsAnalysisTableType!.recycleDataSource = this.fileStatisticsAnalysisTypeData; @@ -424,7 +426,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { if (this.typeName.length > 0) { title += this.typeName; } - this.titleEl!.textContent = title; + this.fileSystemTitleEl!.textContent = title; this.fsPieChart?.hideTip(); } @@ -467,7 +469,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { if (this.typeName.length > 0) { title += this.typeName; } - this.titleEl!.textContent = title; + this.fileSystemTitleEl!.textContent = title; this.tabName!.textContent = 'Statistic By Thread AllDuration'; this.fileStatisticsAnalysisThreadData.unshift(this.threadStatisticsData); this.fileStatisticsAnalysisTableThread!.recycleDataSource = this.fileStatisticsAnalysisThreadData; @@ -503,7 +505,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { if (this.fileStatisticsAnalysisThreadName.length > 0) { title += this.fileStatisticsAnalysisThreadName; } - this.titleEl!.textContent = title; + this.fileSystemTitleEl!.textContent = title; this.fsPieChart?.hideTip(); } private libraryPieChart(): void { @@ -545,21 +547,21 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { }, ], }; - let title = ''; + let fileSystemTitle = ''; if (this.fsProcessName.length > 0) { - title += this.fsProcessName + ' / '; + fileSystemTitle += this.fsProcessName + ' / '; } if (this.typeName.length > 0) { if (this.hideThreadCheckBox?.checked) { - title += this.typeName; + fileSystemTitle += this.typeName; } else { - title += this.typeName + ' / '; + fileSystemTitle += this.typeName + ' / '; } } if (this.fileStatisticsAnalysisThreadName.length > 0) { - title += this.fileStatisticsAnalysisThreadName; + fileSystemTitle += this.fileStatisticsAnalysisThreadName; } - this.titleEl!.textContent = title; + this.fileSystemTitleEl!.textContent = fileSystemTitle; this.tabName!.textContent = 'Statistic By Library AllDuration'; this.fileStatisticsAnalysisSoData.unshift(this.libStatisticsData); this.fileStatisticsAnalysisTableSo!.recycleDataSource = this.fileStatisticsAnalysisSoData; @@ -585,7 +587,7 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { if (it.tableName.length > 0) { title += it.tableName; } - this.titleEl!.textContent = title; + this.fileSystemTitleEl!.textContent = title; this.fsPieChart?.hideTip(); } @@ -1088,109 +1090,15 @@ export class TabPaneFilesystemStatisticsAnalysis extends BaseElement { this.fileStatisticsAnalysisTableType!.style.height = this.parentElement!.clientHeight - 50 + 'px'; this.fileStatisticsAnalysisTableType?.reMeauseHeight(); if (this.parentElement!.clientHeight >= 0 && this.parentElement!.clientHeight <= 31) { - this.filterEl!.style.display = 'none'; + this.fileSystemFilterEl!.style.display = 'none'; } else { - this.filterEl!.style.display = 'flex'; + this.fileSystemFilterEl!.style.display = 'flex'; } } }).observe(this.parentElement!); } initHtml(): string { - return ` - - -
      - -
      -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - - - -
      -
      - -`; + return TabPaneFilesystemStatisticsAnalysisHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..181e751376ec875bffa22f764284a16e42254908 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.html.ts @@ -0,0 +1,109 @@ +/* + * 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. + */ +export const TabPaneIOTierStatisticsAnalysisHtml = ` + + +
      + +
      +
      +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + + + + + + + + + + +
      +
      + +`; \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts index 0388ccaf43128a0dcbc13c152d589752cfb92223..16015aa597cb5ad0cb523dcf66e95557599f7812 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIOTierStatisticsAnalysis.ts @@ -25,6 +25,7 @@ import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; import { TabPaneFilter } from '../TabPaneFilter'; import { initSort } from '../SheetUtils'; import { TabPaneIOCallTree } from './TabPaneIOCallTree'; +import { TabPaneIOTierStatisticsAnalysisHtml } from './TabPaneIOTierStatisticsAnalysis.html'; @element('tabpane-tb-vm-statistics') export class TabPaneIOTierStatisticsAnalysis extends BaseElement { @@ -38,7 +39,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { private typeData!: any[]; private ioTierTableProcess: LitTable | null | undefined; private ioTierTableThread: LitTable | null | undefined; - private tableType: LitTable | null | undefined; + private tierTableType: LitTable | null | undefined; private ioTierTableSo: LitTable | null | undefined; private tableFunction: LitTable | null | undefined; private sumDur: number = 0; @@ -58,8 +59,8 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { private threadStatisticsData!: {}; private libStatisticsData!: {}; private functionStatisticsData!: {}; - private titleEl: HTMLDivElement | undefined | null; - private filterEl: TabPaneFilter | undefined | null; + private tierTitleEl: HTMLDivElement | undefined | null; + private tierFilterEl: TabPaneFilter | undefined | null; private hideProcessCheckBox: LitCheckBox | undefined | null; private hideThreadCheckBox: LitCheckBox | undefined | null; private checkBoxs: NodeListOf | undefined | null; @@ -82,7 +83,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { this.hideProcessCheckBox!.checked = false; this.hideThreadCheckBox!.checked = false; this.currentSelection = ioTierStatisticsAnalysisSelection; - this.titleEl!.textContent = ''; + this.tierTitleEl!.textContent = ''; this.tabName!.textContent = ''; this.range!.textContent = 'Selected range: ' + @@ -115,15 +116,15 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { this.ioTierTableThread = this.shadowRoot!.querySelector('#tb-thread-usage'); this.ioTierTableSo = this.shadowRoot!.querySelector('#tb-so-usage'); this.tableFunction = this.shadowRoot!.querySelector('#tb-function-usage'); - this.tableType = this.shadowRoot!.querySelector('#tb-type-usage'); + this.tierTableType = this.shadowRoot!.querySelector('#tb-type-usage'); this.iOTierStatisticsAnalysisBack = this.shadowRoot!.querySelector('.io-tier-go-back'); this.tabName = this.shadowRoot!.querySelector('.io-tier-subheading'); this.progressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; this.goBack(); - this.titleEl = this.shadowRoot!.querySelector('.title'); - this.filterEl = this.shadowRoot?.querySelector('#filter'); - this.filterEl!.setOptionsList(['Hide Process', 'Hide Thread']); - let popover = this.filterEl!.shadowRoot!.querySelector('#check-popover'); + this.tierTitleEl = this.shadowRoot!.querySelector('.title'); + this.tierFilterEl = this.shadowRoot?.querySelector('#filter'); + this.tierFilterEl!.setOptionsList(['Hide Process', 'Hide Thread']); + let popover = this.tierFilterEl!.shadowRoot!.querySelector('#check-popover'); this.hideProcessCheckBox = popover!!.querySelector('div > #hideProcess'); this.hideThreadCheckBox = popover!!.querySelector('div > #hideThread'); this.checkBoxs = popover!.querySelectorAll('.check-wrap > lit-check-box'); @@ -149,7 +150,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { }; addRowClickEventListener(this.ioTierTableProcess!, this.ioTierProcessLevelClickEvent.bind(this)); - addRowClickEventListener(this.tableType!, this.ioTierTypeLevelClickEvent.bind(this)); + addRowClickEventListener(this.tierTableType!, this.ioTierTypeLevelClickEvent.bind(this)); addRowClickEventListener(this.ioTierTableThread!, this.ioTierThreadLevelClickEvent.bind(this)); addRowClickEventListener(this.ioTierTableSo!, this.ioTierSoLevelClickEvent.bind(this)); } @@ -200,10 +201,10 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { } ioTab!.rowClickData = detail.data; let title = ''; - if (this.titleEl?.textContent === '') { + if (this.tierTitleEl?.textContent === '') { title = detail.data.tableName; } else { - title = this.titleEl?.textContent + ' / ' + detail.data.tableName; + title = this.tierTitleEl?.textContent + ' / ' + detail.data.tableName; } ioTab!.pieTitle = title; // 是否是在表格上右键点击跳转到火焰图的 @@ -236,17 +237,17 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { this.iOTierStatisticsAnalysisBack!.style.visibility = 'visible'; } else { this.iOTierStatisticsAnalysisBack!.style.visibility = 'hidden'; - this.titleEl!.textContent = ''; + this.tierTitleEl!.textContent = ''; } if (this.ioTableArray) { - for (let table of this.ioTableArray) { - if (table === showTable) { - initSort(table!, this.ioSortColumn, this.ioSortType); - table.style.display = 'grid'; - table.setAttribute('hideDownload', ''); + for (let tierTable of this.ioTableArray) { + if (tierTable === showTable) { + initSort(tierTable!, this.ioSortColumn, this.ioSortType); + tierTable.style.display = 'grid'; + tierTable.setAttribute('hideDownload', ''); } else { - table!.style.display = 'none'; - table!.removeAttribute('hideDownload'); + tierTable!.style.display = 'none'; + tierTable!.removeAttribute('hideDownload'); } } } @@ -255,7 +256,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { private clearData(): void { this.ioPieChart!.dataSource = []; this.ioTierTableProcess!.recycleDataSource = []; - this.tableType!.recycleDataSource = []; + this.tierTableType!.recycleDataSource = []; this.ioTierTableThread!.recycleDataSource = []; this.ioTierTableSo!.recycleDataSource = []; this.tableFunction!.recycleDataSource = []; @@ -273,7 +274,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { this.iOTierStatisticsAnalysisBack!.addEventListener('click', () => { if (this.tabName!.textContent === 'Statistic By type AllDuration') { this.iOTierStatisticsAnalysisBack!.style.visibility = 'hidden'; - this.showAssignLevel(this.ioTierTableProcess!, this.tableType!, 0); + this.showAssignLevel(this.ioTierTableProcess!, this.tierTableType!, 0); this.processPieChart(); } else if (this.tabName!.textContent === 'Statistic By Thread AllDuration') { if (this.hideProcessCheckBox?.checked) { @@ -281,14 +282,14 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { } else { this.iOTierStatisticsAnalysisBack!.style.visibility = 'visible'; } - this.showAssignLevel(this.tableType!, this.ioTierTableThread!, 1); + this.showAssignLevel(this.tierTableType!, this.ioTierTableThread!, 1); this.typePieChart(); } else if (this.tabName!.textContent === 'Statistic By Library AllDuration') { if (this.hideThreadCheckBox?.checked) { if (this.hideProcessCheckBox?.checked) { this.iOTierStatisticsAnalysisBack!.style.visibility = 'hidden'; } - this.showAssignLevel(this.tableType!, this.ioTierTableSo!, 1); + this.showAssignLevel(this.tierTableType!, this.ioTierTableSo!, 1); this.typePieChart(); } else { this.showAssignLevel(this.ioTierTableThread!, this.ioTierTableSo!, 2); @@ -302,13 +303,13 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { } private hideProcess(): void { - this.reset(this.tableType!, false); + this.reset(this.tierTableType!, false); this.processName = ''; this.getIOTierType(null); } private hideThread(it?: any): void { - this.reset(this.tableType!, true); + this.reset(this.tierTableType!, true); this.processName = ''; this.threadName = ''; if (it) { @@ -350,7 +351,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = ''; + this.tierTitleEl!.textContent = ''; this.tabName!.textContent = 'Statistic By Process AllDuration'; this.pidData.unshift(this.processStatisticsData); this.ioTierTableProcess!.recycleDataSource = this.pidData; @@ -361,11 +362,11 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { } private ioTierProcessLevelClickEvent(it: any): void { - this.reset(this.tableType!, true); + this.reset(this.tierTableType!, true); this.getIOTierType(it); this.processName = it.tableName; this.ioPieChart?.hideTip(); - this.titleEl!.textContent = this.processName; + this.tierTitleEl!.textContent = this.processName; } private typePieChart(): void { @@ -386,9 +387,9 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { }, hoverHandler: (ioTierData): void => { if (ioTierData) { - this.tableType!.setCurrentHover(ioTierData); + this.tierTableType!.setCurrentHover(ioTierData); } else { - this.tableType!.mouseOut(); + this.tierTableType!.mouseOut(); } }, interactions: [ @@ -397,14 +398,14 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = this.processName; + this.tierTitleEl!.textContent = this.processName; this.tabName!.textContent = 'Statistic By type AllDuration'; this.typeData.unshift(this.typeStatisticsData); - this.tableType!.recycleDataSource = this.typeData; + this.tierTableType!.recycleDataSource = this.typeData; // @ts-ignore this.typeData.shift(this.typeStatisticsData); this.currentLevelData = this.typeData; - this.tableType?.reMeauseHeight(); + this.tierTableType?.reMeauseHeight(); } private ioTierTypeLevelClickEvent(it: any): void { @@ -417,14 +418,14 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { } this.typeName = it.tableName; this.ioPieChart?.hideTip(); - let title = ''; + let tierTitle = ''; if (this.processName.length > 0) { - title += this.processName + ' / '; + tierTitle += this.processName + ' / '; } if (this.typeName.length > 0) { - title += this.typeName; + tierTitle += this.typeName; } - this.titleEl!.textContent = title; + this.tierTitleEl!.textContent = tierTitle; } private threadPieChart(): void { @@ -468,7 +469,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { if (this.typeName.length > 0) { title += this.typeName; } - this.titleEl!.textContent = title; + this.tierTitleEl!.textContent = title; this.tabName!.textContent = 'Statistic By Thread AllDuration'; this.threadData.unshift(this.threadStatisticsData); this.ioTierTableThread!.recycleDataSource = this.threadData; @@ -502,7 +503,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { if (this.threadName.length > 0) { title += this.threadName; } - this.titleEl!.textContent = title; + this.tierTitleEl!.textContent = title; } private libraryPieChart(): void { @@ -558,7 +559,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { if (this.threadName.length > 0) { title += this.threadName; } - this.titleEl!.textContent = title; + this.tierTitleEl!.textContent = title; this.tabName!.textContent = 'Statistic By Library AllDuration'; this.soData.unshift(this.libStatisticsData); this.ioTierTableSo!.recycleDataSource = this.soData; @@ -585,7 +586,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { if (it.tableName.length > 0) { title += it.tableName; } - this.titleEl!.textContent = title; + this.tierTitleEl!.textContent = title; } private sortByColumn(): void { @@ -595,7 +596,7 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { ioTierCurrentTable = this.ioTierTableProcess; break; case 1: - ioTierCurrentTable = this.tableType; + ioTierCurrentTable = this.tierTableType; break; case 2: ioTierCurrentTable = this.ioTierTableThread; @@ -981,9 +982,9 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { type: 'outer', }, tip: this.getTip(), - hoverHandler: (data): void => { - if (data) { - this.tableFunction!.setCurrentHover(data); + hoverHandler: (tierData): void => { + if (tierData) { + this.tableFunction!.setCurrentHover(tierData); } else { this.tableFunction!.mouseOut(); } @@ -1094,112 +1095,18 @@ export class TabPaneIOTierStatisticsAnalysis extends BaseElement { this.ioTierTableSo?.reMeauseHeight(); this.tableFunction!.style.height = this.parentElement!.clientHeight - 50 + 'px'; this.tableFunction?.reMeauseHeight(); - this.tableType!.style.height = this.parentElement!.clientHeight - 50 + 'px'; - this.tableType?.reMeauseHeight(); + this.tierTableType!.style.height = this.parentElement!.clientHeight - 50 + 'px'; + this.tierTableType?.reMeauseHeight(); if (this.parentElement!.clientHeight >= 0 && this.parentElement!.clientHeight <= 31) { - this.filterEl!.style.display = 'none'; + this.tierFilterEl!.style.display = 'none'; } else { - this.filterEl!.style.display = 'flex'; + this.tierFilterEl!.style.display = 'flex'; } } }).observe(this.parentElement!); } initHtml(): string { - return ` - - -
      - -
      -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - - - -
      -
      - -`; + return TabPaneIOTierStatisticsAnalysisHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..96fc9be582d17e7ae57d1b13c30738a64ed121c9 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.html.ts @@ -0,0 +1,91 @@ +/* + * 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. + */ +export const TabPaneIoCompletionTimesHtml = ` + +
      +
      + +
      + + + + + + + + + + + + + + + +
      + + + + + + + + +
      +
      + + +
      +
      +`; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts index 3e68cf871a97dfff3996612627ef2f8767fc3097..b0cf348a38b350bbaa2059027b73031fc506c78e 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneIoCompletionTimes.ts @@ -26,6 +26,7 @@ import { } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; import { FilterData, TabPaneFilter } from '../TabPaneFilter'; import { getTabIoCompletionTimesType } from '../../../../database/sql/SqlLite.sql'; +import { TabPaneIoCompletionTimesHtml } from './TabPaneIoCompletionTimes.html'; @element('tabpane-io-completiontimes') export class TabPaneIoCompletionTimes extends BaseElement { @@ -50,28 +51,36 @@ export class TabPaneIoCompletionTimes extends BaseElement { this.initFilterTypes(ioCompletionTimesSelection!).then(() => { this.queryData(ioCompletionTimesSelection!); }); - // @ts-ignore - this.ioCompletionTimesTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - // @ts-ignore - this.ioCompletionTimesTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - this.ioCompletionTimesTbl!.recycleDataSource = []; - this.ioCompletionTimesTblData!.recycleDataSource = []; + if (this.ioCompletionTimesTbl) { + // @ts-ignore + this.ioCompletionTimesTbl.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 20 - 31 }px`; + this.ioCompletionTimesTbl.recycleDataSource = []; + } + if (this.ioCompletionTimesTblData) { + // @ts-ignore + this.ioCompletionTimesTblData.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 20 - 31 }px`; + this.ioCompletionTimesTblData.recycleDataSource = []; + } } connectedCallback() { new ResizeObserver((entries) => { if (this.parentElement?.clientHeight != 0) { - // @ts-ignore - this.ioCompletionTimesTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.ioCompletionTimesTbl?.reMeauseHeight(); - // @ts-ignore - this.ioCompletionTimesTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.ioCompletionTimesTblData?.reMeauseHeight(); - this.ioCompletionTimesLoadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; + if (this.ioCompletionTimesTbl) { + // @ts-ignore + this.ioCompletionTimesTbl.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 10 - 33 }px`; + this.ioCompletionTimesTbl.reMeauseHeight(); + } + if (this.ioCompletionTimesTblData) { + // @ts-ignore + this.ioCompletionTimesTblData.shadowRoot.querySelector('.table').style.height = + `${this.parentElement!.clientHeight - 10 - 33 }px`; + this.ioCompletionTimesTblData.reMeauseHeight(); + } + this.ioCompletionTimesLoadingPage.style.height = `${this.parentElement!.clientHeight - 24 }px`; } }).observe(this.parentElement!); } @@ -146,14 +155,14 @@ export class TabPaneIoCompletionTimes extends BaseElement { if (this.currentSelection != ioCompletionTimeParam) { this.currentSelection = ioCompletionTimeParam; filter!.setSelectList(this.native_type, null, 'Tier'); - filter!.firstSelect = typeIndexOf + ''; + filter!.firstSelect = `${typeIndexOf }`; this.queryData(ioCompletionTimeParam); } else { if (typeIndexOf == parseInt(filter!.firstSelect)) { return; } filter!.setSelectList(this.native_type, null, 'Tier'); - filter!.firstSelect = typeIndexOf + ''; + filter!.firstSelect = `${typeIndexOf }`; this.filterTypeData(ioCompletionTimeParam?.fileSystemIoData?.path || undefined); ioCompletionTimeParam.fileSystemIoData = undefined; this.ioCompletionTimesTbl!.recycleDataSource = this.ioCompletionTimesSource; @@ -233,124 +242,79 @@ export class TabPaneIoCompletionTimes extends BaseElement { this.ioCompletionTimesTbl!.recycleDataSource = this.ioCompletionTimesSource; } else { let arr = Array.from(this.ioCompletionTimesSource); - arr.sort((ioCompletionTimesA, ioCompletionTimesB): number => { - if (ioCompletionTimesKey === 'startTsStr') { - return type === 1 - ? ioCompletionTimesA.startTs - ioCompletionTimesB.startTs - : ioCompletionTimesB.startTs - ioCompletionTimesA.startTs; - } else if (ioCompletionTimesKey === 'durStr') { - return type === 1 - ? ioCompletionTimesA.dur - ioCompletionTimesB.dur - : ioCompletionTimesB.dur - ioCompletionTimesA.dur; - } else if (ioCompletionTimesKey === 'process') { - return ioCompletionTimesA.process === ioCompletionTimesB.process - ? 0 : (type === 2 ? (ioCompletionTimesA.process > ioCompletionTimesB.process ? 1 : -1) - : (ioCompletionTimesA.process > ioCompletionTimesB.process ? -1 : 1)); - } else if (ioCompletionTimesKey === 'durPer4kStr') { - return type === 1 - ? ioCompletionTimesA.durPer4k - ioCompletionTimesB.durPer4k - : ioCompletionTimesB.durPer4k - ioCompletionTimesA.durPer4k; - } else if (ioCompletionTimesKey === 'thread') { - return ioCompletionTimesA.thread > ioCompletionTimesB.thread - ? (type === 2 ? 1 : -1) : (ioCompletionTimesA.thread === ioCompletionTimesB.thread - ? 0 : (type === 2 ? -1 : 1)); - } else if (ioCompletionTimesKey === 'operation') { - return ioCompletionTimesA.operation > ioCompletionTimesB.operation - ? (type === 2 ? 1 : -1) : (ioCompletionTimesA.operation === ioCompletionTimesB.operation - ? 0 : (type === 2 ? -1 : 1)); - } else if (ioCompletionTimesKey === 'sizeStr') { - return type === 1 - ? ioCompletionTimesA.size - ioCompletionTimesB.size - : ioCompletionTimesB.size - ioCompletionTimesA.size; - } else if (ioCompletionTimesKey === 'tier') { - return type === 1 - ? ioCompletionTimesA.tier - ioCompletionTimesB.tier - : ioCompletionTimesB.tier - ioCompletionTimesA.tier; - } else { - return 0; - } - }); + this.sortHandle(arr, ioCompletionTimesKey, type); this.ioCompletionTimesTbl!.recycleDataSource = arr; } } + private sortHandle(arr: IoCompletionTimes[], ioCompletionTimesKey: string, type: number) { + arr.sort((ioCompletionTimesA, ioCompletionTimesB): number => { + if (ioCompletionTimesKey == 'startTsStr') { + return type === 1 + ? ioCompletionTimesA.startTs - ioCompletionTimesB.startTs + : ioCompletionTimesB.startTs - ioCompletionTimesA.startTs; + } else if (ioCompletionTimesKey == 'durStr') { + return type === 1 + ? ioCompletionTimesA.dur - ioCompletionTimesB.dur + : ioCompletionTimesB.dur - ioCompletionTimesA.dur; + } else if (ioCompletionTimesKey == 'process') { + return this.sortProcessCase(ioCompletionTimesA, ioCompletionTimesB, type); + } else if (ioCompletionTimesKey == 'durPer4kStr') { + return type === 1 + ? ioCompletionTimesA.durPer4k - ioCompletionTimesB.durPer4k + : ioCompletionTimesB.durPer4k - ioCompletionTimesA.durPer4k; + } else if (ioCompletionTimesKey == 'thread') { + return this.sortThreadCase(ioCompletionTimesA, ioCompletionTimesB, type); + } else if (ioCompletionTimesKey == 'operation') { + return this.sortOperationCase(ioCompletionTimesA, ioCompletionTimesB, type); + } else if (ioCompletionTimesKey == 'sizeStr') { + return type === 1 + ? ioCompletionTimesA.size - ioCompletionTimesB.size + : ioCompletionTimesB.size - ioCompletionTimesA.size; + } else if (ioCompletionTimesKey == 'tier') { + return type === 1 + ? ioCompletionTimesA.tier - ioCompletionTimesB.tier + : ioCompletionTimesB.tier - ioCompletionTimesA.tier; + } else { + return 0; + } + }); + } + + private sortOperationCase(ioCompletionTimesA: IoCompletionTimes, + ioCompletionTimesB: IoCompletionTimes, type: number): number { + if (ioCompletionTimesA.operation > ioCompletionTimesB.operation) { + return type === 2 ? 1 : -1; + } else if (ioCompletionTimesA.operation == ioCompletionTimesB.operation) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + + private sortThreadCase(ioCompletionTimesA: IoCompletionTimes, + ioCompletionTimesB: IoCompletionTimes, type: number): number { + if (ioCompletionTimesA.thread > ioCompletionTimesB.thread) { + return type === 2 ? 1 : -1; + } else if (ioCompletionTimesA.thread == ioCompletionTimesB.thread) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + + private sortProcessCase(ioCompletionTimesA: IoCompletionTimes, + ioCompletionTimesB: IoCompletionTimes, type: number): number { + if (ioCompletionTimesA.process > ioCompletionTimesB.process) { + return type === 2 ? 1 : -1; + } else if (ioCompletionTimesA.process == ioCompletionTimesB.process) { + return 0; + } else { + return type === 2 ? -1 : 1; + } + } + initHtml(): string { - return ` - -
      -
      - -
      - - - - - - - - - - - - - - - -
      - - - - - - - - -
      -
      - - -
      -
      -`; + return TabPaneIoCompletionTimesHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..77a51de1f729b6d0e796157b943d04afea2f57a1 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.html.ts @@ -0,0 +1,78 @@ +/* + * 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. + */ +export const TabPaneVMEventsHtml = ` + +
      +
      + +
      + + + + + + + + +
      + + + + + + + + +
      +
      + + +
      +
      +`; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts index 0053590301e49754bbdf40ed832671579d138294..71912250d50847d60225fcaec3d5dcab0e2c0a2a 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVMEvents.ts @@ -21,7 +21,8 @@ import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressB import { procedurePool } from '../../../../database/Procedure'; import { VirtualMemoryEvent, VM_TYPE_MAP } from '../../../../database/logic-worker/ProcedureLogicWorkerFileSystem'; import { FilterData, TabPaneFilter } from '../TabPaneFilter'; -import {getTabVirtualMemoryType} from "../../../../database/sql/Memory.sql"; +import {getTabVirtualMemoryType} from '../../../../database/sql/Memory.sql'; +import { TabPaneVMEventsHtml } from './TabPaneVMEvents.html'; @element('tabpane-virtualmemory-event') export class TabPaneVirtualMemoryEvents extends BaseElement { @@ -46,26 +47,34 @@ export class TabPaneVirtualMemoryEvents extends BaseElement { this.initFilterTypes(vmEventSelection!).then(() => { this.queryData(vmEventSelection!); }); - // @ts-ignore - this.vmEventTbl?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 20 - 31 + 'px'; - // @ts-ignore - this.vmEventTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 31 + 'px'; - this.vmEventTbl!.recycleDataSource = []; - this.vmEventTblData!.recycleDataSource = []; + if (this.vmEventTbl) { + // @ts-ignore + this.vmEventTbl.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 20 - 31 + 'px'; + this.vmEventTbl.recycleDataSource = []; + } + if (this.vmEventTblData) { + // @ts-ignore + this.vmEventTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 31 + 'px'; + this.vmEventTblData.recycleDataSource = []; + } } connectedCallback() { new ResizeObserver((entries) => { if (this.parentElement?.clientHeight != 0) { - // @ts-ignore - this.vmEventTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.vmEventTbl?.reMeauseHeight(); - // @ts-ignore - this.vmEventTblData?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 10 - 33 + 'px'; - this.vmEventTblData?.reMeauseHeight(); + if (this.vmEventTbl) { + // @ts-ignore + this.vmEventTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 33 + 'px'; + this.vmEventTbl.reMeauseHeight(); + } + if (this.vmEventTblData) { + // @ts-ignore + this.vmEventTblData.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 10 - 33 + 'px'; + this.vmEventTblData.reMeauseHeight(); + } this.loadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; } }).observe(this.parentElement!); @@ -273,69 +282,6 @@ export class TabPaneVirtualMemoryEvents extends BaseElement { } initHtml(): string { - return ` - -
      -
      - -
      - - - - - - - - -
      - - - - - - - - -
      -
      - - -
      -
      -`; + return TabPaneVMEventsHtml; } } diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts index b2331a8ee0c47c9003f293d754fec79e7827e08b..ee14617ed34912cfd5f5ec86de4a7cfbd5d9cfb2 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatistics.ts @@ -121,7 +121,7 @@ export class TabPaneVirtualMemoryStatistics extends BaseElement { }); } - sortStatus(result: Array, firstLevel: string, secondLevel: string) { + sortStatus(result: Array, firstLevel: string, secondLevel: string): void { let vmMemoryStatFatherMap = new Map(); let vmMemoryStatChildMap = new Map(); let vmMemoryStatAllNode: any = { diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.html.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..d70db43feaed862d8b88eaa00777d901050d6c7b --- /dev/null +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.html.ts @@ -0,0 +1,104 @@ +/* + * 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. + */ +export const TabPaneVirtualMemoryStatisticsAnalysisHtml = ` + + +
      + +
      +
      +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + + + + + + + + + + +
      +
      + +`; diff --git a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts index 77838e9df781bfe1f4d12e162464309fd58f7798..9945f22e2023d3654894cdc52b3745412cdfa225 100644 --- a/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/file-system/TabPaneVirtualMemoryStatisticsAnalysis.ts @@ -25,6 +25,7 @@ import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; import { TabPaneFilter } from '../TabPaneFilter'; import { initSort } from '../SheetUtils'; import { TabPaneVMCallTree } from './TabPaneIOCallTree'; +import { TabPaneVirtualMemoryStatisticsAnalysisHtml } from './TabPaneVirtualMemoryStatisticsAnalysis.html'; @element('tabpane-virtual-memory-statistics-analysis') export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { @@ -58,8 +59,8 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { private threadStatisticsData!: {}; private libStatisticsData!: {}; private functionStatisticsData!: {}; - private titleEl: HTMLDivElement | undefined | null; - private filterEl: TabPaneFilter | undefined | null; + private virtualMemoryTitleEl: HTMLDivElement | undefined | null; + private virtualMemoryFilterEl: TabPaneFilter | undefined | null; private hideProcessCheckBox: LitCheckBox | undefined | null; private hideThreadCheckBox: LitCheckBox | undefined | null; private checkBoxs: NodeListOf | undefined | null; @@ -82,7 +83,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.hideProcessCheckBox!.checked = false; this.hideThreadCheckBox!.checked = false; this.vmCurrentSelection = vmStatisticsAnalysisSelection; - this.titleEl!.textContent = ''; + this.virtualMemoryTitleEl!.textContent = ''; this.tabName!.textContent = ''; this.vmStatisticsAnalysisRange!.textContent = 'Selected range: ' + @@ -120,10 +121,10 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.tabName = this.shadowRoot!.querySelector('.vm-subheading'); this.vmStatisticsAnalysisProgressEL = this.shadowRoot?.querySelector('.vm-progress') as LitProgressBar; this.goBack(); - this.titleEl = this.shadowRoot!.querySelector('.title'); - this.filterEl = this.shadowRoot?.querySelector('#filter'); - this.filterEl!.setOptionsList(['Hide Process', 'Hide Thread']); - let popover = this.filterEl!.shadowRoot!.querySelector('#check-popover'); + this.virtualMemoryTitleEl = this.shadowRoot!.querySelector('.title'); + this.virtualMemoryFilterEl = this.shadowRoot?.querySelector('#filter'); + this.virtualMemoryFilterEl!.setOptionsList(['Hide Process', 'Hide Thread']); + let popover = this.virtualMemoryFilterEl!.shadowRoot!.querySelector('#check-popover'); this.hideProcessCheckBox = popover!!.querySelector('div > #hideProcess'); this.hideThreadCheckBox = popover!!.querySelector('div > #hideThread'); this.checkBoxs = popover!.querySelectorAll('.check-wrap > lit-check-box'); @@ -197,10 +198,10 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { } vmTab!.rowClickData = detail.data; let title = ''; - if (this.titleEl?.textContent === '') { + if (this.virtualMemoryTitleEl?.textContent === '') { title = detail.data.tableName; } else { - title = this.titleEl?.textContent + ' / ' + detail.data.tableName; + title = this.virtualMemoryTitleEl?.textContent + ' / ' + detail.data.tableName; } vmTab!.pieTitle = title; // 是否是在表格上右键点击跳转到火焰图的 @@ -232,17 +233,17 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.vmBack!.style.visibility = 'visible'; } else { this.vmBack!.style.visibility = 'hidden'; - this.titleEl!.textContent = ''; + this.virtualMemoryTitleEl!.textContent = ''; } if (this.vmTableArray) { - for (let table of this.vmTableArray) { - if (table === showTable) { - initSort(table!, this.vmSortColumn, this.vmSortType); - table.style.display = 'grid'; - table.setAttribute('hideDownload', ''); + for (let virtualMemoryTable of this.vmTableArray) { + if (virtualMemoryTable === showTable) { + initSort(virtualMemoryTable!, this.vmSortColumn, this.vmSortType); + virtualMemoryTable.style.display = 'grid'; + virtualMemoryTable.setAttribute('hideDownload', ''); } else { - table!.style.display = 'none'; - table!.removeAttribute('hideDownload'); + virtualMemoryTable!.style.display = 'none'; + virtualMemoryTable!.removeAttribute('hideDownload'); } } } @@ -346,7 +347,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = ''; + this.virtualMemoryTitleEl!.textContent = ''; this.tabName!.textContent = 'Statistic By Process AllDuration'; this.vmStatisticsAnalysisPidData.unshift(this.processStatisticsData); this.vmStatisticsAnalysisTableProcess!.recycleDataSource = this.vmStatisticsAnalysisPidData; @@ -371,7 +372,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.reset(this.vmStatisticsAnalysisTableType!, true); this.getVirtualMemoryType(it); this.vmProcessName = it.tableName; - this.titleEl!.textContent = this.vmProcessName; + this.virtualMemoryTitleEl!.textContent = this.vmProcessName; this.vmPieChart?.hideTip(); } @@ -402,7 +403,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { }, ], }; - this.titleEl!.textContent = this.vmProcessName; + this.virtualMemoryTitleEl!.textContent = this.vmProcessName; this.tabName!.textContent = 'Statistic By type AllDuration'; this.vmStatisticsAnalysisTypeData.unshift(this.typeStatisticsData); this.vmStatisticsAnalysisTableType!.recycleDataSource = this.vmStatisticsAnalysisTypeData; @@ -429,7 +430,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { if (this.vmtypeName.length > 0) { title += this.vmtypeName; } - this.titleEl!.textContent = title; + this.virtualMemoryTitleEl!.textContent = title; } private threadPieChart(): void { @@ -471,7 +472,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { if (this.vmtypeName.length > 0) { title += this.vmtypeName; } - this.titleEl!.textContent = title; + this.virtualMemoryTitleEl!.textContent = title; this.tabName!.textContent = 'Statistic By Thread AllDuration'; this.vmStatisticsAnalysisThreadData.unshift(this.threadStatisticsData); this.vmStatisticsAnalysisTableThread!.recycleDataSource = this.vmStatisticsAnalysisThreadData; @@ -486,17 +487,17 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.getVirtualMemorySo(it); this.vmThreadName = it.tableName; this.vmPieChart?.hideTip(); - let title = ''; + let virtualMemoryTitleTitle = ''; if (this.vmProcessName.length > 0) { - title += this.vmProcessName + ' / '; + virtualMemoryTitleTitle += this.vmProcessName + ' / '; } if (this.vmtypeName.length > 0) { - title += this.vmtypeName + ' / '; + virtualMemoryTitleTitle += this.vmtypeName + ' / '; } if (this.vmThreadName.length > 0) { - title += this.vmThreadName; + virtualMemoryTitleTitle += this.vmThreadName; } - this.titleEl!.textContent = title; + this.virtualMemoryTitleEl!.textContent = virtualMemoryTitleTitle; } private libraryPieChart(): void { @@ -552,7 +553,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { if (this.vmThreadName.length > 0) { title += this.vmThreadName; } - this.titleEl!.textContent = title; + this.virtualMemoryTitleEl!.textContent = title; this.tabName!.textContent = 'Statistic By Library AllDuration'; this.vmStatisticsAnalysisSoData.unshift(this.libStatisticsData); this.vmStatisticsAnalysisTableSo!.recycleDataSource = this.vmStatisticsAnalysisSoData; @@ -579,7 +580,7 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { if (it.tableName.length > 0) { title += it.tableName; } - this.titleEl!.textContent = title; + this.virtualMemoryTitleEl!.textContent = title; } private sortByColumn(): void { @@ -1076,109 +1077,15 @@ export class TabPaneVirtualMemoryStatisticsAnalysis extends BaseElement { this.vmStatisticsAnalysisTableFunction!.style.height = this.parentElement!.clientHeight - 50 + 'px'; this.vmStatisticsAnalysisTableFunction?.reMeauseHeight(); if (this.parentElement!.clientHeight >= 0 && this.parentElement!.clientHeight <= 31) { - this.filterEl!.style.display = 'none'; + this.virtualMemoryFilterEl!.style.display = 'none'; } else { - this.filterEl!.style.display = 'flex'; + this.virtualMemoryFilterEl!.style.display = 'flex'; } } }).observe(this.parentElement!); } initHtml(): string { - return ` - - -
      - -
      -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - - - - - - - - - - - - - -
      -
      - -`; + return TabPaneVirtualMemoryStatisticsAnalysisHtml; } } diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts deleted file mode 100644 index 35827ad2750227e741a2b96df6d5275145e2d62a..0000000000000000000000000000000000000000 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqDataCut.ts +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Copyright (C) 2023 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, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; -import { SelectionParam } from '../../../../bean/BoxSelection'; -import '../../../StackBar'; -import { getTabRunningPercent } from '../../../../database/sql/ProcessThread.sql'; -import { queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/sql/Cpu.sql'; -import { querySearchFuncData } from '../../../../database/sql/Func.sql'; -import { Utils } from '../../base/Utils'; -import { resizeObserver } from '../SheetUtils'; -import { LitChartScatter } from '../../../../../base-ui/chart/scatter/LitChartScatter'; -import { SpSegmentationChart } from '../../../chart/SpSegmentationChart'; -import { TabPaneFreqUsageConfig, type TabPaneRunningConfig, TabPaneCpuFreqConfig} from './TabPaneFreqUsageConfig'; - -@element('tabpane-freqdatacut') -export class TabPaneFreqDataCut extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private threadStatesTblSource: Array = []; - private currentSelectionParam: SelectionParam | any; - private threadStatesDIV: HTMLDivElement | null | undefined; - private scatterInput: HTMLInputElement | null | undefined; - private initData: Map> = new Map(); - private processArr: Array = []; - private threadArr: Array = []; - private statisticsScatter: LitChartScatter | null | undefined; - - set data(threadStatesParam: SelectionParam) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } - this.currentSelectionParam = threadStatesParam; - this.initData = new Map(); - this.threadArr = []; - this.initUI(); - this.init(threadStatesParam); - let pidArr: Array = []; - // 整理进程级的数组信息 - let processArr: Array = - threadStatesParam.processIds.length > 1 - ? [...new Set(threadStatesParam.processIds)] - : threadStatesParam.processIds; - for (let i of processArr) { - pidArr.push( - new TabPaneFreqUsageConfig( - Utils.PROCESS_MAP.get(i) === null ? 'Process ' + i : Utils.PROCESS_MAP.get(i) + ' ' + i, - '', i, '', 0, '', '', 0, '', 0, 'process', -1, []) - ); - } - // 拷贝给私有属性,以便后续进行数据切割时免除整理进程层级数据 - this.processArr = pidArr; - } - /** - * 初始化数据 - */ - async init(threadStatesParam: SelectionParam): Promise { - let {runningMap, sum}: { - runningMap: Map>, - sum: number - } - = await this.queryRunningData(threadStatesParam); - let cpuFreqData: Array = await this.queryCpuFreqData( - threadStatesParam - ); - if (runningMap.size > 0) { - // 将cpu频点数据与running状态数据整合,保证其上该段时长内有对应的cpu频点数据 - this.mergeFreqData(runningMap, cpuFreqData, sum); - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - } - } - /** - * 重置UI输入框等组件为默认状态 - */ - initUI(): void { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - // @ts-ignore - this.threadStatesTbl.value = []; - // @ts-ignore - this.shadowRoot?.querySelector('#dataCutThreadId').style.border = '1px solid rgb(151,151,151)'; - // @ts-ignore - this.shadowRoot?.querySelector('#dataCutThreadFunc').style.border = '1px solid rgb(151,151,151)'; - // @ts-ignore - this.shadowRoot?.querySelector('#maxFreq').style.border = '1px solid rgb(151,151,151)'; - // @ts-ignore - this.shadowRoot?.querySelector('#maxHz').style.border = '1px solid rgb(151,151,151)'; - // @ts-ignore - this.shadowRoot?.querySelector('#cycle-a-start-range').value = ''; - // @ts-ignore - this.shadowRoot?.querySelector('#cycle-a-end-range').value = ''; - // @ts-ignore - this.shadowRoot?.querySelector('#cycle-b-start-range').value = ''; - // @ts-ignore - this.shadowRoot?.querySelector('#cycle-b-end-range').value = ''; - // @ts-ignore - this.shadowRoot?.querySelector('#cycleQuery')!.style.display = 'none'; - // @ts-ignore - this.statisticsScatter!.config = undefined; - this.parentElement!.style.overflow = 'hidden'; - } - /** - * 查询cpu频点信息 - */ - async queryCpuFreqData(threadStatesParam: SelectionParam): Promise> { - // 查询cpu及id信息 - let result: Array<{ id: number; cpu: number }> = await queryCpuFreqFilterId(); - // 以键值对形式将cpu及id进行对应,后续会将频点数据与其对应cpu进行整合 - let idMap: Map = new Map(); - let queryId: Array = []; - for (let i = 0; i < result.length; i++) { - queryId.push(result[i].id); - idMap.set(result[i].id, result[i].cpu); - } - let dealArr: Array = []; - // 通过id去查询频点数据 - let res: Array<{ - startNS: number; - filter_id: number; - value: number; - dur: number} - > = await queryCpuFreqUsageData(queryId); - for (let i of res) { - dealArr.push( - new TabPaneCpuFreqConfig( - i.startNS + threadStatesParam.recordStartNs, - idMap.get(i.filter_id)!, - i.value, - i.dur - )); - } - return dealArr; - } - - /** - * 查询框选区域内的所有running状态数据 - */ - async queryRunningData(threadStatesParam: SelectionParam): - Promise<{runningMap: Map>; sum: number}> { - let result: Array - = await getTabRunningPercent(threadStatesParam.threadIds, threadStatesParam.leftNs, threadStatesParam.rightNs); - let needDeal: Map> = new Map(); - let sum: number = 0; - if (result !== null && result.length > 0) { - let processArr: Array = threadStatesParam.processIds.length > 1 - ? [...new Set(threadStatesParam.processIds)] : threadStatesParam.processIds; - for (let e of result) { - if (processArr.includes(e.pid)) { - if (needDeal.get(e.pid + '_' + e.tid) === undefined) { - this.threadArr.push( - new TabPaneFreqUsageConfig(Utils.THREAD_MAP.get(e.tid) + ' ' + e.tid, - '', e.pid, e.tid, 0, '', '', 0, '', 0, 'thread', -1, []) - ); - needDeal.set(e.pid + '_' + e.tid, new Array()); - } - if (e.ts < threadStatesParam.leftNs + threadStatesParam.recordStartNs && - e.ts + e.dur > threadStatesParam.leftNs + threadStatesParam.recordStartNs) { - const ts = e.ts; - e.ts = threadStatesParam.leftNs + threadStatesParam.recordStartNs; - e.dur = ts + e.dur - (threadStatesParam.leftNs + threadStatesParam.recordStartNs); - } - if (e.ts + e.dur > threadStatesParam.rightNs + threadStatesParam.recordStartNs) { - e.dur = threadStatesParam.rightNs + threadStatesParam.recordStartNs - e.ts; - } - e.process = Utils.PROCESS_MAP.get(e.pid) === null ? '[NULL]' : Utils.PROCESS_MAP.get(e.pid)!; - e.thread = Utils.THREAD_MAP.get(e.tid) === null ? '[NULL]' : Utils.THREAD_MAP.get(e.tid)!; - let arr: Array | undefined = needDeal.get(e.pid + '_' + e.tid); - sum += e.dur; - arr?.push(e); - } - } - } - return {'runningMap': needDeal, 'sum': sum}; - } - - /** - * 将cpu频点数据与running状态数据整合,保证其上该段时长内有对应的cpu频点数据 - */ - mergeFreqData( - needDeal: Map>, - dealArr: Array, - sum: number - ): void { - needDeal.forEach((value: Array, key: string) => { - let resultList: Array = []; - for (let i = 0; i < value.length; i++) { - for (let j = 0; j < dealArr.length; j++) { - // 只需要判断running状态数据与频点数据cpu相同的情况 - if (value[i].cpu === dealArr[j].cpu) { - // running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running状态数据的持续时间小于频点结束时间减去running状态数据开始时间的情况 - if (value[i].ts > dealArr[j].startNS && - value[i].ts < dealArr[j].startNS + dealArr[j].dur && - value[i].dur < dealArr[j].startNS + dealArr[j].dur - value[i].ts) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, - value[i].tid, 0, value[i].cpu,dealArr[j].value, value[i].dur, '', (value[i].dur / sum) * 100, - 'freqdata', -1, undefined)); - break; - } - // running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running状态数据的持续时间大于频点结束时间减去running状态数据开始时间的情况 - if (value[i].ts > dealArr[j].startNS && - value[i].ts < dealArr[j].startNS + dealArr[j].dur && - value[i].dur > dealArr[j].startNS + dealArr[j].dur - value[i].ts) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, - value[i].tid, 0, value[i].cpu, dealArr[j].value, dealArr[j].startNS + dealArr[j].dur - value[i].ts, '', - ((dealArr[j].startNS + dealArr[j].dur - value[i].ts) / sum) * 100, 'freqdata', -1, undefined)); - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的结束时间大于频点数据开始时间。且running状态数据在频点数据开始时间后的持续时间小于频点数据持续时间的情况 - if (value[i].ts < dealArr[j].startNS && - value[i].ts + value[i].dur > dealArr[j].startNS && - value[i].dur + value[i].ts - dealArr[j].startNS < dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, dealArr[j].startNS, value[i].pid, - value[i].tid, 0, value[i].cpu, dealArr[j].value, value[i].dur + value[i].ts - dealArr[j].startNS, '', - ((value[i].dur + value[i].ts - dealArr[j].startNS) / sum) * 100, 'freqdata', -1, undefined )); - break; - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的结束时间大于频点数据开始时间。且running状态数据在频点数据开始时间后的持续时间大于频点数据持续时间的情况 - if (value[i].ts < dealArr[j].startNS && - value[i].ts + value[i].dur > dealArr[j].startNS && - value[i].dur + value[i].ts - dealArr[j].startNS > dealArr[j].dur) { - resultList.push(new TabPaneFreqUsageConfig( value[i].thread, dealArr[j].startNS, value[i].pid, value[i].tid, - 0, value[i].cpu, dealArr[j].value, dealArr[j].dur, '', (dealArr[j].dur / sum) * 100, 'freqdata', -1, undefined)); - } - // running状态数据的开始时间小于频点数据开始时间,running状态数据的持续时间小于频点数据开始时间的情况 - if (value[i].ts < dealArr[j].startNS && value[i].ts + value[i].dur < dealArr[j].startNS) { - resultList.push(new TabPaneFreqUsageConfig(value[i].thread, value[i].ts, value[i].pid, value[i].tid, - 0, value[i].cpu, 'unknown', value[i].dur, '', (value[i].dur / sum) * 100, 'freqdata', -1, undefined)); - break; - } - } - } - } - this.initData.set(key, resultList); - }); - } - /** - * single方式切割数据功能 - */ - dataSingleCut( - threadId: HTMLInputElement, - threadFunc: HTMLInputElement, - resultList: Map> - ): void { - let threadIdValue: string = threadId.value.trim(); - let threadFuncName: string = threadFunc.value.trim(); - let rightNS: number = this.currentSelectionParam.rightNs; - let recordStartNs: number = this.currentSelectionParam.recordStartNs; - // @ts-ignore - this.threadStatesTbl.value = []; - if (threadIdValue !== '' && threadFuncName !== '') { - // 根据用户输入的线程ID,方法名去查询数据库,得到对应的方法起始时间,持续时间等数据,以便作为依据进行后续数据切割 - querySearchFuncData(threadFuncName, Number(threadIdValue), this.currentSelectionParam.leftNs, rightNS).then((result) => { - if (result !== null && result.length > 0) { - // targetMap为全局initData的拷贝对象,dealArr数组用来存放周期切割依据数据 - let targetMap: Map> = new Map(); - let dealArr: Array<{ts: number, dur: number}> = []; - // 新创建map对象接收传过来的实参map - resultList.forEach((item: Array, key: string) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }); - // 整理周期切割依据的数据 - for (let i of result) { - if (i.startTime! + recordStartNs + i.dur! < rightNS + recordStartNs) { - dealArr.push({ts: i.startTime! + recordStartNs, dur: i.dur!}); - } - } - let cycleMap: Map> = new Map(); - let totalList: Map> = new Map(); - this.mergeSingleData(dealArr, targetMap, cycleMap, totalList); - // 拷贝线程数组,防止数据污染 - let threadArr: Array = JSON.parse(JSON.stringify(this.threadArr)); - // 拷贝进程数组,防止数据污染 - let processArr: Array = JSON.parse(JSON.stringify(this.processArr)); - // 将周期层级防止到线程层级下 - this.mergeThreadData(threadArr, cycleMap); - // 将原始数据放置到对应的线程层级下,周期数据前 - this.mergeTotalData(threadArr, this.merge(totalList)); - // 合并数据到进程层级下 - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - } - this.threadStatesTbl!.loading = false; - }); - } else { - this.threadStatesTbl!.loading = false; - if (threadIdValue === '') { - threadId.style.border = '2px solid rgb(255,0,0)'; - } - if (threadFuncName === '') { - threadFunc.style.border = '2px solid rgb(255,0,0)'; - } - } - } - /** - * 整合Single切割方式中的频点数据与方法周期数据 - */ - mergeSingleData( - dealArr: Array<{ts: number, dur: number}>, - targetMap: Map>, - cycleMap: Map>, - totalList: Map> - ): void { - let timeDur = this.currentSelectionParam.recordStartNs; - targetMap.forEach((value: any, key) => { - cycleMap.set(key, new Array()); - totalList.set(key, new Array()); - for (let i = 0; i < dealArr.length; i++) { - let cpuArr: Array = []; - let resList: Array = []; - let cpuMap: Map> = new Map(); - // 时间倍数值 - const countMutiple: number = 1000000; - const MIN_NUM: number = 3; - cpuMap.set(key, new Array()); - cycleMap.get(key)?.push( - new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[0].thread, - ((dealArr[i].ts - timeDur) / countMutiple).toFixed(MIN_NUM), key.split('_')[0], key.split('_')[1], - 0, '', '', 0, (dealArr[i].dur / countMutiple).toFixed(MIN_NUM), 0, 'cycle', i + 1, [] )); - this.dismantlingSingle( - value, - dealArr[i], - { - i: i, - key: key, - countMutiple: countMutiple, - cpuArr, - cpuMap - }, - resList, - totalList - ); - this.mergeData(resList); - // 整理排序相同周期下的数据 - this.mergeCpuData(cpuMap.get(key)!, resList); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)![i], cpuMap.get(key)!); - } - }); - } - - /** - * 拆解Single大函数 - * @param value 频点数据数组 - * @param funData 方法对象 - * @param constant 常量 - * @param resList 周期数组 - * @param totalList total数组 - */ - dismantlingSingle( - value: Array, funData: {ts: number, dur: number}, - constant: {i: number, key: string, countMutiple: number, cpuArr: Array, cpuMap: Map>}, - resList: Array, - totalList: Map> - ): void{ - // 判断若用户导入json文件,则替换为对应cpu下的对应频点的算力值进行算力消耗计算 - for (let j = 0; j < value.length; j++) { - let startTime = Number(value[j].ts); - let percent = Number(value[j].percent); - // @ts-ignore - let consumptionMap: Map = - SpSegmentationChart.freqInfoMapData.size > 0 && SpSegmentationChart.freqInfoMapData.get(Number(value[j].cpu)); - // 若存在算力值,则直接取值做计算。若不存在算力值,且频点值不为unknown的情况,则取频点值做计算,若为unknown,则取0做兼容 - const consumption: number = Number(consumptionMap && consumptionMap.get(Number(value[j].freq)) - ? consumptionMap.get(Number(value[j].freq)) : (value[j].freq === 'unknown' ? 0 : value[j].freq)); - if (!constant.cpuArr.includes(Number(value[j].cpu))) { - constant.cpuArr.push(Number(value[j].cpu)); - constant.cpuMap.get(constant.key)?.push( - new TabPaneFreqUsageConfig('cycle' + (constant.i + 1) + '—' + value[j].thread, '', - value[j].pid, value[j].tid, 0, value[j].cpu, '', 0, '', 0, 'cpu', -1, [])); - } - // 以下为频点数据按Single周期切割数据如何取舍的判断条件,dealArr为周期切割依据,value为某一线程下的频点汇总数据 - // 如果频点数据开始时间大于某一周期起始时间,小于该周期的结束时间。且频点数据结束时间小于周期结束时间的情况 - if (funData.ts < startTime && funData.ts + funData.dur > startTime && - funData.ts + funData.dur > startTime + value[j].dur) { - resList.push(this.returnSingleObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 1)!); - totalList.get(constant.key)?.push(this.returnSingleObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 1)!); - } - // 如果频点数据开始时间大于某一周期起始时间,小于该周期的结束时间。且频点数据结束时间大于等于周期结束时间的情况 - if (funData.ts < startTime && funData.ts + funData.dur > startTime && - funData.ts + funData.dur <= startTime + value[j].dur) { - resList.push(this.returnSingleObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 2)!); - totalList.get(constant.key)?.push(this.returnSingleObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 2)!); - break; - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该周期的开始时间。且频点数据结束时间大于周期结束时间的情况 - if (funData.ts > startTime && startTime + value[j].dur > funData.ts && - startTime + value[j].dur > funData.ts + funData.dur) { - resList.push(this.returnSingleObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 3)!); - totalList.get(constant.key)?.push(this.returnSingleObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 3)!); - break; - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该周期的开始时间。且频点数据结束时间小于等于周期结束时间的情况 - if (funData.ts > startTime && startTime + value[j].dur > funData.ts && - startTime + value[j].dur <= funData.ts + funData.dur) { - resList.push(this.returnSingleObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 4)!); - totalList.get(constant.key)?.push(this.returnSingleObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], funData, 4)!); - } - } - } - /** - * - * @param str 周期列头 - * @param arg 常量参数 - * @param value 频点数据对象 - * @param funData 方法对象 - * @param flag 标志位 - * @returns 频点数据对象 - */ - returnSingleObj( - str: string, - arg: {i: number, percent: number, startTime: number, consumption: number, countMutiple: number}, - value: TabPaneFreqUsageConfig, - funData: {ts: number, dur: number}, - flag: number - ): TabPaneFreqUsageConfig | undefined{ - switch (flag) { - case 1: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, (arg.consumption * value.dur) / arg.countMutiple, - value.cpu, value.freq, value.dur, '', arg.percent, 'freqdata', arg.i, undefined); - case 2: - return new TabPaneFreqUsageConfig(str,'', value.pid, value.tid, ((funData.ts + funData.dur - arg.startTime) - * arg.consumption) / arg.countMutiple, value.cpu, value.freq, funData.ts + funData.dur - arg.startTime, '', - ((funData.ts + funData.dur - arg.startTime) / value.dur) * arg.percent, 'freqdata', arg.i, undefined); - case 3: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, (funData.dur * arg.consumption) / arg.countMutiple, value.cpu, - value.freq, funData.dur, '', (funData.dur / value.dur) * arg.percent, 'freqdata', arg.i, undefined); - case 4: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, - ((arg.startTime + value.dur - funData.ts) * arg.consumption) / arg.countMutiple, - value.cpu, value.freq, arg.startTime + value.dur - funData.ts, '', - ((arg.startTime + value.dur - funData.ts) / value.dur) * arg.percent, - 'freqdata', arg.i, undefined); - default: - break; - } - } - - /** - * Loop方式切割数据功能 - */ - dataLoopCut( - threadId: HTMLInputElement, - threadFunc: HTMLInputElement, - resultList: Map> - ): void { - let threadIdValue: string = threadId.value.trim(); - let threadFuncName: string = threadFunc.value.trim(); - let rightNS: number = this.currentSelectionParam.rightNs; - let recordStartNs: number = this.currentSelectionParam.recordStartNs; - // @ts-ignore - this.threadStatesTbl.value = []; - if (threadIdValue !== '' && threadFuncName !== '') { - querySearchFuncData(threadFuncName, Number(threadIdValue), this.currentSelectionParam.leftNs, rightNS).then((res) => { - if (res !== null && res.length > 0) { - // targetMap为全局initData的拷贝对象,cutArr数组用来存放周期切割依据数据 - let targetMap: Map> = new Map(); - let cutArr: Array<{ts: number, dur?: number}> = []; - // 新创建map对象接收传过来的实参map - resultList.forEach((item: Array, key: string) => { - targetMap.set(key, JSON.parse(JSON.stringify(item))); - }); - // 根据线程id及方法名获取的数据,处理后用作切割时间依据,时间跨度为整个方法开始时间到末个方法开始时间 - for (let i of res) { - cutArr[cutArr.length - 1] && (cutArr[cutArr.length - 1].dur = i.startTime ? i.startTime + - recordStartNs - cutArr[cutArr.length - 1].ts : 0); - cutArr.push({ts: i.startTime! + recordStartNs}); - } - let cycleMap: Map> = new Map(); - let totalList: Map> = new Map(); - this.mergeLoopData(cutArr, targetMap, cycleMap, totalList); - let threadArr: Array = JSON.parse(JSON.stringify(this.threadArr)); - let processArr: Array = JSON.parse(JSON.stringify(this.processArr)); - this.mergeThreadData(threadArr, cycleMap); - this.mergeTotalData(threadArr, this.merge(totalList)); - this.mergePidData(processArr, threadArr); - this.fixedDeal(processArr); - this.threadStatesTblSource = processArr; - this.threadStatesTbl!.recycleDataSource = processArr; - this.threadClick(processArr); - } else { - this.threadStatesTblSource = []; - this.threadStatesTbl!.recycleDataSource = []; - } - }); - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTbl!.loading = false; - if (threadIdValue === '') { - threadId.style.border = '2px solid rgb(255,0,0)'; - } - if (threadFuncName === '') { - threadFunc.style.border = '2px solid rgb(255,0,0)'; - } - } - } - /** - * 整合Loop切割方式中的频点数据与方法周期数据 - */ - mergeLoopData( - cutArr: Array<{ts: number, dur?: number}>, - targetMap: Map>, - cycleMap: Map>, - totalList: Map> - ): void { - let timeDur: number = this.currentSelectionParam.recordStartNs; - targetMap.forEach((value: any, key) => { - cycleMap.set(key, new Array()); - totalList.set(key, new Array()); - for (let i = 0; i < cutArr.length - 1; i++) { - let cpuArr: Array = []; - let resList: Array = []; - let cpuMap: Map> = new Map(); - // 时间倍数值 - const countMutiple: number = 1000000; - const MIN_NUM: number = 3; - cpuMap.set(key, new Array()); - // 创建周期层级数据 - cycleMap.get(key)?.push(new TabPaneFreqUsageConfig('cycle' + (i + 1) + '—' + value[0].thread, - ((cutArr[i].ts - timeDur) / countMutiple).toFixed(MIN_NUM), key.split('_')[0], key.split('_')[1], 0, '', - '', 0, (cutArr[i].dur! / countMutiple).toFixed(MIN_NUM), 0, 'cycle', i + 1, [])); - this.dismantlingLoop( - value, - cutArr, - { - i: i, - key: key, - countMutiple: countMutiple, - cpuArr, - cpuMap - }, - resList, - totalList - ); - // 合并相同周期内的数据 - this.mergeData(resList); - // 整理排序相同周期下的数据 - this.mergeCpuData(cpuMap.get(key)!, resList); - // 将cpu数据放置到对应周期层级下 - this.mergeCycleData(cycleMap.get(key)![i], cpuMap.get(key)!); - } - }); - } - /** - * 拆解Loop大函数 - * @param value 频点数据数组 - * @param funData 方法对象 - * @param constant 常量 - * @param resList 周期数组 - * @param totalList total数组 - */ - dismantlingLoop( - value: Array, cutArr:Array<{ts: number, dur?: number}>, - constant: {i: number, key: string, countMutiple: number, cpuArr: Array, cpuMap: Map>}, - resList: Array, - totalList: Map>): void { - for (let j = 0; j < value.length; j++) { - // 判断若用户导入json文件,则替换为对应cpu下的对应频点的算力值进行算力消耗计算 - let startTime = Number(value[j].ts); - let percent = Number(value[j].percent); - // @ts-ignore - let consumptionMap: Map = - SpSegmentationChart.freqInfoMapData.size > 0 && SpSegmentationChart.freqInfoMapData.get(Number(value[j].cpu)); - // 若存在算力值,则直接取值做计算。若不存在算力值,且频点值不为unknown的情况,则取频点值做计算,若为unknown,则取0做兼容 - const consumption: number = Number(consumptionMap && consumptionMap.get(Number(value[j].freq)) - ? consumptionMap.get(Number(value[j].freq)) : (value[j].freq === 'unknown' ? 0 : value[j].freq)); - if (!constant.cpuArr.includes(Number(value[j].cpu))) { - constant.cpuArr.push(Number(value[j].cpu)); - // 创建cpu层级数据,以便后续生成树结构 - constant.cpuMap.get(constant.key)?.push(new TabPaneFreqUsageConfig('cycle' + (constant.i + 1) + '—' + value[j].thread, - '', value[j].pid, value[j].tid, 0, value[j].cpu, '', 0, '', 0, 'cpu', -1, [])); - } - // 以下为频点数据按Loop周期切割数据如何取舍的判断条件,cutArr为周期切割依据,value为某一线程下的频点汇总数据 - // 如果频点数据开始时间大于某一周期起始时间,且结束时间小于等于下一同名方法开始时间的情况 - if (startTime >= cutArr[constant.i].ts && startTime + value[j].dur <= cutArr[constant.i + 1].ts) { - resList.push(this.returnLoopObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 1)!); - totalList.get(constant.key)?.push(this.returnLoopObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 1)!); - } - // 如果频点数据开始时间大于某一周期起始时间,且结束时间大于下一同名方法开始时间的情况 - if (startTime >= cutArr[constant.i].ts && startTime + value[j].dur > cutArr[constant.i + 1].ts) { - if (cutArr[constant.i + 1].ts - startTime > 0) { - resList.push(this.returnLoopObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 2)!); - totalList.get(constant.key)?.push(this.returnLoopObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 2)!); - break; - } - } - // 如果频点数据开始时间小于某一周期起始时间,且结束时间大于下一同名方法开始时间的情况 - if (startTime < cutArr[constant.i].ts && startTime + value[j].dur > cutArr[constant.i + 1].ts) { - resList.push(this.returnLoopObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 3)!); - totalList.get(constant.key)?.push(this.returnLoopObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 3)!); - } - // 如果频点数据开始时间小于某一周期起始时间,结束时间大于该方法开始时间。且频点数据结束时间小于下一同名方法开始时间 - if (startTime < cutArr[constant.i].ts && - startTime + value[j].dur > cutArr[constant.i].ts && startTime + value[j].dur < cutArr[constant.i + 1].ts) { - resList.push(this.returnLoopObj('cycle' + (constant.i + 1) + '—' + value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 4)!); - totalList.get(constant.key)?.push(this.returnLoopObj(value[j].thread, - {i: constant.i, percent, startTime, consumption, countMutiple: constant.countMutiple} ,value[j], cutArr, 4)!); - } - } - } - - /** - * - * @param str 周期列头 - * @param arg 常量参数 - * @param value 频点数据对象 - * @param funData 方法对象 - * @param flag 标志位 - * @returns 频点数据对象 - */ - returnLoopObj( - str: string, - arg: {i: number, percent: number, startTime: number, consumption: number, countMutiple: number}, - value: TabPaneFreqUsageConfig, - cutArr: Array<{ts: number, dur?: number}>, - flag: number - ): TabPaneFreqUsageConfig | undefined{ - switch (flag) { - case 1: - return new TabPaneFreqUsageConfig(str, '', value.pid, - value.tid, (arg.consumption * value.dur) / arg.countMutiple, value.cpu, value.freq, - value.dur, '', value.percent, 'freqdata', arg.i, undefined); - case 2: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, - (arg.consumption * (cutArr[arg.i + 1].ts - arg.startTime)) / arg.countMutiple, value.cpu, value.freq, - cutArr[arg.i + 1].ts - arg.startTime, '', arg.percent * ((cutArr[arg.i + 1].ts - arg.startTime) / value.dur), - 'freqdata', arg.i, undefined); - case 3: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, - (arg.consumption * (cutArr[arg.i + 1].ts - cutArr[arg.i].ts)) / arg.countMutiple, value.cpu, value.freq, - cutArr[arg.i + 1].ts - cutArr[arg.i].ts, '', arg.percent * ((cutArr[arg.i + 1].ts - cutArr[arg.i].ts) / value.dur), - 'freqdata', arg.i, undefined); - case 4: - return new TabPaneFreqUsageConfig(str, '', value.pid, value.tid, (arg.consumption * (value.dur + arg.startTime - cutArr[arg.i].ts)) - / arg.countMutiple, value.cpu, value.freq, value.dur + arg.startTime - cutArr[arg.i].ts, '', arg.percent - * ((value.dur + arg.startTime - cutArr[arg.i].ts) / value.dur), 'freqdata', arg.i, undefined); - default: - break; - } - } - - /** - * 切割后整合好的周期频点数据放置到对应的线程下 - */ - mergeThreadData( - threadArr: Array, - cycleMap: Map> - ): void { - for (let i = 0; i < threadArr.length; i++) { - let cycleMapData: Array = cycleMap.get( - threadArr[i].pid + '_' + threadArr[i].tid - )!; - for (let j = 0; j < cycleMapData!.length; j++) { - threadArr[i].children?.push(cycleMapData![j]); - threadArr[i].count += cycleMapData![j].count; - threadArr[i].dur += cycleMapData![j].dur; - // @ts-ignore - threadArr[i].percent += cycleMapData![j].percent; - } - } - } - /** - * 切割后整合好的线程级频点数据放置到对应的进程 - */ - mergePidData( - pidArr: Array, - threadArr: Array - ): void { - for (let i = 0; i < pidArr.length; i++) { - for (let j = 0; j < threadArr.length; j++) { - if (pidArr[i].pid === threadArr[j].pid) { - pidArr[i].children?.push(threadArr[j]); - pidArr[i].count += threadArr[j].count; - pidArr[i].dur += threadArr[j].dur; - // @ts-ignore - pidArr[i].percent += threadArr[j].percent; - } - } - } - } - /** - * 合并相同周期内运行所在cpu相同、频点相同的数据 - */ - mergeData(resList: Array): void { - // 合并相同周期内的数据 - for (let i = 0; i < resList.length; i++) { - for (let j = i + 1; j < resList.length; j++) { - if ( - resList[i].cpu === resList[j].cpu && - resList[i].freq === resList[j].freq && - resList[i].id === resList[j].id - ) { - resList[i].dur += resList[j].dur; - // @ts-ignore - resList[i].percent += resList[j].percent; - resList[i].count += resList[j].count; - resList.splice(j, 1); - j--; - } - } - } - } - /** - * 将cpu层级数据放到对应的周期层级下 - */ - mergeCycleData( - obj: TabPaneFreqUsageConfig, - arr: Array - ): void { - for (let i = 0; i < arr!.length; i++) { - if (arr![i].count === 0 && arr![i].dur === 0) { - continue; - } - obj.children?.push(arr![i]); - obj.count += arr![i].count; - obj.dur += arr![i].dur; - // @ts-ignore - obj.percent += arr![i].percent; - } - } - /** - * 将切割好的不区分周期的数据作为total数据放到对应的线程层级下,周期数据前 - */ - mergeTotalData( - threadArr: Array, - totalData: Array - ): void { - for (let i = 0; i < threadArr.length; i++) { - for (let j = 0; j < totalData.length; j++) { - if ( - Number(threadArr[i].pid) === Number(totalData[j].pid) && - Number(threadArr[i].tid) === Number(totalData[j].tid) - ) { - totalData[j].thread = 'TotalData'; - // @ts-ignore - threadArr[i].children.unshift(totalData[j]); - } - } - } - } - /** - * 整理排序相同周期下的数据 - */ - mergeCpuData( - cpuArray: Array, - resList: Array - ): void { - // 以算力消耗降序排列 - resList.sort((a, b) => b.count - a.count); - // 以cpu升序排列 - cpuArray.sort(( - a: TabPaneFreqUsageConfig, - b: TabPaneFreqUsageConfig - ) => Number(a.cpu) - Number(b.cpu)); - cpuArray.forEach((item: TabPaneFreqUsageConfig) => { - for (let s = 0; s < resList.length; s++) { - if (item.cpu === resList[s].cpu) { - item.children?.push(resList[s]); - item.count += resList[s].count; - item.dur += resList[s].dur; - // @ts-ignore - item.percent += resList[s].percent; - } - } - }); - } - /** - * 切割好的不区分周期的数据,以相同cpu相同频点的进行整合 - */ - merge( - totalList: Map> - ): Array { - let result: Array = new Array(); - totalList.forEach((value: Array, key: string) => { - let countNum = result.push( - new TabPaneFreqUsageConfig('', '', key.split('_')[0], key.split('_')[1], - 0, '', '', 0, '', 0, 'cycle', 0, [] - ) - ); - let cpuArr: Array = []; - let flagArr: Array = []; - for (let i = 0; i < value.length; i++) { - if (!flagArr.includes(value[i].cpu)) { - flagArr.push(value[i].cpu); - let flag = cpuArr.push( - new TabPaneFreqUsageConfig(value[i].thread, '', value[i].pid, value[i].tid, - 0, value[i].cpu, '', 0, '', 0, 'cpu', -1, [] - ) - ); - result[countNum - 1].children?.push(cpuArr[flag - 1]); - } - for (let j = i + 1; j < value.length; j++) { - if (value[i].cpu === value[j].cpu && value[i].freq === value[j].freq) { - value[i].dur += value[j].dur; - // @ts-ignore - value[i].percent += value[j].percent; - value[i].count += value[j].count; - value.splice(j, 1); - j--; - } - } - } - result[countNum - 1].children?.sort((a: TabPaneFreqUsageConfig, b: TabPaneFreqUsageConfig) => Number(a.cpu) - Number(b.cpu)); - for (let i = 0; i < cpuArr.length; i++) { - for (let j = 0; j < value.length; j++) { - if (cpuArr[i].cpu === value[j].cpu) { - cpuArr[i].children?.push(value[j]); - cpuArr[i].dur += value[j].dur; - cpuArr[i].count += value[j].count; - // @ts-ignore - cpuArr[i].percent += value[j].percent; - } - } - result[countNum - 1].dur += cpuArr[i].dur; - result[countNum - 1].count += cpuArr[i].count; - // @ts-ignore - result[countNum - 1].percent += cpuArr[i].percent; - } - }); - return result; - } - /** - * 递归整理数据,取小数位数,转换单位 - */ - fixedDeal(arr: Array): void { - if (arr === undefined) { - return; - } - for (let i = 0; i < arr.length; i++) { - // @ts-ignore - arr[i].percent = arr[i].percent.toFixed(2); - // @ts-ignore - arr[i].dur = (arr[i].dur / 1000000).toFixed(3); - if (arr[i].freq !== '') { - if (arr[i].freq === 'unknown') { - arr[i].freq = 'unknown'; - } else { - // @ts-ignore - arr[i].freq = arr[i].freq / 1000; - } - } - if (!(SpSegmentationChart.freqInfoMapData.size > 0)) { - // @ts-ignore - arr[i].count = (arr[i].count / 1000).toFixed(3); - } else { - // @ts-ignore - arr[i].count = arr[i].count.toFixed(3); - } - // @ts-ignore - this.fixedDeal(arr[i].children); - } - } - - /** - * 绑定表格点击事件 - */ - private threadClick(data: Array): void { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (!this.threadStatesTblSource.length && !this.threadStatesTbl!.recycleDataSource.length) { - data = []; - } - if (label.includes('Process') && i === 0) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Thread') && i === 1) { - for (let item of data) { - // @ts-ignore - item.status = true; - if (item.children !== undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement( data, RedrawTreeForm.Retract); - } else if (label.includes('Cycle') && i === 2) { - for (let item of data) { - // @ts-ignore - item.status = true; - for (let value of item.children ? item.children : []) { - // @ts-ignore - value.status = true; - if (value.children !== undefined && value.children.length > 0) { - this.threadStatesTbl!.setStatus(value.children, false); - } - } - } - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('CPU') && i === 3) { - this.threadStatesTbl!.setStatus(data, true); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - } - }); - } - } - } - /** - * 散点图渲染数据整理 - */ - render(res: Array, str: string, queryCycleScatter: Array): void { - let maxFreq: HTMLInputElement = this.scatterInput!.querySelector('#maxFreq')!; - let maxHz: HTMLInputElement = this.scatterInput!.querySelector('#maxHz')!; - if (maxFreq.value && maxHz.value) { - if (/^[0-9]*$/.test(maxFreq.value) && /^[0-9]*$/.test(maxHz.value)) { - this.organizeData(res, str, queryCycleScatter, maxFreq.value, maxHz.value); - } else { - if (!/^[0-9]*$/.test(maxFreq.value)) { - maxFreq.style.border = '2px solid rgb(255,0,0)'; - } - if (!/^[0-9]*$/.test(maxHz.value)) { - maxHz.style.border = '2px solid rgb(255,0,0)'; - } - } - } else { - if (maxFreq.value === '') { - maxFreq.style.border = '2px solid rgb(255,0,0)'; - } - if (maxHz.value === '') { - maxHz.style.border = '2px solid rgb(255,0,0)'; - } - SpSegmentationChart.setChartData('CPU-FREQ', []); - } - } - /** - * 数据整理 - */ - organizeData( - res: Array, - str: string, - queryCycleScatter: Array, - maxFreqValue: string, - maxHzValue: string - ): void { - // @ts-ignore - this.shadowRoot?.querySelector('#cycleQuery')!.style.display = 'block'; - // @ts-ignore - let freq: Map = SpSegmentationChart.freqInfoMapData.size > 0 && - SpSegmentationChart.freqInfoMapData.get(SpSegmentationChart.freqInfoMapData.size - 1); - // @ts-ignore - let yAxis: number = freq && freq.get(Number(maxFreqValue) * 1000) - ? freq.get(Number(maxFreqValue) * 1000) : Number(maxFreqValue); - let xAxis: number = (yAxis * 1000) / Number(maxHzValue); - // 需要做筛选时,会利用下面的cycleA、cycleB数组 - let scatterArr: Array> = []; - let traceRowdata: Array<{ - dur: number; - startNS: number; - value: number; - cycle: number; - }> = []; - let cycleA: Array> = []; - let cycleB: Array> = []; - let cycleAStart: number = queryCycleScatter[0] || 0; - let cycleAEnd: number = queryCycleScatter[1] || 0; - let cycleBStart: number = queryCycleScatter[2] || 0; - let cycleBEnd: number = queryCycleScatter[3] || 0; - for (let i = 1; i < res.length; i++) { - const count: number = Number(res[i].count); - const dur: number = Number(res[i].cdur); - const rdur: number = Number(res[i].dur); //MHz·ms ms ms - scatterArr.push([count, count / dur, i, dur, rdur]); - traceRowdata.push({ - dur: dur * 1000000, - value: count, - startNS: Number(res[i].ts) * 1000000, - cycle: i - 1, - }); - if (dur >= cycleAStart && dur < cycleAEnd) { - cycleA.push([count, count / dur, i, dur, rdur]); - } - if (dur >= cycleBStart && dur < cycleBEnd) { - cycleB.push([count, count / dur, i, dur, rdur]); - } - } - this.setConfig(Number(maxHzValue), str, scatterArr, yAxis, xAxis, cycleA, cycleB); - SpSegmentationChart.setChartData('CPU-FREQ', traceRowdata); - } - - /** - * 配置散点图 - */ - setConfig(maxHz: number, str: string, scatterArr: Array>, - yAxis: number, xAxis: number, cycleA: Array>, cycleB: Array> - ): void { - const DELTA: number = 5; - this.statisticsScatter!.config = { - // 纵轴坐标值 - yAxisLabel: [ - Math.round(yAxis / DELTA), - Math.round((yAxis * 2) / DELTA), - Math.round((yAxis * 3) / DELTA), - Math.round((yAxis * 4) / DELTA), - Math.round(yAxis), - ], - // 横轴坐标值 - xAxisLabel: [ - Math.round(xAxis / DELTA), - Math.round((xAxis * 2) / DELTA), - Math.round((xAxis * 3) / DELTA), - Math.round((xAxis * 4) / DELTA), - Math.round(xAxis), - Math.round((xAxis * 6) / DELTA), - ], - // 横轴字段、纵轴字段 - axisLabel: ['负载', '算力供给'], - // 是否加载最大负载线及均衡线 - drawload: true, - // 最大负载线及均衡线值 - load: [xAxis, maxHz], - // 绘制点数据信息存储数组 - paintingData: [], - // 当前移入点坐标信息 - hoverData: {}, - // 颜色池 - colorPool: () => ['#2f72f8', '#ffab67', '#a285d2'], - // 移入数据点时是否触发函数 - //@ts-ignore - hoverEvent: SpSegmentationChart.tabHover, - // 渐变色背景信息 - globalGradient: undefined, - // 渲染数据点 - data: [scatterArr, cycleA, cycleB], - // 散点图title - title: str, - colorPoolText: (): Array => ['Total', 'CycleA', 'CycleB'], - tip: (data: {c: Array}): string => { - return ` -
      - Cycle: ${data.c[2]};
      - Comsumption: ${data.c[0]};
      - Cycle_dur: ${data.c[3]} ms;
      - Running_dur: ${data.c[4]} ms;
      -
      - `; - }, - }; - } - - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-running-datacut'); - // 绑定事件 - this.addListener(); - this.statisticsScatter = this.shadowRoot?.querySelector('#chart-scatter'); - // 增加表格thread层级点击更新散点图事件、周期层级点击高亮泳道图对应段事件 - let scatterData: Array = new Array(); - let str: string = ''; - this.threadStatesTbl!.addEventListener('row-click', (evt): void => { - // @ts-ignore - if (evt.detail.flag === 'thread') { - // @ts-ignore - scatterData = evt.detail.children; - // @ts-ignore - str = evt.detail.thread; - this.render(scatterData, str, []); - } - // @ts-ignore - if (evt.detail.flag === 'cycle' && evt.detail.pid === scatterData[evt.detail.id - 1].pid - // @ts-ignore - && evt.detail.tid === scatterData[evt.detail.id - 1].tid && evt.detail.id > 0) { - // @ts-ignore - SpSegmentationChart.tabHover('CPU-FREQ', true, evt.detail.id - 1); - } - }); - this.scatterInput = this.shadowRoot?.querySelector('.chart-box'); - this.shadowRoot?.querySelector('#query-btn')!.addEventListener('click', (e) => { - // @ts-ignore - let cycleAStartValue = this.shadowRoot?.querySelector('#cycle-a-start-range')!.value; - // @ts-ignore - let cycleAEndValue = this.shadowRoot?.querySelector('#cycle-a-end-range')!.value; - // @ts-ignore - let cycleBStartValue = this.shadowRoot?.querySelector('#cycle-b-start-range')!.value; - // @ts-ignore - let cycleBEndValue = this.shadowRoot?.querySelector('#cycle-b-end-range')!.value; - let queryCycleScatter = [Number(cycleAStartValue), Number(cycleAEndValue), Number(cycleBStartValue), Number(cycleBEndValue)]; - this.render(scatterData, str, queryCycleScatter); - }); - } - /** - * 配置监听事件 - */ - addListener(): void { - // 绑定single、loop按钮点击事件 - this.threadStatesDIV = this.shadowRoot?.querySelector('#dataCut'); - this.threadStatesDIV?.children[2].children[0].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; - // @ts-ignore - this.dataSingleCut(this.threadStatesDIV?.children[0]!, this.threadStatesDIV?.children[1]!, this.initData); - } - ); - this.threadStatesDIV?.children[2].children[1].addEventListener('click', (e) => { - this.threadStatesTbl!.loading = true; - // @ts-ignore - this.dataLoopCut(this.threadStatesDIV?.children[0]!, this.threadStatesDIV?.children[1]!, this.initData); - } - ); - this.threadStatesDIV?.children[0].addEventListener('focus', (e) => { - // @ts-ignore - this.threadStatesDIV?.children[0]!.style.border = '1px solid rgb(151,151,151)'; - } - ); - this.threadStatesDIV?.children[1].addEventListener('focus', (e) => { - // @ts-ignore - this.threadStatesDIV?.children[1]!.style.border = '1px solid rgb(151,151,151)'; - } - ); - this.shadowRoot?.querySelector('#maxFreq')?.addEventListener('focus', (e) => { - // @ts-ignore - this.shadowRoot?.querySelector('#maxFreq')!.style.border = '1px solid rgb(151,151,151)'; - }); - this.shadowRoot?.querySelector('#maxHz')?.addEventListener('focus', (e) => { - // @ts-ignore - this.shadowRoot?.querySelector('#maxHz')!.style.border = '1px solid rgb(151,151,151)'; - }); - } - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - } - - initHtml(): string { - return ` - - ` + this.htmlUp() + this.htmlDown(); - } - - htmlUp(): string { - return ` -
      - - -
      - - -
      -
      - - -
      - - - - - - - - - - - - - - - - - - -
      - `; - } - - htmlDown(): string { - return ` - -
      -
      - maxFreq: - - Fps: - -
      -
      -
      - - -
      -
      -
      - `; - } -} diff --git a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts index 77cb916c9952cd7d2c03f3dfb0b2121a45a1c35b..350c5055cd71f19c45cd16b8240bf86f01b006aa 100644 --- a/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts +++ b/ide/src/trace/component/trace/sheet/frequsage/TabPaneFreqUsage.ts @@ -21,7 +21,6 @@ import { getTabRunningPercent } from '../../../../database/sql/ProcessThread.sql import { queryCpuFreqUsageData, queryCpuFreqFilterId } from '../../../../database/sql/Cpu.sql'; import { Utils } from '../../base/Utils'; import { resizeObserver } from '../SheetUtils'; -import { SpSegmentationChart } from '../../../chart/SpSegmentationChart'; import { TabPaneFreqUsageConfig, type TabPaneRunningConfig, TabPaneCpuFreqConfig } from './TabPaneFreqUsageConfig'; @element('tabpane-frequsage') @@ -186,8 +185,7 @@ export class TabPaneFreqUsage extends BaseElement { for (let i = 0; i < value.length; i++) { this.pushCpuMap(cpuArr, cpuMap, value[i], key); for (let j = 0; j < dealArr.length; j++) { - const consumption: number = (SpSegmentationChart.freqInfoMapData.size > 0 - ? SpSegmentationChart.freqInfoMapData.get(value[i].cpu)?.get(dealArr[j].value) : dealArr[j].value)!; + const consumption: number = dealArr[j].value!; // 只需要合并相同cpu的数据 if (value[i].cpu === dealArr[j].cpu) { // 当running状态数据的开始时间大于频点数据开始时间,小于频点结束时间。且running数据的持续时间小于频点结束时间减去running数据开始时间的差值的情况 diff --git a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts index d7cbbad79393cb6cf356758bb53952105ad0f2c5..2c84305af566590c4446917f49b8a808c99ab75a 100644 --- a/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts +++ b/ide/src/trace/component/trace/sheet/gpu/TabPaneGpuClickSelect.ts @@ -69,9 +69,7 @@ export class TabPaneGpuClickSelect extends BaseElement { }); } protected createTreeData(result: any): Array { - let gpuDataObj = result.reduce( - ( - group: any, + let gpuDataObj = result.reduce((group: any, item: { categoryId: number; size: number; windowNameId: number; moduleId: number; windowId: any } ) => { let categoryItem: GpuTreeItem = { @@ -104,23 +102,19 @@ export class TabPaneGpuClickSelect extends BaseElement { id: item.windowNameId, size: item.size, sizeStr: Utils.getBinaryByteWithUnit(item.size), - children: [ - { + children: [{ name: SpSystemTrace.DATA_DICT.get(item.moduleId), id: item.moduleId, size: item.size, sizeStr: Utils.getBinaryByteWithUnit(item.size), children: [categoryItem], - }, - ], + }], }; } return group; - }, - {} + },{} ); - let items = Object.values(gpuDataObj) as GpuTreeItem[]; - return items; + return Object.values(gpuDataObj) as GpuTreeItem[]; } initElements(): void { this.gpuTbl = this.shadowRoot?.querySelector('#tb-gpu'); diff --git a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqDataCut.ts b/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqDataCut.ts deleted file mode 100644 index 79c2f419855eba57e447ba71b62c3caccd1601f3..0000000000000000000000000000000000000000 --- a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqDataCut.ts +++ /dev/null @@ -1,484 +0,0 @@ -/* - * Copyright (C) 2023 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 { LitButton } from '../../../../../base-ui/button/LitButton'; -import { type LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; -import { SelectionParam } from '../../../../bean/BoxSelection'; -import { getGpufreqData, getGpufreqDataCut } from '../../../../database/sql/Perf.sql'; -import { resizeObserver } from '../SheetUtils'; -import { SpSegmentationChart } from '../../../chart/SpSegmentationChart'; -import { GpuCountBean, TreeDataBean, type SearchGpuFuncBean } from '../../../../bean/GpufreqBean'; - -@element('tabpane-gpufreqdatacut') -export class TabPaneGpufreqDataCut extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private currentSelectionParam: SelectionParam | undefined; - private _single: Element | null | undefined; - private _loop: Element | null | undefined; - private _threadId: HTMLInputElement | null | undefined; - private _threadFunc: HTMLInputElement | null | undefined; - private threadIdValue: string = ''; - private threadFuncName: string = ''; - private initData: Array = []; - private SUB_LENGTH: number = 3; - private PERCENT_SUB_LENGTH: number = 2; - - set data(threadStatesParam: SelectionParam) { - if (this.currentSelectionParam === threadStatesParam) { - return; - } else { - SpSegmentationChart.setChartData('GPU-FREQ', []); - }; - this.currentSelectionParam = threadStatesParam; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - this.getGpufreqData(threadStatesParam.leftNs, threadStatesParam.rightNs, false).then((result) => { - if (result !== null && result.length > 0) { - let resultList: Array = JSON.parse(JSON.stringify(result)); - if (result.length === 1) { - resultList[0].dur = String(threadStatesParam.rightNs - threadStatesParam.leftNs); - resultList[0].count = String(Number(resultList[0].dur) * Number(resultList[0].value)); - } else { - resultList[0].dur = String(Number(resultList[1].startNS) - threadStatesParam.leftNs); - resultList[0].count = String(Number(resultList[0].dur) * Number(resultList[0].value)); - - resultList[resultList.length - 1].dur = String( - threadStatesParam.rightNs - Number(resultList[resultList.length - 1].startNS) - ); - resultList[resultList.length - 1].count = String( - Number(resultList[resultList.length - 1].dur) * Number(resultList[resultList.length - 1].value) - ); - }; - - this.initData = resultList; - this.threadStatesTbl!.loading = false; - } else { - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - }; - }); - this._threadId!.style.border = '1px solid rgb(151, 151, 151)'; - this._threadFunc!.style.border = '1px solid rgb(151, 151, 151)'; - }; - - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-gpufreq-percent'); - this._single = this.shadowRoot?.querySelector('#single'); - this._loop = this.shadowRoot?.querySelector('#loop'); - this._threadId = this.shadowRoot?.querySelector('#dataCutThreadId'); - this._threadFunc = this.shadowRoot?.querySelector('#dataCutThreadFunc'); - this.threadIdValue = this._threadId!.value.trim(); - this.threadFuncName = this._threadFunc!.value.trim(); - //点击single - this._single?.addEventListener('click', (e) => { - this.clickFun(this._single!.innerHTML); - }); - //点击loop - this._loop?.addEventListener('click', (e) => { - this.clickFun(this._loop!.innerHTML); - }); - this.threadStatesTbl?.addEventListener('row-click', (event: Event) => { - const EVENT_LEVEL: number = 2; - // @ts-ignore - if (event.detail.level === EVENT_LEVEL && event.detail.thread.includes('cycle')) { - // @ts-ignore - SpSegmentationChart.tabHover('GPU-FREQ', true, event.detail.data.cycle); - }; - }); - - this.addInputBorderEvent(this._threadId!); - this.addInputBorderEvent(this._threadFunc!); - }; - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - }; - - initHtml(): string { - return ` -
      - - -
      - - -
      -
      - - - - - - - - - - - - - - `; - }; - - private clickFun(fun: string): void { - this.threadIdValue = this._threadId!.value.trim(); - this.threadFuncName = this._threadFunc!.value.trim(); - this.threadStatesTbl!.loading = true; - SpSegmentationChart.tabHover('GPU-FREQ', false, -1); - this.validationFun(this.threadIdValue, this.threadFuncName, fun); - } - - private addInputBorderEvent(inputElement: HTMLInputElement): void { - if (inputElement) { - inputElement.addEventListener('change', function () { - if (this.value.trim() !== '') { - this.style.border = '1px solid rgb(151, 151, 151)'; - } - }); - } - } - - private validationFun(threadIdValue: string, threadFuncName: string, fun: string): void { - if (threadIdValue === '') { - this.handleEmptyInput(this._threadId!); - - } else if (threadFuncName === '') { - this.handleEmptyInput(this._threadFunc!); - } else { - this._threadId!.style.border = '1px solid rgb(151, 151, 151)'; - this._threadFunc!.style.border = '1px solid rgb(151, 151, 151)'; - if (fun === 'Single') { - this.isTrue(threadIdValue, threadFuncName, true, false); - }; - if (fun === 'Loop') { - this.isTrue(threadIdValue, threadFuncName, false, true); - }; - }; - }; - - private handleEmptyInput(input: HTMLInputElement): void { - this.threadStatesTbl!.loading = false; - input!.style.border = '1px solid rgb(255,0,0)'; - this.threadStatesTbl!.recycleDataSource = []; - }; - - private isTrue(threadIdValue: string, threadFuncName: string, single: boolean, loop: boolean): void { - this.getGpufreqDataCut(threadIdValue, threadFuncName, - this.currentSelectionParam!.leftNs, - this.currentSelectionParam!.rightNs, - single, loop - ).then((result: Array) => { - let _initData = JSON.parse(JSON.stringify(this.initData)); - this.handleDataCut(_initData, result); - }); - }; - - private handleDataCut(initData: Array, dataCut: Array): void { - if (initData.length > 0 && dataCut.length > 0) { - this.getGpufreqData(this.currentSelectionParam!.leftNs, this.currentSelectionParam!.rightNs, true).then( - (result: Array) => { - if (result !== null && result.length > 0 && dataCut.length > 0) { - this.filterData(initData, dataCut, result); - } else { - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - }; - } - ); - } else { - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - SpSegmentationChart.setChartData('GPU-FREQ', []); - }; - }; - - async getGpufreqData(leftNs: number, rightNs: number, isTrue: boolean): Promise> { - let result: Array = await getGpufreqData(leftNs, rightNs, isTrue); - return result; - }; - - async getGpufreqDataCut( - tIds: string, - funcName: string, - leftNS: number, - rightNS: number, - single: boolean, - loop: boolean - ): Promise> { - let result: Array = await getGpufreqDataCut(tIds, funcName, leftNS, rightNS, single, loop); - return result; - }; - - private filterData( - initData: Array, - dataCut: Array, - result: Array - ): void { - let finalGpufreqData: Array = new Array(); - let earliest: number = Number(result[0].startNS); - let _dataCut: Array = dataCut.filter((i) => i.startTime >= earliest); - let _lastList: Array = []; - for (let i = 0; i < _dataCut.length; i++) { - let e: SearchGpuFuncBean = _dataCut[i]; - for (let j of initData) { - _lastList.push(...this.segmentationData(j, e, i)); - }; - }; - let tree: TreeDataBean = this.createTree(_lastList); - finalGpufreqData.push(tree); - this.threadStatesTbl!.recycleDataSource = finalGpufreqData; - this.threadStatesTbl!.loading = false; - this.clickTableHeader(finalGpufreqData); - }; - - private segmentationData(j: GpuCountBean, e: SearchGpuFuncBean, i: number): Array { - let lastList: Array = []; - if (e.startTime >= Number(j.startNS) && e.startTime <= Number(j.endTime)) { - if (e.endTime <= Number(j.endTime)) { - lastList.push( - new GpuCountBean( - j.filterId, j.freq, String((e.endTime - e.startTime) * Number(j.value)), - j.value, String(e.startTime + this.currentSelectionParam!.recordStartNs), - String(e.endTime - e.startTime), String(e.startTime), String(e.endTime), - j.thread, i - ) - ); - } else { - lastList.push( - new GpuCountBean( - j.filterId, j.freq, String((Number(j.endTime) - e.startTime) * Number(j.value)), - j.value, String(e.startTime + this.currentSelectionParam!.recordStartNs), - String(Number(j.endTime) - e.startTime), String(e.startTime), String(j.endTime), - j.thread, i - ) - ); - }; - } else if (e.startTime <= Number(j.startNS) && Number(j.endTime) <= e.endTime) { - lastList.push( - new GpuCountBean( - j.filterId, j.freq, String((Number(j.endTime) - Number(j.startNS)) * Number(j.value)), - j.value, String(Number(j.startNS) + this.currentSelectionParam!.recordStartNs), - String(Number(j.endTime) - Number(j.startNS)), String(j.startNS), String(j.endTime), - j.thread, i - ) - ); - } else if (Number(j.startNS) <= e.endTime && e.endTime <= Number(j.endTime)) { - lastList.push( - new GpuCountBean( - j.filterId, j.freq, String((e.endTime - Number(j.startNS)) * Number(j.value)), - j.value, String(Number(j.startNS) + this.currentSelectionParam!.recordStartNs), - String(e.endTime - Number(j.startNS)), String(j.startNS), String(e.endTime), - j.thread, i - ) - ); - }; - return lastList; - }; - - private createTree(data: Array): TreeDataBean { - if (data.length > 0) { - const root = { - thread: 'gpufreq Frequency', - count: '0', - freq: '', - dur: '0', - percent: '100', - level: 1, - children: [], - }; - const valueMap: { [parentIndex: string]: TreeDataBean } = {}; - data.forEach((item: GpuCountBean) => { - let parentIndex: number = item.parentIndex !== undefined ? item.parentIndex : 0; - let freq: string = item.freq; - const UNIT: number = 1000000; - const KUNIT: number = 1000000000000; - let _dur: number = Number(item.dur); - let _count: number = Number(item.count); - let _freq: number = Number(item.freq); - item.thread = `${item.thread} Frequency`; - item.level = 4; - item.dur = (_dur / UNIT).toFixed(this.SUB_LENGTH); - item.count = (_count / KUNIT).toFixed(this.SUB_LENGTH); - item.freq = _freq.toFixed(this.SUB_LENGTH); - this.updateValueMap(item, parentIndex, freq, valueMap, UNIT); - }); - Object.values(valueMap).forEach((node: TreeDataBean) => { - const parentNode: TreeDataBean = valueMap[Number(node.value) - 1]; - if (parentNode) { - this.updateChildNode(node, parentNode); - } else { - this.updateRootNode(node, root); - }; - }); - // 移除 key 值 - root.children.forEach((item: TreeDataBean) => { - item.children = Object.values(item.children); - }); - this.calculatePercent(root, root); - SpSegmentationChart.setChartData('GPU-FREQ', root.children); - return root; - } else { - return new TreeDataBean(); - }; - }; - - private updateValueMap(item: GpuCountBean, parentIndex: number, freq: string, - valueMap: { [parentIndex: string]: TreeDataBean }, UNIT: number - ): void { - if (!valueMap[parentIndex]) { - valueMap[parentIndex] = { - thread: `cycle ${parentIndex + 1} ${item.thread}`, - count: item.count, - dur: item.dur, - ts: item.ts, - startTime: (Number(item.startNS) / UNIT).toFixed(this.SUB_LENGTH), - startNS: item.startNS, - percent: '100', - level: 2, - cycle: parentIndex + 1, - children: [], - }; - } else { - let fdur: number = Number(valueMap[parentIndex].dur); - let fcount: number = Number(valueMap[parentIndex].count); - let idur: number = Number(item.dur); - let icount: number = Number(item.count); - fdur += idur; - valueMap[parentIndex].dur = fdur.toFixed(this.SUB_LENGTH); - fcount += icount; - valueMap[parentIndex].count = fcount.toFixed(this.SUB_LENGTH); - }; - if (!valueMap[parentIndex].children[Number(freq)]) { - valueMap[parentIndex].children[Number(freq)] = { - thread: item.thread, - count: item.count, - gpufreq: item.freq, - dur: item.dur, - percent: '100', - level: 3, - children: [], - }; - } else { - let zdur: number = Number(valueMap[parentIndex].children[Number(freq)].dur); - let zcount: number = Number(valueMap[parentIndex].children[Number(freq)].count); - let idur: number = Number(item.dur); - let icount: number = Number(item.count); - zdur += idur; - valueMap[parentIndex].children[Number(freq)].dur = zdur.toFixed(this.SUB_LENGTH); - zcount += icount; - valueMap[parentIndex].children[Number(freq)].count = zcount.toFixed(this.SUB_LENGTH); - }; - valueMap[parentIndex].children[Number(freq)].children.push(item as unknown as TreeDataBean); - }; - - private updateChildNode(node: TreeDataBean, parentNode: TreeDataBean): void { - parentNode.children.push(node); - let pdur: number = Number(parentNode.dur); - let pcount: number = Number(parentNode.count); - let ndur: number = Number(node.dur); - let ncount: number = Number(node.count); - pdur += ndur; - parentNode.dur = pdur.toFixed(this.SUB_LENGTH); - pcount += ncount; - parentNode.count += pcount.toFixed(this.SUB_LENGTH); - }; - - private updateRootNode(node: TreeDataBean, root: TreeDataBean): void { - root.children.push(node); - let rdur: number = Number(root.dur); - let rcount: number = Number(root.count); - let ndur: number = Number(node.dur); - let ncount: number = Number(node.count); - rdur += ndur; - root.dur = rdur.toFixed(this.SUB_LENGTH); - rcount += ncount; - root.count = rcount.toFixed(this.SUB_LENGTH); - }; - - private calculatePercent(node: TreeDataBean, root: TreeDataBean): void { - const UNIT: number = 100 - node.percent = ((Number(node.count) / Number(root.count)) * UNIT).toFixed(this.PERCENT_SUB_LENGTH); - - if (node.children && node.children.length > 0) { - node.children.forEach((childNode) => this.calculatePercent(childNode, root)); - } else { - return; - }; - }; - - private clickTableHeader(data: Array): void { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - const THREAD_INDEX: number = 0; - const CYCLE_INDEX: number = 1; - const FREQ_INDEX: number = 2; - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - if (label.includes('Thread') && i === THREAD_INDEX) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Cycle') && i === CYCLE_INDEX) { - for (let item of data) { - item.status = true; - if (item.children !== undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - }; - }; - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - } else if (label.includes('Freq') && i === FREQ_INDEX) { - for (let item of data) { - item.status = true; - for (let e of item.children ? item.children : []) { - e.status = true; - if (e.children !== undefined && e.children.length > 0) { - this.threadStatesTbl!.setStatus(e.children, false, 0); - }; - }; - }; - - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - }; - }); - }; - }; - }; -}; diff --git a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts b/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts deleted file mode 100644 index 95db3a1066e94cdc3caa927c436c437875e0dfef..0000000000000000000000000000000000000000 --- a/ide/src/trace/component/trace/sheet/gpufreq/tabPaneGpufreqUsage.ts +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2023 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 { type LitTable, RedrawTreeForm } from '../../../../../base-ui/table/lit-table'; -import { type SelectionParam } from '../../../../bean/BoxSelection'; -import { getGpufreqData } from '../../../../database/sql/Perf.sql'; -import { resizeObserver } from '../SheetUtils'; -import { type GpuCountBean, TreeDataBean } from '../../../../bean/GpufreqBean' - -@element('tabpane-gpufreq') -export class TabPaneGpufreq extends BaseElement { - private threadStatesTbl: LitTable | null | undefined; - private currentSelectionParam: SelectionParam | undefined; - private SUB_LENGTH: number = 3; - private PERCENT_SUB_LENGTH: number = 2; - - set data(clockCounterValue: SelectionParam) { - let finalGpufreqData: Array = []; - if (this.currentSelectionParam === clockCounterValue) { - return; - }; - this.currentSelectionParam = clockCounterValue; - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = true; - getGpufreqData(clockCounterValue.leftNs, clockCounterValue.rightNs, false).then((result: Array): void => { - if (result !== null && result.length > 0) { - let resultList: Array = JSON.parse(JSON.stringify(result)); - if (result.length === 1) { - resultList[0].dur = String(clockCounterValue.rightNs - clockCounterValue.leftNs); - resultList[0].count = String(Number(resultList[0].dur) * Number(resultList[0].value)); - } else { - resultList[0].dur = String(Number(resultList[1].startNS) - clockCounterValue.leftNs); - resultList[0].count = String(Number(resultList[0].dur) * Number(resultList[0].value)); - - resultList[resultList.length - 1].dur = String(clockCounterValue.rightNs - Number(resultList[resultList.length - 1].startNS)); - resultList[resultList.length - 1].count = String(Number(resultList[resultList.length - 1].dur) * Number(resultList[resultList.length - 1].value)); - }; - let tree: TreeDataBean = this.createTree(resultList); - finalGpufreqData.push(tree); - this.threadStatesTbl!.recycleDataSource = finalGpufreqData; - this.threadStatesTbl!.loading = false; - this.clickTableHeader(finalGpufreqData); - } else { - this.threadStatesTbl!.recycleDataSource = []; - this.threadStatesTbl!.loading = false; - }; - - }); - }; - - initElements(): void { - this.threadStatesTbl = this.shadowRoot?.querySelector('#tb-gpufreq-percent'); - }; - - connectedCallback(): void { - super.connectedCallback(); - resizeObserver(this.parentElement!, this.threadStatesTbl!); - }; - - initHtml(): string { - return ` - - - - - - - - - - - - - - `; - }; - - private createTree(data: Array): TreeDataBean { - if (data.length > 0) { - const root = { - thread: 'gpufreq Frequency', - count: '0', - freq: '', - dur: '0', - percent: '100', - children: [], - }; - - const valueMap: { [freq: string]: TreeDataBean } = {}; - data.forEach((item: GpuCountBean) => { - let freq: string = item.freq; - let UNIT: number = 1000000; - const KUNIT: number = 1000000000000; - let _dur: number = Number(item.dur); - let _count: number = Number(item.count); - let _freq: number = Number(item.freq); - item.dur = (_dur / UNIT).toFixed(this.SUB_LENGTH); - item.count = (_count / KUNIT).toFixed(this.SUB_LENGTH); - item.freq = _freq.toFixed(this.SUB_LENGTH); - item.thread = `${item.thread} Frequency`; - this.updateValueMap(item, freq, valueMap); - }); - Object.values(valueMap).forEach((node: TreeDataBean) => { - const parentNode: TreeDataBean = valueMap[Number(node.value) - 1]; - if (parentNode) { - this.updateChildNode(node, parentNode); - } else { - this.updateRootNode(node, root); - }; - }); - - this.calculatePercent(root, root); - - return root; - - }; - return new TreeDataBean(); - }; - - private updateValueMap(item: GpuCountBean, freq: string, valueMap: { [freq: string]: TreeDataBean }): void { - if (!valueMap[freq]) { - valueMap[freq] = { - thread: 'gpufreq Frequency', - count: item.count, - gpufreq: item.freq, - dur: item.dur, - percent: '100', - children: [], - }; - } else { - let fdur: number = Number(valueMap[freq].dur); - let fcount: number = Number(valueMap[freq].count); - let idur: number = Number(item.dur); - let icount: number = Number(item.count); - fdur += idur; - valueMap[freq].dur = fdur.toFixed(this.SUB_LENGTH); - fcount += icount; - valueMap[freq].count = fcount.toFixed(this.SUB_LENGTH); - }; - valueMap[freq].children.push(item as unknown as TreeDataBean); - }; - - private updateChildNode(node: TreeDataBean, parentNode: TreeDataBean): void { - parentNode.children.push(node); - let pdur: number = Number(parentNode.dur); - let pcount: number = Number(parentNode.count); - let ndur: number = Number(node.dur); - let ncount: number = Number(node.count); - pdur += ndur; - parentNode.dur = pdur.toFixed(this.SUB_LENGTH); - pcount += ncount; - parentNode.count = pcount.toFixed(this.SUB_LENGTH); - }; - - private updateRootNode(node: TreeDataBean, root: TreeDataBean): void { - root.children.push(node); - let rdur: number = Number(root.dur); - let rcount: number = Number(root.count); - let ndur: number = Number(node.dur); - let ncount: number = Number(node.count); - rdur += ndur; - root.dur = rdur.toFixed(this.SUB_LENGTH); - rcount += ncount; - root.count = rcount.toFixed(this.SUB_LENGTH); - }; - - private calculatePercent(node: TreeDataBean, root: TreeDataBean): void { - const UNIT: number = 100 - node.percent = (Number(node.count) / Number(root.count) * UNIT).toFixed(this.PERCENT_SUB_LENGTH); - - if (node.children && node.children.length > 0) { - node.children.forEach((childNode) => this.calculatePercent(childNode, root)); - } else { - return; - }; - }; - - private clickTableHeader(data: Array): void { - let labels = this.threadStatesTbl?.shadowRoot?.querySelector('.th > .td')!.querySelectorAll('label'); - const THREAD_INDEX: number = 0; - const FREQ_INDEX: number = 1; - if (labels) { - for (let i = 0; i < labels.length; i++) { - let label = labels[i].innerHTML; - labels[i].addEventListener('click', (e) => { - - if (label.includes('Thread') && i === THREAD_INDEX) { - this.threadStatesTbl!.setStatus(data, false); - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Retract); - - } else if (label.includes('Freq') && i === FREQ_INDEX) { - - for (let item of data) { - item.status = true; - if (item.children !== undefined && item.children.length > 0) { - this.threadStatesTbl!.setStatus(item.children, false); - }; - }; - this.threadStatesTbl!.recycleDs = this.threadStatesTbl!.meauseTreeRowElement(data, RedrawTreeForm.Expand); - - }; - }); - }; - }; - }; -} \ No newline at end of file diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.html.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..a232e8e4e1a6af5c2800e95b240512aab9a53ff8 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.html.ts @@ -0,0 +1,91 @@ +/* + * 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. + */ + +export const TabPaneHiLogSummaryHtml = ` +
      +
      +
      + + +
      + + + + +
      + +
      +
      + + `; diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts index 6a868c9b56a43eea8052e52b39ffe1be078712ef..714e2565bcf84e989f4f513fdc6f40a1e8c213e1 100644 --- a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogSummary.ts @@ -19,6 +19,8 @@ import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog'; import { ColorUtils } from '../../base/ColorUtils'; import { LitTable } from '../../../../../base-ui/table/lit-table'; import { LitIcon } from '../../../../../base-ui/icon/LitIcon'; +import { TabPaneHiLogSummaryHtml } from './TabPaneHiLogSummary.html'; +import { NUM_30, NUM_40 } from '../../../../bean/NumBean'; @element('tab-hi-log-summary') export class TabPaneHiLogSummary extends BaseElement { @@ -75,84 +77,7 @@ export class TabPaneHiLogSummary extends BaseElement { } initHtml(): string { - return ` -
      -
      -
      - - -
      - - - - -
      - -
      -
      - - `; + return TabPaneHiLogSummaryHtml; } connectedCallback(): void { @@ -266,7 +191,7 @@ export class TabPaneHiLogSummary extends BaseElement { private refreshRowNodeTable(useCacheRefresh: boolean = false): void { this.logSummaryTable!.innerHTML = ''; if (this.logSummaryTable && this.parentElement) { - this.logSummaryTable.style.height = `${this.parentElement!.clientHeight - 30}px`; + this.logSummaryTable.style.height = `${this.parentElement!.clientHeight - NUM_30}px`; } if (!useCacheRefresh) { this.logTreeNodes = this.buildTreeTblNodes(this.systemLogSource); @@ -281,7 +206,7 @@ export class TabPaneHiLogSummary extends BaseElement { tableTreeEl.className = 'log-tree-table'; let tableCountEl: HTMLDivElement = document.createElement('div'); if (this.parentElement) { - tableTreeEl.style.height = `${this.parentElement!.clientHeight - 40}px`; + tableTreeEl.style.height = `${this.parentElement!.clientHeight - NUM_40}px`; } this.createRowNodeTableEL(this.logTreeNodes, tableTreeEl, tableCountEl, ''); let emptyTr = document.createElement('tr'); @@ -297,7 +222,7 @@ export class TabPaneHiLogSummary extends BaseElement { private buildTreeTblNodes(logTreeNodes: LogStruct[]): LogTreeNode[] { let id = 0; - let root: LogTreeNode = { id: id, depth: 0, children: [], logName: 'All', count: 0 }; + let root: LogTreeNode = {id: id, depth: 0, children: [], logName: 'All', count: 0}; logTreeNodes.forEach((item) => { id++; let levelNode = root.children.find((node) => node.logName === item.level); @@ -305,7 +230,7 @@ export class TabPaneHiLogSummary extends BaseElement { levelNode.count++; } else { id++; - levelNode = { id: id, depth: 0, children: [], logName: item.level, count: 1 }; + levelNode = {id: id, depth: 0, children: [], logName: item.level, count: 1}; root.children.push(levelNode); } let processNode = levelNode.children.find((node) => node.logName === item.processName); @@ -313,7 +238,7 @@ export class TabPaneHiLogSummary extends BaseElement { processNode.count++; } else { id++; - processNode = { id: id, depth: 1, children: [], logName: item.processName, count: 1 }; + processNode = {id: id, depth: 1, children: [], logName: item.processName, count: 1}; levelNode.children.push(processNode); } let tagNode = processNode.children.find((node) => node.logName === item.tag); @@ -321,7 +246,7 @@ export class TabPaneHiLogSummary extends BaseElement { tagNode.count++; } else { id++; - tagNode = { id: id, depth: 2, children: [], logName: item.tag, count: 1 }; + tagNode = {id: id, depth: 2, children: [], logName: item.tag, count: 1}; processNode.children.push(tagNode); } let messageNode = tagNode.children.find((node) => node.logName === item.context); @@ -329,7 +254,7 @@ export class TabPaneHiLogSummary extends BaseElement { messageNode.count++; } else { id++; - tagNode.children.push({ id: id, depth: 3, children: [], logName: item.context, count: 1 }); + tagNode.children.push({id: id, depth: 3, children: [], logName: item.context, count: 1}); } root.count++; }); diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.html.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..b88541a2e4f4e13f6f1dbdadb6e820b9ccac2864 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.html.ts @@ -0,0 +1,121 @@ +/* + * 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. + */ + +export const TabPaneHiLogsHtml = ` + +
      + +
      +
      + +
      +
      +
      + +
      + + +
      +
      + + + + + + + + + + + + + + + +`; diff --git a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts index e6652a4dda80f076718299a9bb0591bbb6b38617..331c287b3ebf90f0c40b004c3d39d6000b411738 100644 --- a/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts +++ b/ide/src/trace/component/trace/sheet/hilog/TabPaneHiLogs.ts @@ -24,7 +24,8 @@ import { LogStruct } from '../../../../database/ui-worker/ProcedureWorkerLog'; import { ColorUtils } from '../../base/ColorUtils'; import { LitPageTable } from '../../../../../base-ui/table/LitPageTable'; import { LitProgressBar } from '../../../../../base-ui/progress-bar/LitProgressBar'; -import {queryLogAllData} from "../../../../database/sql/SqlLite.sql"; +import { queryLogAllData } from '../../../../database/sql/SqlLite.sql'; +import { TabPaneHiLogsHtml } from './TabPaneHiLogs.html'; @element('tab-hi-log') export class TabPaneHiLogs extends BaseElement { @@ -61,6 +62,7 @@ export class TabPaneHiLogs extends BaseElement { }); } } + init(): void { this.levelFilterInput = this.shadowRoot?.querySelector('#level-filter'); this.logTableTitle = this.shadowRoot?.querySelector('#log-title'); @@ -68,8 +70,8 @@ export class TabPaneHiLogs extends BaseElement { this.searchFilterInput = this.shadowRoot?.querySelector('#search-filter'); this.processFilter = this.shadowRoot?.querySelector('#process-filter'); this.spSystemTrace = document - .querySelector('body > sp-application') - ?.shadowRoot?.querySelector('#sp-system-trace'); + .querySelector('body > sp-application') + ?.shadowRoot?.querySelector('#sp-system-trace'); this.tableTimeHandle = this.delayedRefresh(this.refreshTable); this.tableTitleTimeHandle = this.delayedRefresh(this.refreshLogsTitle); this.tagFilterDiv = this.shadowRoot!.querySelector('#tagFilter'); @@ -111,6 +113,7 @@ export class TabPaneHiLogs extends BaseElement { this.tableTitleTimeHandle?.(); }); } + initElements(): void { this.init(); this.tagFilterDiv!.onclick = (ev): void => { @@ -138,9 +141,11 @@ export class TabPaneHiLogs extends BaseElement { this.tagFilterInput?.addEventListener('keyup', this.tagFilterKeyEvent); new ResizeObserver((): void => { this.parentElement!.style.overflow = 'hidden'; - // @ts-ignore - this.hiLogsTbl?.shadowRoot?.querySelector('.table').style.height = - this.parentElement!.clientHeight - 20 - 45 + 'px'; + if (this.hiLogsTbl) { + // @ts-ignore + this.hiLogsTbl.shadowRoot.querySelector('.table').style.height = + this.parentElement!.clientHeight - 20 - 45 + 'px'; + } this.tableTimeHandle?.(); this.tableTitleTimeHandle?.(); }).observe(this.parentElement!); @@ -152,45 +157,10 @@ export class TabPaneHiLogs extends BaseElement { } initHtml(): string { - return `${this.initTitleCssStyle()} -
      - -
      -
      - -
      -
      -
      - -
      - - -
      -
      - - - - - - - - - - - - - - - - `; + return TabPaneHiLogsHtml; } - rerefreshLogsTab() { + + rerefreshLogsTab(): void { let tbl = this.hiLogsTbl?.shadowRoot?.querySelector('.table'); let height = 0; if (tbl) { @@ -213,11 +183,13 @@ export class TabPaneHiLogs extends BaseElement { }); } } + refreshLogsTitle(): void { let tbl = this.hiLogsTbl?.shadowRoot?.querySelector('.table'); let height = 0; let firstRowHeight = 27; let tableHeadHeight = 26; + this.rerefreshLogsTab(); if (this.hiLogsTbl && this.hiLogsTbl.currentRecycleList.length > 0) { let startDataIndex = this.hiLogsTbl.startSkip + 1; let endDataIndex = startDataIndex; @@ -293,8 +265,10 @@ export class TabPaneHiLogs extends BaseElement { if (this.systemLogSource?.length > 0) { this.filterData = this.systemLogSource.filter((data) => this.isFilterLog(data)); } - // @ts-ignore - this.hiLogsTbl?.shadowRoot?.querySelector('.table').style.height = this.parentElement.clientHeight - 20 - 45 + 'px'; + if (this.hiLogsTbl) { + // @ts-ignore + this.hiLogsTbl.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 20 - 45 + 'px'; + } if (this.filterData.length > 0) { this.hiLogsTbl!.recycleDataSource = this.filterData; } else { @@ -337,78 +311,6 @@ export class TabPaneHiLogs extends BaseElement { }, dur); }; } - - private initTitleCssStyle(): string { - return ``; - } } let defaultIndex: number = 1; diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..ece0805e46769880ee76cdcec46591200f24e0e4 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.html.ts @@ -0,0 +1,121 @@ +/* + * 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. + */ + +export const TabPanePerfAnalysisHtml = ` + + +
      + +
      +
      +
      +
      + +
      +
      +
      +
      +
      + +
      +
      + + + + +
      +
      + +`; diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts index e6d95ce5dcce3bfc93bd66e6cdd9f9ba24f084b8..5ded46a6b567260947f4e4cd3073c8d97194322d 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPanePerfAnalysis.ts @@ -24,6 +24,7 @@ import { TabPaneFilter } from '../TabPaneFilter'; import { LitCheckBox } from '../../../../../base-ui/checkbox/LitCheckBox'; import { initSort } from '../SheetUtils'; import { TabpanePerfProfile } from './TabPerfProfile'; +import { TabPanePerfAnalysisHtml } from './TabPanePerfAnalysis.html'; @element('tabpane-perf-analysis') export class TabPanePerfAnalysis extends BaseElement { @@ -81,30 +82,14 @@ export class TabPanePerfAnalysis extends BaseElement { this.reset(this.perfTableProcess!, false); this.titleEl!.textContent = ''; this.perfAnalysisRange!.textContent = - 'Selected range: ' + parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) + ' ms'; + `Selected range: ${ parseFloat(((val.rightNs - val.leftNs) / 1000000.0).toFixed(5)) } ms`; if (!this.callChainMap) { this.getCallChainDataFromWorker(val); } } - initElements(): void { - this.perfAnalysisPie = this.shadowRoot!.querySelector('#perf-chart-pie'); - this.perfAnalysisRange = this.shadowRoot?.querySelector('#time-range'); - this.perfTableProcess = this.shadowRoot!.querySelector('#tb-process-usage'); - this.perfTableSo = this.shadowRoot!.querySelector('#tb-so-usage'); - this.tableFunction = this.shadowRoot!.querySelector('#tb-function-usage'); - this.perfTableThread = this.shadowRoot!.querySelector('#tb-thread-usage'); - this.back = this.shadowRoot!.querySelector('.perf-go-back'); - this.tabName = this.shadowRoot!.querySelector('.perf-subheading'); - this.progressEL = this.shadowRoot?.querySelector('.perf-progress') as LitProgressBar; - this.titleEl = this.shadowRoot!.querySelector('.title'); - this.filterEl = this.shadowRoot?.querySelector('#filter'); - this.filterEl!.setOptionsList(['Hide Process', 'Hide Thread']); - let popover = this.filterEl!.shadowRoot!.querySelector('#check-popover'); - this.hideProcessCheckBox = popover!!.querySelector('div > #hideProcess'); - this.hideThreadCheckBox = popover!!.querySelector('div > #hideThread'); - this.checkBoxs = popover!.querySelectorAll('.check-wrap > lit-check-box'); - this.tableArray = this.shadowRoot!.querySelectorAll('lit-table') as NodeListOf; - for (let perfTable of this.tableArray) { + + private initPerfTableListener(): void { + for (let perfTable of this.tableArray!) { let querySelector = perfTable.shadowRoot?.querySelector('.table'); if (querySelector) { querySelector.style.height = 'calc(100% - 31px)'; @@ -120,17 +105,7 @@ export class TabPanePerfAnalysis extends BaseElement { event.preventDefault(); // 阻止默认的上下文菜单弹框 }); perfTable!.addEventListener('row-hover', (evt) => { - // @ts-ignore - let detail = evt.detail; - if (detail.data) { - let data = detail.data; - data.isHover = true; - if (detail.callBack) { - detail.callBack(true); - } - } - this.perfAnalysisPie?.showHover(); - this.perfAnalysisPie?.hideTip(); + this.perfTableRowHover(evt); }); perfTable!.addEventListener('row-click', (evt) => { // @ts-ignore @@ -146,11 +121,11 @@ export class TabPanePerfAnalysis extends BaseElement { detail.data.tid = undefined; } perfProfileTab!.rowClickData = detail.data; - let title = ''; + let title; if (this.titleEl?.textContent === '') { title = detail.data.tableName; } else { - title = this.titleEl?.textContent + ' / ' + detail.data.tableName; + title = `${this.titleEl?.textContent } / ${ detail.data.tableName}`; } perfProfileTab!.pieTitle = title; // 是否是在表格上右键点击跳转到火焰图的 @@ -159,8 +134,43 @@ export class TabPanePerfAnalysis extends BaseElement { } }); } + } + + private perfTableRowHover(evt: Event): void { + // @ts-ignore + let detail = evt.detail; + if (detail.data) { + let data = detail.data; + data.isHover = true; + if (detail.callBack) { + detail.callBack(true); + } + } + this.perfAnalysisPie?.showHover(); + this.perfAnalysisPie?.hideTip(); + } + + initElements(): void { + this.perfAnalysisPie = this.shadowRoot!.querySelector('#perf-chart-pie'); + this.perfAnalysisRange = this.shadowRoot?.querySelector('#time-range'); + this.perfTableProcess = this.shadowRoot!.querySelector('#tb-process-usage'); + this.perfTableSo = this.shadowRoot!.querySelector('#tb-so-usage'); + this.tableFunction = this.shadowRoot!.querySelector('#tb-function-usage'); + this.perfTableThread = this.shadowRoot!.querySelector('#tb-thread-usage'); + this.back = this.shadowRoot!.querySelector('.perf-go-back'); + this.tabName = this.shadowRoot!.querySelector('.perf-subheading'); + this.progressEL = this.shadowRoot?.querySelector('.perf-progress') as LitProgressBar; + this.titleEl = this.shadowRoot!.querySelector('.title'); + this.filterEl = this.shadowRoot?.querySelector('#filter'); + this.filterEl!.setOptionsList(['Hide Process', 'Hide Thread']); + let popover = this.filterEl!.shadowRoot!.querySelector('#check-popover'); + this.hideProcessCheckBox = popover!!.querySelector('div > #hideProcess'); + this.hideThreadCheckBox = popover!!.querySelector('div > #hideThread'); + this.checkBoxs = popover!.querySelectorAll('.check-wrap > lit-check-box'); + this.tableArray = this.shadowRoot!.querySelectorAll('lit-table') as NodeListOf; + this.initPerfTableListener(); for (let box of this.checkBoxs) { - box!.addEventListener('change', (event) => { + box!.addEventListener('change', () => { if ( (this.hideProcessCheckBox!.checked && this.hideThreadCheckBox!.checked) || (this.hideThreadCheckBox!.checked && @@ -178,22 +188,21 @@ export class TabPanePerfAnalysis extends BaseElement { }); } this.getBack(); + this.addRowClickEventListener(this.perfTableProcess!, this.perfProcessLevelClickEvent.bind(this)); + this.addRowClickEventListener(this.perfTableThread!, this.perfThreadLevelClickEvent.bind(this)); + this.addRowClickEventListener(this.perfTableSo!, this.perfSoLevelClickEvent.bind(this)); + } - const addRowClickEventListener = (table: LitTable, clickEvent: Function) => { - table.addEventListener('row-click', (evt) => { - // @ts-ignore - const detail = evt.detail; - // @ts-ignore - const data = detail.data; - if (detail.button === 0 && data.tableName !== '' && data.count !== 0) { - clickEvent(data, this.currentSelection); - } - }); - }; - - addRowClickEventListener(this.perfTableProcess!, this.perfProcessLevelClickEvent.bind(this)); - addRowClickEventListener(this.perfTableThread!, this.perfThreadLevelClickEvent.bind(this)); - addRowClickEventListener(this.perfTableSo!, this.perfSoLevelClickEvent.bind(this)); + private addRowClickEventListener(table: LitTable, clickEvent: Function): void { + table.addEventListener('row-click', (evt) => { + // @ts-ignore + const detail = evt.detail; + // @ts-ignore + const data = detail.data; + if (detail.button === 0 && data.tableName !== '' && data.count !== 0) { + clickEvent(data, this.currentSelection); + } + }); } private reset(showTable: LitTable, isShowBack: boolean): void { @@ -241,7 +250,7 @@ export class TabPanePerfAnalysis extends BaseElement { } private getBack(): void { - this.back!.addEventListener('click', (e) => { + this.back!.addEventListener('click', () => { if (this.tabName!.textContent === 'Statistic By Thread Count') { this.showAssignLevel(this.perfTableProcess!, this.perfTableThread!, 0, this.pidData); this.back!.style.visibility = 'hidden'; @@ -257,7 +266,7 @@ export class TabPanePerfAnalysis extends BaseElement { } } else if (this.tabName!.textContent === 'Statistic By Function Count') { this.showAssignLevel(this.perfTableSo!, this.tableFunction!, 2, this.soData); - this.libraryPieChart(this.currentSelection); + this.libraryPieChart(); } if ( (this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) || @@ -314,7 +323,7 @@ export class TabPanePerfAnalysis extends BaseElement { }, angleClick: (it): void => { // @ts-ignore - if (it.tableName != 'other') { + if (it.tableName !== 'other') { this.perfProcessLevelClickEvent(it, val); } }, @@ -376,18 +385,13 @@ export class TabPanePerfAnalysis extends BaseElement { type: 'outer', }, tip: (obj): string => { - return `
      -
      Thread:${obj.obj.tableName}
      -
      Sample Count:${obj.obj.count}
      -
      Percent:${obj.obj.percent}%
      -
      Event Count:${obj.obj.eventCount}
      -
      Percent:${obj.obj.eventPercent}%
      -
      - `; + return `
      Thread:${obj.obj.tableName}
      Sample Count:${obj.obj.count}
      +
      Percent:${obj.obj.percent}%
      Event Count:${obj.obj.eventCount}
      +
      Percent:${obj.obj.eventPercent}%
      `; }, angleClick: (it): void => { // @ts-ignore - if (it.tableName != 'other') { + if (it.tableName !== 'other') { this.perfThreadLevelClickEvent(it, val); } }, @@ -398,11 +402,7 @@ export class TabPanePerfAnalysis extends BaseElement { this.perfTableThread!.mouseOut(); } }, - interactions: [ - { - type: 'element-active', - }, - ], + interactions: [{type: 'element-active',}], }; this.tabName!.textContent = 'Statistic By Thread Count'; this.threadData.unshift(this.allThreadCount); @@ -418,7 +418,7 @@ export class TabPanePerfAnalysis extends BaseElement { this.getHiperfSo(it, val); let pName = this.processName; if (this.processName.length > 0 && it.tableName.length > 0) { - pName = this.processName + ' / '; + pName = `${this.processName } / `; } this.titleEl!.textContent = pName + it.tableName; // @ts-ignore @@ -426,9 +426,7 @@ export class TabPanePerfAnalysis extends BaseElement { this.perfAnalysisPie?.hideTip(); } - private libraryPieChart(val: SelectionParam): void { - // @ts-ignore - this.sumCount = this.allLibCount.allCount; + private initPerfAnalysisPieConfig(): void { this.perfAnalysisPie!.config = { appendPadding: 0, data: this.getPerfPieChartData(this.soData), @@ -450,8 +448,8 @@ export class TabPanePerfAnalysis extends BaseElement { }, angleClick: (it): void => { // @ts-ignore - if (it.tableName != 'other') { - this.perfSoLevelClickEvent(it, val); + if (it.tableName !== 'other') { + this.perfSoLevelClickEvent(it); } }, hoverHandler: (data): void => { @@ -467,9 +465,15 @@ export class TabPanePerfAnalysis extends BaseElement { }, ], }; + } + + private libraryPieChart(): void { + // @ts-ignore + this.sumCount = this.allLibCount.allCount; + this.initPerfAnalysisPieConfig(); let pName = this.processName; if (this.processName.length > 0 && this.threadName.length > 0) { - pName = this.processName + ' / '; + pName = `${this.processName } / `; } this.titleEl!.textContent = pName + this.threadName; this.tabName!.textContent = 'Statistic By Library Count'; @@ -481,15 +485,15 @@ export class TabPanePerfAnalysis extends BaseElement { this.currentLevelData = this.soData; } - private perfSoLevelClickEvent(it: any, val: SelectionParam): void { + private perfSoLevelClickEvent(it: any): void { this.reset(this.tableFunction!, true); this.getHiperfFunction(it); let title = ''; if (this.processName.length > 0) { - title += this.processName + ' / '; + title += `${this.processName } / `; } if (this.threadName.length > 0) { - title += this.threadName + ' / '; + title += `${this.threadName } / `; } if (it.tableName.length > 0) { title += it.tableName; @@ -535,55 +539,59 @@ export class TabPanePerfAnalysis extends BaseElement { } currentTable!.recycleDataSource = arr; } else { - let array = [...this.currentLevelData]; - if (this.sortColumn === 'tableName') { - currentTable!.recycleDataSource = array.sort((leftA, rightB) => { - if (this.sortType === 1) { - if (leftA.tableName > rightB.tableName) { - return 1; - } else if (leftA.tableName === rightB.tableName) { - return 0; - } else { - return -1; - } + this.sortTypeNoZero(currentTable); + } + } + + private sortTypeNoZero(currentTable: LitTable): void{ + let array = [...this.currentLevelData]; + if (this.sortColumn === 'tableName') { + currentTable!.recycleDataSource = array.sort((leftA, rightB) => { + if (this.sortType === 1) { + if (leftA.tableName > rightB.tableName) { + return 1; + } else if (leftA.tableName === rightB.tableName) { + return 0; } else { - if (rightB.tableName > leftA.tableName) { - return 1; - } else if (leftA.tableName === rightB.tableName) { - return 0; - } else { - return -1; - } + return -1; } - }); - } else if (this.sortColumn === 'count' || this.sortColumn === 'percent') { - currentTable!.recycleDataSource = array.sort((a, b) => { - return this.sortType === 1 ? a.count - b.count : b.count - a.count; - }); - } else if (this.sortColumn === 'eventCount' || this.sortColumn === 'eventPercent') { - currentTable!.recycleDataSource = array.sort((a, b) => { - return this.sortType === 1 ? a.eventCount - b.eventCount : b.eventCount - a.eventCount; - }); - } - switch (this.currentLevel) { - case 0: - array.unshift(this.allProcessCount); - break; - case 1: - array.unshift(this.allThreadCount); - break; - case 2: - array.unshift(this.allLibCount); - break; - case 3: - array.unshift(this.allSymbolCount); - break; - } - currentTable!.recycleDataSource = array; + } else { + if (rightB.tableName > leftA.tableName) { + return 1; + } else if (leftA.tableName === rightB.tableName) { + return 0; + } else { + return -1; + } + } + }); + } else if (this.sortColumn === 'count' || this.sortColumn === 'percent') { + currentTable!.recycleDataSource = array.sort((a, b) => { + return this.sortType === 1 ? a.count - b.count : b.count - a.count; + }); + } else if (this.sortColumn === 'eventCount' || this.sortColumn === 'eventPercent') { + currentTable!.recycleDataSource = array.sort((a, b) => { + return this.sortType === 1 ? a.eventCount - b.eventCount : b.eventCount - a.eventCount; + }); } + switch (this.currentLevel) { + case 0: + array.unshift(this.allProcessCount); + break; + case 1: + array.unshift(this.allThreadCount); + break; + case 2: + array.unshift(this.allLibCount); + break; + case 3: + array.unshift(this.allSymbolCount); + break; + } + currentTable!.recycleDataSource = array; } - async getHiperfProcess(val: SelectionParam): Promise { + private initHiPerfProcessSelect(val: SelectionParam): void{ this.reset(this.perfTableProcess!, false); this.progressEL!.loading = true; if (!this.processData || this.processData.length === 0) { @@ -600,6 +608,10 @@ export class TabPanePerfAnalysis extends BaseElement { } return; } + } + + async getHiperfProcess(val: SelectionParam): Promise { + this.initHiPerfProcessSelect(val); let allCount = 0; let allEventCount = 0; let pidMap = new Map>(); @@ -613,7 +625,7 @@ export class TabPanePerfAnalysis extends BaseElement { if (pidMap.has(itemData.pid)) { pidMap.get(itemData.pid)?.push(itemData); } else { - let itemArray = new Array(); + let itemArray: Array = []; itemArray.push(itemData); pidMap.set(itemData.pid, itemArray); } @@ -626,7 +638,7 @@ export class TabPanePerfAnalysis extends BaseElement { count += item.count; eventCount += item.eventCount; } - const pName = arr[0].processName + '(' + pid + ')'; + const pName = `${arr[0].processName }(${ pid })`; const pidData = { tableName: pName, pid: pid, @@ -662,7 +674,7 @@ export class TabPanePerfAnalysis extends BaseElement { if (threadMap.has(itemData.tid)) { threadMap.get(itemData.tid)?.push(itemData); } else { - let itemArray = new Array(); + let itemArray: Array = []; itemArray.push(itemData); threadMap.set(itemData.tid, itemArray); } @@ -671,7 +683,7 @@ export class TabPanePerfAnalysis extends BaseElement { threadMap.forEach((arr: Array, tid: number) => { let threadCount = 0; let threadEventCount = 0; - let tName = arr[0].threadName + '(' + tid + ')'; + let tName = `${arr[0].threadName }(${ tid })`; for (let item of arr) { threadCount += item.count; threadEventCount += item.eventCount; @@ -694,6 +706,23 @@ export class TabPanePerfAnalysis extends BaseElement { this.threadPieChart(val); } + private getHiPerfSoIdByProcessData(item: any, itemData: any): boolean { + if (!this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { + if (item && (itemData.pid !== item.pid || itemData.tid !== item.tid)) { + return true; + } + } else if (!this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { + if (item && itemData.pid !== item.pid) { + return true; + } + } else if (this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { + if (item && itemData.tid !== item.tid) { + return true; + } + } + return false; + } + private getHiperfSo(item: any, val: SelectionParam): void { this.progressEL!.loading = true; let parentEventCount = 0; @@ -704,34 +733,24 @@ export class TabPanePerfAnalysis extends BaseElement { return; } for (let itemData of this.processData) { - if (!this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { - if (item && (itemData.pid !== item.pid || itemData.tid !== item.tid)) { - continue; - } - } else if (!this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { - if (item && itemData.pid !== item.pid) { - continue; - } - } else if (this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { - if (item && itemData.tid !== item.tid) { - continue; - } + if (this.getHiPerfSoIdByProcessData(item, itemData)) { + continue; } allCount += itemData.count; allEventCount += itemData.eventCount; - if (libMap.has(itemData.libId + '-' + itemData.libName)) { - libMap.get(itemData.libId + '-' + itemData.libName)?.push(itemData); + if (libMap.has(`${itemData.libId }-${ itemData.libName}`)) { + libMap.get(`${itemData.libId }-${ itemData.libName}`)?.push(itemData); } else { - let dataArray = new Array(); + let dataArray: Array = []; dataArray.push(itemData); - libMap.set(itemData.libId + '-' + itemData.libName, dataArray); + libMap.set(`${itemData.libId }-${ itemData.libName}`, dataArray); } } if (!item) { parentEventCount = allEventCount; } this.soData = []; - libMap.forEach((arr: Array, libInfo: string) => { + libMap.forEach((arr: Array) => { let libCount = 0; let libEventCount = 0; let libName = arr[0].libName; @@ -752,11 +771,15 @@ export class TabPanePerfAnalysis extends BaseElement { }; this.soData.push(libData); }); + this.initPerfSoData(allCount, allEventCount); + } + + private initPerfSoData(allCount: number, allEventCount: number): void { this.allLibCount = this.totalCountData(allCount, allEventCount); this.soData.sort((a, b) => b.count - a.count); this.currentLevel = 2; this.progressEL!.loading = false; - this.libraryPieChart(val); + this.libraryPieChart(); } private getHiperfFunction(item: any): void { @@ -764,9 +787,6 @@ export class TabPanePerfAnalysis extends BaseElement { this.shadowRoot!.querySelector('.perf-subheading')!.textContent = 'Statistic By Function Count'; let parentCount = item.count; let parentEventCount = item.eventCount; - let tid = item.tid; - let pid = item.pid; - let libId = item.libId; let allCount = 0; let allEventCount = 0; let symbolMap = new Map>(); @@ -774,35 +794,21 @@ export class TabPanePerfAnalysis extends BaseElement { return; } for (let itemData of this.processData) { - if (!this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { - if (itemData.pid !== pid || itemData.tid !== tid || itemData.libId !== libId) { - continue; - } - } else if (!this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { - if (itemData.pid !== pid || itemData.libId !== libId) { - continue; - } - } else if (this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { - if (itemData.tid !== tid || itemData.libId !== libId) { - continue; - } - } else if (this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { - if (itemData.libId !== libId) { - continue; - } + if (this.getIdByProcessData(itemData, item)) { + continue; } allCount += itemData.count; allEventCount += itemData.eventCount; - if (symbolMap.has(itemData.symbolId + '-' + itemData.symbolName)) { - symbolMap.get(itemData.symbolId + '-' + itemData.symbolName)?.push(itemData); + if (symbolMap.has(`${itemData.symbolId }-${ itemData.symbolName}`)) { + symbolMap.get(`${itemData.symbolId }-${ itemData.symbolName}`)?.push(itemData); } else { - let dataArray = new Array(); + let dataArray: Array = []; dataArray.push(itemData); - symbolMap.set(itemData.symbolId + '-' + itemData.symbolName, dataArray); + symbolMap.set(`${itemData.symbolId }-${ itemData.symbolName}`, dataArray); } } this.functionData = []; - symbolMap.forEach((arr, symbolInfo) => { + symbolMap.forEach((arr) => { let symbolCount = 0; let symbolEventCount = 0; for (let item of arr) { @@ -824,6 +830,35 @@ export class TabPanePerfAnalysis extends BaseElement { }; this.functionData.push(symbolData); }); + this.initPerfFunData(allCount, allEventCount); + } + + private getIdByProcessData(itemData: any, item: any): boolean { + let tid = item.tid; + let pid = item.pid; + let libId = item.libId; + let isContinue = false; + if (!this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { + if (itemData.pid !== pid || itemData.tid !== tid || itemData.libId !== libId) { + isContinue = true; + } + } else if (!this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { + if (itemData.pid !== pid || itemData.libId !== libId) { + isContinue = true; + } + } else if (this.hideProcessCheckBox?.checked && !this.hideThreadCheckBox?.checked) { + if (itemData.tid !== tid || itemData.libId !== libId) { + isContinue = true; + } + } else if (this.hideProcessCheckBox?.checked && this.hideThreadCheckBox?.checked) { + if (itemData.libId !== libId) { + isContinue = true; + } + } + return isContinue; + } + + private initPerfFunData(allCount: number, allEventCount: number): void { this.functionData.sort((a, b) => b.count - a.count); this.allSymbolCount = this.totalCountData(allCount, allEventCount); this.currentLevel = 3; @@ -953,14 +988,14 @@ export class TabPanePerfAnalysis extends BaseElement { } public connectedCallback(): void { - new ResizeObserver((entries) => { - this.perfTableProcess!.style.height = this.parentElement!.clientHeight - 50 + 'px'; + new ResizeObserver(() => { + this.perfTableProcess!.style.height = `${this.parentElement!.clientHeight - 50 }px`; this.perfTableProcess?.reMeauseHeight(); - this.perfTableThread!.style.height = this.parentElement!.clientHeight - 50 + 'px'; + this.perfTableThread!.style.height = `${this.parentElement!.clientHeight - 50 }px`; this.perfTableThread?.reMeauseHeight(); - this.tableFunction!.style.height = this.parentElement!.clientHeight - 50 + 'px'; + this.tableFunction!.style.height = `${this.parentElement!.clientHeight - 50 }px`; this.tableFunction?.reMeauseHeight(); - this.perfTableSo!.style.height = this.parentElement!.clientHeight - 50 + 'px'; + this.perfTableSo!.style.height = `${this.parentElement!.clientHeight - 50 }px`; this.perfTableSo?.reMeauseHeight(); if (this.parentElement!.clientHeight >= 0 && this.parentElement!.clientHeight <= 31) { this.filterEl!.style.display = 'none'; @@ -971,101 +1006,6 @@ export class TabPanePerfAnalysis extends BaseElement { } initHtml(): string { - return ` - - -
      - -
      -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - - - - -
      -
      - -`; + return TabPanePerfAnalysisHtml; } } diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts index ed000f5f3233ebb9c04064bc0f5dd5804d337d90..6c509a6fcbddd7d9b9597b27e632c1c3d55b1ba6 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfBottomUp.ts @@ -16,7 +16,7 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { type LitTable } from '../../../../../base-ui/table/lit-table'; import '../TabPaneFilter'; -import { type FilterData, TabPaneFilter } from '../TabPaneFilter'; +import { TabPaneFilter } from '../TabPaneFilter'; import { SelectionParam } from '../../../../bean/BoxSelection'; import '../../../chart/FrameChart'; import '../../../../../base-ui/slicer/lit-slicer'; @@ -28,7 +28,6 @@ import { findSearchNode } from '../../../../database/ui-worker/ProcedureWorkerCo @element('tabpane-perf-bottom-up') export class TabpanePerfBottomUp extends BaseElement { - private treeTable: HTMLDivElement | undefined | null; private bottomUpTable: LitTable | null | undefined; private stackTable: LitTable | null | undefined; private sortKey = ''; @@ -38,16 +37,16 @@ export class TabpanePerfBottomUp extends BaseElement { private progressEL: LitProgressBar | null | undefined; private searchValue: string = ''; private currentSelection: SelectionParam | undefined; + public initElements(): void { this.bottomUpTable = this.shadowRoot?.querySelector('#callTreeTable') as LitTable; this.stackTable = this.shadowRoot?.querySelector('#stackTable') as LitTable; - this.treeTable = this.bottomUpTable!.shadowRoot?.querySelector('.thead') as HTMLDivElement; this.progressEL = this.shadowRoot?.querySelector('.progress') as LitProgressBar; this.bottomUpFilter = this.shadowRoot?.querySelector('#filter') as TabPaneFilter; this.bottomUpTable!.addEventListener('row-click', (evt) => this.bottomUpTableRowClickHandler(evt)); this.stackTable!.addEventListener('row-click', (evt) => this.stackTableRowClick(evt)); this.bottomUpTable!.addEventListener('column-click', (evt) => this.bottomUpTableColumnClickHandler(evt)); - this.bottomUpFilter!.getFilterData((data: FilterData) => { + this.bottomUpFilter!.getFilterData(() => { if (this.searchValue !== this.bottomUpFilter!.filterValue) { this.searchValue = this.bottomUpFilter!.filterValue; findSearchNode(this.bottomUpSource, this.searchValue, false); @@ -80,18 +79,16 @@ export class TabpanePerfBottomUp extends BaseElement { } set data(data: SelectionParam) { - if (data instanceof SelectionParam) { - if (data == this.currentSelection) { - return; - } - this.currentSelection = data; - this.sortKey = ''; - this.sortType = 0; - this.bottomUpFilter!.filterValue = ''; - this.getDataByWorker(data, (results: Array) => { - this.setBottomUpTableData(results); - }); + if (data == this.currentSelection) { + return; } + this.currentSelection = data; + this.sortKey = ''; + this.sortType = 0; + this.bottomUpFilter!.filterValue = ''; + this.getDataByWorker(data, (results: Array) => { + this.setBottomUpTableData(results); + }); } private setBottomUpTableData(results: Array): void { @@ -149,7 +146,7 @@ export class TabpanePerfBottomUp extends BaseElement { const bottomUpData = evt.detail.data as PerfBottomUpStruct; document.dispatchEvent( new CustomEvent('number_calibration', { - detail: { time: bottomUpData.tsArray }, + detail: {time: bottomUpData.tsArray}, }) ); callStack!.push(bottomUpData); @@ -177,6 +174,7 @@ export class TabpanePerfBottomUp extends BaseElement { this.sortType = evt.detail.sort; this.setBottomUpTableData(this.bottomUpSource); } + private stackTableRowClick(evt: Event): void { //@ts-ignore const data = evt.detail.data as PerfBottomUpStruct; @@ -210,9 +208,11 @@ export class TabpanePerfBottomUp extends BaseElement { private sortTree(arr: Array): Array { const defaultSortType = 0; + function defaultSort(callTreeLeftData: PerfBottomUpStruct, callTreeRightData: PerfBottomUpStruct): number { return callTreeRightData.totalTime - callTreeLeftData.totalTime; } + const CallTreeSortArr = arr.sort((callTreeLeftData, callTreeRightData) => { if (this.sortKey === 'selfTime' || this.sortKey === 'selfTimePercent') { if (this.sortType === defaultSortType) { @@ -269,6 +269,7 @@ export class TabpanePerfBottomUp extends BaseElement { `; } + public initHtml(): string { return ` ${this.initHtmlStyle()} @@ -287,8 +288,10 @@ export class TabpanePerfBottomUp extends BaseElement { align="flex-start" order> - - + + diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.html.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.html.ts new file mode 100644 index 0000000000000000000000000000000000000000..2f18a9209c3e8de4c38c5d6f2d2640f6c7e2d1c7 --- /dev/null +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.html.ts @@ -0,0 +1,99 @@ +/* + * 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. + */ + +export const TabPerfProfileHtml = ` + +
      + + + +
      + + + + + + + + + + +
      + + + Heaviest Stack Trace + + + + + +
      + + + + + + + +
      +`; diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts index e713b83fb8e26ee233c61f3b6ef1eedd59d1f93f..20722f90366f16f50220a8b5c6bdd94290b77964 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfProfile.ts @@ -29,6 +29,7 @@ import { procedurePool } from '../../../../database/Procedure'; import { showButtonMenu } from '../SheetUtils'; import '../../../../../base-ui/headline/lit-headline'; import { LitHeadLine } from '../../../../../base-ui/headline/lit-headline'; +import { TabPerfProfileHtml } from './TabPerfProfile.html'; const InvertOptionIndex: number = 0; const hideThreadOptionIndex: number = 3; @@ -278,7 +279,7 @@ export class TabpanePerfProfile extends BaseElement { let len = perfProfileParentsList.length; this.perfProfilerRightSource = perfProfileParentsList; let rightSource: Array = []; - if (len != 0) { + if (len !== 0) { rightSource = this.perfProfilerRightSource.filter((item): boolean => { return item.canCharge; }); @@ -302,6 +303,12 @@ export class TabpanePerfProfile extends BaseElement { }); this.perfProfilerTbl!.rememberScrollTop = true; this.perfProfilerFilter = this.shadowRoot?.querySelector('#filter'); + this.perfProfilerList = this.shadowRoot?.querySelector('#tb-perf-list'); + this.perfProfilerList = this.shadowRoot?.querySelector('#tb-perf-list'); + this.initPerfProfilerDataAndListener(); + } + + private initPerfProfilerDataAndListener(): void { this.perfProfilerTbl!.addEventListener('row-click', (evt: any): void => { // @ts-ignore let data = evt.detail.data as PerfCallChainMerageData; @@ -321,7 +328,6 @@ export class TabpanePerfProfile extends BaseElement { (evt.detail as any).callBack(true); } }); - this.perfProfilerList = this.shadowRoot?.querySelector('#tb-perf-list'); this.perfProfilerList!.addEventListener('row-click', (evt: any): void => { // @ts-ignore let data = evt.detail.data as PerfCallChainMerageData; @@ -334,203 +340,221 @@ export class TabpanePerfProfile extends BaseElement { (evt.detail as any).callBack(true); } }); - this.perfProfilerList = this.shadowRoot?.querySelector('#tb-perf-list'); - let filterFunc = (data: any): void => { - let perfProfileFuncArgs: any[] = []; - if (data.type === 'check') { - if (data.item.checked) { - perfProfileFuncArgs.push({ - funcName: 'splitTree', - funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'], - }); - } else { - perfProfileFuncArgs.push({ - funcName: 'resotreAllNode', - funcArgs: [[data.item.name]], - }); - perfProfileFuncArgs.push({ - funcName: 'resetAllNode', - funcArgs: [], - }); - perfProfileFuncArgs.push({ - funcName: 'clearSplitMapData', - funcArgs: [data.item.name], - }); - } - } else if (data.type === 'select') { - perfProfileFuncArgs.push({ - funcName: 'resotreAllNode', - funcArgs: [[data.item.name]], - }); + this.perfProfilerFilter!.getDataLibrary(this.filterFunc); + this.perfProfilerFilter!.getDataMining(this.filterFunc); + this.perfProfilerFilter!.getCallTreeData(this.perfProfilerFilterGetCallTree); + this.perfProfilerFilter!.getCallTreeConstraintsData(this.perfProfilerFilterGetCallTreeConstraints); + this.perfProfilerFilter!.getFilterData(this.perfProfilerFilterGetFilter); + this.perfProfilerTbl!.addEventListener('column-click', (evt): void => { + // @ts-ignore + this.perfProfileSortKey = evt.detail.key; + // @ts-ignore + this.perfProfileSortType = evt.detail.sort; + // @ts-ignore + this.setPerfProfilerLeftTableData(this.perfProfilerDataSource); + this.perfProfileFrameChart!.data = this.perfProfilerDataSource; + }); + } + + private filterFuncByCheckType(data: any, perfProfileFuncArgs: any[]): void { + if (data.item.checked) { + perfProfileFuncArgs.push({ + funcName: 'splitTree', + funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'], + }); + } else { + perfProfileFuncArgs.push({ + funcName: 'resotreAllNode', + funcArgs: [[data.item.name]], + }); + perfProfileFuncArgs.push({ + funcName: 'resetAllNode', + funcArgs: [], + }); + perfProfileFuncArgs.push({ + funcName: 'clearSplitMapData', + funcArgs: [data.item.name], + }); + } + } + + private filterFuncBySelect(data: any, perfProfileFuncArgs: any[]): void { + perfProfileFuncArgs.push({ + funcName: 'resotreAllNode', + funcArgs: [[data.item.name]], + }); + perfProfileFuncArgs.push({ + funcName: 'clearSplitMapData', + funcArgs: [data.item.name], + }); + perfProfileFuncArgs.push({ + funcName: 'splitTree', + funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'], + }); + } + + private filterFuncByButton(data: any, perfProfileFuncArgs: any[]): void { + if (data.item === 'symbol') { + if (this.perfSelectedData && !this.perfSelectedData.canCharge) { + return; + } + if (this.perfSelectedData !== undefined) { + this.perfProfilerFilter!.addDataMining({ name: this.perfSelectedData.symbolName }, data.item); perfProfileFuncArgs.push({ - funcName: 'clearSplitMapData', - funcArgs: [data.item.name], + funcName: 'splitTree', + funcArgs: [this.perfSelectedData.symbolName, false, true], }); + } else { + return; + } + } else if (data.item === 'library') { + if (this.perfSelectedData && !this.perfSelectedData.canCharge) { + return; + } + if (this.perfSelectedData !== undefined && this.perfSelectedData.libName !== '') { + this.perfProfilerFilter!.addDataMining({ name: this.perfSelectedData.libName }, data.item); perfProfileFuncArgs.push({ funcName: 'splitTree', - funcArgs: [data.item.name, data.item.select === '0', data.item.type === 'symbol'], + funcArgs: [this.perfSelectedData.libName, false, false], }); - } else if (data.type === 'button') { - if (data.item === 'symbol') { - if (this.perfSelectedData && !this.perfSelectedData.canCharge) { - return; - } - if (this.perfSelectedData !== undefined) { - this.perfProfilerFilter!.addDataMining({ name: this.perfSelectedData.symbolName }, data.item); - perfProfileFuncArgs.push({ - funcName: 'splitTree', - funcArgs: [this.perfSelectedData.symbolName, false, true], - }); - } else { - return; - } - } else if (data.item === 'library') { - if (this.perfSelectedData && !this.perfSelectedData.canCharge) { - return; - } - if (this.perfSelectedData !== undefined && this.perfSelectedData.libName !== '') { - this.perfProfilerFilter!.addDataMining({ name: this.perfSelectedData.libName }, data.item); - perfProfileFuncArgs.push({ - funcName: 'splitTree', - funcArgs: [this.perfSelectedData.libName, false, false], - }); - } else { - return; - } - } else if (data.item === 'restore') { - if (data.remove !== undefined && data.remove.length > 0) { - let list = data.remove.map((item: any) => { - return item.name; - }); - perfProfileFuncArgs.push({ - funcName: 'resotreAllNode', - funcArgs: [list], - }); - perfProfileFuncArgs.push({ - funcName: 'resetAllNode', - funcArgs: [], - }); - list.forEach((symbolName: string): void => { - perfProfileFuncArgs.push({ - funcName: 'clearSplitMapData', - funcArgs: [symbolName], - }); - }); - } - } + } else { + return; } - this.getDataByWorker(perfProfileFuncArgs, (result: any[]): void => { - this.setPerfProfilerLeftTableData(result); - this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - if (this.isChartShow) this.perfProfileFrameChart?.calculateChartData(); - this.perfProfilerTbl!.move1px(); - if (this.perfSelectedData) { - this.perfSelectedData.isSelected = false; - this.perfProfilerTbl?.clearAllSelection(this.perfSelectedData); - this.perfProfilerList!.recycleDataSource = []; - this.perfSelectedData = undefined; - } - }); - }; - this.perfProfilerFilter!.getDataLibrary(filterFunc); - this.perfProfilerFilter!.getDataMining(filterFunc); - this.perfProfilerFilter!.getCallTreeData((data: any): void => { - if (callTreeValueNoSample.includes(data.value)) { - this.refreshAllNode({ - ...this.perfProfilerFilter!.getFilterTreeData(), - callTree: data.checks, + } else if (data.item === 'restore') { + if (data.remove !== undefined && data.remove.length > 0) { + let list = data.remove.map((item: any) => { + return item.name; }); - } else { - let perfProfileArgs: any[] = []; - if (data.checks[1]) { - perfProfileArgs.push({ - funcName: 'hideSystemLibrary', - funcArgs: [], - }); - } else { - perfProfileArgs.push({ - funcName: 'resotreAllNode', - funcArgs: [[this.systemRuleName]], - }); - perfProfileArgs.push({ - funcName: 'clearSplitMapData', - funcArgs: [this.systemRuleName], - }); - } - perfProfileArgs.push({ + perfProfileFuncArgs.push({ + funcName: 'resotreAllNode', + funcArgs: [list], + }); + perfProfileFuncArgs.push({ funcName: 'resetAllNode', funcArgs: [], }); - this.getDataByWorker(perfProfileArgs, (result: any[]): void => { - this.setPerfProfilerLeftTableData(result); - this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - if (this.isChartShow) this.perfProfileFrameChart?.calculateChartData(); + list.forEach((symbolName: string): void => { + perfProfileFuncArgs.push({ + funcName: 'clearSplitMapData', + funcArgs: [symbolName], + }); }); } + } + } + + filterFunc = (data: any): void => { + let perfProfileFuncArgs: any[] = []; + if (data.type === 'check') { + this.filterFuncByCheckType(data, perfProfileFuncArgs); + } else if (data.type === 'select') { + this.filterFuncBySelect(data, perfProfileFuncArgs); + } else if (data.type === 'button') { + this.filterFuncByButton(data, perfProfileFuncArgs); + } + this.getDataByWorker(perfProfileFuncArgs, (result: any[]): void => { + this.setPerfProfilerLeftTableData(result); + this.perfProfileFrameChart!.data = this.perfProfilerDataSource; + if (this.isChartShow) {this.perfProfileFrameChart?.calculateChartData()} + this.perfProfilerTbl!.move1px(); + if (this.perfSelectedData) { + this.perfSelectedData.isSelected = false; + this.perfProfilerTbl?.clearAllSelection(this.perfSelectedData); + this.perfProfilerList!.recycleDataSource = []; + this.perfSelectedData = undefined; + } }); - this.perfProfilerFilter!.getCallTreeConstraintsData((data: any): void => { - let perfProfilerConstraintsArgs: any[] = [ + }; + + perfProfilerFilterGetFilter = (data: FilterData): void => { + if (this.searchValue !== this.perfProfilerFilter!.filterValue) { + this.searchValue = this.perfProfilerFilter!.filterValue; + let perfArgs = [ { - funcName: 'resotreAllNode', - funcArgs: [[this.perfProfileNumRuleName]], + funcName: 'setSearchValue', + funcArgs: [this.searchValue], }, { - funcName: 'clearSplitMapData', - funcArgs: [this.perfProfileNumRuleName], + funcName: 'resetAllNode', + funcArgs: [], }, ]; - if (data.checked) { - perfProfilerConstraintsArgs.push({ - funcName: 'hideNumMaxAndMin', - funcArgs: [parseInt(data.min), data.max], + this.getDataByWorker(perfArgs, (result: any[]): void => { + this.perfProfilerTbl!.isSearch = true; + this.perfProfilerTbl!.setStatus(result, true); + this.setPerfProfilerLeftTableData(result); + this.perfProfileFrameChart!.data = this.perfProfilerDataSource; + this.switchFlameChart(data); + }); + } else { + this.perfProfilerTbl!.setStatus(this.perfProfilerDataSource, true); + this.setPerfProfilerLeftTableData(this.perfProfilerDataSource); + this.switchFlameChart(data); + } + }; + + perfProfilerFilterGetCallTreeConstraints = (data: any): void => { + let perfProfilerConstraintsArgs: any[] = [ + { + funcName: 'resotreAllNode', + funcArgs: [[this.perfProfileNumRuleName]], + }, + { + funcName: 'clearSplitMapData', + funcArgs: [this.perfProfileNumRuleName], + }, + ]; + if (data.checked) { + perfProfilerConstraintsArgs.push({ + funcName: 'hideNumMaxAndMin', + funcArgs: [parseInt(data.min), data.max], + }); + } + perfProfilerConstraintsArgs.push({ + funcName: 'resetAllNode', + funcArgs: [], + }); + this.getDataByWorker(perfProfilerConstraintsArgs, (result: any[]): void => { + this.setPerfProfilerLeftTableData(result); + this.perfProfileFrameChart!.data = this.perfProfilerDataSource; + if (this.isChartShow) {this.perfProfileFrameChart?.calculateChartData()} + }); + }; + + perfProfilerFilterGetCallTree = (data: any): void => { + if (callTreeValueNoSample.includes(data.value)) { + this.refreshAllNode({ + ...this.perfProfilerFilter!.getFilterTreeData(), + callTree: data.checks, + }); + } else { + let perfProfileArgs: any[] = []; + if (data.checks[1]) { + perfProfileArgs.push({ + funcName: 'hideSystemLibrary', + funcArgs: [], + }); + } else { + perfProfileArgs.push({ + funcName: 'resotreAllNode', + funcArgs: [[this.systemRuleName]], + }); + perfProfileArgs.push({ + funcName: 'clearSplitMapData', + funcArgs: [this.systemRuleName], }); } - perfProfilerConstraintsArgs.push({ + perfProfileArgs.push({ funcName: 'resetAllNode', funcArgs: [], }); - this.getDataByWorker(perfProfilerConstraintsArgs, (result: any[]): void => { + this.getDataByWorker(perfProfileArgs, (result: any[]): void => { this.setPerfProfilerLeftTableData(result); this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - if (this.isChartShow) this.perfProfileFrameChart?.calculateChartData(); + if (this.isChartShow) {this.perfProfileFrameChart?.calculateChartData()} }); - }); - this.perfProfilerFilter!.getFilterData((data: FilterData): void => { - if (this.searchValue != this.perfProfilerFilter!.filterValue) { - this.searchValue = this.perfProfilerFilter!.filterValue; - let perfArgs = [ - { - funcName: 'setSearchValue', - funcArgs: [this.searchValue], - }, - { - funcName: 'resetAllNode', - funcArgs: [], - }, - ]; - this.getDataByWorker(perfArgs, (result: any[]): void => { - this.perfProfilerTbl!.isSearch = true; - this.perfProfilerTbl!.setStatus(result, true); - this.setPerfProfilerLeftTableData(result); - this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - this.switchFlameChart(data); - }); - } else { - this.perfProfilerTbl!.setStatus(this.perfProfilerDataSource, true); - this.setPerfProfilerLeftTableData(this.perfProfilerDataSource); - this.switchFlameChart(data); - } - }); - this.perfProfilerTbl!.addEventListener('column-click', (evt): void => { - // @ts-ignore - this.perfProfileSortKey = evt.detail.key; - // @ts-ignore - this.perfProfileSortType = evt.detail.sort; - // @ts-ignore - this.setPerfProfilerLeftTableData(this.perfProfilerDataSource); - this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - }); - } + } + }; connectedCallback(): void { super.connectedCallback(); @@ -540,7 +564,7 @@ export class TabpanePerfProfile extends BaseElement { let filterHeight = 0; new ResizeObserver((entries): void => { let perfProfileTabFilter = this.shadowRoot!.querySelector('#filter') as HTMLElement; - if (perfProfileTabFilter.clientHeight > 0) filterHeight = perfProfileTabFilter.clientHeight; + if (perfProfileTabFilter.clientHeight > 0) {filterHeight = perfProfileTabFilter.clientHeight} if (this.parentElement!.clientHeight > filterHeight) { perfProfileTabFilter.style.display = 'flex'; } else { @@ -557,14 +581,14 @@ export class TabpanePerfProfile extends BaseElement { // @ts-ignore this.perfProfilerTbl?.shadowRoot.querySelector('.table').style.height = // @ts-ignore - this.parentElement.clientHeight - 10 - 35 + 'px'; + `${this.parentElement.clientHeight - 10 - 35 }px`; this.perfProfilerTbl?.reMeauseHeight(); // @ts-ignore this.perfProfilerList?.shadowRoot.querySelector('.table').style.height = // @ts-ignore - this.parentElement.clientHeight - 45 - 21 + 'px'; + `${this.parentElement.clientHeight - 45 - 21 }px`; this.perfProfilerList?.reMeauseHeight(); - this.perfProfileLoadingPage.style.height = this.parentElement!.clientHeight - 24 + 'px'; + this.perfProfileLoadingPage.style.height = `${this.parentElement!.clientHeight - 24 }px`; } }).observe(this.parentElement!); } @@ -617,7 +641,6 @@ export class TabpanePerfProfile extends BaseElement { funcArgs: [], }); } - if (filterData.callTreeConstraints.checked) { perfProfileArgs.push({ funcName: 'hideNumMaxAndMin', @@ -632,6 +655,10 @@ export class TabpanePerfProfile extends BaseElement { funcName: 'resetAllNode', funcArgs: [], }); + this.refreshAllNodeExtend(perfProfileArgs); + } + + refreshAllNodeExtend(perfProfileArgs: any[]): void{ if (this._rowClickData && this._rowClickData.libId !== undefined && this._currentLevel === 2) { perfProfileArgs.push({ funcName: 'showLibLevelData', @@ -646,7 +673,9 @@ export class TabpanePerfProfile extends BaseElement { this.getDataByWorker(perfProfileArgs, (result: any[]): void => { this.setPerfProfilerLeftTableData(result); this.perfProfileFrameChart!.data = this.perfProfilerDataSource; - if (this.isChartShow) this.perfProfileFrameChart?.calculateChartData(); + if (this.isChartShow) { + this.perfProfileFrameChart?.calculateChartData(); + } }); } @@ -692,81 +721,6 @@ export class TabpanePerfProfile extends BaseElement { } initHtml(): string { - return ` - -
      - - - -
      - - - - - - - - - - -
      - - - Heaviest Stack Trace - - - - - -
      - - - - - - - -
      - `; + return TabPerfProfileHtml; } } diff --git a/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts b/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts index 1a06d5cb25bb9fd4b3e8604c873fd168b9754e3b..0ea0b68a8820fe3011c5b8560159691b50b767e6 100644 --- a/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts +++ b/ide/src/trace/component/trace/sheet/hiperf/TabPerfSampleList.ts @@ -17,18 +17,16 @@ import { BaseElement, element } from '../../../../../base-ui/BaseElement'; import { LitTable } from '../../../../../base-ui/table/lit-table'; import { SelectionParam } from '../../../../bean/BoxSelection'; import { perfDataQuery } from '../../../chart/PerfDataQuery'; -import { PerfFile, PerfSample, PerfStack, PerfThread } from '../../../../bean/PerfProfile'; +import { PerfFile, PerfSample, PerfThread } from '../../../../bean/PerfProfile'; import { Utils } from '../../base/Utils'; -import { SpApplication } from '../../../../SpApplication'; import { log } from '../../../../../log/Log'; import '../../../../../base-ui/slicer/lit-slicer'; -import { Cmd } from '../../../../../command/Cmd'; import { SpSystemTrace } from '../../../SpSystemTrace'; import { queryPerfProcess, queryPerfSampleCallChain, queryPerfSampleListByTimeRange -} from "../../../../database/sql/Perf.sql"; +} from '../../../../database/sql/Perf.sql'; @element('tabpane-perf-sample') export class TabPanePerfSample extends BaseElement { @@ -43,10 +41,10 @@ export class TabPanePerfSample extends BaseElement { this.perfSampleTbl!.style.visibility = 'visible'; // @ts-ignore this.perfSampleTbl?.shadowRoot?.querySelector('.table')?.style?.height = - this.parentElement!.clientHeight - 40 + 'px'; + `${this.parentElement!.clientHeight - 40 }px`; this.perfSampleTbl!.recycleDataSource = []; // @ts-ignore - this.tblData?.shadowRoot?.querySelector('.table')?.style?.height = this.parentElement!.clientHeight - 25 + 'px'; + this.tblData?.shadowRoot?.querySelector('.table')?.style?.height = `${this.parentElement!.clientHeight - 25 }px`; this.tblData!.recycleDataSource = []; if (perfSampleSelection) { Promise.all([ @@ -61,46 +59,50 @@ export class TabPanePerfSample extends BaseElement { ), ]).then((results) => { let processes = results[0] as Array; - log('queryPerfProcess size : ' + processes.length); + log(`queryPerfProcess size : ${ processes.length}`); let samples = results[1] as Array; - log('queryPerfSampleListByTimeRange size : ' + samples.length); + log(`queryPerfSampleListByTimeRange size : ${ samples.length}`); this.processMap.clear(); for (let process of processes) { this.processMap.set(process.pid, process); } - for (let sample of samples) { - let process = this.processMap.get(sample.pid); - sample.processName = - process == null || process == undefined - ? `Process(${sample.pid})` - : `${process!.processName || 'Process'}(${sample.pid})`; - sample.threadName = - sample.threadName == null || sample.threadName == undefined - ? `Thread(${sample.tid})` - : `${sample.threadName}(${sample.tid})`; - sample.coreName = `CPU ${sample.core}`; - sample.timeString = Utils.getTimeString(sample.time); - sample.backtrace = []; - let call = perfDataQuery.callChainMap.get(sample.sampleId); - if (call == undefined || call == null) { - sample.depth = 0; - sample.backtrace.push('No Effective Call Stack'); - } else { - sample.depth = call.depth; - if (typeof call.name === 'number') { - call.name = SpSystemTrace.DATA_DICT.get(call.name) || ''; - } - sample.backtrace.push(call.name); - sample.backtrace.push(`(${sample.depth} other frames)`); - } - } - this.perfSampleSource = samples; - this.sortPerfSampleTable(this.sortKey, this.sortType); + this.initPerfSampleData(samples); }); } } - setRightTableData(sample: PerfSample) { + private initPerfSampleData(samples: PerfSample[]): void{ + for (let sample of samples) { + let process = this.processMap.get(sample.pid); + sample.processName = + process === null || process === undefined ? + `Process(${sample.pid})` : + `${process!.processName || 'Process'}(${sample.pid})`; + sample.threadName = + sample.threadName === null || sample.threadName === undefined ? + `Thread(${sample.tid})` : + `${sample.threadName}(${sample.tid})`; + sample.coreName = `CPU ${sample.core}`; + sample.timeString = Utils.getTimeString(sample.time); + sample.backtrace = []; + let call = perfDataQuery.callChainMap.get(sample.sampleId); + if (call === undefined || call === null) { + sample.depth = 0; + sample.backtrace.push('No Effective Call Stack'); + } else { + sample.depth = call.depth; + if (typeof call.name === 'number') { + call.name = SpSystemTrace.DATA_DICT.get(call.name) || ''; + } + sample.backtrace.push(call.name); + sample.backtrace.push(`(${sample.depth} other frames)`); + } + } + this.perfSampleSource = samples; + this.sortPerfSampleTable(this.sortKey, this.sortType); + } + + setRightTableData(sample: PerfSample): void { queryPerfSampleCallChain(sample.sampleId).then((result) => { for (let stack of result) { if (typeof stack.symbol === 'number') { @@ -132,35 +134,35 @@ export class TabPanePerfSample extends BaseElement { }); } - connectedCallback() { + connectedCallback(): void { super.connectedCallback(); - new ResizeObserver((entries) => { - if (this.parentElement?.clientHeight != 0) { + new ResizeObserver(() => { + if (this.parentElement?.clientHeight !== 0) { // @ts-ignore this.perfSampleTbl?.shadowRoot.querySelector('.table').style.height = - this.parentElement!.clientHeight - 40 + 'px'; + `${this.parentElement!.clientHeight - 40 }px`; // @ts-ignore - this.tblData?.shadowRoot.querySelector('.table').style.height = this.parentElement.clientHeight - 25 + 'px'; + this.tblData?.shadowRoot.querySelector('.table').style.height = `${this.parentElement.clientHeight - 25 }px`; this.perfSampleTbl?.reMeauseHeight(); this.tblData?.reMeauseHeight(); } }).observe(this.parentElement!); } - sortPerfSampleTable(key: string, type: number) { + sortPerfSampleTable(key: string, type: number): void { this.perfSampleSource.sort((perfSampleA, perfSampleB): number => { - if (key == 'timeString') { - if (type == 0) { + if (key === 'timeString') { + if (type === 0) { return perfSampleA.time - perfSampleB.time; - } else if (type == 1) { + } else if (type === 1) { return perfSampleA.time - perfSampleB.time; } else { return perfSampleB.time - perfSampleA.time; } } else { - if (type == 0) { + if (type === 0) { return perfSampleA.core - perfSampleB.core; - } else if (type == 1) { + } else if (type === 1) { return perfSampleA.core - perfSampleB.core; } else { return perfSampleB.core - perfSampleA.core; @@ -183,24 +185,31 @@ export class TabPanePerfSample extends BaseElement {
      - - - - - - + + + + + +
      - +