提交 c797ad86 编写于 作者: M mindspore-ci-bot 提交者: Gitee

!304 UI add profiling minddata page(3rd commit)

Merge pull request !304 from 潘慧/master_ph2
......@@ -360,7 +360,8 @@
"averageCapacity": "平均使用容量",
"stepTraceMessage": "当前FP和BP为自动选点,如不合乎预期,请自行修改。",
"FPMessage": "FP起始算子:",
"BPMessage": "BP终止算子:"
"BPMessage": "BP终止算子:",
"approximateTime": "总时长 ≈ "
},
"components": {
"summaryTitle": "训练选择",
......
......@@ -88,8 +88,8 @@ export default new Router({
component: () => import('./views/train-manage/operator.vue'),
},
{
path: 'minddata',
component: () => import('./views/train-manage/minddata.vue'),
path: 'data-process',
component: () => import('./views/train-manage/data-process.vue'),
},
],
},
......
......@@ -29,7 +29,7 @@ export default {
queryLineagesData(params) {
return axios({
method: 'post',
url: '/v1/mindinsight/lineagemgr/lineages',
url: 'v1/mindinsight/lineagemgr/lineages',
data: params.body,
});
},
......@@ -37,7 +37,7 @@ export default {
putLineagesData(params) {
return axios({
method: 'put',
url: '/v1/mindinsight/lineagemgr/lineages?train_id=' + params.train_id,
url: 'v1/mindinsight/lineagemgr/lineages?train_id=' + params.train_id,
data: params.body,
});
},
......@@ -46,7 +46,7 @@ export default {
querySummaryList(params, isIgnoreError) {
return axios({
method: 'get',
url: '/v1/mindinsight/datavisual/train-jobs',
url: 'v1/mindinsight/datavisual/train-jobs',
params: params,
headers: {
ignoreError: isIgnoreError,
......@@ -154,21 +154,21 @@ export default {
getHistogramData(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/datavisual/histograms',
url: 'v1/mindinsight/datavisual/histograms',
params: params,
});
},
getProfilerDeviceData(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/profile/devices',
url: 'v1/mindinsight/profile/devices',
params: params,
});
},
getProfilerOpData(params) {
return axios({
method: 'post',
url: '/v1/mindinsight/profile/ops/search',
url: 'v1/mindinsight/profile/ops/search',
params: params.params,
data: params.body,
headers: {
......@@ -180,7 +180,7 @@ export default {
queryDataOfProfileHelper(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/profile/summary/propose',
url: 'v1/mindinsight/profile/summary/propose',
params: params,
});
},
......@@ -188,7 +188,7 @@ export default {
queryTrainingTrace(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/profile/training-trace/graph',
url: 'v1/mindinsight/profile/training-trace/graph',
params: params,
headers: {
ignoreError: true,
......@@ -198,7 +198,7 @@ export default {
targetTimeInfo(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/profile/training-trace/target-time-info',
url: 'v1/mindinsight/profile/training-trace/target-time-info',
params: params,
headers: {
ignoreError: true,
......@@ -208,7 +208,7 @@ export default {
queryTimeline(params) {
return axios({
method: 'get',
url: '/v1/mindinsight/profile/timeline',
url: 'v1/mindinsight/profile/timeline',
params: params,
headers: {
ignoreError: true,
......
<!--
Copyright 2019 Huawei Technologies Co., Ltd.All Rights Reserved.
Copyright 2020 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.
......@@ -373,7 +373,7 @@ export default {
allGraphData: {},
graphviz: null,
totalMemory: 16777216 * 2, // Memory size of the graph plug-in
scaleRange: [1, 10000], // graph zooms in and zooms out.
scaleRange: [0.0001, 10000], // graph zooms in and zooms out.
initQueue: '',
trainId: '',
selected: '',
......@@ -386,13 +386,13 @@ export default {
this.dir = newValue.query.dir;
this.trainId = newValue.query.id;
this.currentCard = newValue.curCardNum;
if (this.trainingJobId) {
if (this.trainId) {
document.title =
`${decodeURIComponent(this.trainingJobId)}` +
`-${this.$t('profiling.profilingDashboard')}-MindInsight`;
`${decodeURIComponent(this.trainId)}` +
`-${this.$t('profiling.mindData')}-MindInsight`;
} else {
document.title = `${this.$t(
'profiling.profilingDashboard',
'profiling.mindData',
)}-MindInsight`;
}
if (this.activeName === 'queueInfo') {
......@@ -422,6 +422,7 @@ export default {
});
}
}
this.resizeCallback();
},
init() {
this.queryQueueInfo(this.connectQueueChart);
......@@ -1024,41 +1025,81 @@ export default {
* Initializing the Zoom Function of a Graph
*/
initZooming() {
const graphDom = document.querySelector('#graph0');
const svgDom = document.querySelector('#graph svg');
const svgRect = svgDom.getBoundingClientRect();
const graphDom = document.querySelector('#graph #graph0');
const graphBox = graphDom.getBBox();
const graphRect = graphDom.getBoundingClientRect();
let graphTransform = {};
const minScale = Math.min(
svgRect.width / 2 / graphRect.width,
svgRect.height / 2 / graphRect.height,
);
const padding = 4;
const pointer = {
start: {
x: 0,
y: 0,
},
end: {
x: 0,
y: 0,
},
};
const minDistance = 20;
const pointer = {start: {x: 0, y: 0}, end: {x: 0, y: 0}};
const zoom = d3
.zoom()
.on('start', (target) => {
.on('start', () => {
pointer.start.x = event.x;
pointer.start.y = event.y;
})
.on('zoom', (target) => {
.on('zoom', () => {
const transformData = this.getTransformData(graphDom);
if (!Object.keys(graphTransform).length) {
graphTransform = {
x: transformData.translate[0],
y: transformData.translate[1],
k: transformData.scale[0],
};
}
let tempStr = '';
let change = {};
let scale = transformData.scale[0];
const graphRect = graphDom.getBoundingClientRect();
const mapping = {
width: graphBox.width / graphRect.width,
height: graphBox.height / graphRect.height,
};
const transRate = graphBox.width / graphRect.width;
if (event.type === 'mousemove') {
pointer.end.x = event.x;
pointer.end.y = event.y;
let tempX = pointer.end.x - pointer.start.x;
let tempY = pointer.end.y - pointer.start.y;
const paddingTrans = Math.max(
(padding / transRate) * scale,
minDistance,
);
if (
graphRect.left + paddingTrans + tempX >=
svgRect.left + svgRect.width
) {
tempX = Math.min(tempX, 0);
}
if (
graphRect.left + graphRect.width - paddingTrans + tempX <=
svgRect.left
) {
tempX = Math.max(tempX, 0);
}
if (
graphRect.top + paddingTrans + tempY >=
svgRect.top + svgRect.height
) {
tempY = Math.min(tempY, 0);
}
if (
graphRect.top + graphRect.height - paddingTrans + tempY <=
svgRect.top
) {
tempY = Math.max(tempY, 0);
}
change = {
x: (pointer.end.x - pointer.start.x) * mapping.width * scale,
y: (pointer.end.y - pointer.start.y) * mapping.height * scale,
x: tempX * transRate * scale,
y: tempY * transRate * scale,
};
pointer.start.x = pointer.end.x;
pointer.start.y = pointer.end.y;
......@@ -1069,29 +1110,42 @@ export default {
wheelDelta > 0
? transformData.scale[0] * rate
: transformData.scale[0] / rate;
scale = Math.max(this.scaleRange[0], scale);
scale = Math.max(this.scaleRange[0], scale, minScale);
scale = Math.min(this.scaleRange[1], scale);
change = {
x:
(graphRect.x + padding / mapping.width - event.x) *
mapping.width *
(graphRect.x + padding / transRate - event.x) *
transRate *
(scale - transformData.scale[0]),
y:
(graphRect.bottom - padding / mapping.height - event.y) *
mapping.height *
(graphRect.bottom - padding / transRate - event.y) *
transRate *
(scale - transformData.scale[0]),
};
}
tempStr = `translate(${transformData.translate[0] +
change.x},${transformData.translate[1] +
change.y}) scale(${scale})`;
graphTransform = {
x: transformData.translate[0] + change.x,
y: transformData.translate[1] + change.y,
k: scale,
};
tempStr = `translate(${graphTransform.x},${graphTransform.y}) scale(${graphTransform.k})`;
graphDom.setAttribute('transform', tempStr);
event.stopPropagation();
event.preventDefault();
});
const svg = d3.select('svg');
const svg = d3.select('#graph svg');
svg.on('.zoom', null);
svg.call(zoom);
svg.on('dblclick.zoom', null);
svg.on('wheel.zoom', null);
const graph0 = d3.select('#graph #graph0');
graph0.on('.zoom', null);
graph0.call(zoom);
},
/**
* Obtains the transform data of a node.
......@@ -1259,7 +1313,6 @@ export default {
&:last-child {
height: 50%;
}
height: 50%;
& > .title {
margin-bottom: 15px;
font-weight: bold;
......@@ -1270,7 +1323,7 @@ export default {
.chart-wrap {
float: left;
width: calc(50% - 12px);
height: 100%;
height: calc(100% - 10px);
border-radius: 4px;
overflow-y: auto;
border: 1px solid #eee;
......
......@@ -165,8 +165,8 @@
{{ $t('operator.operatorStatistics') }}
</span>
<div class="cl-search-box">
<el-input v-model="searchByCPUNameInput"
:placeholder="$t('operator.searchByName')"
<el-input v-model="searchByCPUTypeInput"
:placeholder="$t('operator.searchByType')"
clearable
@clear="searchOpCpuList()"
@keyup.enter.native="searchOpCpuList()"></el-input>
......@@ -256,7 +256,7 @@ export default {
statisticType: 0, // ai core table statistic type
searchByTypeInput: '', // search by ai core type name
searchByNameInput: '', // search by ai core detail name
searchByCPUNameInput: '', // search by ai cpu name
searchByCPUTypeInput: '', // search by ai cpu name
opTypeCol: [], // table headers list of operator type
opTypeList: [], // table list of operator type
opCpuList: {
......@@ -310,7 +310,7 @@ export default {
this.profile_dir = newValue.query.dir;
this.train_id = newValue.query.id;
this.currentCard = newValue.curCardNum;
this.init();
this.cardChange();
}
},
deep: true,
......@@ -323,9 +323,6 @@ export default {
this.$bus.$off('collapse');
},
methods: {
init() {
this.getCoreTypeList();
},
resizeEchart() {
if (this.coreCharts.chartDom) {
setTimeout(() => {
......@@ -343,7 +340,7 @@ export default {
this.getCoreTypeList();
} else if (this.apiType === 'cpu') {
this.clearCpuData();
this.getCpuList(true);
this.getCpuList();
}
},
opTypeSortChange() {
......@@ -358,7 +355,7 @@ export default {
* clear cpu data
*/
clearCpuData() {
this.searchByCPUNameInput = '';
this.searchByCPUTypeInput = '';
this.opCpuList = {
opDetailCol: [],
opDetailList: [],
......@@ -635,9 +632,9 @@ export default {
*/
searchOpCpuList() {
this.opCpuList.op_filter_condition = {};
if (this.searchByCPUNameInput) {
if (this.searchByCPUTypeInput) {
this.opCpuList.op_filter_condition = {
op_name: {partial_match_str_in: [this.searchByCPUNameInput]},
op_type: {partial_match_str_in: [this.searchByCPUTypeInput]},
};
} else {
this.opCpuList.op_filter_condition = {};
......
......@@ -46,7 +46,9 @@ limitations under the License.
</div>
<br />
<div>{{$t('profiling.statistics')}}</div>
<div>{{$t('profiling.totalTime')}}<span>{{totalTime}}{{$t('profiling.millisecond')}}</span></div>
<div>{{$t('profiling.totalTime')}}
<span>{{totalTime}}{{$t('profiling.millisecond')}}</span>
</div>
<div>{{$t('profiling.totalSteps')}}<span>{{totalSteps}}</span></div>
<div>{{$t('profiling.fpbpTimeRatio')}}<span>{{fpAndBp}}</span></div>
<div>{{$t('profiling.iterationGapTimeRatio')}}<span>{{iterationInterval}}</span></div>
......@@ -101,7 +103,7 @@ limitations under the License.
<div class="title-wrap">
<div class="title">{{ $t('profiling.mindData') }}</div>
<div class="view-detail">
<button @click="viewDetail('minddata')"
<button @click="viewDetail('data-process')"
:disabled="processSummary.noData"
:class="{disabled:processSummary.noData}">
{{ $t('profiling.viewDetail') }}
......@@ -117,18 +119,18 @@ limitations under the License.
<div>{{$t('profiling.dataProcessInfo')}}</div>
<div>{{$t('profiling.analysisOne')}}</div>
<div>{{$t('profiling.analysisTwo')}}</div>
<div v-show="deviceInfoShow||queueInfoShow">{{$t('profiling.higherAnalysis')}}</div>
<div v-show="deviceInfoShow || queueInfoShow">{{$t('profiling.higherAnalysis')}}</div>
<br />
<div v-show="deviceInfoShow||queueInfoShow">{{$t('profiling.statistics')}}</div>
<div v-show="deviceInfoShow || queueInfoShow">{{$t('profiling.statistics')}}</div>
<div v-show="queueInfoShow">{{$t('profiling.chipInfo')}}
<span>{{queueInfoEmptyNum}}/{{queueInfoTotalNum}}</span>
<span>{{queueInfoEmptyNum}} / {{queueInfoTotalNum}}</span>
</div>
<div v-show="deviceInfoShow">
<div>{{$t('profiling.hostIsEmpty')}}
<span>{{deviceInfoEmptyNum}}/{{deviceInfoTotalNum}}</span>
<span>{{deviceInfoEmptyNum}} / {{deviceInfoTotalNum}}</span>
</div>
<div>{{$t('profiling.hostIsFull')}}
<span>{{deviceInfoFullNum}}/{{deviceInfoTotalNum}}</span>
<span>{{deviceInfoFullNum}} / {{deviceInfoTotalNum}}</span>
</div>
</div>
</div>
......@@ -162,18 +164,19 @@ 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')}}
<span class="num">
{{processSummary.device.empty}}/{{processSummary.device.total}}
{{processSummary.device.empty}} / {{processSummary.device.total}}
</span>
</div>
<div class="item"
v-if="processSummary.device.full || processSummary.device.full === 0">
{{$t('profiling.queueTip1')}}
<span class="num">
{{processSummary.device.empty}}/{{processSummary.device.total}}
{{processSummary.device.empty}} / {{processSummary.device.total}}
</span>
</div>
</div>
......@@ -206,18 +209,19 @@ 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')}}
<span class="num">
{{processSummary.get_next.empty}}/{{processSummary.get_next.total}}
{{processSummary.get_next.empty}} / {{processSummary.get_next.total}}
</span>
</div>
<div class="item"
v-if="processSummary.get_next.full || processSummary.get_next.full === 0">
{{$t('profiling.queueTip1')}}
<span class="num">
{{processSummary.get_next.empty}}/{{processSummary.get_next.total}}
{{processSummary.get_next.empty}} / {{processSummary.get_next.total}}
</span>
</div>
</div>
......@@ -451,8 +455,7 @@ export default {
const data = JSON.parse(JSON.stringify(resp.data));
this.processSummary.count = Object.keys(data).length;
this.dealProcess(data);
// 芯片侧
// Chip side
if (resp.data.get_next_queue_info) {
this.queueInfoShow = true;
this.queueInfoEmptyNum =
......@@ -460,7 +463,7 @@ export default {
this.queueInfoTotalNum =
resp.data.get_next_queue_info.summary.total_batch;
}
// 主机侧
// Host side
if (resp.data.device_queue_info) {
this.deviceInfoShow = true;
this.deviceInfoEmptyNum =
......@@ -498,13 +501,14 @@ export default {
option.series = [
{
type: 'pie',
center: ['55%', '55%'],
center: ['50%', '50%'],
data: this.pieChart.data,
radius: '50%',
lable: {
position: 'outer',
alignTo: 'none',
bleedMargin: 5,
radius: '80%',
label: {
normal: {
show: false,
positionL: 'inner',
},
},
itemStyle: {
normal: {
......@@ -550,7 +554,7 @@ export default {
if (res.data.object) {
this.pieChart.data = [];
res.data.object.forEach((item) => {
if (this.pieChart.data && this.pieChart.data.length < 19) {
if (this.pieChart.data && this.pieChart.data.length < 5) {
this.pieChart.data.push({
name: item[0],
value: item[1],
......@@ -558,15 +562,15 @@ export default {
percent: item[3],
});
} else {
if (!this.pieChart.data[19]) {
this.pieChart.data[19] = {
if (!this.pieChart.data[5]) {
this.pieChart.data[5] = {
name: 'Other',
value: 0,
percent: 0,
};
}
this.pieChart.data[19].value += item[1];
this.pieChart.data[19].percent += item[3];
this.pieChart.data[5].value += item[1];
this.pieChart.data[5].percent += item[3];
}
});
this.setPieOption();
......@@ -751,7 +755,9 @@ export default {
line.setAttribute('marker-start', 'url(#marker_start)');
const text = document.createElementNS(this.svg.namespaceURI, 'text');
text.textContent = `${data.duration.toFixed(4)}ms`;
text.textContent = `${
rowIndex === 0 ? this.$t('profiling.approximateTime') : ''
}${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(text.textContent);
text.setAttribute(
'x',
......@@ -884,7 +890,7 @@ export default {
};
this.processSummary.noData = true;
if (data) {
if (data && Object.keys(data).length) {
if (data.device_queue_info && data.device_queue_info.summary) {
this.processSummary.device = {
empty: data.device_queue_info.summary.empty_batch_count,
......@@ -1089,6 +1095,13 @@ export default {
overflow: hidden;
width: 100%;
text-align: center;
.line {
width: 1px;
height: 40px;
margin: 20px 0;
border-left: 1px solid #979797;
display: inline-block;
}
.item {
font-size: 12px;
line-height: 16px;
......
......@@ -186,10 +186,22 @@ export default {
const divDom = document.createElement('div');
divDom.setAttribute('class', 'content-style');
const content = `${this.$t(`profiling`)[item].desc}`
.replace(`{n1}`, deviceEmpty)
.replace(`{n2}`, deviceTotal)
.replace(`{n3}`, deviceFull)
.replace(`{n4}`, deviceTotal);
.replace(
`{n1}`,
`<span class="nowrap-style"> ${deviceEmpty}</span>`,
)
.replace(
`{n2}`,
`<span class="nowrap-style"> ${deviceTotal}</span>`,
)
.replace(
`{n3}`,
`<span class="nowrap-style"> ${deviceFull}</span>`,
)
.replace(
`{n4}`,
`<span class="nowrap-style"> ${deviceTotal}</span>`,
);
divDom.innerHTML = `<div class="content-icon el-icon-caret-right"></div>
<div class="helper-content-style">${content}</div>`;
helperDiv.appendChild(divDom);
......@@ -205,8 +217,14 @@ export default {
const divDom = document.createElement('div');
divDom.setAttribute('class', 'content-style');
const content = `${this.$t(`profiling`)[item].desc}`
.replace(`{n1}`, getNextEmpty)
.replace(`{n2}`, getNextTotal);
.replace(
`{n1}`,
`<span class="nowrap-style"> ${getNextEmpty}</span>`,
)
.replace(
`{n2}`,
`<span class="nowrap-style"> ${getNextTotal}</span>`,
);
divDom.innerHTML = `<div class="content-icon el-icon-caret-right"></div>
<div class="helper-content-style">${content}</div>`;
helperDiv.appendChild(divDom);
......@@ -216,7 +234,7 @@ export default {
divDom.setAttribute('class', 'content-style');
divDom.innerHTML = `<div class="content-icon el-icon-caret-right"></div>
<div class="helper-content-style">
<a href="${this.$t(`profiling`)[item].url[0]}">
<a target="_blank" href="${this.$t(`profiling`)[item].url[0]}">
${this.$t(`profiling`)[item].desc}</a></div>`;
helperDiv.appendChild(divDom);
} else {
......@@ -227,7 +245,7 @@ export default {
for (let i = 0; i < anchorList.length; i++) {
const desc = anchorContent.relpace(
anchorList[i],
`<a href="${this.$t(`profiling`)[item].url[i]}">
`<a target="_blank" href="${this.$t(`profiling`)[item].url[i]}">
${anchorList[i]}</a>`,
);
anchorContent = desc;
......@@ -288,8 +306,13 @@ export default {
.helper {
padding: 32px;
height: 100%;
overflow-y: auto;
margin-left: 32px;
background: #edf0f5;
word-wrap: break-word;
.nowrap-style{
white-space: nowrap;
}
.cur-card {
margin-bottom: 32px;
.card-select {
......
......@@ -32,6 +32,11 @@ limitations under the License.
</div>
</div>
</div>
<div class="step-message">
<div class="step-padding-right">{{$t('profiling.stepTraceMessage')}}</div>
<div class="step-padding-right">{{$t('profiling.FPMessage')}}<span>{{fp_start}}</span></div>
<div class="step-padding-right">{{$t('profiling.BPMessage')}}<span>{{bp_end}}</span></div>
</div>
<div class="pf-content-middle"
v-show="!tabsArr[0].noData && !tabsArr[1].noData && !tabsArr[2].noData && !svg.noData">
<div id="trace-container">
......@@ -84,11 +89,11 @@ limitations under the License.
class="chart-wrap">
<div class="title">{{ item.name }}</div>
<div class="rate-wrap">
<div v-if="item.timeSummary.total_time !== undefined && item.timeSummary[item.rate] !== undefined">
<span>{{item.timeLabel}}:</span>
{{(item.timeSummary.total_time*parseFloat(item.timeSummary[item.rate])/100).toFixed(4)}}ms</div>
<div v-if="item.timeSummary[item.rate] !== undefined">
<span>{{item.rateLabel}}:</span>{{item.timeSummary[item.rate]}}</div>
<span>{{item.timeLabel}}:</span>
{{item.timeSummary[item.rate]}}ms</div>
<div v-if="item.timeSummary[item.percent] !== undefined">
<span>{{item.rateLabel}}:</span>{{item.timeSummary[item.percent]}}</div>
<div v-if="item.timeSummary.total_steps !== undefined">
<span>{{$t('profiling.stepNum')}}:</span>{{item.timeSummary.total_steps}}</div>
</div>
......@@ -125,6 +130,8 @@ export default {
dir: this.$route.query.dir,
train_id: this.$route.query.id,
relativePath: this.$route.query.path,
fp_start: '--',
bp_end: '--',
steps: [],
selectedStep: '',
charts: [],
......@@ -157,6 +164,7 @@ export default {
timeLabel: this.$t('profiling.iterGapTimeLabel'),
rateLabel: this.$t('profiling.iterGapRateLabel'),
noData: false,
percent: 'iteration_interval_percent',
},
{
name: 'Fp+bp',
......@@ -166,6 +174,7 @@ export default {
timeLabel: this.$t('profiling.fpBpTimeLabel'),
rateLabel: this.$t('profiling.fpBpRateLabel'),
noData: false,
percent: 'fp_and_bp_percent',
},
{
name: this.$t('profiling.lterationTail'),
......@@ -175,6 +184,7 @@ export default {
timeLabel: this.$t('profiling.tailTimeLabel'),
rateLabel: this.$t('profiling.tailRateLabel'),
noData: false,
percent: 'tail_percent',
},
],
};
......@@ -348,7 +358,7 @@ export default {
},
resizeEchart() {
setTimeout(() => {
this.charts.forEach((val)=>{
this.charts.forEach((val) => {
val.resize();
});
}, 300);
......@@ -367,6 +377,13 @@ export default {
res.data.training_trace_graph.length
) {
this.svg.noData = false;
if (res.data.point_info && res.data.point_info.length) {
this.fp_start = res.data.point_info.fp_start;
this.bp_end = res.data.point_info.bp_end;
} else {
this.fp_start = '--';
this.bp_end = '--';
}
document.querySelector('#trace').style.height = `${res.data
.training_trace_graph.length * this.svg.rowHeight}px`;
this.svg.data = JSON.parse(
......@@ -377,12 +394,16 @@ export default {
this.dealTraceData();
}, 100);
} else {
this.fp_start = '--';
this.bp_end = '--';
this.svg.data = [];
this.svg.noData = true;
this.removeTrace();
}
},
(error) => {
this.fp_start = '--';
this.bp_end = '--';
this.svg.data = [];
this.svg.noData = true;
this.removeTrace();
......@@ -498,7 +519,9 @@ export default {
line.setAttribute('marker-start', 'url(#marker_start)');
const text = document.createElementNS(this.svg.namespaceURI, 'text');
text.textContent = `${data.duration.toFixed(4)}ms`;
text.textContent = `${
rowIndex === 0 ? this.$t('profiling.approximateTime') : ''
}${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(text.textContent);
text.setAttribute(
'x',
......@@ -599,9 +622,20 @@ export default {
font-weight: normal;
}
}
.step-message {
display: flex;
height: 24px;
line-height: 24px;
margin-top: 6px;
margin-left: 14px;
overflow-y: auto;
}
.step-padding-right {
padding-right: 6px;
}
.pf-content-middle {
padding: 15px 15px 0;
height: calc(100% - 32px);
height: calc(100% - 62px);
#trace-container {
width: 100%;
height: 50%;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册