From: @xia_yi_fan1 Reviewed-by: @weiyanxi Signed-off-by:tags/v1.2.0-rc1
| @@ -477,6 +477,8 @@ | |||
| "processCpuUtil": "Process CPU Usage", | |||
| "operatorCpuUtil": "Operator CPU Usage", | |||
| "utilizationTitle": "Usage(%)", | |||
| "trainingPerformance": "Training Performance", | |||
| "resourceUtilization": "Resource Utilization", | |||
| "memory": { | |||
| "memoryDetailLink": "Memory Usage Information", | |||
| "overView": "Memory Allocation OverView", | |||
| @@ -476,6 +476,8 @@ | |||
| "processCpuUtil": "进程CPU利用率", | |||
| "operatorCpuUtil": "算子CPU利用率", | |||
| "utilizationTitle": "利用率(%)", | |||
| "trainingPerformance": "训练性能", | |||
| "resourceUtilization": "资源利用", | |||
| "memory": { | |||
| "memoryDetailLink": "内存使用情况", | |||
| "overView": "内存分配概览", | |||
| @@ -103,6 +103,14 @@ export default new Router({ | |||
| path: 'memory-detail', | |||
| component: () => import('./views/profiling/memory-detail.vue'), | |||
| }, | |||
| { | |||
| path: 'cpu-detail', | |||
| component: () => import('./views/profiling/cpu-detail.vue'), | |||
| }, | |||
| { | |||
| path: 'resource-utilization', | |||
| component: () => import('./views/profiling/resource-utilization.vue'), | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| @@ -123,10 +131,18 @@ export default new Router({ | |||
| path: 'operator', | |||
| component: () => import('./views/profiling-gpu/operator.vue'), | |||
| }, | |||
| { | |||
| path: 'resource-utilization', | |||
| component: () => import('./views/profiling-gpu/resource-utilization.vue'), | |||
| }, | |||
| { | |||
| path: 'step-trace', | |||
| component: () => import('./views/profiling/step-trace.vue'), | |||
| }, | |||
| { | |||
| path: 'cpu-detail', | |||
| component: () => import('./views/profiling/cpu-detail.vue'), | |||
| }, | |||
| ], | |||
| }, | |||
| { | |||
| @@ -1197,11 +1197,11 @@ export default { | |||
| } | |||
| .operator .operator-title { | |||
| padding: 0 15px; | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| } | |||
| .operator .cl-profiler { | |||
| height: calc(100% - 21px); | |||
| height: calc(100% - 24px); | |||
| overflow-y: auto; | |||
| width: 100%; | |||
| background: #fff; | |||
| @@ -1,5 +1,5 @@ | |||
| <!-- | |||
| Copyright 2020 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Copyright 2020-2021 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| @@ -180,7 +180,6 @@ limitations under the License. | |||
| </div> | |||
| <div class="title">{{$t('profiling.connectorQuene')}}</div> | |||
| <div class="description"> | |||
| <div class="line"></div> | |||
| <div class="item" | |||
| v-if="processSummary.device.empty || processSummary.device.empty === 0"> | |||
| {{$t('profiling.queueTip2')}} | |||
| @@ -224,7 +223,6 @@ limitations under the License. | |||
| </div> | |||
| <div class="title">{{$t('profiling.dataQueue')}}</div> | |||
| <div class="description"> | |||
| <div class="line"></div> | |||
| <div class="item" | |||
| v-if="processSummary.get_next.empty || processSummary.get_next.empty === 0"> | |||
| {{$t('profiling.queueTip2')}} | |||
| @@ -1252,8 +1250,8 @@ export default { | |||
| height: 100%; | |||
| } | |||
| .pro-router-wrap > div > div { | |||
| border: 1px solid #eee; | |||
| border-radius: 4px; | |||
| border: 1px solid #d9d9d9; | |||
| border-radius: 1px; | |||
| } | |||
| .pro-router-wrap > div .title-wrap { | |||
| padding: 15px; | |||
| @@ -1261,7 +1259,7 @@ export default { | |||
| .pro-router-wrap > div .title-wrap .title { | |||
| float: left; | |||
| font-weight: bold; | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| } | |||
| .pro-router-wrap > div .title-wrap .tip-icon { | |||
| float: right; | |||
| @@ -1297,7 +1295,7 @@ export default { | |||
| color: #c0c4cc; | |||
| } | |||
| .pro-router-wrap > div .title-wrap::after { | |||
| content: ""; | |||
| content: ''; | |||
| clear: both; | |||
| display: block; | |||
| } | |||
| @@ -1326,7 +1324,7 @@ export default { | |||
| padding-right: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .step-trace { | |||
| height: 45%; | |||
| height: calc(100% - 275px); | |||
| margin-bottom: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .step-trace .trace-container { | |||
| @@ -1350,11 +1348,11 @@ export default { | |||
| overflow: visible; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata { | |||
| height: calc(55% - 15px); | |||
| height: 260px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container { | |||
| width: 100%; | |||
| padding: 20px 20px; | |||
| padding: 0 20px; | |||
| height: calc(100% - 52px); | |||
| display: flex; | |||
| font-size: 0; | |||
| @@ -1429,14 +1427,9 @@ export default { | |||
| white-space: nowrap; | |||
| overflow: visible; | |||
| width: 100%; | |||
| min-width: 100px; | |||
| text-align: center; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container .queue-container .description .line { | |||
| width: 1px; | |||
| height: 40px; | |||
| margin: 20px 0; | |||
| border-left: 1px solid #979797; | |||
| display: inline-block; | |||
| margin-top: 30px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container .queue-container .description .item { | |||
| font-size: 12px; | |||
| @@ -1452,7 +1445,7 @@ export default { | |||
| width: 400px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .op-time-consume { | |||
| height: calc(60% - 15px); | |||
| height: calc(100% - 275px); | |||
| margin-bottom: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .op-time-consume .time-list { | |||
| @@ -1506,7 +1499,7 @@ export default { | |||
| height: 25px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .time-line { | |||
| height: 40%; | |||
| height: 260px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .time-line .timeline-info { | |||
| width: 100%; | |||
| @@ -15,15 +15,20 @@ limitations under the License. | |||
| --> | |||
| <template> | |||
| <div class="prof-wrap"> | |||
| <div class="prof-head"> | |||
| <span class="cl-title-left">{{$t('summaryManage.viewProfiler')}}</span> | |||
| <div class="path-message"> | |||
| <span>{{$t('symbols.leftbracket')}}</span> | |||
| <span>{{$t('trainingDashboard.summaryDirPath')}}</span> | |||
| <span>{{summaryPath}}</span> | |||
| <span>{{$t('symbols.rightbracket')}}</span> | |||
| </div> | |||
| </div> | |||
| <div class="prof-content"> | |||
| <div class="prof-content-left" | |||
| :class="{collapse:collapse}"> | |||
| <div class="helper" | |||
| v-show="!collapse"> | |||
| <div class="summary-path"> | |||
| {{$t('trainingDashboard.summaryDirPath')}} | |||
| <span>{{ summaryPath}}</span> | |||
| </div> | |||
| <div class="cur-card"> | |||
| <label>{{$t('profiling.curCard')}}</label> | |||
| <el-select v-model="curDashboardInfo.curCardNum" | |||
| @@ -50,10 +55,26 @@ limitations under the License. | |||
| </div> | |||
| <div class="prof-content-right" | |||
| :class="{collapse:collapse}"> | |||
| <router-view></router-view> | |||
| <div class="tab-container" | |||
| v-show="$route.path === '/profiling-gpu/profiling-dashboard' | |||
| || $route.path === '/profiling-gpu/resource-utilization'"> | |||
| <el-tabs v-model="tabData.activeName" | |||
| @tab-click="paneChange"> | |||
| <el-tab-pane v-for="pane in tabData.tabPanes" | |||
| :key="pane.name" | |||
| :label="pane.label" | |||
| :name="pane.name"></el-tab-pane> | |||
| </el-tabs> | |||
| </div> | |||
| <div class="router-container" | |||
| :class="$route.path === '/profiling-gpu/profiling-dashboard' | |||
| || $route.path === '/profiling-gpu/resource-utilization'?'dashboard':'detail'"> | |||
| <router-view></router-view> | |||
| </div> | |||
| <div class="close" | |||
| @click="backToDdashboard" | |||
| v-if="$route.path !== '/profiling-gpu/profiling-dashboard'"> | |||
| v-if="$route.path !== '/profiling-gpu/profiling-dashboard' | |||
| && $route.path !== '/profiling-gpu/resource-utilization'"> | |||
| <img src="@/assets/images/close-page.png"> | |||
| </div> | |||
| </div> | |||
| @@ -84,10 +105,27 @@ export default { | |||
| curCardNum: null, | |||
| query: {}, | |||
| }, | |||
| tabData: { | |||
| activeName: '0', | |||
| tabPanes: [ | |||
| { | |||
| name: '0', | |||
| label: this.$t('profiling.trainingPerformance'), | |||
| }, | |||
| { | |||
| name: '1', | |||
| label: this.$t('profiling.resourceUtilization'), | |||
| }, | |||
| ], | |||
| }, | |||
| }; | |||
| }, | |||
| watch: {}, | |||
| mounted() { | |||
| if ( | |||
| this.$route.path === 'resource-utilization') { | |||
| this.tabData.activeName = this.tabData.tabPanes[1].name; | |||
| } | |||
| this.$nextTick(() => { | |||
| this.init(); | |||
| }); | |||
| @@ -101,12 +139,15 @@ export default { | |||
| this.curDashboardInfo.query.id = this.$route.query.id; | |||
| this.curDashboardInfo.query.dir = this.$route.query.dir; | |||
| this.curDashboardInfo.query.path = this.$route.query.path; | |||
| this.summaryPath = decodeURIComponent( this.$route.query.id); | |||
| this.tabData.activeName = | |||
| this.$route.query.activePane || this.tabData.tabPanes[0].name; | |||
| this.summaryPath = decodeURIComponent(this.$route.query.id); | |||
| this.getDeviceList(); | |||
| } else { | |||
| this.curDashboardInfo.query.trainingJobId = ''; | |||
| this.curDashboardInfo.query.dir = ''; | |||
| this.curDashboardInfo.query.path = ''; | |||
| this.tabData.activeName = this.tabData.tabPanes[0].name; | |||
| this.$message.error(this.$t('trainingDashboard.invalidId')); | |||
| } | |||
| }, | |||
| @@ -298,12 +339,18 @@ export default { | |||
| * Router back to profiling-dashboard | |||
| */ | |||
| backToDdashboard() { | |||
| let path = '/profiling-gpu/profiling-dashboard'; | |||
| if (this.tabData.activeName === this.tabData.tabPanes[1].name) { | |||
| path = '/profiling-gpu/resource-utilization'; | |||
| } | |||
| this.$router.push({ | |||
| path: '/profiling-gpu/profiling-dashboard', | |||
| path: path, | |||
| query: { | |||
| dir: this.curDashboardInfo.query.dir, | |||
| id: this.curDashboardInfo.query.id, | |||
| path: this.curDashboardInfo.query.path, | |||
| activePane: this.tabData.activeName, | |||
| cardNum: this.curDashboardInfo.curCardNum, | |||
| }, | |||
| }); | |||
| }, | |||
| @@ -311,6 +358,35 @@ export default { | |||
| this.collapse = !this.collapse; | |||
| this.$bus.$emit('collapse'); | |||
| }, | |||
| /** | |||
| * Tab button click | |||
| * @param {Object} tabItem Tab | |||
| */ | |||
| paneChange(tabItem) { | |||
| if (tabItem && tabItem.name) { | |||
| let path = ''; | |||
| switch (tabItem.name) { | |||
| case this.tabData.tabPanes[0].name: | |||
| path = '/profiling-gpu/profiling-dashboard'; | |||
| break; | |||
| case this.tabData.tabPanes[1].name: | |||
| path = '/profiling-gpu/resource-utilization'; | |||
| break; | |||
| } | |||
| if (path) { | |||
| this.$router.push({ | |||
| path: path, | |||
| query: { | |||
| dir: this.curDashboardInfo.query.dir, | |||
| id: this.curDashboardInfo.query.id, | |||
| path: this.curDashboardInfo.query.path, | |||
| activePane: this.tabData.activeName, | |||
| cardNum: this.curDashboardInfo.curCardNum, | |||
| }, | |||
| }); | |||
| } | |||
| } | |||
| }, | |||
| }, | |||
| destroyed() { | |||
| this.$bus.$off('collapse'); | |||
| @@ -322,9 +398,20 @@ export default { | |||
| height: 100%; | |||
| background: #fff; | |||
| } | |||
| .prof-wrap .prof-head { | |||
| height: 50px; | |||
| line-height: 50px; | |||
| display: inline-block; | |||
| } | |||
| .prof-wrap .prof-head .path-message { | |||
| display: inline-block; | |||
| line-height: 20px; | |||
| padding: 18px 0; | |||
| font-weight: bold; | |||
| } | |||
| .prof-wrap .prof-content { | |||
| height: 100%; | |||
| padding: 24px 24px 24px 0; | |||
| height: calc(100% - 50px); | |||
| padding: 0 24px 24px 0; | |||
| } | |||
| .prof-wrap .prof-content > div { | |||
| float: left; | |||
| @@ -347,25 +434,12 @@ export default { | |||
| background: #edf0f5; | |||
| word-wrap: break-word; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .summary-path { | |||
| line-height: 24px; | |||
| font-size: 14px; | |||
| overflow: hidden; | |||
| font-weight: bold; | |||
| padding-bottom: 10px; | |||
| word-break: break-all; | |||
| text-overflow: -o-ellipsis-lastline; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| display: -webkit-box; | |||
| -webkit-line-clamp: 4; | |||
| -webkit-box-orient: vertical; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .nowrap-style { | |||
| white-space: nowrap; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .cur-card { | |||
| margin-bottom: 32px; | |||
| padding-bottom: 20px; | |||
| border-bottom: 1px solid #d9d9d9; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .cur-card .card-select { | |||
| width: calc(100% - 120px); | |||
| @@ -374,9 +448,9 @@ export default { | |||
| margin-right: 14px; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .helper-title { | |||
| font-size: 20px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| margin-bottom: 32px; | |||
| margin: 24px 0; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .helper-title .el-icon-rank { | |||
| float: right; | |||
| @@ -399,6 +473,10 @@ export default { | |||
| margin-bottom: 20px; | |||
| font-size: 16px; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .link-title { | |||
| cursor: pointer; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .container-bottom { | |||
| margin-bottom: 16px; | |||
| } | |||
| @@ -450,6 +528,25 @@ export default { | |||
| transition: width 0.2s; | |||
| position: relative; | |||
| } | |||
| .prof-content-right .tab-container { | |||
| width: 100%; | |||
| padding-bottom: 5px; | |||
| } | |||
| .prof-content-right .tab-container .el-tabs__item { | |||
| font-size: 14px; | |||
| line-height: 14px; | |||
| height: 27px; | |||
| } | |||
| .prof-content-right .tab-container .el-tabs__item.is-active { | |||
| color: #00a5a7; | |||
| font-weight: bold; | |||
| } | |||
| .prof-content-right .router-container.detail { | |||
| height: 100%; | |||
| } | |||
| .prof-content-right .router-container.dashboard { | |||
| height: calc(100% - 46px); | |||
| } | |||
| .prof-wrap .prof-content .prof-content-right .close { | |||
| position: absolute; | |||
| right: 0; | |||
| @@ -0,0 +1,473 @@ | |||
| <!-- | |||
| Copyright 2021 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| 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. | |||
| --> | |||
| <template> | |||
| <div class="cl-resource-content"> | |||
| <div class="dashboard-item"> | |||
| <div class="title-item"> | |||
| <div class="title-text"> | |||
| {{$t('profiling.structuralCpuUtil')}} | |||
| </div> | |||
| <div class="detail-link" | |||
| :class="{disabled:!cpuInfo.initOver || cpuInfo.noData}"> | |||
| <button :disabled="!cpuInfo.initOver || cpuInfo.noData" | |||
| @click="jumpToCpuDetail"> | |||
| {{$t('profiling.viewDetail')}} | |||
| <i class="el-icon-d-arrow-right"></i> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <div class="content-item"> | |||
| <div class="cpu-info" v-if="!cpuInfo.noData"> | |||
| <div class="cpu-chart" | |||
| id="deviceCpuChart" | |||
| ref="deviceCpuChart"></div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.logicCores')}}</span><span>{{deviceCpuChart.logicCores}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIOUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgIO)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIdleUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgFree)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgWaitingProcess')}}</span><span>{{deviceCpuChart.cpuAvgProcess}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSwitchCount')}}</span><span>{{deviceCpuChart.cpuAvgSwitch}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="noData-content" v-else> | |||
| <img :src="require('@/assets/images/nodata.png')" alt="" /> | |||
| <p>{{cpuInfo.initOver?$t("public.noData"):$t("public.dataLoading")}}</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import RequestService from '../../services/request-service'; | |||
| import echarts from 'echarts'; | |||
| export default { | |||
| data() { | |||
| return { | |||
| // ------------------------common-------------------- | |||
| queryData: { | |||
| dir: '', | |||
| id: '', | |||
| path: '', | |||
| activePane: '', | |||
| }, | |||
| summaryPath: '', | |||
| curCardNum: '', | |||
| pageResizeTimer: null, // Timer for changing the window size | |||
| firstInit: true, // First init of page | |||
| // ------------------------cpu----------------------- | |||
| deviceCpuChart: { | |||
| id: 'deviceCpuChart', | |||
| chartDom: null, | |||
| option: { | |||
| tooltip: { | |||
| trigger: 'axis', | |||
| formatter: null, | |||
| confine: true, | |||
| }, | |||
| legend: { | |||
| right: 70, | |||
| top: 8, | |||
| data: [], | |||
| }, | |||
| xAxis: { | |||
| name: '', | |||
| data: [], | |||
| }, | |||
| yAxis: { | |||
| name: this.$t('profiling.utilizationTitle'), | |||
| type: 'value', | |||
| }, | |||
| dataZoom: [ | |||
| { | |||
| start: 0, | |||
| end: 100, | |||
| bottom: 0, | |||
| }, | |||
| { | |||
| start: 0, | |||
| end: 100, | |||
| type: 'inside', | |||
| bottom: 0, | |||
| }, | |||
| ], | |||
| grid: { | |||
| left: 40, | |||
| top: 40, | |||
| right: 70, | |||
| bottom: 60, | |||
| }, | |||
| series: [], | |||
| }, | |||
| logicCores: 0, | |||
| cpuAvgUser: 0, | |||
| cpuAvgSystem: 0, | |||
| cpuAvgIO: 0, | |||
| cpuAvgFree: 0, | |||
| cpuAvgProcess: 0, | |||
| cpuAvgSwitch: 0, | |||
| }, // The total data of device cpu info | |||
| cpuInfo: { | |||
| initOver: false, | |||
| noData: true, | |||
| stepArray: [], | |||
| cpuInfoStr: { | |||
| user_utilization: this.$t('profiling.userUtilization'), | |||
| sys_utilization: this.$t('profiling.sysUtilization'), | |||
| io_utilization: this.$t('profiling.ioUtilization'), | |||
| idle_utilization: this.$t('profiling.idleUtilization'), | |||
| }, | |||
| samplingInterval: 0, | |||
| }, | |||
| }; | |||
| }, | |||
| watch: { | |||
| // Listening card number | |||
| '$parent.curDashboardInfo.curCardNum': { | |||
| handler(newValue) { | |||
| if (isNaN(newValue) || newValue === this.curCardNum || this.firstInit) { | |||
| return; | |||
| } | |||
| this.curCardNum = newValue; | |||
| this.noGraphicsDataFlag = false; | |||
| this.graphicsInitOver = false; | |||
| this.init(); | |||
| }, | |||
| deep: true, | |||
| immediate: true, | |||
| }, | |||
| }, | |||
| mounted() { | |||
| window.addEventListener('resize', this.resizeCallback, false); | |||
| this.$bus.$on('collapse', this.resizeCallback); | |||
| this.queryData = { | |||
| dir: this.$route.query.dir, | |||
| id: this.$route.query.id, | |||
| path: this.$route.query.path, | |||
| activePane: this.$route.query.activePane, | |||
| }; | |||
| if ( | |||
| this.$route.query && | |||
| this.$route.query.path && | |||
| !isNaN(this.$route.query.cardNum) | |||
| ) { | |||
| this.summaryPath = this.$route.query.path; | |||
| this.curCardNum = this.$route.query.cardNum; | |||
| this.init(); | |||
| } | |||
| this.firstInit = false; | |||
| }, | |||
| methods: { | |||
| // ------------------common--------------------- | |||
| init() { | |||
| this.queryCpuInfo(); | |||
| }, | |||
| /** | |||
| * Window resize | |||
| */ | |||
| resizeCallback() { | |||
| if (this.pageResizeTimer) { | |||
| clearTimeout(this.pageResizeTimer); | |||
| this.pageResizeTimer = null; | |||
| } | |||
| this.pageResizeTimer = setTimeout(() => { | |||
| if (this.deviceCpuChart.chartDom) { | |||
| this.deviceCpuChart.chartDom.resize(); | |||
| } | |||
| }, 300); | |||
| }, | |||
| // ----------------cpu----------------------------------- | |||
| /** | |||
| * The logic of add percent sign | |||
| * @param {number | string} number | |||
| * @return {string} | |||
| */ | |||
| addPercentSign(number) { | |||
| if (number === 0 || number === '0') { | |||
| return '0'; | |||
| } else { | |||
| return `${number}%`; | |||
| } | |||
| }, | |||
| /** | |||
| * Query cpu info | |||
| */ | |||
| queryCpuInfo( ) { | |||
| const params = { | |||
| params: { | |||
| profile: this.queryData.dir, | |||
| train_id: this.queryData.id, | |||
| }, | |||
| body: { | |||
| device_id: this.curCardNum, | |||
| filter_condition: {}, | |||
| }, | |||
| }; | |||
| this.cpuInfo.noData = true; | |||
| this.cpuInfo.initOver = false; | |||
| RequestService.getCpuUtilization(params).then( | |||
| (res) => { | |||
| this.cpuInfo.initOver = true; | |||
| if (res && res.data) { | |||
| this.cpuInfo.noData = !res.data.step_total_num; | |||
| this.cpuInfo.stepArray = res.data.step_info; | |||
| this.samplingInterval = res.data.sampling_interval; | |||
| this.deviceCpuChart.logicCores = res.data.cpu_processor_num; | |||
| const deviceInfo = res.data.device_info; | |||
| if (deviceInfo && this.samplingInterval) { | |||
| this.initDeviceCpu(deviceInfo); | |||
| } else { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.noData = true; | |||
| } | |||
| } else { | |||
| this.clearCpuChart(); | |||
| } | |||
| }, | |||
| () => { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.initOver = true; | |||
| }, | |||
| ); | |||
| }, | |||
| /** | |||
| * clear cpu chart | |||
| */ | |||
| clearCpuChart() { | |||
| if (this.deviceCpuChart.chartDom) { | |||
| this.deviceCpuChart.chartDom.clear(); | |||
| } | |||
| }, | |||
| /** | |||
| * format chart tip | |||
| * @param {Object} params | |||
| * @param {Array} stepArray | |||
| * @return {String} | |||
| */ | |||
| formatCpuChartTip(params, stepArray) { | |||
| const data = params; | |||
| let str = ''; | |||
| if (data && data.length) { | |||
| const colorArray = [ | |||
| '#c23531', | |||
| '#2f4554', | |||
| '#61a0a8', | |||
| '#d48265', | |||
| ]; | |||
| const index = data[0].dataIndex; | |||
| str += `step: ${stepArray[index]}`; | |||
| data.forEach((item, index) => { | |||
| str += `<br><span class="cpu-chart-tip" style="background-color:${colorArray[index]};"></span>` + | |||
| `${item.seriesName}: ${item.data}`; | |||
| }); | |||
| str += `</div>`; | |||
| } | |||
| return str; | |||
| }, | |||
| /** | |||
| * Init device cpu chart | |||
| * @param {Object} deviceInfo | |||
| */ | |||
| initDeviceCpu(deviceInfo) { | |||
| const series = []; | |||
| const legend = []; | |||
| Object.keys(this.cpuInfo.cpuInfoStr).forEach((val) => { | |||
| const info = deviceInfo[val]; | |||
| if (info && info.metrics) { | |||
| const item = { | |||
| type: 'line', | |||
| name: this.cpuInfo.cpuInfoStr[val], | |||
| data: info.metrics, | |||
| showSymbol: false, | |||
| }; | |||
| series.push(item); | |||
| legend.push(item.name); | |||
| } | |||
| }); | |||
| this.deviceCpuChart.cpuAvgUser = deviceInfo.user_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgSystem = deviceInfo.sys_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgIO = deviceInfo.io_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgFree = deviceInfo.idle_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgProcess = deviceInfo.runable_processes.avg_value; | |||
| this.deviceCpuChart.cpuAvgSwitch = deviceInfo.context_switch_count.avg_value; | |||
| this.deviceCpuChart.option.series = series; | |||
| this.deviceCpuChart.option.xAxis.name = `${this.$t('profiling.sampleInterval')}\n${ | |||
| this.$t('symbols.leftbracket')}${this.samplingInterval}ms${this.$t('symbols.rightbracket')}`; | |||
| this.deviceCpuChart.option.xAxis.data = deviceInfo[Object.keys(deviceInfo)[0]].metrics.map( | |||
| (val, index) => index + 1, | |||
| ); | |||
| this.deviceCpuChart.option.legend.data = legend; | |||
| this.deviceCpuChart.option.tooltip.formatter = (params) => { | |||
| return this.formatCpuChartTip(params, this.cpuInfo.stepArray); | |||
| }; | |||
| this.$nextTick(() => { | |||
| if (!this.deviceCpuChart.chartDom) { | |||
| if (this.$refs.deviceCpuChart) { | |||
| this.deviceCpuChart.chartDom = echarts.init(this.$refs.deviceCpuChart); | |||
| } | |||
| } | |||
| this.deviceCpuChart.chartDom.setOption(this.deviceCpuChart.option); | |||
| }); | |||
| }, | |||
| /** | |||
| * Router to memory-detail | |||
| */ | |||
| jumpToCpuDetail() { | |||
| if (this.$route.path !== '/profiling-gpu/cpu-detail') { | |||
| this.$router.push({ | |||
| path: '/profiling-gpu/cpu-detail', | |||
| query: { | |||
| dir: this.queryData.dir, | |||
| id: this.queryData.id, | |||
| cardNum: this.curCardNum, | |||
| path: this.queryData.path, | |||
| activePane: this.queryData.activePane, | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| }, | |||
| destroyed() { | |||
| // Remove the listener of window size change | |||
| window.removeEventListener('resize', this.resizeCallback); | |||
| // Remove timer | |||
| if (this.pageResizeTimer) { | |||
| clearTimeout(this.pageResizeTimer); | |||
| this.pageResizeTimer = null; | |||
| } | |||
| // Remove bus | |||
| this.$bus.$off('collapse'); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style> | |||
| .cl-resource-content { | |||
| height: 100%; | |||
| } | |||
| .cl-resource-content .dashboard-item { | |||
| width: 100%; | |||
| height: 100%; | |||
| padding: 15px; | |||
| border: solid 1px #d9d9d9; | |||
| border-radius: 4px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item { | |||
| display: flex; | |||
| height: 24px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .title-text { | |||
| flex: 1; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| line-height: 24px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link { | |||
| cursor: pointer; | |||
| font-size: 12px; | |||
| height: 18px; | |||
| line-height: 12px; | |||
| padding-top: 2px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link a { | |||
| color: #00a5a7; | |||
| padding-right: 6px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link button { | |||
| color: #00a5a7; | |||
| border: none; | |||
| background-color: #fff; | |||
| cursor: pointer; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link.disabled button { | |||
| color: #c0c4cc; | |||
| cursor: not-allowed; | |||
| } | |||
| .cl-resource-content .dashboard-item .content-item { | |||
| height: calc(100% - 38px); | |||
| margin-top: 20px; | |||
| } | |||
| .cl-resource-content .dashboard-item .content-item .dashboard-chart-content { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| .cl-resource-content .margin-item { | |||
| margin-top: 20px; | |||
| } | |||
| .cl-resource-content .noData-content { | |||
| width: 100%; | |||
| height: 100%; | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| flex-direction: column; | |||
| } | |||
| .cl-resource-content .noData-content p, | |||
| .cl-resource-content .noData-content .noData-text { | |||
| font-size: 16px; | |||
| } | |||
| .content-item .cpu-info { | |||
| display: grid; | |||
| grid-template-columns: 1fr 300px; | |||
| height: 100%; | |||
| } | |||
| .content-item .cpu-info .cpu-chart { | |||
| height: 100%; | |||
| width: 100% | |||
| } | |||
| .content-item .cpu-info .cpu-chart-info { | |||
| height: 100%; | |||
| width: 100%; | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: center; | |||
| padding-left: 20px; | |||
| background-color: #f1f1f1; | |||
| } | |||
| .content-item .cpu-chart-info .info-title { | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| line-height: 30px; | |||
| } | |||
| .content-item .cpu-chart-info .info-line { | |||
| line-height: 30px; | |||
| } | |||
| .cpu-chart-tip { | |||
| display: inline-block; | |||
| margin-right: 5px; | |||
| border-radius: 10px; | |||
| width: 10px; | |||
| height: 10px; | |||
| } | |||
| </style> | |||
| @@ -13,16 +13,141 @@ 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. | |||
| --> | |||
| <template> | |||
| <div class="data-process-wrap"> | |||
| <div class="title">{{$t('profiling.cpuUtilization')}}</div> | |||
| <div class="cpu-info" v-if="!cpuInfo.noData"> | |||
| <div class="step-filter"> | |||
| <label>{{cpuInfo.stepTip}}</label> | |||
| <label>{{$t('profiling.startStep')}}</label> | |||
| <el-input class="step-input" | |||
| v-model.number="cpuInfo.startStep.showStep"></el-input> | |||
| <label>{{$t('profiling.endStep')}}</label> | |||
| <el-input class="step-input" | |||
| v-model.number="cpuInfo.endStep.showStep"></el-input> | |||
| <el-button @click="viewStepFilter">{{$t('profiling.filterStep')}}</el-button> | |||
| <el-button @click="resetStepFilter">{{$t('profiling.resetStep')}}</el-button> | |||
| </div> | |||
| <div class="cpu-detail"> | |||
| <div class="cpu-detail-item"> | |||
| <div class="detail-item-title">{{$t('profiling.structuralCpuUtil')}}</div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="deviceCpuChart" | |||
| ref="deviceCpuChart"></div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.logicCores')}}</span><span>{{deviceCpuChart.logicCores}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIOUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgIO)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIdleUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgFree)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgWaitingProcess')}}</span><span>{{deviceCpuChart.cpuAvgProcess}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSwitchCount')}}</span><span>{{deviceCpuChart.cpuAvgSwitch}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="cpu-detail-item cpu-detail-item-top"> | |||
| <div class="detail-item-title">{{$t('profiling.processCpuUtil')}}</div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="processCpuChart" | |||
| ref="processCpuChart"> | |||
| </div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(processCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(processCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="cpu-detail-item cpu-detail-item-top"> | |||
| <div class="detail-item-title">{{$t('profiling.operatorCpuUtil')}}</div> | |||
| <div class="detail-item-graph" | |||
| id="operator-graph"></div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="operatorCpuChart" | |||
| ref="operatorCpuChart"> | |||
| </div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-title"> | |||
| {{$t('profiling.allOperators')}} | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgTotalUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgTotalSystem)}}</span> | |||
| </div> | |||
| <div class="info-title"> | |||
| {{$t('profiling.currentOperator')}} | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgOpUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgOpSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.workersNum')}}{{$t('symbols.colon')}}</span> | |||
| <span>{{operatorCpuChart.processNumber}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="image-noData" v-else> | |||
| <div> | |||
| <img :src="require('@/assets/images/nodata.png')" | |||
| alt="" /> | |||
| </div> | |||
| <p>{{cpuInfo.initOver?$t("public.noData"):$t("public.dataLoading")}}</p> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import echarts from 'echarts'; | |||
| import {select, selectAll} from 'd3'; | |||
| const d3 = {select, selectAll}; | |||
| import RequestService from '../../services/request-service'; | |||
| import initDot from '../../mixins/init-dot'; | |||
| import {select, selectAll, zoom} from 'd3'; | |||
| import 'd3-graphviz'; | |||
| import RequestService from '@/services/request-service'; | |||
| import initDot from '../mixins/init-dot'; | |||
| const d3 = {select, selectAll, zoom}; | |||
| export default { | |||
| props: {}, | |||
| data() { | |||
| return { | |||
| dir: '', // Profiler path | |||
| currentCard: '', // Current card number | |||
| trainId: '', | |||
| chartGrid: { | |||
| grid: { | |||
| left: 40, | |||
| @@ -165,14 +290,93 @@ export default { | |||
| prevGraph: undefined, // The previous clicked graph | |||
| operatorCPUList: [], // The list of operator cpu info | |||
| selIndex: null, // The index of selected graph node, to get right operator cpu info | |||
| resizeDebounce: null, // The function of resize callback | |||
| }; | |||
| }, | |||
| watch: { | |||
| '$parent.curDashboardInfo.curCardNum': { | |||
| handler(newValue) { | |||
| if (newValue || newValue === 0) { | |||
| this.dir = this.$route.query.dir; | |||
| this.trainId = this.$route.query.id; | |||
| this.currentCard = newValue; | |||
| if (this.trainId) { | |||
| document.title = `${decodeURIComponent(this.trainId)}` | |||
| + `-${this.$t('profiling.cpuUtilization')}-MindInsight`; | |||
| } else { | |||
| document.title = `${this.$t('profiling.cpuUtilization')}-MindInsight`; | |||
| } | |||
| this.cpuInfo.startStep.showStep = ''; | |||
| this.cpuInfo.startStep.step = ''; | |||
| this.cpuInfo.endStep.showStep = ''; | |||
| this.cpuInfo.endStep.step = ''; | |||
| this.queryCpuInfo(false, true); | |||
| } | |||
| }, | |||
| deep: true, | |||
| immediate: true, | |||
| }, | |||
| }, | |||
| computed: {}, | |||
| created() { | |||
| Object.assign(this.deviceCpuChart.option, this.chartGrid, this.chartDataZoom); | |||
| Object.assign(this.processCpuChart.option, this.chartGrid, this.chartDataZoom); | |||
| Object.assign(this.operatorCpuChart.option, this.chartGrid, this.chartDataZoom); | |||
| }, | |||
| mounted() { | |||
| this.resizeDebounce = this.debounce(this.resizeCallback, 200); | |||
| window.addEventListener('resize', this.resizeDebounce, false); | |||
| setTimeout(() => { | |||
| this.$bus.$on('collapse', this.debounce(this.resizeCallback, 200)); | |||
| }, 500); | |||
| }, | |||
| methods: { | |||
| /** | |||
| * The logic of add percent sign | |||
| * @param {number | string} number | |||
| * @return {string} | |||
| */ | |||
| addPercentSign(number) { | |||
| if (number === 0 || number === '0') { | |||
| return '0'; | |||
| } else { | |||
| return `${number}%`; | |||
| } | |||
| }, | |||
| /** | |||
| * Anti-shake | |||
| * @param { Function } fn callback function | |||
| * @param { Number } delay delay time | |||
| * @return { Function } | |||
| */ | |||
| debounce(fn, delay) { | |||
| let timer = null; | |||
| return function() { | |||
| if (timer) { | |||
| clearTimeout(timer); | |||
| } | |||
| timer = setTimeout(fn, delay); | |||
| }; | |||
| }, | |||
| init() { | |||
| this.queryCpuInfo(); | |||
| }, | |||
| /** | |||
| * Resize callback function | |||
| */ | |||
| resizeCallback() { | |||
| const chartArr = [ | |||
| 'deviceCpuChart', | |||
| 'processCpuChart', | |||
| 'operatorCpuChart', | |||
| ]; | |||
| chartArr.forEach((val) => { | |||
| if (this[val].chartDom) { | |||
| this[val].chartDom.resize(); | |||
| } | |||
| }); | |||
| }, | |||
| /** | |||
| * The logic of query and render graph info of cpu | |||
| * @return {Promise} | |||
| @@ -345,9 +549,9 @@ export default { | |||
| }, | |||
| /** | |||
| * Query average rate info | |||
| * @param {Boolean} isFilter wherter filter step | |||
| * @param {Boolean} isInitGraph wherter init graph | |||
| * Query cpu info | |||
| * @param {Boolean} isFilter whether filter step | |||
| * @param {Boolean} isInitGraph whether init graph | |||
| */ | |||
| queryCpuInfo(isFilter, isInitGraph) { | |||
| this.cpuInfo.deviceId = this.currentCard; | |||
| @@ -373,8 +577,8 @@ export default { | |||
| this.cpuInfo.noData = !res.data.step_total_num; | |||
| this.cpuInfo.step = res.data.step_total_num; | |||
| this.cpuInfo.stepArray = res.data.step_info; | |||
| this.cpuInfo.stepTip = this.$t('profiling.cpuStepTip', {max: `${this.cpuInfo.step}`}); | |||
| this.cpuInfo.cpuStepInputTip = this.$t('profiling.cpuStepInputTip', {max: `${this.cpuInfo.step}`}); | |||
| this.cpuInfo.stepTip = this.$t('profiling.cpuStepTip', {max: this.cpuInfo.step}); | |||
| this.cpuInfo.cpuStepInputTip = this.$t('profiling.cpuStepInputTip', {max: this.cpuInfo.step}); | |||
| this.samplingInterval = res.data.sampling_interval; | |||
| this.deviceCpuChart.logicCores = res.data.cpu_processor_num; | |||
| const deviceInfo = res.data.device_info; | |||
| @@ -396,6 +600,7 @@ export default { | |||
| } | |||
| } else { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.noData = true; | |||
| } | |||
| } else { | |||
| this.clearCpuChart(); | |||
| @@ -404,8 +609,8 @@ export default { | |||
| }, | |||
| () => { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.initOver = true; | |||
| this.cpuInfo.noData = true; | |||
| this.cpuInfo.initOver = true; | |||
| }, | |||
| ); | |||
| }, | |||
| @@ -427,9 +632,10 @@ export default { | |||
| * filter step to view cpu info | |||
| */ | |||
| viewStepFilter() { | |||
| const stepValidation = new RegExp('^[0-9]*[1-9][0-9]*$'); | |||
| if ( | |||
| /^[0-9]*[1-9][0-9]*$/.test(this.cpuInfo.startStep.showStep) && | |||
| /^[0-9]*[1-9][0-9]*$/.test(this.cpuInfo.endStep.showStep) && | |||
| stepValidation.test(this.cpuInfo.startStep.showStep) && | |||
| stepValidation.test(this.cpuInfo.endStep.showStep) && | |||
| this.cpuInfo.startStep.showStep <= this.cpuInfo.endStep.showStep && | |||
| this.cpuInfo.endStep.showStep <= this.cpuInfo.step | |||
| ) { | |||
| @@ -437,14 +643,14 @@ export default { | |||
| this.cpuInfo.endStep.step = this.cpuInfo.endStep.showStep; | |||
| this.queryCpuInfo(true, false); | |||
| } else if (this.cpuInfo.endStep.showStep === '' && | |||
| /^[0-9]*[1-9][0-9]*$/.test(this.cpuInfo.startStep.showStep) && | |||
| stepValidation.test(this.cpuInfo.startStep.showStep) && | |||
| this.cpuInfo.startStep.showStep <= this.cpuInfo.step) { | |||
| this.cpuInfo.startStep.step = this.cpuInfo.startStep.showStep; | |||
| this.cpuInfo.endStep.step = this.cpuInfo.step; | |||
| this.cpuInfo.endStep.showStep = this.cpuInfo.step; | |||
| this.queryCpuInfo(true, false); | |||
| } else if (this.cpuInfo.startStep.showStep === '' && | |||
| /^[0-9]*[1-9][0-9]*$/.test(this.cpuInfo.endStep.showStep) && | |||
| stepValidation.test(this.cpuInfo.endStep.showStep) && | |||
| this.cpuInfo.endStep.showStep <= this.cpuInfo.step) { | |||
| this.cpuInfo.startStep.step = 1; | |||
| this.cpuInfo.startStep.showStep = 1; | |||
| @@ -475,7 +681,7 @@ export default { | |||
| * @param {Array} stepArray | |||
| * @return {String} | |||
| */ | |||
| formateCpuChartTip(params, stepArray) { | |||
| formatCpuChartTip(params, stepArray) { | |||
| const data = params; | |||
| let str = ''; | |||
| if (data && data.length) { | |||
| @@ -530,11 +736,13 @@ export default { | |||
| ); | |||
| this.deviceCpuChart.option.legend.data = legend; | |||
| this.deviceCpuChart.option.tooltip.formatter = (params) => { | |||
| return this.formateCpuChartTip(params, this.cpuInfo.stepArray); | |||
| return this.formatCpuChartTip(params, this.cpuInfo.stepArray); | |||
| }; | |||
| this.$nextTick(() => { | |||
| if (this.$refs.deviceCpuChart) { | |||
| this.deviceCpuChart.chartDom = echarts.init(this.$refs.deviceCpuChart); | |||
| if (!this.deviceCpuChart.chartDom) { | |||
| if (this.$refs.deviceCpuChart) { | |||
| this.deviceCpuChart.chartDom = echarts.init(this.$refs.deviceCpuChart); | |||
| } | |||
| } | |||
| this.deviceCpuChart.chartDom.setOption(this.deviceCpuChart.option); | |||
| }); | |||
| @@ -569,11 +777,13 @@ export default { | |||
| ); | |||
| this.processCpuChart.option.legend.data = legend; | |||
| this.processCpuChart.option.tooltip.formatter = (params) => { | |||
| return this.formateCpuChartTip(params, this.cpuInfo.stepArray); | |||
| return this.formatCpuChartTip(params, this.cpuInfo.stepArray); | |||
| }; | |||
| this.$nextTick(() => { | |||
| if (this.$refs.processCpuChart) { | |||
| this.processCpuChart.chartDom = echarts.init(this.$refs.processCpuChart); | |||
| if (!this.processCpuChart.chartDom) { | |||
| if (this.$refs.processCpuChart) { | |||
| this.processCpuChart.chartDom = echarts.init(this.$refs.processCpuChart); | |||
| } | |||
| } | |||
| this.processCpuChart.chartDom.setOption(this.processCpuChart.option); | |||
| }); | |||
| @@ -635,11 +845,11 @@ export default { | |||
| ); | |||
| this.operatorCpuChart.option.legend.data = legend; | |||
| this.operatorCpuChart.option.tooltip.formatter = (params) => { | |||
| return this.formateCpuChartTip(params, this.cpuInfo.stepArray); | |||
| return this.formatCpuChartTip(params, this.cpuInfo.stepArray); | |||
| }; | |||
| this.$nextTick(() => { | |||
| if (this.$refs.operatorCpuChart) { | |||
| if (!this.operatorCpuChart.chartDom) { | |||
| if (!this.operatorCpuChart.chartDom) { | |||
| if (this.$refs.operatorCpuChart) { | |||
| this.operatorCpuChart.chartDom = echarts.init(this.$refs.operatorCpuChart); | |||
| } | |||
| } | |||
| @@ -649,5 +859,120 @@ export default { | |||
| } | |||
| }, | |||
| }, | |||
| destroyed() { | |||
| // Remove the listener of window size change | |||
| window.removeEventListener('resize', this.resizeDebounce); | |||
| this.$bus.$off('collapse'); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style> | |||
| .data-process-wrap { | |||
| height: 100%; | |||
| background: #fff; | |||
| padding: 0 16px; | |||
| } | |||
| .data-process-wrap .title { | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| text-align: left; | |||
| } | |||
| .data-process-wrap .image-noData { | |||
| width: 100%; | |||
| height: calc(100% - 37px); | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| flex-direction: column; | |||
| } | |||
| .data-process-wrap .image-noData p { | |||
| font-size: 16px; | |||
| padding-top: 10px; | |||
| } | |||
| .data-process-wrap .el-button { | |||
| border: 1px solid #00a5a7; | |||
| border-radius: 2px; | |||
| background-color: white; | |||
| color: #00a5a7; | |||
| padding: 7px 15px; | |||
| } | |||
| .data-process-wrap .el-button:hover { | |||
| background: rgb(230, 246, 246); | |||
| } | |||
| .cpu-info { | |||
| height: calc(100% - 24px); | |||
| display: flex; | |||
| flex-direction: column; | |||
| } | |||
| .cpu-info .step-filter { | |||
| min-height: 44px; | |||
| } | |||
| .cpu-info .step-filter .step-input { | |||
| width: 100px; | |||
| margin-right: 20px; | |||
| } | |||
| .cpu-info .step-filter:first-child label { | |||
| margin-right: 10px; | |||
| } | |||
| .cpu-info .cpu-detail { | |||
| height: calc(100% - 44px); | |||
| flex-grow: 1; | |||
| overflow-x: hidden; | |||
| overflow-y: scroll; | |||
| } | |||
| .cpu-info .cpu-detail .cpu-detail-item { | |||
| padding: 16px; | |||
| border: 1px solid #d9d9d9; | |||
| border-radius: 4px; | |||
| margin-right: 8px; | |||
| } | |||
| .cpu-info .cpu-detail .cpu-detail-item-top { | |||
| margin-top: 16px; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item-title { | |||
| height: 20px; | |||
| font-size: 15px; | |||
| font-weight: bold; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item-graph { | |||
| height: 120px; | |||
| background-color: #f7faff; | |||
| margin: 10px 0; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item { | |||
| height: 400px; | |||
| display: flex; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item:last-of-type { | |||
| padding-bottom: 0; | |||
| border-bottom: none; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart { | |||
| height: 100%; | |||
| flex-grow: 1; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info { | |||
| height: 100%; | |||
| width: 300px; | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: center; | |||
| padding-left: 20px; | |||
| background-color: #f1f1f1; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info .info-title { | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| line-height: 30px; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info .info-line { | |||
| line-height: 30px; | |||
| } | |||
| .cpu-chart-tip { | |||
| display: inline-block; | |||
| margin-right: 5px; | |||
| border-radius: 10px; | |||
| width: 10px; | |||
| height: 10px; | |||
| } | |||
| </style> | |||
| @@ -113,7 +113,8 @@ limitations under the License. | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="data-process-bottom" v-show="!processSummary.noData"> | |||
| <div class="data-process-bottom" | |||
| v-show="!processSummary.noData"> | |||
| <div class="queue-step-wrap" | |||
| v-if="processSummary.count === processSummary.maxCount"> | |||
| <div class="title">{{$t('profiling.queueStep')}}</div> | |||
| @@ -302,141 +303,17 @@ limitations under the License. | |||
| <p>{{initOver?$t("public.noData"):$t("public.dataLoading")}}</p> | |||
| </div> | |||
| </el-tab-pane> | |||
| <!-- CPU --> | |||
| <el-tab-pane :label="$t('profiling.cpuUtilization')" | |||
| name="cpuInfo"> | |||
| <div class="cpu-info" | |||
| v-if="!cpuInfo.noData"> | |||
| <div class="step-filter"> | |||
| <label>{{cpuInfo.stepTip}}</label> | |||
| <label>{{$t('profiling.startStep')}}</label> | |||
| <el-input class="step-input" | |||
| v-model.number="cpuInfo.startStep.showStep"></el-input> | |||
| <label>{{$t('profiling.endStep')}}</label> | |||
| <el-input class="step-input" | |||
| v-model.number="cpuInfo.endStep.showStep"></el-input> | |||
| <el-button @click="viewStepFilter">{{$t('profiling.filterStep')}}</el-button> | |||
| <el-button @click="resetStepFilter">{{$t('profiling.resetStep')}}</el-button> | |||
| </div> | |||
| <div class="cpu-detail"> | |||
| <div class="cpu-detail-item"> | |||
| <div class="detail-item-title">{{$t('profiling.structuralCpuUtil')}}</div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="deviceCpuChart" | |||
| ref="deviceCpuChart"></div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.logicCores')}}</span><span>{{deviceCpuChart.logicCores}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIOUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgIO)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIdleUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgFree)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgWaitingProcess')}}</span><span>{{deviceCpuChart.cpuAvgProcess}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSwitchCount')}}</span><span>{{deviceCpuChart.cpuAvgSwitch}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="cpu-detail-item cpu-detail-item-top"> | |||
| <div class="detail-item-title">{{$t('profiling.processCpuUtil')}}</div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="processCpuChart" | |||
| ref="processCpuChart"> | |||
| </div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(processCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(processCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="cpu-detail-item cpu-detail-item-top"> | |||
| <div class="detail-item-title">{{$t('profiling.operatorCpuUtil')}}</div> | |||
| <div class="detail-item-graph" | |||
| id="operator-graph"></div> | |||
| <div class="detail-item"> | |||
| <div class="cpu-chart" | |||
| id="operatorCpuChart" | |||
| ref="operatorCpuChart"> | |||
| </div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-title"> | |||
| {{$t('profiling.allOperators')}} | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgTotalUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgTotalSystem)}}</span> | |||
| </div> | |||
| <div class="info-title"> | |||
| {{$t('profiling.currentOperator')}} | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgOpUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(operatorCpuChart.cpuAvgOpSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.workersNum')}}{{$t('symbols.colon')}}</span> | |||
| <span>{{operatorCpuChart.processNumber}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="image-noData" | |||
| v-else> | |||
| <div> | |||
| <img :src="require('@/assets/images/nodata.png')" | |||
| alt="" /> | |||
| </div> | |||
| <p>{{cpuInfo.initOver?$t("public.noData"):$t("public.dataLoading")}}</p> | |||
| </div> | |||
| </el-tab-pane> | |||
| </el-tabs> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import echarts from 'echarts'; | |||
| import RequestService from '../../services/request-service'; | |||
| import cpuUtilizaton from '../../mixins/cpu-utilization.vue'; | |||
| import {select, selectAll, zoom} from 'd3'; | |||
| import {event as currentEvent} from 'd3-selection'; | |||
| import 'd3-graphviz'; | |||
| const d3 = {select, selectAll, zoom}; | |||
| export default { | |||
| mixins: [cpuUtilizaton], | |||
| props: {}, | |||
| data() { | |||
| return { | |||
| @@ -533,15 +410,13 @@ export default { | |||
| }, | |||
| watch: { | |||
| '$parent.curDashboardInfo.curCardNum': { | |||
| handler(newValue, oldValue) { | |||
| handler(newValue) { | |||
| if (newValue || newValue === 0) { | |||
| this.dir = this.$route.query.dir; | |||
| this.trainId = this.$route.query.id; | |||
| this.currentCard = newValue; | |||
| if (this.trainId) { | |||
| document.title = | |||
| `${decodeURIComponent(this.trainId)}` + | |||
| `-${this.$t('profiling.mindData')}-MindInsight`; | |||
| document.title = `${decodeURIComponent(this.trainId)}` + `-${this.$t('profiling.mindData')}-MindInsight`; | |||
| } else { | |||
| document.title = `${this.$t('profiling.mindData')}-MindInsight`; | |||
| } | |||
| @@ -549,12 +424,6 @@ export default { | |||
| this.init(); | |||
| } else if (this.activeName === 'pipeLine') { | |||
| this.queryAverageRate(); | |||
| } else { | |||
| this.cpuInfo.startStep.showStep = ''; | |||
| this.cpuInfo.startStep.step = ''; | |||
| this.cpuInfo.endStep.showStep = ''; | |||
| this.cpuInfo.endStep.step = ''; | |||
| this.queryCpuInfo(false, true); | |||
| } | |||
| } | |||
| if (this.activeName === 'queueInfo' && this.$parent.curDashboardInfo.initOver) { | |||
| @@ -567,11 +436,7 @@ export default { | |||
| }, | |||
| computed: {}, | |||
| mounted() { | |||
| window.addEventListener( | |||
| 'resize', | |||
| this.debounce(this.resizeCallback, 200), | |||
| false, | |||
| ); | |||
| window.addEventListener('resize', this.debounce(this.resizeCallback, 200), false); | |||
| setTimeout(() => { | |||
| this.$bus.$on('collapse', this.debounce(this.resizeCallback, 200)); | |||
| }, 500); | |||
| @@ -612,15 +477,6 @@ export default { | |||
| this.queryAverageRate(); | |||
| } else if (this.activeName === 'queueInfo' && this.connectQueueChart.deviceId !== this.currentCard) { | |||
| this.init(); | |||
| } else if ( | |||
| this.activeName === 'cpuInfo' && | |||
| this.cpuInfo.deviceId !== this.currentCard | |||
| ) { | |||
| this.cpuInfo.startStep.showStep = ''; | |||
| this.cpuInfo.startStep.step = ''; | |||
| this.cpuInfo.endStep.showStep = ''; | |||
| this.cpuInfo.endStep.step = ''; | |||
| this.queryCpuInfo(false, true); | |||
| } | |||
| this.$nextTick(() => { | |||
| this.resizeCallback(); | |||
| @@ -641,9 +497,6 @@ export default { | |||
| 'getNextChart', | |||
| 'averageRateChart', | |||
| 'queueDeepChart', | |||
| 'deviceCpuChart', | |||
| 'processCpuChart', | |||
| 'operatorCpuChart', | |||
| ]; | |||
| chartArr.forEach((val) => { | |||
| if (this[val].chartDom) { | |||
| @@ -919,11 +772,7 @@ export default { | |||
| this.dealPipeLineData(data); | |||
| this.pipeData = !!!(res.data.object && res.data.object.length); | |||
| if ( | |||
| res.data.object && | |||
| res.data.object.length && | |||
| res.data.col_name | |||
| ) { | |||
| if (res.data.object && res.data.object.length && res.data.col_name) { | |||
| const result = res.data.object.map((val) => { | |||
| const obj = {}; | |||
| res.data.col_name.forEach((value, key) => { | |||
| @@ -1469,12 +1318,12 @@ export default { | |||
| padding: 0 16px; | |||
| } | |||
| .data-process-wrap .title { | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| text-align: left; | |||
| } | |||
| .data-process-wrap .el-tabs.el-tabs--top { | |||
| height: calc(100% - 22px); | |||
| height: calc(100% - 24px); | |||
| } | |||
| .data-process-wrap .el-tabs__content { | |||
| height: calc(100% - 54px); | |||
| @@ -1590,15 +1439,15 @@ export default { | |||
| .data-process-wrap .data-process-bottom .queue-step-wrap > .title { | |||
| margin-bottom: 15px; | |||
| font-weight: bold; | |||
| font-size: 15px; | |||
| font-size: 16px; | |||
| } | |||
| .data-process-wrap .data-process-bottom .queue-step-wrap .chart-content { | |||
| height: calc(100% - 30px); | |||
| height: calc(100% - 31px); | |||
| } | |||
| .data-process-wrap .data-process-bottom .queue-step-wrap .chart-content .chart-wrap { | |||
| float: left; | |||
| width: calc(50% - 12px); | |||
| height: calc(100% - 5px); | |||
| height: calc(100% - 10px); | |||
| border-radius: 4px; | |||
| overflow-y: auto; | |||
| border: 1px solid #D9D9D9; | |||
| @@ -1628,7 +1477,7 @@ export default { | |||
| border-color: #3399ff; | |||
| } | |||
| .data-process-wrap .data-process-bottom .queue-step-wrap .chart-content.second { | |||
| height: calc(100% - 25px); | |||
| height: calc(100% - 26px); | |||
| } | |||
| .data-process-wrap .data-process-bottom .queue-step-wrap.single { | |||
| height: 100%; | |||
| @@ -1643,12 +1492,12 @@ export default { | |||
| height: 35%; | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-top .pipeline-top-title { | |||
| font-size: 15px; | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-top .average-rate-wrap { | |||
| overflow-y: auto; | |||
| height: calc(100% - 20px); | |||
| height: calc(100% - 21px); | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-top .average-rate-wrap #average-rate { | |||
| height: 100%; | |||
| @@ -1659,11 +1508,11 @@ export default { | |||
| height: 30%; | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-middle .pipeline-middle-title { | |||
| font-size: 15px; | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-middle .operator-graph { | |||
| height: calc(100% - 20px); | |||
| height: calc(100% - 21px); | |||
| } | |||
| .data-process-wrap .pipeline-wrap .pipeline-middle .operator-graph #graph { | |||
| width: 100%; | |||
| @@ -1756,79 +1605,4 @@ export default { | |||
| .data-process-wrap .el-button:hover { | |||
| background: rgb(230, 246, 246); | |||
| } | |||
| .cpu-info { | |||
| height: 100%; | |||
| display: flex; | |||
| flex-direction: column; | |||
| } | |||
| .cpu-info .step-filter { | |||
| min-height: 44px; | |||
| } | |||
| .cpu-info .step-filter .step-input { | |||
| width: 100px; | |||
| margin-right: 20px; | |||
| } | |||
| .cpu-info .step-filter:first-child label { | |||
| margin-right: 10px; | |||
| } | |||
| .cpu-info .cpu-detail { | |||
| flex-grow: 1; | |||
| overflow-x: hidden; | |||
| overflow-y: scroll; | |||
| } | |||
| .cpu-info .cpu-detail .cpu-detail-item { | |||
| padding: 16px; | |||
| border: 1px solid #d9d9d9; | |||
| border-radius: 4px; | |||
| margin-right: 8px; | |||
| } | |||
| .cpu-info .cpu-detail .cpu-detail-item-top { | |||
| margin-top: 16px; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item-title { | |||
| height: 20px; | |||
| font-size: 15px; | |||
| font-weight: bold; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item-graph { | |||
| height: 120px; | |||
| background-color: #f7faff; | |||
| margin: 10px 0; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item { | |||
| height: 400px; | |||
| display: flex; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item:last-of-type { | |||
| padding-bottom: 0; | |||
| border-bottom: none; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart { | |||
| height: 100%; | |||
| flex-grow: 1; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info { | |||
| height: 100%; | |||
| width: 300px; | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: center; | |||
| padding-left: 20px; | |||
| background-color: #f1f1f1; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info .info-title { | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| line-height: 30px; | |||
| } | |||
| .cpu-info .cpu-detail .detail-item .cpu-chart-info .info-line { | |||
| line-height: 30px; | |||
| } | |||
| .cpu-chart-tip { | |||
| display: inline-block; | |||
| margin-right: 5px; | |||
| border-radius: 10px; | |||
| width: 10px; | |||
| height: 10px; | |||
| } | |||
| </style> | |||
| @@ -220,13 +220,14 @@ export default { | |||
| curSelectedPointIndex: 0, // Subscript of the current selection point | |||
| curGraphId: '', // ID of the current graphics | |||
| breakdownsInitOver: false, // BreakDown data request complete | |||
| firstInit: true, // First init of page | |||
| }; | |||
| }, | |||
| watch: { | |||
| // Listening card number | |||
| '$parent.curDashboardInfo.curCardNum': { | |||
| handler(newValue, oldValue) { | |||
| if (isNaN(newValue) || newValue === this.curCardNum) { | |||
| handler(newValue) { | |||
| if (isNaN(newValue) || newValue === this.curCardNum || this.firstInit) { | |||
| return; | |||
| } | |||
| this.curCardNum = newValue; | |||
| @@ -290,6 +291,10 @@ export default { | |||
| */ | |||
| getMemorySummary() { | |||
| if (!this.summaryPath || isNaN(this.curCardNum)) { | |||
| this.overViewInitOver = true; | |||
| this.noGraphicsDataFlag = true; | |||
| this.graphicsInitOver = true; | |||
| this.breakdownsInitOver = true; | |||
| return; | |||
| } | |||
| const params = { | |||
| @@ -347,13 +352,14 @@ export default { | |||
| this.breakdownsInitOver = true; | |||
| return; | |||
| } | |||
| this.noGraphicsDataFlag = false; | |||
| const resData = res.data[Object.keys(res.data)[0]]; | |||
| this.curGraphId = resData.graph_id; | |||
| this.currentGraphicsDic = resData; | |||
| this.graphicsOption = this.formateGraphicsOption(); | |||
| this.graphicsOption = this.formatGraphicsOption(); | |||
| this.drawGraphics(); | |||
| this.$nextTick(() => { | |||
| this.formateBreakdowns(); | |||
| this.formatBreakdowns(); | |||
| }); | |||
| }, | |||
| () => { | |||
| @@ -366,7 +372,7 @@ export default { | |||
| /** | |||
| * Sort out the memory allocation data in a table | |||
| */ | |||
| formateBreakdowns() { | |||
| formatBreakdowns() { | |||
| this.breakdownsInitOver = false; | |||
| this.currentBreakdownsData = []; | |||
| if (!this.currentGraphicsDic.nodes) { | |||
| @@ -420,7 +426,7 @@ export default { | |||
| * Sorting chart data | |||
| * @return {Object} Chart data | |||
| */ | |||
| formateGraphicsOption() { | |||
| formatGraphicsOption() { | |||
| if (!this.currentGraphicsDic) { | |||
| return {}; | |||
| } | |||
| @@ -618,7 +624,7 @@ export default { | |||
| if (!this.graphicsChart) { | |||
| this.graphicsChart = echarts.init(this.$refs.memoryChart, null); | |||
| } | |||
| this.graphicsChart.setOption(this.graphicsOption, false); | |||
| this.graphicsChart.setOption(this.graphicsOption); | |||
| if (!this.chartClickListenerOn) { | |||
| this.chartClickListenerOn = true; | |||
| this.graphicsChart.on( | |||
| @@ -654,7 +660,7 @@ export default { | |||
| seriesData.markPoint.data[0].coord = seriesData.data[dataIndex]; | |||
| this.drawGraphics(); | |||
| this.curSelectedPointIndex = dataIndex; | |||
| this.formateBreakdowns(); | |||
| this.formatBreakdowns(); | |||
| } | |||
| }, | |||
| /** | |||
| @@ -720,6 +726,7 @@ export default { | |||
| )}-MindInsight`; | |||
| } | |||
| window.addEventListener('resize', this.resizeCallback, false); | |||
| this.$bus.$on('collapse', this.resizeCallback); | |||
| if ( | |||
| this.$route.query && | |||
| this.$route.query.path && | |||
| @@ -729,7 +736,7 @@ export default { | |||
| this.curCardNum = this.$route.query.cardNum; | |||
| this.init(); | |||
| } | |||
| this.$bus.$on('collapse', this.resizeCallback); | |||
| this.firstInit = false; | |||
| }, | |||
| }; | |||
| </script> | |||
| @@ -757,12 +764,12 @@ export default { | |||
| } | |||
| .cl-memory-detail .title-content .title-text { | |||
| font-size: 20px; | |||
| font-size: 18px; | |||
| } | |||
| .cl-memory-detail .top-content .content-item { | |||
| display: flex; | |||
| height: calc(100% - 24px); | |||
| height: calc(100% - 21px); | |||
| width: 100%; | |||
| } | |||
| @@ -817,7 +824,7 @@ export default { | |||
| .cl-memory-detail .bottom-content .chart-container .chart-content, | |||
| .cl-memory-detail .bottom-content .table-container .table-content { | |||
| margin-top: 16px; | |||
| height: calc(100% - 30px); | |||
| height: calc(100% - 37px); | |||
| } | |||
| .cl-memory-detail .bottom-content .chart-container { | |||
| height: calc(60% - 20px); | |||
| @@ -827,7 +834,7 @@ export default { | |||
| height: 40%; | |||
| } | |||
| .cl-memory-detail .title-item { | |||
| font-size: 18px; | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| } | |||
| .cl-memory-detail .el-table td, | |||
| @@ -1521,11 +1521,11 @@ export default { | |||
| } | |||
| .operator .operator-title { | |||
| padding: 0 15px; | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| } | |||
| .operator .cl-profiler { | |||
| height: calc(100% - 21px); | |||
| height: calc(100% - 24px); | |||
| overflow-y: auto; | |||
| width: 100%; | |||
| background: #fff; | |||
| @@ -1,5 +1,5 @@ | |||
| <!-- | |||
| Copyright 2020 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Copyright 2020-2021 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| @@ -179,7 +179,6 @@ limitations under the License. | |||
| </div> | |||
| <div class="title">{{$t('profiling.connectorQuene')}}</div> | |||
| <div class="description"> | |||
| <div class="line"></div> | |||
| <div class="item" | |||
| v-if="processSummary.device.empty || processSummary.device.empty === 0"> | |||
| {{$t('profiling.queueTip2')}} | |||
| @@ -223,7 +222,6 @@ limitations under the License. | |||
| </div> | |||
| <div class="title">{{$t('profiling.dataQueue')}}</div> | |||
| <div class="description"> | |||
| <div class="line"></div> | |||
| <div class="item" | |||
| v-if="processSummary.get_next.empty || processSummary.get_next.empty === 0"> | |||
| {{$t('profiling.queueTip2')}} | |||
| @@ -1257,8 +1255,8 @@ export default { | |||
| height: 100%; | |||
| } | |||
| .pro-router-wrap > div > div { | |||
| border: 1px solid #eee; | |||
| border-radius: 4px; | |||
| border: 1px solid #d9d9d9; | |||
| border-radius: 1px; | |||
| } | |||
| .pro-router-wrap > div .title-wrap { | |||
| padding: 15px; | |||
| @@ -1266,7 +1264,7 @@ export default { | |||
| .pro-router-wrap > div .title-wrap .title { | |||
| float: left; | |||
| font-weight: bold; | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| } | |||
| .pro-router-wrap > div .title-wrap .tip-icon { | |||
| float: right; | |||
| @@ -1331,7 +1329,7 @@ export default { | |||
| padding-right: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .step-trace { | |||
| height: 45%; | |||
| height: calc(100% - 275px); | |||
| margin-bottom: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .step-trace .trace-container { | |||
| @@ -1355,11 +1353,11 @@ export default { | |||
| overflow: visible; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata { | |||
| height: calc(55% - 15px); | |||
| height: 260px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container { | |||
| width: 100%; | |||
| padding: 20px 20px; | |||
| padding: 0 20px; | |||
| height: calc(100% - 52px); | |||
| display: flex; | |||
| font-size: 0; | |||
| @@ -1434,14 +1432,9 @@ export default { | |||
| white-space: nowrap; | |||
| overflow: visible; | |||
| width: 100%; | |||
| min-width: 100px; | |||
| text-align: center; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container .queue-container .description .line { | |||
| width: 1px; | |||
| height: 40px; | |||
| margin: 20px 0; | |||
| border-left: 1px solid #979797; | |||
| display: inline-block; | |||
| margin-top: 30px; | |||
| } | |||
| .pro-router-wrap .pro-router-left .minddata .pipeline-container .queue-container .description .item { | |||
| font-size: 12px; | |||
| @@ -1457,7 +1450,7 @@ export default { | |||
| width: 400px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .op-time-consume { | |||
| height: calc(60% - 15px); | |||
| height: calc(100% - 275px); | |||
| margin-bottom: 15px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .op-time-consume .time-list { | |||
| @@ -1511,7 +1504,7 @@ export default { | |||
| height: 25px; | |||
| } | |||
| .pro-router-wrap .pro-router-right .time-line { | |||
| height: 40%; | |||
| height: 260px; | |||
| overflow: hidden; | |||
| } | |||
| .pro-router-wrap .pro-router-right .time-line .timeline-info { | |||
| @@ -15,15 +15,20 @@ limitations under the License. | |||
| --> | |||
| <template> | |||
| <div class="prof-wrap"> | |||
| <div class="prof-head"> | |||
| <span class="cl-title-left">{{$t('summaryManage.viewProfiler')}}</span> | |||
| <div class="path-message"> | |||
| <span>{{$t('symbols.leftbracket')}}</span> | |||
| <span>{{$t('trainingDashboard.summaryDirPath')}}</span> | |||
| <span>{{summaryPath}}</span> | |||
| <span>{{$t('symbols.rightbracket')}}</span> | |||
| </div> | |||
| </div> | |||
| <div class="prof-content"> | |||
| <div class="prof-content-left" | |||
| :class="{collapse:collapse}"> | |||
| <div class="helper" | |||
| v-show="!collapse"> | |||
| <div class="summary-path"> | |||
| {{$t('trainingDashboard.summaryDirPath')}} | |||
| <span>{{ summaryPath}}</span> | |||
| </div> | |||
| <div class="cur-card"> | |||
| <label>{{$t('profiling.curCard')}}</label> | |||
| <el-select v-model="curDashboardInfo.curCardNum" | |||
| @@ -42,13 +47,6 @@ limitations under the License. | |||
| </div> | |||
| <div class="suggested-title">{{$t("profiling.suggestions")}}</div> | |||
| <div id="helper-tips"></div> | |||
| <div class="memory-title-container"> | |||
| <div class="memory-title"> | |||
| {{$t("profiling.memory.memoryDetailLink")}}</div> | |||
| <div class="memory-link" | |||
| @click="jumpToMemoryDetail"> | |||
| {{$t('profiling.viewDetail')}}</div> | |||
| </div> | |||
| </div> | |||
| <div class="collapse-btn" | |||
| :class="{collapse:collapse}" | |||
| @@ -57,10 +55,26 @@ limitations under the License. | |||
| </div> | |||
| <div class="prof-content-right" | |||
| :class="{collapse:collapse}"> | |||
| <router-view></router-view> | |||
| <div class="tab-container" | |||
| v-show="$route.path === '/profiling/profiling-dashboard' | |||
| || $route.path === '/profiling/resource-utilization'"> | |||
| <el-tabs v-model="tabData.activeName" | |||
| @tab-click="paneChange"> | |||
| <el-tab-pane v-for="pane in tabData.tabPanes" | |||
| :key="pane.name" | |||
| :label="pane.label" | |||
| :name="pane.name"></el-tab-pane> | |||
| </el-tabs> | |||
| </div> | |||
| <div class="router-container" | |||
| :class="$route.path === '/profiling/profiling-dashboard' | |||
| || $route.path === '/profiling/resource-utilization'?'dashboard':'detail'"> | |||
| <router-view></router-view> | |||
| </div> | |||
| <div class="close" | |||
| @click="backToDdashboard" | |||
| v-if="$route.path !== '/profiling/profiling-dashboard'"> | |||
| v-if="$route.path !== '/profiling/profiling-dashboard' | |||
| && $route.path !== '/profiling/resource-utilization'"> | |||
| <img src="@/assets/images/close-page.png"> | |||
| </div> | |||
| </div> | |||
| @@ -92,10 +106,29 @@ export default { | |||
| query: {}, | |||
| initOver: false, | |||
| }, | |||
| tabData: { | |||
| activeName: '0', | |||
| tabPanes: [ | |||
| { | |||
| name: '0', | |||
| label: this.$t('profiling.trainingPerformance'), | |||
| }, | |||
| { | |||
| name: '1', | |||
| label: this.$t('profiling.resourceUtilization'), | |||
| }, | |||
| ], | |||
| }, | |||
| }; | |||
| }, | |||
| watch: {}, | |||
| mounted() { | |||
| if ( | |||
| this.$route.path === 'resource-utilization' || | |||
| this.$route.path === '/profiling/memory-detail' | |||
| ) { | |||
| this.tabData.activeName = this.tabData.tabPanes[1].name; | |||
| } | |||
| this.$nextTick(() => { | |||
| this.init(); | |||
| }); | |||
| @@ -109,12 +142,15 @@ export default { | |||
| this.curDashboardInfo.query.id = this.$route.query.id; | |||
| this.curDashboardInfo.query.dir = this.$route.query.dir; | |||
| this.curDashboardInfo.query.path = this.$route.query.path; | |||
| this.summaryPath = decodeURIComponent( this.$route.query.id); | |||
| this.tabData.activeName = | |||
| this.$route.query.activePane || this.tabData.tabPanes[0].name; | |||
| this.summaryPath = decodeURIComponent(this.$route.query.id); | |||
| this.getDeviceList(); | |||
| } else { | |||
| this.curDashboardInfo.query.trainingJobId = ''; | |||
| this.curDashboardInfo.query.dir = ''; | |||
| this.curDashboardInfo.query.path = ''; | |||
| this.tabData.activeName = this.tabData.tabPanes[0].name; | |||
| this.$message.error(this.$t('trainingDashboard.invalidId')); | |||
| } | |||
| }, | |||
| @@ -306,35 +342,54 @@ export default { | |||
| * Router back to profiling-dashboard | |||
| */ | |||
| backToDdashboard() { | |||
| let path = '/profiling/profiling-dashboard'; | |||
| if (this.tabData.activeName === this.tabData.tabPanes[1].name) { | |||
| path = '/profiling/resource-utilization'; | |||
| } | |||
| this.$router.push({ | |||
| path: '/profiling/profiling-dashboard', | |||
| path: path, | |||
| query: { | |||
| dir: this.curDashboardInfo.query.dir, | |||
| id: this.curDashboardInfo.query.id, | |||
| path: this.curDashboardInfo.query.path, | |||
| activePane: this.tabData.activeName, | |||
| cardNum: this.curDashboardInfo.curCardNum, | |||
| }, | |||
| }); | |||
| }, | |||
| /** | |||
| * Router to memory-detail | |||
| */ | |||
| jumpToMemoryDetail() { | |||
| if (this.$route.path !== '/profiling/memory-detail') { | |||
| this.$router.push({ | |||
| path: '/profiling/memory-detail', | |||
| query: { | |||
| dir: this.curDashboardInfo.query.dir, | |||
| id: this.curDashboardInfo.query.id, | |||
| cardNum: this.curDashboardInfo.curCardNum, | |||
| path: this.curDashboardInfo.query.path, | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| collapseLeft() { | |||
| this.collapse = !this.collapse; | |||
| this.$bus.$emit('collapse'); | |||
| }, | |||
| /** | |||
| * Tab button click | |||
| * @param {Object} tabItem Tab | |||
| */ | |||
| paneChange(tabItem) { | |||
| if (tabItem && tabItem.name) { | |||
| let path = ''; | |||
| switch (tabItem.name) { | |||
| case this.tabData.tabPanes[0].name: | |||
| path = '/profiling/profiling-dashboard'; | |||
| break; | |||
| case this.tabData.tabPanes[1].name: | |||
| path = '/profiling/resource-utilization'; | |||
| break; | |||
| } | |||
| if (path) { | |||
| this.$router.push({ | |||
| path: path, | |||
| query: { | |||
| dir: this.curDashboardInfo.query.dir, | |||
| id: this.curDashboardInfo.query.id, | |||
| path: this.curDashboardInfo.query.path, | |||
| activePane: this.tabData.activeName, | |||
| cardNum: this.curDashboardInfo.curCardNum, | |||
| }, | |||
| }); | |||
| } | |||
| } | |||
| }, | |||
| }, | |||
| destroyed() { | |||
| this.$bus.$off('collapse'); | |||
| @@ -346,9 +401,20 @@ export default { | |||
| height: 100%; | |||
| background: #fff; | |||
| } | |||
| .prof-wrap .prof-head { | |||
| height: 50px; | |||
| line-height: 50px; | |||
| display: inline-block; | |||
| } | |||
| .prof-wrap .prof-head .path-message { | |||
| display: inline-block; | |||
| line-height: 20px; | |||
| padding: 18px 0; | |||
| font-weight: bold; | |||
| } | |||
| .prof-wrap .prof-content { | |||
| height: 100%; | |||
| padding: 24px 24px 24px 0; | |||
| height: calc(100% - 50px); | |||
| padding: 0 24px 24px 0; | |||
| } | |||
| .prof-wrap .prof-content > div { | |||
| float: left; | |||
| @@ -371,25 +437,12 @@ export default { | |||
| background: #edf0f5; | |||
| word-wrap: break-word; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .summary-path { | |||
| line-height: 24px; | |||
| font-size: 14px; | |||
| overflow: hidden; | |||
| font-weight: bold; | |||
| padding-bottom: 10px; | |||
| word-break: break-all; | |||
| text-overflow: -o-ellipsis-lastline; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| display: -webkit-box; | |||
| -webkit-line-clamp: 4; | |||
| -webkit-box-orient: vertical; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .nowrap-style { | |||
| white-space: nowrap; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .cur-card { | |||
| margin-bottom: 32px; | |||
| padding-bottom: 20px; | |||
| border-bottom: 1px solid #d9d9d9; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .cur-card .card-select { | |||
| width: calc(100% - 120px); | |||
| @@ -398,9 +451,9 @@ export default { | |||
| margin-right: 14px; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .helper-title { | |||
| font-size: 20px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| margin-bottom: 32px; | |||
| margin: 24px 0; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .helper-title .el-icon-rank { | |||
| float: right; | |||
| @@ -423,24 +476,6 @@ export default { | |||
| margin-bottom: 20px; | |||
| font-size: 16px; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .memory-title-container { | |||
| margin-top: 20px; | |||
| padding-top: 20px; | |||
| border-top: 1px solid #d9d9d9; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .memory-title-container .memory-title { | |||
| float: left; | |||
| font-weight: bold; | |||
| font-size: 16px; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .memory-title-container .memory-link { | |||
| float: right; | |||
| line-height: 21px; | |||
| cursor: pointer; | |||
| color: #3399ff; | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .helper .link-title { | |||
| cursor: pointer; | |||
| @@ -482,10 +517,10 @@ export default { | |||
| line-height: 86px; | |||
| z-index: 1; | |||
| text-align: center; | |||
| background-image: url("../../assets/images/collapse-left.svg"); | |||
| background-image: url('../../assets/images/collapse-left.svg'); | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left .collapse-btn.collapse { | |||
| background-image: url("../../assets/images/collapse-right.svg"); | |||
| background-image: url('../../assets/images/collapse-right.svg'); | |||
| } | |||
| .prof-wrap .prof-content .prof-content-left.collapse { | |||
| width: 0; | |||
| @@ -496,6 +531,25 @@ export default { | |||
| transition: width 0.2s; | |||
| position: relative; | |||
| } | |||
| .prof-content-right .tab-container { | |||
| width: 100%; | |||
| padding-bottom: 5px; | |||
| } | |||
| .prof-content-right .tab-container .el-tabs__item { | |||
| font-size: 14px; | |||
| line-height: 14px; | |||
| height: 27px; | |||
| } | |||
| .prof-content-right .tab-container .el-tabs__item.is-active { | |||
| color: #00a5a7; | |||
| font-weight: bold; | |||
| } | |||
| .prof-content-right .router-container.detail { | |||
| height: 100%; | |||
| } | |||
| .prof-content-right .router-container.dashboard { | |||
| height: calc(100% - 46px); | |||
| } | |||
| .prof-wrap .prof-content .prof-content-right .close { | |||
| position: absolute; | |||
| right: 0; | |||
| @@ -0,0 +1,816 @@ | |||
| <!-- | |||
| Copyright 2021 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| 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. | |||
| --> | |||
| <template> | |||
| <div class="cl-resource-content"> | |||
| <div class="dashboard-item"> | |||
| <div class="title-item"> | |||
| <div class="title-text"> | |||
| {{$t('profiling.structuralCpuUtil')}} | |||
| </div> | |||
| <div class="detail-link" | |||
| :class="{disabled:!cpuInfo.initOver || cpuInfo.noData}"> | |||
| <button :disabled="!cpuInfo.initOver || cpuInfo.noData" | |||
| @click="jumpToCpuDetail"> | |||
| {{$t('profiling.viewDetail')}} | |||
| <i class="el-icon-d-arrow-right"></i> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <div class="content-item"> | |||
| <div class="cpu-info" v-if="!cpuInfo.noData"> | |||
| <div class="cpu-chart" | |||
| id="deviceCpuChart" | |||
| ref="deviceCpuChart"></div> | |||
| <div class="cpu-chart-info"> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.logicCores')}}</span><span>{{deviceCpuChart.logicCores}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgUserUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgUser)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSysUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgSystem)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIOUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgIO)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgIdleUtilization')}}</span> | |||
| <span>{{addPercentSign(deviceCpuChart.cpuAvgFree)}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgWaitingProcess')}}</span><span>{{deviceCpuChart.cpuAvgProcess}}</span> | |||
| </div> | |||
| <div class="info-line"> | |||
| <span>{{$t('profiling.avgSwitchCount')}}</span><span>{{deviceCpuChart.cpuAvgSwitch}}</span> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="noData-content" v-else> | |||
| <img :src="require('@/assets/images/nodata.png')" alt="" /> | |||
| <p>{{cpuInfo.initOver?$t("public.noData"):$t("public.dataLoading")}}</p> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="dashboard-item margin-item"> | |||
| <div class="title-item"> | |||
| <div class="title-text"> | |||
| {{$t('profiling.memory.usedMemory')}} | |||
| </div> | |||
| <div class="detail-link" | |||
| :class="{disabled:!graphicsInitOver || noGraphicsDataFlag}"> | |||
| <button :disabled="!graphicsInitOver || noGraphicsDataFlag" | |||
| @click="jumpToMemoryDetail"> | |||
| {{$t('profiling.viewDetail')}} | |||
| <i class="el-icon-d-arrow-right"></i> | |||
| </button> | |||
| </div> | |||
| </div> | |||
| <div class="content-item"> | |||
| <div class="noData-content" | |||
| v-show="!graphicsInitOver || noGraphicsDataFlag"> | |||
| <div> | |||
| <img :src="require('@/assets/images/nodata.png')" | |||
| alt="" /> | |||
| </div> | |||
| <div v-if="graphicsInitOver && noGraphicsDataFlag" | |||
| class="noData-text">{{$t("public.noData")}}</div> | |||
| <div v-else | |||
| class="noData-text">{{$t("public.dataLoading")}}</div> | |||
| </div> | |||
| <div class="dashboard-chart-content" | |||
| v-show="!noGraphicsDataFlag && graphicsInitOver" | |||
| ref="dashboardMemoryChart"></div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import RequestService from '../../services/request-service'; | |||
| import echarts from 'echarts'; | |||
| export default { | |||
| data() { | |||
| return { | |||
| // ------------------------common-------------------- | |||
| queryData: { | |||
| dir: '', | |||
| id: '', | |||
| path: '', | |||
| activePane: '', | |||
| }, | |||
| summaryPath: '', | |||
| curCardNum: '', | |||
| pageResizeTimer: null, // Timer for changing the window size | |||
| firstInit: true, // First init of page | |||
| // ------------------------memory-------------------- | |||
| graphicsInitOver: false, // Graphics loading completed | |||
| noGraphicsDataFlag: false, // No graphics data | |||
| totalMemory: '-', // Total memory | |||
| memoryGraphicsChart: null, // Memory chart object | |||
| // ------------------------cpu----------------------- | |||
| deviceCpuChart: { | |||
| id: 'deviceCpuChart', | |||
| chartDom: null, | |||
| option: { | |||
| tooltip: { | |||
| trigger: 'axis', | |||
| formatter: null, | |||
| confine: true, | |||
| }, | |||
| legend: { | |||
| right: 70, | |||
| top: 8, | |||
| data: [], | |||
| }, | |||
| xAxis: { | |||
| name: '', | |||
| data: [], | |||
| }, | |||
| yAxis: { | |||
| name: this.$t('profiling.utilizationTitle'), | |||
| type: 'value', | |||
| }, | |||
| dataZoom: [ | |||
| { | |||
| start: 0, | |||
| end: 100, | |||
| bottom: 0, | |||
| }, | |||
| { | |||
| start: 0, | |||
| end: 100, | |||
| type: 'inside', | |||
| bottom: 0, | |||
| }, | |||
| ], | |||
| grid: { | |||
| left: 40, | |||
| top: 40, | |||
| right: 70, | |||
| bottom: 60, | |||
| }, | |||
| series: [], | |||
| }, | |||
| logicCores: 0, | |||
| cpuAvgUser: 0, | |||
| cpuAvgSystem: 0, | |||
| cpuAvgIO: 0, | |||
| cpuAvgFree: 0, | |||
| cpuAvgProcess: 0, | |||
| cpuAvgSwitch: 0, | |||
| }, // The total data of device cpu info | |||
| cpuInfo: { | |||
| initOver: false, | |||
| noData: true, | |||
| stepArray: [], | |||
| cpuInfoStr: { | |||
| user_utilization: this.$t('profiling.userUtilization'), | |||
| sys_utilization: this.$t('profiling.sysUtilization'), | |||
| io_utilization: this.$t('profiling.ioUtilization'), | |||
| idle_utilization: this.$t('profiling.idleUtilization'), | |||
| }, | |||
| samplingInterval: 0, | |||
| }, | |||
| }; | |||
| }, | |||
| watch: { | |||
| // Listening card number | |||
| '$parent.curDashboardInfo.curCardNum': { | |||
| handler(newValue) { | |||
| if (isNaN(newValue) || newValue === this.curCardNum || this.firstInit) { | |||
| return; | |||
| } | |||
| this.curCardNum = newValue; | |||
| this.noGraphicsDataFlag = false; | |||
| this.graphicsInitOver = false; | |||
| this.init(); | |||
| }, | |||
| deep: true, | |||
| immediate: true, | |||
| }, | |||
| }, | |||
| mounted() { | |||
| window.addEventListener('resize', this.resizeCallback, false); | |||
| this.$bus.$on('collapse', this.resizeCallback); | |||
| this.queryData = { | |||
| dir: this.$route.query.dir, | |||
| id: this.$route.query.id, | |||
| path: this.$route.query.path, | |||
| activePane: this.$route.query.activePane, | |||
| }; | |||
| if ( | |||
| this.$route.query && | |||
| this.$route.query.path && | |||
| !isNaN(this.$route.query.cardNum) | |||
| ) { | |||
| this.summaryPath = this.$route.query.path; | |||
| this.curCardNum = this.$route.query.cardNum; | |||
| this.init(); | |||
| } | |||
| this.firstInit = false; | |||
| }, | |||
| methods: { | |||
| // ------------------common--------------------- | |||
| init() { | |||
| this.getMemorySummary(); | |||
| this.queryCpuInfo(); | |||
| }, | |||
| /** | |||
| * Window resize | |||
| */ | |||
| resizeCallback() { | |||
| if (this.pageResizeTimer) { | |||
| clearTimeout(this.pageResizeTimer); | |||
| this.pageResizeTimer = null; | |||
| } | |||
| this.pageResizeTimer = setTimeout(() => { | |||
| if (this.memoryGraphicsChart) { | |||
| this.memoryGraphicsChart.resize(); | |||
| } | |||
| if (this.deviceCpuChart.chartDom) { | |||
| this.deviceCpuChart.chartDom.resize(); | |||
| } | |||
| }, 300); | |||
| }, | |||
| // ----------------memory----------------------------------- | |||
| /** | |||
| * Router to memory-detail | |||
| */ | |||
| jumpToMemoryDetail() { | |||
| this.$router.push({ | |||
| path: '/profiling/memory-detail', | |||
| query: { | |||
| dir: this.queryData.dir, | |||
| id: this.queryData.id, | |||
| cardNum: this.curCardNum, | |||
| path: this.queryData.path, | |||
| activePane: this.queryData.activePane, | |||
| }, | |||
| }); | |||
| }, | |||
| /** | |||
| * Obtains base memory information | |||
| */ | |||
| getMemorySummary() { | |||
| if (!this.summaryPath || isNaN(this.curCardNum)) { | |||
| this.noGraphicsDataFlag = true; | |||
| this.graphicsInitOver = true; | |||
| return; | |||
| } | |||
| const params = { | |||
| dir: this.summaryPath, | |||
| device_id: this.curCardNum, | |||
| }; | |||
| RequestService.queryMemorySummary(params) | |||
| .then( | |||
| (res) => { | |||
| if (res && res.data && res.data.summary) { | |||
| const resData = res.data.summary; | |||
| this.totalMemory = isNaN(resData.capacity) | |||
| ? '-' | |||
| : resData.capacity; | |||
| } else { | |||
| this.totalMemory = '-'; | |||
| } | |||
| }, | |||
| () => { | |||
| this.overViewInitOver = true; | |||
| }, | |||
| ) | |||
| .then(() => { | |||
| this.getMemoryGraphics(); | |||
| }); | |||
| }, | |||
| /** | |||
| * Obtains memory details | |||
| */ | |||
| getMemoryGraphics() { | |||
| const params = { | |||
| dir: this.summaryPath, | |||
| device_id: this.curCardNum, | |||
| }; | |||
| RequestService.queryMemoryGraphics(params).then( | |||
| (res) => { | |||
| this.graphicsInitOver = true; | |||
| if (!res || !res.data || !Object.keys(res.data).length) { | |||
| this.noGraphicsDataFlag = true; | |||
| return; | |||
| } | |||
| this.noGraphicsDataFlag = false; | |||
| const resData = res.data[Object.keys(res.data)[0]]; | |||
| this.currentGraphicsDic = resData; | |||
| this.graphicsOption = this.formatGraphicsOption(); | |||
| this.drawGraphics(); | |||
| }, | |||
| () => { | |||
| this.graphicsInitOver = true; | |||
| this.noGraphicsDataFlag = true; | |||
| }, | |||
| ); | |||
| }, | |||
| /** | |||
| * Sorting chart data | |||
| * @return {Object} Chart data | |||
| */ | |||
| formatGraphicsOption() { | |||
| if (!this.currentGraphicsDic) { | |||
| return {}; | |||
| } | |||
| const that = this; | |||
| const allocationData = []; | |||
| const topData = []; | |||
| const staticData = []; | |||
| const lifeCycle = []; | |||
| let startIndex = -1; | |||
| let endIndex = -1; | |||
| this.currentGraphicsDic.nodes.forEach((node, index) => { | |||
| if (node.node_id === this.currentGraphicsDic.fp_start) { | |||
| startIndex = index; | |||
| } else if (node.node_id === this.currentGraphicsDic.bp_end) { | |||
| endIndex = index; | |||
| } | |||
| allocationData.push([ | |||
| node.node_id, | |||
| this.currentGraphicsDic.lines[index], | |||
| ]); | |||
| topData.push([node.node_id, this.totalMemory]); | |||
| staticData.push([node.node_id, this.currentGraphicsDic.static_mem]); | |||
| const curLifeCycle = []; | |||
| node.outputs.forEach((output) => { | |||
| curLifeCycle.push([output.life_start, output.life_end]); | |||
| }); | |||
| lifeCycle.push(curLifeCycle); | |||
| }); | |||
| const allocationLine = { | |||
| id: this.graphicsId, | |||
| name: this.$t('profiling.memory.curMemorySize'), | |||
| data: allocationData, | |||
| type: 'line', | |||
| showSymbol: false, | |||
| lineStyle: { | |||
| color: '#00a5a7', | |||
| }, | |||
| color: '#00a5a7', | |||
| markLine: { | |||
| lineStyle: { | |||
| color: '#00a5a7', | |||
| }, | |||
| label: { | |||
| formatter(param) { | |||
| let labelStr = ''; | |||
| if (param.dataIndex) { | |||
| labelStr = `${that.$t('profiling.memory.bpEnd')}${that.$t( | |||
| 'symbols.colon', | |||
| )}${endIndex}`; | |||
| } else { | |||
| labelStr = `${that.$t('profiling.memory.fpStart')}${that.$t( | |||
| 'symbols.colon', | |||
| )}${startIndex}`; | |||
| } | |||
| return labelStr; | |||
| }, | |||
| }, | |||
| symbol: ['none', 'none'], | |||
| data: [{xAxis: startIndex}, {xAxis: endIndex}], | |||
| }, | |||
| markPoint: { | |||
| symbol: 'emptyCircle', | |||
| symbolSize: 8, | |||
| itemStyle: { | |||
| color: '#f45c5e', | |||
| }, | |||
| data: [ | |||
| { | |||
| coord: allocationData[this.curSelectedPointIndex], | |||
| }, | |||
| ], | |||
| }, | |||
| }; | |||
| const topLine = { | |||
| data: topData, | |||
| name: this.$t('profiling.memory.totalMemory'), | |||
| type: 'line', | |||
| smooth: 0, | |||
| symbol: 'none', | |||
| lineStyle: { | |||
| color: '#fdca5a', | |||
| }, | |||
| color: '#fdca5a', | |||
| }; | |||
| const staticLine = { | |||
| data: staticData, | |||
| name: this.$t('profiling.memory.staticMenory'), | |||
| type: 'line', | |||
| smooth: 0, | |||
| symbol: 'none', | |||
| lineStyle: { | |||
| color: '#3d58a6', | |||
| }, | |||
| color: '#3d58a6', | |||
| }; | |||
| const seriesData = [allocationLine, staticLine]; | |||
| const selectedDic = {}; | |||
| selectedDic[this.$t('profiling.memory.curMemorySize')] = true; | |||
| selectedDic[this.$t('profiling.memory.staticMenory')] = true; | |||
| const legendData = [ | |||
| this.$t('profiling.memory.curMemorySize'), | |||
| this.$t('profiling.memory.staticMenory'), | |||
| ]; | |||
| if (!isNaN(this.totalMemory)) { | |||
| seriesData.push(topLine); | |||
| legendData.unshift(this.$t('profiling.memory.totalMemory')); | |||
| selectedDic[this.$t('profiling.memory.totalMemory')] = false; | |||
| } | |||
| const optionData = { | |||
| legend: { | |||
| show: true, | |||
| icon: 'circle', | |||
| data: legendData, | |||
| selected: selectedDic, | |||
| }, | |||
| grid: { | |||
| top: 60, | |||
| bottom: 60, | |||
| }, | |||
| xAxis: { | |||
| name: this.$t('profiling.memory.chartXaxisUnit'), | |||
| type: 'value', | |||
| show: true, | |||
| }, | |||
| yAxis: { | |||
| name: this.$t('profiling.memory.chartYaxisUnit'), | |||
| scale: true, | |||
| nameGap: 24, | |||
| }, | |||
| tooltip: { | |||
| trigger: 'axis', | |||
| axisPointer: { | |||
| type: 'line', | |||
| }, | |||
| formatter(params) { | |||
| let tipStr = ''; | |||
| params.forEach((param) => { | |||
| if (param.seriesId === that.graphicsId) { | |||
| const dataIndex = param.dataIndex; | |||
| const curData = that.currentGraphicsDic.nodes[dataIndex]; | |||
| if (curData) { | |||
| tipStr = | |||
| `<div>${that.$t('profiling.memory.curOperaterId')}` + | |||
| `${that.$t('symbols.colon')}${curData.node_id}</div>` + | |||
| `<div>${that.$t('profiling.memory.curOperator')}` + | |||
| `${that.$t('symbols.colon')}${curData.name}</div>` + | |||
| `<div>${that.$t( | |||
| 'profiling.memory.curOperatorMemorySize', | |||
| )}` + | |||
| `${that.$t('symbols.colon')}${that.formmateNummber( | |||
| curData.size, | |||
| )}</div>` + | |||
| `<div>${that.$t('profiling.memory.curMemorySize')}` + | |||
| `${that.$t('symbols.colon')}${that.formmateNummber( | |||
| that.currentGraphicsDic.lines[dataIndex], | |||
| )}</div>` + | |||
| `<div>${that.$t('profiling.memory.memoryChanged')}` + | |||
| `${that.$t('symbols.colon')}${that.formmateNummber( | |||
| curData.allocated, | |||
| )}</div>`; | |||
| } | |||
| } | |||
| }); | |||
| return tipStr; | |||
| }, | |||
| }, | |||
| dataZoom: [ | |||
| { | |||
| type: 'inside', | |||
| filterMode: 'empty', | |||
| orient: 'horizontal', | |||
| xAxisIndex: 0, | |||
| }, | |||
| { | |||
| type: 'slider', | |||
| filterMode: 'empty', | |||
| orient: 'horizontal', | |||
| xAxisIndex: 0, | |||
| bottom: 10, | |||
| }, | |||
| ], | |||
| series: seriesData, | |||
| }; | |||
| return optionData; | |||
| }, | |||
| /** | |||
| * Charting | |||
| */ | |||
| drawGraphics() { | |||
| if (!this.graphicsOption) { | |||
| return; | |||
| } | |||
| this.$nextTick(() => { | |||
| if (!this.memoryGraphicsChart) { | |||
| this.memoryGraphicsChart = echarts.init( | |||
| this.$refs.dashboardMemoryChart, | |||
| null, | |||
| ); | |||
| } | |||
| this.memoryGraphicsChart.setOption(this.graphicsOption); | |||
| this.memoryGraphicsChart.resize(); | |||
| }); | |||
| }, | |||
| /** | |||
| * Convert Numeric display format | |||
| * @param {Number} number | |||
| * @return {String} Formatted number | |||
| */ | |||
| formmateNummber(number) { | |||
| const digitMax = 10; | |||
| const digitMin = 1; | |||
| if (!isNaN(number) && number.toString().length > this.numberLimit) { | |||
| if (number > digitMin && number < digitMax) { | |||
| return number.toFixed(4); | |||
| } else { | |||
| return number.toExponential(4); | |||
| } | |||
| } else { | |||
| return number; | |||
| } | |||
| }, | |||
| // ----------------cpu----------------------------------- | |||
| /** | |||
| * The logic of add percent sign | |||
| * @param {number | string} number | |||
| * @return {string} | |||
| */ | |||
| addPercentSign(number) { | |||
| if (number === 0 || number === '0') { | |||
| return '0'; | |||
| } else { | |||
| return `${number}%`; | |||
| } | |||
| }, | |||
| /** | |||
| * Query cpu info | |||
| */ | |||
| queryCpuInfo( ) { | |||
| const params = { | |||
| params: { | |||
| profile: this.queryData.dir, | |||
| train_id: this.queryData.id, | |||
| }, | |||
| body: { | |||
| device_id: this.curCardNum, | |||
| filter_condition: {}, | |||
| }, | |||
| }; | |||
| this.cpuInfo.noData = true; | |||
| this.cpuInfo.initOver = false; | |||
| RequestService.getCpuUtilization(params).then( | |||
| (res) => { | |||
| this.cpuInfo.initOver = true; | |||
| if (res && res.data) { | |||
| this.cpuInfo.noData = !res.data.step_total_num; | |||
| this.cpuInfo.stepArray = res.data.step_info; | |||
| this.samplingInterval = res.data.sampling_interval; | |||
| this.deviceCpuChart.logicCores = res.data.cpu_processor_num; | |||
| const deviceInfo = res.data.device_info; | |||
| if (deviceInfo && this.samplingInterval) { | |||
| this.initDeviceCpu(deviceInfo); | |||
| } else { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.noData = true; | |||
| } | |||
| } else { | |||
| this.clearCpuChart(); | |||
| } | |||
| }, | |||
| () => { | |||
| this.clearCpuChart(); | |||
| this.cpuInfo.initOver = true; | |||
| }, | |||
| ); | |||
| }, | |||
| /** | |||
| * clear cpu chart | |||
| */ | |||
| clearCpuChart() { | |||
| if (this.deviceCpuChart.chartDom) { | |||
| this.deviceCpuChart.chartDom.clear(); | |||
| } | |||
| }, | |||
| /** | |||
| * format chart tip | |||
| * @param {Object} params | |||
| * @param {Array} stepArray | |||
| * @return {String} | |||
| */ | |||
| formatCpuChartTip(params, stepArray) { | |||
| const data = params; | |||
| let str = ''; | |||
| if (data && data.length) { | |||
| const colorArray = [ | |||
| '#c23531', | |||
| '#2f4554', | |||
| '#61a0a8', | |||
| '#d48265', | |||
| ]; | |||
| const index = data[0].dataIndex; | |||
| str += `step: ${stepArray[index]}`; | |||
| data.forEach((item, index) => { | |||
| str += `<br><span class="cpu-chart-tip" style="background-color:${colorArray[index]};"></span>` + | |||
| `${item.seriesName}: ${item.data}`; | |||
| }); | |||
| str += `</div>`; | |||
| } | |||
| return str; | |||
| }, | |||
| /** | |||
| * Init device cpu chart | |||
| * @param {Object} deviceInfo | |||
| */ | |||
| initDeviceCpu(deviceInfo) { | |||
| const series = []; | |||
| const legend = []; | |||
| Object.keys(this.cpuInfo.cpuInfoStr).forEach((val) => { | |||
| const info = deviceInfo[val]; | |||
| if (info && info.metrics) { | |||
| const item = { | |||
| type: 'line', | |||
| name: this.cpuInfo.cpuInfoStr[val], | |||
| data: info.metrics, | |||
| showSymbol: false, | |||
| }; | |||
| series.push(item); | |||
| legend.push(item.name); | |||
| } | |||
| }); | |||
| this.deviceCpuChart.cpuAvgUser = deviceInfo.user_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgSystem = deviceInfo.sys_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgIO = deviceInfo.io_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgFree = deviceInfo.idle_utilization.avg_value; | |||
| this.deviceCpuChart.cpuAvgProcess = deviceInfo.runable_processes.avg_value; | |||
| this.deviceCpuChart.cpuAvgSwitch = deviceInfo.context_switch_count.avg_value; | |||
| this.deviceCpuChart.option.series = series; | |||
| this.deviceCpuChart.option.xAxis.name = `${this.$t('profiling.sampleInterval')}\n${ | |||
| this.$t('symbols.leftbracket')}${this.samplingInterval}ms${this.$t('symbols.rightbracket')}`; | |||
| this.deviceCpuChart.option.xAxis.data = deviceInfo[Object.keys(deviceInfo)[0]].metrics.map( | |||
| (val, index) => index + 1, | |||
| ); | |||
| this.deviceCpuChart.option.legend.data = legend; | |||
| this.deviceCpuChart.option.tooltip.formatter = (params) => { | |||
| return this.formatCpuChartTip(params, this.cpuInfo.stepArray); | |||
| }; | |||
| this.$nextTick(() => { | |||
| if (!this.deviceCpuChart.chartDom) { | |||
| if (this.$refs.deviceCpuChart) { | |||
| this.deviceCpuChart.chartDom = echarts.init(this.$refs.deviceCpuChart); | |||
| } | |||
| } | |||
| this.deviceCpuChart.chartDom.setOption(this.deviceCpuChart.option); | |||
| }); | |||
| }, | |||
| /** | |||
| * Router to memory-detail | |||
| */ | |||
| jumpToCpuDetail() { | |||
| if (this.$route.path !== '/profiling/cpu-detail') { | |||
| this.$router.push({ | |||
| path: '/profiling/cpu-detail', | |||
| query: { | |||
| dir: this.queryData.dir, | |||
| id: this.queryData.id, | |||
| cardNum: this.curCardNum, | |||
| path: this.queryData.path, | |||
| activePane: this.queryData.activePane, | |||
| }, | |||
| }); | |||
| } | |||
| }, | |||
| }, | |||
| destroyed() { | |||
| // Remove the listener of window size change | |||
| window.removeEventListener('resize', this.resizeCallback); | |||
| // Remove timer | |||
| if (this.pageResizeTimer) { | |||
| clearTimeout(this.pageResizeTimer); | |||
| this.pageResizeTimer = null; | |||
| } | |||
| // Remove bus | |||
| this.$bus.$off('collapse'); | |||
| }, | |||
| }; | |||
| </script> | |||
| <style> | |||
| .cl-resource-content { | |||
| height: 100%; | |||
| } | |||
| .cl-resource-content .dashboard-item { | |||
| width: 100%; | |||
| height: calc(50% - 10px); | |||
| padding: 15px; | |||
| border: solid 1px #d9d9d9; | |||
| border-radius: 4px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item { | |||
| display: flex; | |||
| height: 24px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .title-text { | |||
| flex: 1; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| line-height: 24px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link { | |||
| cursor: pointer; | |||
| font-size: 12px; | |||
| height: 18px; | |||
| line-height: 12px; | |||
| padding-top: 2px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link a { | |||
| color: #00a5a7; | |||
| padding-right: 6px; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link button { | |||
| color: #00a5a7; | |||
| border: none; | |||
| background-color: #fff; | |||
| cursor: pointer; | |||
| } | |||
| .cl-resource-content .dashboard-item .title-item .detail-link.disabled button { | |||
| color: #c0c4cc; | |||
| cursor: not-allowed; | |||
| } | |||
| .cl-resource-content .dashboard-item .content-item { | |||
| height: calc(100% - 44px); | |||
| margin-top: 20px; | |||
| } | |||
| .cl-resource-content .dashboard-item .content-item .dashboard-chart-content { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| .cl-resource-content .margin-item { | |||
| margin-top: 20px; | |||
| } | |||
| .cl-resource-content .noData-content { | |||
| width: 100%; | |||
| height: 100%; | |||
| display: flex; | |||
| justify-content: center; | |||
| align-items: center; | |||
| flex-direction: column; | |||
| } | |||
| .cl-resource-content .noData-content p, | |||
| .cl-resource-content .noData-content .noData-text { | |||
| font-size: 16px; | |||
| } | |||
| .content-item .cpu-info { | |||
| display: grid; | |||
| grid-template-columns: 1fr 300px; | |||
| height: 100%; | |||
| } | |||
| .content-item .cpu-info .cpu-chart { | |||
| height: 100%; | |||
| width: 100% | |||
| } | |||
| .content-item .cpu-info .cpu-chart-info { | |||
| height: 100%; | |||
| width: 100%; | |||
| display: flex; | |||
| flex-direction: column; | |||
| justify-content: center; | |||
| padding-left: 20px; | |||
| background-color: #f1f1f1; | |||
| } | |||
| .content-item .cpu-chart-info .info-title { | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| line-height: 30px; | |||
| } | |||
| .content-item .cpu-chart-info .info-line { | |||
| line-height: 30px; | |||
| } | |||
| .cpu-chart-tip { | |||
| display: inline-block; | |||
| margin-right: 5px; | |||
| border-radius: 10px; | |||
| width: 10px; | |||
| height: 10px; | |||
| } | |||
| </style> | |||
| @@ -1,5 +1,5 @@ | |||
| <!-- | |||
| Copyright 2020 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Copyright 2020-2021 Huawei Technologies Co., Ltd.All Rights Reserved. | |||
| Licensed under the Apache License, Version 2.0 (the "License"); | |||
| you may not use this file except in compliance with the License. | |||
| @@ -945,7 +945,7 @@ export default { | |||
| } | |||
| .step-trace .step-trace-title { | |||
| padding: 0 15px; | |||
| font-size: 16px; | |||
| font-size: 18px; | |||
| font-weight: bold; | |||
| } | |||
| .step-trace .step-trace-title .el-icon-question { | |||
| @@ -999,12 +999,12 @@ export default { | |||
| } | |||
| .step-trace .pf-content-middle { | |||
| padding: 10px 15px 0; | |||
| height: calc(100% - 62px); | |||
| height: calc(100% - 64px); | |||
| } | |||
| .step-trace .pf-content-middle #trace-container { | |||
| width: 100%; | |||
| height: 50%; | |||
| border: 1px solid #ccc; | |||
| border: 1px solid #D9D9D9; | |||
| overflow: auto; | |||
| } | |||
| .step-trace .pf-content-middle #trace-container .training-trace { | |||
| @@ -1024,13 +1024,13 @@ export default { | |||
| } | |||
| .step-trace .pf-content-middle .chart-wrap { | |||
| float: left; | |||
| height: calc(50% - 20px); | |||
| height: calc(50% - 25px); | |||
| margin-top: 20px; | |||
| margin-right: 15px; | |||
| width: calc(33.3% - 10px); | |||
| border: 1px solid #ccc; | |||
| border: 1px solid #D9D9D9; | |||
| padding: 30px 30px 0; | |||
| border-radius: 4px; | |||
| border-radius: 1px; | |||
| overflow: auto; | |||
| } | |||
| .step-trace .pf-content-middle .chart-wrap:last-child { | |||
| @@ -1045,6 +1045,7 @@ export default { | |||
| .step-trace .pf-content-middle .chart-wrap .title { | |||
| margin: 0 0 15px 20px; | |||
| font-weight: bold; | |||
| font-size: 16px; | |||
| } | |||
| .step-trace .pf-content-middle .chart-wrap .rate-wrap { | |||
| font-size: 12px; | |||