提交 5518cb7d 编写于 作者: W WeiFeng-mindinsight

UI fix bug of step trace page that graph covers others and graph data show clearly

上级 c35b45ff
...@@ -73,8 +73,8 @@ limitations under the License. ...@@ -73,8 +73,8 @@ limitations under the License.
markerHeight="8" markerHeight="8"
orient="auto"> orient="auto">
<path d="M1,1 L1,7 L9,4 z" <path d="M1,1 L1,7 L9,4 z"
fill="#E6EBF5" fill="#6c7280"
stroke="#E6EBF5"></path> stroke="#6c7280"></path>
</marker> </marker>
<marker id="marker_start" <marker id="marker_start"
refX="5" refX="5"
...@@ -83,8 +83,8 @@ limitations under the License. ...@@ -83,8 +83,8 @@ limitations under the License.
markerHeight="8" markerHeight="8"
orient="auto"> orient="auto">
<path d="M9,1 L9,7 L1,4 z" <path d="M9,1 L9,7 L1,4 z"
fill="#E6EBF5" fill="#6c7280"
stroke="#E6EBF5"></path> stroke="#6c7280"></path>
</marker> </marker>
</defs> </defs>
</svg> </svg>
...@@ -372,18 +372,25 @@ export default { ...@@ -372,18 +372,25 @@ export default {
svgPadding: 20, svgPadding: 20,
totalWidth: 0, totalWidth: 0,
totalTime: 0, totalTime: 0,
rowHeight: 60, cellHeight: 40,
cellPadding: 0,
rowPadding: 20,
rowMargin: 10,
totalHeight: 0,
markerPadding: 4, markerPadding: 4,
minRate: 0.01, minRate: 0.1,
minTime: 0,
minWidth: 1,
fontSize: 12,
textMargin: 21,
namespaceURI: 'http://www.w3.org/2000/svg', namespaceURI: 'http://www.w3.org/2000/svg',
resizeTimer: null, resizeTimer: null,
colorList: [ colors: {
['#A6DD82', '#edf8e6'], iteration_interval: ['#A6DD82', '#edf8e6'],
['#6CBFFF', '#e2f2ff'], fp_and_bp: ['#6CBFFF', '#e2f2ff'],
['#fa8e5b', '#fff4de'], tail: ['#fa8e5b', '#fff4de'],
['#01a5a7', '#cceded'], stream_parallel: ['#01a5a7', '#cceded'],
], },
colorIndex: 0,
noData: false, noData: false,
}, },
trainingJobId: this.$route.query.id, trainingJobId: this.$route.query.id,
...@@ -630,15 +637,13 @@ export default { ...@@ -630,15 +637,13 @@ export default {
res.data.training_trace_graph.length res.data.training_trace_graph.length
) { ) {
this.svg.noData = false; this.svg.noData = false;
document.querySelector('#trace').style.height = `${res.data
.training_trace_graph.length * this.svg.rowHeight}px`;
this.svg.data = JSON.parse(
JSON.stringify(res.data.training_trace_graph),
);
this.removeTrace(); this.removeTrace();
setTimeout(() => { this.$nextTick(() => {
this.dealTraceData(); this.packageTraceData(
}, 100); JSON.parse(JSON.stringify(res.data.training_trace_graph)),
);
});
if (res.data.summary) { if (res.data.summary) {
this.fp_and_bp_percent = res.data.summary.fp_and_bp_percent; this.fp_and_bp_percent = res.data.summary.fp_and_bp_percent;
this.iteration_interval_percent = this.iteration_interval_percent =
...@@ -669,47 +674,80 @@ export default { ...@@ -669,47 +674,80 @@ export default {
); );
}, },
packageTraceData(traceGraph) {
this.svg.totalTime = 0;
this.svg.minTime = 0;
this.svg.totalHeight = 0;
const data = [];
if (traceGraph && traceGraph[0] && traceGraph[0][0]) {
this.svg.totalTime = traceGraph[0][0].duration;
this.svg.minTime = this.svg.minRate * this.svg.totalTime;
traceGraph.forEach((row, index) => {
const rowObj = {
rowCount: 0,
data: [],
height: 0,
startY: this.svg.totalHeight,
};
let obj = [];
for (let i = 0; i < row.length; i++) {
if (row[i].duration < this.svg.minTime) {
if (obj.length) {
rowObj.data.push(obj);
obj = [];
rowObj.rowCount++;
}
rowObj.data.push([row[i]]);
rowObj.rowCount++;
} else {
obj.push(row[i]);
}
if (i === row.length - 1 && obj.length) {
rowObj.data.push(obj);
obj = [];
rowObj.rowCount++;
}
}
rowObj.height =
rowObj.rowCount * this.svg.cellHeight +
(rowObj.rowCount - 1) * this.svg.cellPadding +
(index ? this.svg.rowPadding * 2 : 0);
this.svg.totalHeight += rowObj.height + this.svg.rowMargin;
data.push(rowObj);
});
this.svg.totalHeight += this.svg.rowPadding;
document.querySelector(
'#trace',
).style.height = `${this.svg.totalHeight}px`;
this.svg.data = JSON.parse(JSON.stringify(data));
this.$nextTick(() => {
this.dealTraceData();
});
}
},
dealTraceData() { dealTraceData() {
const traceDom = document.querySelector('#trace'); const traceDom = document.querySelector('#trace');
if (traceDom) { if (traceDom) {
this.svg.totalWidth = traceDom.offsetWidth - this.svg.svgPadding * 2; this.svg.totalWidth = traceDom.offsetWidth - this.svg.svgPadding * 2;
if (this.svg.data[0] && this.svg.data[0].length) { if (this.svg.data[0] && this.svg.data[0].data.length) {
const svg = traceDom.querySelector('svg'); const svg = traceDom.querySelector('svg');
this.svg.totalTime = this.svg.data[0][0].duration;
if (this.svg.totalTime) { if (this.svg.totalTime) {
this.svg.colorIndex = 0; this.svg.data.forEach((item, index) => {
const minTime = this.svg.minRate * this.svg.totalTime; let itemDom = {};
if (index) {
this.svg.data.forEach((row, index) => { itemDom = this.createMultipleRowContainer(item);
if (row && row.length) { } else {
const dashedLine = this.addDashedLine(index); itemDom = this.createRowContainer(item.data, item.startY);
svg.insertBefore(dashedLine, svg.querySelector('g'));
let textOffsets = 0;
row.forEach((i) => {
if (i.duration) {
if (i.name) {
if (i.duration < minTime) {
textOffsets++;
} else {
textOffsets = 0;
}
i.textOffsets = textOffsets;
const tempDom = this.createRect(i, index);
const tempStr = `g${
i.duration > minTime ? '' : '.arrow'
}`;
svg.insertBefore(tempDom, svg.querySelector(tempStr));
} else {
const tempDom = this.createArrow(i, index);
svg.appendChild(tempDom);
}
}
});
} }
svg.appendChild(itemDom);
}); });
} }
} else { } else {
...@@ -717,39 +755,69 @@ export default { ...@@ -717,39 +755,69 @@ export default {
} }
} }
}, },
addDashedLine(index) {
const x1 = this.svg.svgPadding; createMultipleRowContainer(item) {
const x2 = this.svg.svgPadding + this.svg.totalWidth; const rectContainer = document.createElementNS(
const y = index * this.svg.rowHeight; this.svg.namespaceURI,
const line = document.createElementNS(this.svg.namespaceURI, 'line'); 'g',
line.setAttribute('x1', x1); );
line.setAttribute('y1', y); rectContainer.setAttribute('class', 'container');
line.setAttribute('x2', x2);
line.setAttribute('y2', y); const rect = document.createElementNS(this.svg.namespaceURI, 'rect');
line.setAttribute('style', 'stroke:#E2E2E2;stroke-width:1'); rect.setAttribute('x', this.svg.svgPadding);
line.setAttribute('stroke-dasharray', '5 5'); rect.setAttribute('y', item.startY + this.svg.rowPadding);
rect.setAttribute('height', item.height);
rect.setAttribute('width', this.svg.totalWidth);
rect.setAttribute('style', 'fill:#edf0f5;stroke:#E2E2E2;stroke-width:1');
rectContainer.appendChild(rect);
const temp = this.createRowContainer(
item.data,
item.startY + this.svg.rowPadding,
);
rectContainer.appendChild(temp);
return rectContainer;
},
createRowContainer(data, startY) {
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'dashedLine');
g.appendChild(line); data.forEach((row, index) => {
const y =
startY +
this.svg.rowPadding +
index * (this.svg.cellPadding + this.svg.cellHeight);
row.forEach((i) => {
if (i.duration) {
let temp;
if (i.name) {
temp = this.createRect(i, y);
g.insertBefore(temp, g.querySelector('g'));
} else {
temp = this.createArrow(i, y);
g.appendChild(temp);
}
}
});
});
return g; return g;
}, },
createRect(data, rowIndex) {
const color = this.svg.colorList[ createRect(data, startY) {
rowIndex > 1 ? 3 : this.svg.colorIndex++ % 4 const color =
]; data.name && this.svg.colors[data.name]
const height = 40; ? this.svg.colors[data.name]
const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth; : this.svg.colors.stream_parallel;
const fontSize = 12;
const x1 = const x1 =
(data.start / this.svg.totalTime) * this.svg.totalWidth + (data.start / this.svg.totalTime) * this.svg.totalWidth +
this.svg.svgPadding; this.svg.svgPadding;
const y1 =
rowIndex * this.svg.rowHeight + (this.svg.rowHeight - height) / 2;
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const width = Math.max(
g.setAttribute('class', 'rect'); this.svg.minWidth,
const gChild = document.createElementNS(this.svg.namespaceURI, 'g'); (data.duration / this.svg.totalTime) * this.svg.totalWidth,
);
let name = ''; let name = '';
switch (data.name) { switch (data.name) {
case 'iteration_interval': case 'iteration_interval':
...@@ -766,102 +834,117 @@ export default { ...@@ -766,102 +834,117 @@ export default {
break; break;
} }
const textContent = `${name}: ${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(textContent);
const normalSize = data.duration >= this.svg.minTime;
const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'rect');
const rect = document.createElementNS(this.svg.namespaceURI, 'rect'); const rect = document.createElementNS(this.svg.namespaceURI, 'rect');
rect.setAttribute('x', x1); rect.setAttribute('x', x1);
rect.setAttribute('y', y1); rect.setAttribute('y', startY);
rect.setAttribute('height', height); rect.setAttribute('height', this.svg.cellHeight);
rect.setAttribute('width', width); rect.setAttribute('width', width);
rect.setAttribute('style', `fill:${color[1]};stroke:${color[1]};`); rect.setAttribute('style', `fill:${color[1]};stroke:${color[0]};`);
const foreignObject = document.createElementNS( const foreignObject = document.createElementNS(
this.svg.namespaceURI, this.svg.namespaceURI,
'foreignObject', 'foreignObject',
); );
foreignObject.textContent = `${name}: ${data.duration.toFixed(4)}ms`; foreignObject.textContent = textContent;
const textWidth = this.getTextWidth(foreignObject.textContent);
foreignObject.setAttribute( foreignObject.setAttribute(
'x', 'x',
!data.textOffsets normalSize
? x1 ? x1
: Math.min( : Math.min(
this.svg.svgPadding * 2 + this.svg.totalWidth - textWidth, this.svg.svgPadding * 2 +
Math.max(0, x1 + width / 2 - textWidth / 2), this.svg.totalWidth -
textWidth -
this.svg.textMargin,
Math.max(this.svg.textMargin, x1 + width / 2 - textWidth / 2),
), ),
); );
foreignObject.setAttribute( foreignObject.setAttribute('y', startY);
'y', foreignObject.setAttribute('height', this.svg.cellHeight);
y1 + (height - fontSize) / 2 + data.textOffsets * fontSize,
);
foreignObject.setAttribute('height', fontSize);
foreignObject.setAttribute('width', width); foreignObject.setAttribute('width', width);
foreignObject.setAttribute('style', `color:${color[0]}`); foreignObject.setAttribute('style', `color:${color[0]}`);
foreignObject.setAttribute( foreignObject.setAttribute(
'class', 'class',
`content${!data.textOffsets ? '' : ' content-mini'}`, `content${normalSize ? '' : ' content-mini'}`,
); );
const title = document.createElementNS(this.svg.namespaceURI, 'title'); const title = document.createElementNS(this.svg.namespaceURI, 'title');
title.textContent = `${name}: ${data.duration.toFixed(4)}ms`; title.textContent = textContent;
gChild.appendChild(rect); g.appendChild(rect);
gChild.appendChild(foreignObject); g.appendChild(foreignObject);
gChild.appendChild(title); g.appendChild(title);
g.appendChild(gChild);
return g; return g;
}, },
createArrow(data, rowIndex) { createArrow(data, startY) {
const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth; const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth;
const x1 = const x1 =
(data.start / this.svg.totalTime) * this.svg.totalWidth + (data.start / this.svg.totalTime) * this.svg.totalWidth +
this.svg.markerPadding +
this.svg.svgPadding; this.svg.svgPadding;
const x2 = x1 + width - this.svg.markerPadding * 2; const centerY = startY + this.svg.cellHeight / 2;
const y = rowIndex * this.svg.rowHeight + this.svg.rowHeight / 2;
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'arrow'); g.setAttribute('class', 'arrow');
const line = document.createElementNS(this.svg.namespaceURI, 'line'); const line = document.createElementNS(this.svg.namespaceURI, 'line');
line.setAttribute('x1', x1); line.setAttribute('y1', centerY);
line.setAttribute('y1', y); line.setAttribute('y2', centerY);
line.setAttribute('x2', x2); line.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
line.setAttribute('y2', y); if (width > this.svg.markerPadding) {
line.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); line.setAttribute('x1', x1 + this.svg.markerPadding);
line.setAttribute('marker-end', 'url(#marker_end)'); line.setAttribute('x2', x1 + width - this.svg.markerPadding);
line.setAttribute('marker-start', 'url(#marker_start)'); line.setAttribute('marker-end', 'url(#marker_end)');
line.setAttribute('marker-start', 'url(#marker_start)');
} else {
line.setAttribute('x1', x1);
line.setAttribute('x2', x1 + width);
}
const text = document.createElementNS(this.svg.namespaceURI, 'text'); const text = document.createElementNS(this.svg.namespaceURI, 'text');
text.textContent = `${ text.textContent = `${
rowIndex === 0 ? this.$t('profiling.approximateTime') : '' data.duration === this.svg.totalTime
? this.$t('profiling.approximateTime')
: ''
}${data.duration.toFixed(4)}ms`; }${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(text.textContent); const textWidth = text.textContent
? this.getTextWidth(text.textContent)
: 0;
text.setAttribute( text.setAttribute(
'x', 'x',
Math.min( Math.min(
this.svg.svgPadding * 2 + this.svg.totalWidth - textWidth, this.svg.svgPadding * 2 +
Math.max(0, (x2 - x1) / 2 + x1 - textWidth / 2), this.svg.totalWidth -
textWidth -
this.svg.textMargin,
Math.max(this.svg.textMargin, width / 2 + x1 - textWidth / 2),
), ),
); );
text.setAttribute('y', y - 6); text.setAttribute('y', centerY - this.svg.fontSize / 2);
text.setAttribute('font-size', 12); text.setAttribute('font-size', this.svg.fontSize);
text.setAttribute('fill', '#6c7280'); text.setAttribute('fill', 'black');
const startLine = document.createElementNS(this.svg.namespaceURI, 'line'); const startLine = document.createElementNS(this.svg.namespaceURI, 'line');
startLine.setAttribute('x1', x1 - this.svg.markerPadding); startLine.setAttribute('x1', x1);
startLine.setAttribute('y1', y - this.svg.rowHeight / 4); startLine.setAttribute('y1', startY);
startLine.setAttribute('x2', x1 - this.svg.markerPadding); startLine.setAttribute('x2', x1);
startLine.setAttribute('y2', y + this.svg.rowHeight / 4); startLine.setAttribute('y2', startY + this.svg.cellHeight);
startLine.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); startLine.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
g.appendChild(startLine); g.appendChild(startLine);
const endLine = document.createElementNS(this.svg.namespaceURI, 'line'); const endLine = document.createElementNS(this.svg.namespaceURI, 'line');
endLine.setAttribute('x1', x1 + width - this.svg.markerPadding); endLine.setAttribute('x1', x1 + width);
endLine.setAttribute('y1', y - this.svg.rowHeight / 4); endLine.setAttribute('y1', startY);
endLine.setAttribute('x2', x1 + width - this.svg.markerPadding); endLine.setAttribute('x2', x1 + width);
endLine.setAttribute('y2', y + this.svg.rowHeight / 4); endLine.setAttribute('y2', startY + this.svg.cellHeight);
endLine.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); endLine.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
g.appendChild(endLine); g.appendChild(endLine);
g.appendChild(line); g.appendChild(line);
g.appendChild(text); g.appendChild(text);
...@@ -1100,7 +1183,7 @@ export default { ...@@ -1100,7 +1183,7 @@ export default {
margin-bottom: 15px; margin-bottom: 15px;
.trace-container { .trace-container {
width: 100%; width: 100%;
height: calc(100% - 50px); height: calc(100% - 54px);
overflow: auto; overflow: auto;
.training-trace { .training-trace {
position: relative; position: relative;
...@@ -1111,7 +1194,7 @@ export default { ...@@ -1111,7 +1194,7 @@ export default {
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
font-size: 12px; font-size: 12px;
line-height: 12px; line-height: 40px;
} }
.content-mini { .content-mini {
overflow: visible; overflow: visible;
......
...@@ -59,10 +59,6 @@ limitations under the License. ...@@ -59,10 +59,6 @@ limitations under the License.
<div id="trace-container"> <div id="trace-container">
<div id="trace" <div id="trace"
class="training-trace"> class="training-trace">
<div :title="$t('graph.downloadPic')"
class="download-button"
@click="downloadSVG">
</div>
<svg version="1.1" <svg version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
height="100%" height="100%"
...@@ -75,8 +71,8 @@ limitations under the License. ...@@ -75,8 +71,8 @@ limitations under the License.
markerHeight="8" markerHeight="8"
orient="auto"> orient="auto">
<path d="M1,1 L1,7 L9,4 z" <path d="M1,1 L1,7 L9,4 z"
fill="#E6EBF5" fill="#6c7280"
stroke="#E6EBF5"></path> stroke="#6c7280"></path>
</marker> </marker>
<marker id="marker_start" <marker id="marker_start"
refX="5" refX="5"
...@@ -85,8 +81,8 @@ limitations under the License. ...@@ -85,8 +81,8 @@ limitations under the License.
markerHeight="8" markerHeight="8"
orient="auto"> orient="auto">
<path d="M9,1 L9,7 L1,4 z" <path d="M9,1 L9,7 L1,4 z"
fill="#E6EBF5" fill="#6c7280"
stroke="#E6EBF5"></path> stroke="#6c7280"></path>
</marker> </marker>
</defs> </defs>
</svg> </svg>
...@@ -162,18 +158,25 @@ export default { ...@@ -162,18 +158,25 @@ export default {
svgPadding: 20, svgPadding: 20,
totalWidth: 0, totalWidth: 0,
totalTime: 0, totalTime: 0,
rowHeight: 60, cellHeight: 40,
cellPadding: 0,
rowPadding: 20,
rowMargin: 10,
totalHeight: 0,
markerPadding: 4, markerPadding: 4,
minRate: 0.01, minRate: 0.1,
minTime: 0,
minWidth: 1,
fontSize: 12,
textMargin: 21,
namespaceURI: 'http://www.w3.org/2000/svg', namespaceURI: 'http://www.w3.org/2000/svg',
resizeTimer: null, resizeTimer: null,
colorList: [ colors: {
['#A6DD82', '#edf8e6'], iteration_interval: ['#A6DD82', '#edf8e6'],
['#6CBFFF', '#e2f2ff'], fp_and_bp: ['#6CBFFF', '#e2f2ff'],
['#fa8e5b', '#fff4de'], tail: ['#fa8e5b', '#fff4de'],
['#01a5a7', '#cceded'], stream_parallel: ['#01a5a7', '#cceded'],
], },
colorIndex: 0,
noData: false, noData: false,
}, },
deviceId: 0, deviceId: 0,
...@@ -438,15 +441,13 @@ export default { ...@@ -438,15 +441,13 @@ export default {
this.fp_start = '--'; this.fp_start = '--';
this.bp_end = '--'; this.bp_end = '--';
} }
document.querySelector('#trace').style.height = `${res.data
.training_trace_graph.length * this.svg.rowHeight}px`;
this.svg.data = JSON.parse(
JSON.stringify(res.data.training_trace_graph),
);
this.removeTrace(); this.removeTrace();
setTimeout(() => { this.$nextTick(() => {
this.dealTraceData(); this.packageTraceData(
}, 100); JSON.parse(JSON.stringify(res.data.training_trace_graph)),
);
});
} else { } else {
this.fp_start = '--'; this.fp_start = '--';
this.bp_end = '--'; this.bp_end = '--';
...@@ -464,48 +465,80 @@ export default { ...@@ -464,48 +465,80 @@ export default {
}, },
); );
}, },
packageTraceData(traceGraph) {
this.svg.totalTime = 0;
this.svg.minTime = 0;
this.svg.totalHeight = 0;
const data = [];
if (traceGraph && traceGraph[0] && traceGraph[0][0]) {
this.svg.totalTime = traceGraph[0][0].duration;
this.svg.minTime = this.svg.minRate * this.svg.totalTime;
traceGraph.forEach((row, index) => {
const rowObj = {
rowCount: 0,
data: [],
height: 0,
startY: this.svg.totalHeight,
};
let obj = [];
for (let i = 0; i < row.length; i++) {
if (row[i].duration < this.svg.minTime) {
if (obj.length) {
rowObj.data.push(obj);
obj = [];
rowObj.rowCount++;
}
rowObj.data.push([row[i]]);
rowObj.rowCount++;
} else {
obj.push(row[i]);
}
if (i === row.length - 1 && obj.length) {
rowObj.data.push(obj);
obj = [];
rowObj.rowCount++;
}
}
rowObj.height =
rowObj.rowCount * this.svg.cellHeight +
(rowObj.rowCount - 1) * this.svg.cellPadding +
(index ? this.svg.rowPadding * 2 : 0);
this.svg.totalHeight += rowObj.height + this.svg.rowMargin;
data.push(rowObj);
});
this.svg.totalHeight += this.svg.rowPadding;
document.querySelector(
'#trace',
).style.height = `${this.svg.totalHeight}px`;
this.svg.data = JSON.parse(JSON.stringify(data));
this.$nextTick(() => {
this.dealTraceData();
});
}
},
dealTraceData() { dealTraceData() {
const traceDom = document.querySelector('#trace'); const traceDom = document.querySelector('#trace');
if (traceDom) { if (traceDom) {
this.svg.totalWidth = traceDom.offsetWidth - this.svg.svgPadding * 2; this.svg.totalWidth = traceDom.offsetWidth - this.svg.svgPadding * 2;
if (this.svg.data[0] && this.svg.data[0].length) { if (this.svg.data[0] && this.svg.data[0].data.length) {
const svg = traceDom.querySelector('svg'); const svg = traceDom.querySelector('svg');
this.svg.totalTime = this.svg.data[0][0].duration;
if (this.svg.totalTime) { if (this.svg.totalTime) {
this.svg.colorIndex = 0; this.svg.data.forEach((item, index) => {
const minTime = this.svg.minRate * this.svg.totalTime; let itemDom = {};
if (index) {
this.svg.data.forEach((row, index) => { itemDom = this.createMultipleRowContainer(item);
if (row && row.length) { } else {
const dashedLine = this.addDashedLine(index); itemDom = this.createRowContainer(item.data, item.startY);
svg.insertBefore(dashedLine, svg.querySelector('g'));
let textOffsets = 0;
row.forEach((i) => {
if (i.duration) {
if (i.name) {
if (i.duration < minTime) {
textOffsets++;
} else {
textOffsets = 0;
}
i.textOffsets = textOffsets;
const tempDom = this.createRect(i, index);
const tempStr = `g${
i.duration > minTime ? '' : '.arrow'
}`;
svg.insertBefore(tempDom, svg.querySelector(tempStr));
} else {
const tempDom = this.createArrow(i, index);
svg.appendChild(tempDom);
}
}
});
} }
svg.appendChild(itemDom);
}); });
} }
} else { } else {
...@@ -513,39 +546,69 @@ export default { ...@@ -513,39 +546,69 @@ export default {
} }
} }
}, },
addDashedLine(index) {
const x1 = this.svg.svgPadding; createMultipleRowContainer(item) {
const x2 = this.svg.svgPadding + this.svg.totalWidth; const rectContainer = document.createElementNS(
const y = index * this.svg.rowHeight; this.svg.namespaceURI,
const line = document.createElementNS(this.svg.namespaceURI, 'line'); 'g',
line.setAttribute('x1', x1); );
line.setAttribute('y1', y); rectContainer.setAttribute('class', 'container');
line.setAttribute('x2', x2);
line.setAttribute('y2', y); const rect = document.createElementNS(this.svg.namespaceURI, 'rect');
line.setAttribute('style', 'stroke:#E2E2E2;stroke-width:1'); rect.setAttribute('x', this.svg.svgPadding);
line.setAttribute('stroke-dasharray', '5 5'); rect.setAttribute('y', item.startY + this.svg.rowPadding);
rect.setAttribute('height', item.height);
rect.setAttribute('width', this.svg.totalWidth);
rect.setAttribute('style', 'fill:#edf0f5;stroke:#E2E2E2;stroke-width:1');
rectContainer.appendChild(rect);
const temp = this.createRowContainer(
item.data,
item.startY + this.svg.rowPadding,
);
rectContainer.appendChild(temp);
return rectContainer;
},
createRowContainer(data, startY) {
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'dashedLine');
g.appendChild(line); data.forEach((row, index) => {
const y =
startY +
this.svg.rowPadding +
index * (this.svg.cellPadding + this.svg.cellHeight);
row.forEach((i) => {
if (i.duration) {
let temp;
if (i.name) {
temp = this.createRect(i, y);
g.insertBefore(temp, g.querySelector('g'));
} else {
temp = this.createArrow(i, y);
g.appendChild(temp);
}
}
});
});
return g; return g;
}, },
createRect(data, rowIndex) {
const color = this.svg.colorList[ createRect(data, startY) {
rowIndex > 1 ? 3 : this.svg.colorIndex++ % 4 const color =
]; data.name && this.svg.colors[data.name]
const height = 40; ? this.svg.colors[data.name]
const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth; : this.svg.colors.stream_parallel;
const fontSize = 12;
const x1 = const x1 =
(data.start / this.svg.totalTime) * this.svg.totalWidth + (data.start / this.svg.totalTime) * this.svg.totalWidth +
this.svg.svgPadding; this.svg.svgPadding;
const y1 =
rowIndex * this.svg.rowHeight + (this.svg.rowHeight - height) / 2;
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const width = Math.max(
g.setAttribute('class', 'rect'); this.svg.minWidth,
const gChild = document.createElementNS(this.svg.namespaceURI, 'g'); (data.duration / this.svg.totalTime) * this.svg.totalWidth,
);
let name = ''; let name = '';
switch (data.name) { switch (data.name) {
case 'iteration_interval': case 'iteration_interval':
...@@ -562,102 +625,117 @@ export default { ...@@ -562,102 +625,117 @@ export default {
break; break;
} }
const textContent = `${name}: ${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(textContent);
const normalSize = data.duration >= this.svg.minTime;
const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'rect');
const rect = document.createElementNS(this.svg.namespaceURI, 'rect'); const rect = document.createElementNS(this.svg.namespaceURI, 'rect');
rect.setAttribute('x', x1); rect.setAttribute('x', x1);
rect.setAttribute('y', y1); rect.setAttribute('y', startY);
rect.setAttribute('height', height); rect.setAttribute('height', this.svg.cellHeight);
rect.setAttribute('width', width); rect.setAttribute('width', width);
rect.setAttribute('style', `fill:${color[1]};stroke:${color[1]};`); rect.setAttribute('style', `fill:${color[1]};stroke:${color[0]};`);
const foreignObject = document.createElementNS( const foreignObject = document.createElementNS(
this.svg.namespaceURI, this.svg.namespaceURI,
'foreignObject', 'foreignObject',
); );
foreignObject.textContent = `${name}: ${data.duration.toFixed(4)}ms`; foreignObject.textContent = textContent;
const textWidth = this.getTextWidth(foreignObject.textContent);
foreignObject.setAttribute( foreignObject.setAttribute(
'x', 'x',
!data.textOffsets normalSize
? x1 ? x1
: Math.min( : Math.min(
this.svg.svgPadding * 2 + this.svg.totalWidth - textWidth, this.svg.svgPadding * 2 +
Math.max(0, x1 + width / 2 - textWidth / 2), this.svg.totalWidth -
textWidth -
this.svg.textMargin,
Math.max(this.svg.textMargin, x1 + width / 2 - textWidth / 2),
), ),
); );
foreignObject.setAttribute( foreignObject.setAttribute('y', startY);
'y', foreignObject.setAttribute('height', this.svg.cellHeight);
y1 + (height - fontSize) / 2 + data.textOffsets * fontSize,
);
foreignObject.setAttribute('height', fontSize);
foreignObject.setAttribute('width', width); foreignObject.setAttribute('width', width);
foreignObject.setAttribute('style', `color:${color[0]}`); foreignObject.setAttribute('style', `color:${color[0]}`);
foreignObject.setAttribute( foreignObject.setAttribute(
'class', 'class',
`content${!data.textOffsets ? '' : ' content-mini'}`, `content${normalSize ? '' : ' content-mini'}`,
); );
const title = document.createElementNS(this.svg.namespaceURI, 'title'); const title = document.createElementNS(this.svg.namespaceURI, 'title');
title.textContent = `${name}: ${data.duration.toFixed(4)}ms`; title.textContent = textContent;
gChild.appendChild(rect); g.appendChild(rect);
gChild.appendChild(foreignObject); g.appendChild(foreignObject);
gChild.appendChild(title); g.appendChild(title);
g.appendChild(gChild);
return g; return g;
}, },
createArrow(data, rowIndex) { createArrow(data, startY) {
const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth; const width = (data.duration / this.svg.totalTime) * this.svg.totalWidth;
const x1 = const x1 =
(data.start / this.svg.totalTime) * this.svg.totalWidth + (data.start / this.svg.totalTime) * this.svg.totalWidth +
this.svg.markerPadding +
this.svg.svgPadding; this.svg.svgPadding;
const x2 = x1 + width - this.svg.markerPadding * 2; const centerY = startY + this.svg.cellHeight / 2;
const y = rowIndex * this.svg.rowHeight + this.svg.rowHeight / 2;
const g = document.createElementNS(this.svg.namespaceURI, 'g'); const g = document.createElementNS(this.svg.namespaceURI, 'g');
g.setAttribute('class', 'arrow'); g.setAttribute('class', 'arrow');
const line = document.createElementNS(this.svg.namespaceURI, 'line'); const line = document.createElementNS(this.svg.namespaceURI, 'line');
line.setAttribute('x1', x1); line.setAttribute('y1', centerY);
line.setAttribute('y1', y); line.setAttribute('y2', centerY);
line.setAttribute('x2', x2); line.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
line.setAttribute('y2', y); if (width > this.svg.markerPadding) {
line.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); line.setAttribute('x1', x1 + this.svg.markerPadding);
line.setAttribute('marker-end', 'url(#marker_end)'); line.setAttribute('x2', x1 + width - this.svg.markerPadding);
line.setAttribute('marker-start', 'url(#marker_start)'); line.setAttribute('marker-end', 'url(#marker_end)');
line.setAttribute('marker-start', 'url(#marker_start)');
} else {
line.setAttribute('x1', x1);
line.setAttribute('x2', x1 + width);
}
const text = document.createElementNS(this.svg.namespaceURI, 'text'); const text = document.createElementNS(this.svg.namespaceURI, 'text');
text.textContent = `${ text.textContent = `${
rowIndex === 0 ? this.$t('profiling.approximateTime') : '' data.duration === this.svg.totalTime
? this.$t('profiling.approximateTime')
: ''
}${data.duration.toFixed(4)}ms`; }${data.duration.toFixed(4)}ms`;
const textWidth = this.getTextWidth(text.textContent); const textWidth = text.textContent
? this.getTextWidth(text.textContent)
: 0;
text.setAttribute( text.setAttribute(
'x', 'x',
Math.min( Math.min(
this.svg.svgPadding * 2 + this.svg.totalWidth - textWidth, this.svg.svgPadding * 2 +
Math.max(0, (x2 - x1) / 2 + x1 - textWidth / 2), this.svg.totalWidth -
textWidth -
this.svg.textMargin,
Math.max(this.svg.textMargin, width / 2 + x1 - textWidth / 2),
), ),
); );
text.setAttribute('y', y - 6); text.setAttribute('y', centerY - this.svg.fontSize / 2);
text.setAttribute('font-size', 12); text.setAttribute('font-size', this.svg.fontSize);
text.setAttribute('fill', '#6c7280'); text.setAttribute('fill', 'black');
const startLine = document.createElementNS(this.svg.namespaceURI, 'line'); const startLine = document.createElementNS(this.svg.namespaceURI, 'line');
startLine.setAttribute('x1', x1 - this.svg.markerPadding); startLine.setAttribute('x1', x1);
startLine.setAttribute('y1', y - this.svg.rowHeight / 4); startLine.setAttribute('y1', startY);
startLine.setAttribute('x2', x1 - this.svg.markerPadding); startLine.setAttribute('x2', x1);
startLine.setAttribute('y2', y + this.svg.rowHeight / 4); startLine.setAttribute('y2', startY + this.svg.cellHeight);
startLine.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); startLine.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
g.appendChild(startLine); g.appendChild(startLine);
const endLine = document.createElementNS(this.svg.namespaceURI, 'line'); const endLine = document.createElementNS(this.svg.namespaceURI, 'line');
endLine.setAttribute('x1', x1 + width - this.svg.markerPadding); endLine.setAttribute('x1', x1 + width);
endLine.setAttribute('y1', y - this.svg.rowHeight / 4); endLine.setAttribute('y1', startY);
endLine.setAttribute('x2', x1 + width - this.svg.markerPadding); endLine.setAttribute('x2', x1 + width);
endLine.setAttribute('y2', y + this.svg.rowHeight / 4); endLine.setAttribute('y2', startY + this.svg.cellHeight);
endLine.setAttribute('style', 'stroke:#E6EBF5;stroke-width:1'); endLine.setAttribute('style', 'stroke:#6c7280;stroke-width:1');
g.appendChild(endLine); g.appendChild(endLine);
g.appendChild(line); g.appendChild(line);
g.appendChild(text); g.appendChild(text);
...@@ -696,15 +774,6 @@ export default { ...@@ -696,15 +774,6 @@ export default {
this.svg.resizeTimer = null; this.svg.resizeTimer = null;
}, 500); }, 500);
}, },
downloadSVG() {
const svgDom = document.querySelector('svg').outerHTML;
const src = `data:image/svg+xml;base64,
${window.btoa(unescape(encodeURIComponent(svgDom)))}`;
const a = document.createElement('a');
a.href = src;
a.download = new Date().valueOf();
a.click();
},
}, },
destroyed() { destroyed() {
window.removeEventListener('resize', this.resizeTrace, false); window.removeEventListener('resize', this.resizeTrace, false);
...@@ -782,23 +851,13 @@ export default { ...@@ -782,23 +851,13 @@ export default {
.training-trace { .training-trace {
position: relative; position: relative;
height: 0; height: 0;
.download-button {
display: none;
position: absolute;
width: 12px;
height: 12px;
right: 10px;
top: 10px;
cursor: pointer;
background-image: url('../../assets/images/download.png');
}
.content { .content {
overflow: hidden; overflow: hidden;
text-align: center; text-align: center;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
font-size: 12px; font-size: 12px;
line-height: 12px; line-height: 40px;
} }
.content-mini { .content-mini {
overflow: visible; overflow: visible;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册