feat(性能测试): 测试报告支持自定义图表,多坐标轴
This commit is contained in:
parent
ec77cd42ff
commit
b469bc5365
|
@ -121,11 +121,18 @@ import MsChart from "@/business/components/common/chart/MsChart";
|
||||||
|
|
||||||
const color = ['#60acfc', '#32d3eb', '#5bc49f', '#feb64d', '#ff7c7c', '#9287e7', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
|
const color = ['#60acfc', '#32d3eb', '#5bc49f', '#feb64d', '#ff7c7c', '#9287e7', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
|
||||||
|
|
||||||
|
const groupBy = function (xs, key) {
|
||||||
|
return xs.reduce(function (rv, x) {
|
||||||
|
(rv[x[key]] = rv[x[key]] || []).push(x);
|
||||||
|
return rv;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
const CHART_MAP = [
|
const CHART_MAP = [
|
||||||
'ActiveThreadsChart',
|
'ActiveThreadsChart',
|
||||||
'TransactionsChart',
|
'TransactionsChart',
|
||||||
'ResponseTimePercentilesChart',
|
|
||||||
'ResponseTimeChart',
|
'ResponseTimeChart',
|
||||||
|
'ResponseTimePercentilesChart',
|
||||||
'ResponseCodeChart',
|
'ResponseCodeChart',
|
||||||
'ErrorsChart',
|
'ErrorsChart',
|
||||||
'LatencyChart',
|
'LatencyChart',
|
||||||
|
@ -156,6 +163,9 @@ export default {
|
||||||
init: false,
|
init: false,
|
||||||
baseOption: {
|
baseOption: {
|
||||||
color: color,
|
color: color,
|
||||||
|
grid: {
|
||||||
|
// right: '35%' // 动态改这个值
|
||||||
|
},
|
||||||
title: {
|
title: {
|
||||||
text: 'Test Details',
|
text: 'Test Details',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
@ -167,7 +177,9 @@ export default {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
show: true,
|
show: true,
|
||||||
trigger: 'axis',
|
trigger: 'axis',
|
||||||
// extraCssText: 'z-index: 999;',
|
axisPointer: {
|
||||||
|
type: 'cross'
|
||||||
|
},
|
||||||
confine: true,
|
confine: true,
|
||||||
formatter: function (params, ticket, callback) {
|
formatter: function (params, ticket, callback) {
|
||||||
let result = "";
|
let result = "";
|
||||||
|
@ -188,23 +200,33 @@ export default {
|
||||||
},
|
},
|
||||||
legend: {},
|
legend: {},
|
||||||
xAxis: {},
|
xAxis: {},
|
||||||
|
yAxis: [],
|
||||||
series: []
|
series: []
|
||||||
},
|
},
|
||||||
chartData: [],
|
seriesData: [],
|
||||||
|
legend: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
resetDefault() {
|
resetDefault() {
|
||||||
this.chartData = [];
|
this.seriesData = [];
|
||||||
|
|
||||||
this.checkList['ActiveThreadsChart'] = ['ALL'];
|
this.checkList['ActiveThreadsChart'] = ['ALL'];
|
||||||
this.checkList['TransactionsChart'] = ['ALL'];
|
this.checkList['TransactionsChart'] = ['ALL'];
|
||||||
this.checkList['ResponseTimeChart'] = ['ALL'];
|
this.checkList['ResponseTimeChart'] = ['ALL'];
|
||||||
|
//
|
||||||
|
// this.checkList['ResponseTimePercentilesChart'] = ['ALL'];
|
||||||
|
// this.checkList['ErrorsChart'] = ['ALL'];
|
||||||
|
// this.checkList['LatencyChart'] = ['ALL'];
|
||||||
|
// this.checkList['BytesThroughputChart'] = ['ALL'];
|
||||||
|
|
||||||
this.getTotalChart();
|
this.getTotalChart();
|
||||||
},
|
},
|
||||||
unselectAll() {
|
unselectAll() {
|
||||||
this.chartData = [];
|
this.seriesData = [];
|
||||||
this.totalOption = {};
|
this.totalOption = {};
|
||||||
|
this.baseOption.yAxis = [];
|
||||||
|
this.legend = [];
|
||||||
for (const name in this.checkList) {
|
for (const name in this.checkList) {
|
||||||
this.checkList[name] = [];
|
this.checkList[name] = [];
|
||||||
}
|
}
|
||||||
|
@ -245,11 +267,11 @@ export default {
|
||||||
},
|
},
|
||||||
getTotalChart() {
|
getTotalChart() {
|
||||||
this.totalOption = {};
|
this.totalOption = {};
|
||||||
this.chartData = [];
|
this.seriesData = [];
|
||||||
|
this.baseOption.yAxis = [];
|
||||||
|
this.legend = [];
|
||||||
for (let name in this.checkList) {
|
for (let name in this.checkList) {
|
||||||
if (this.checkList[name].length > 0) {
|
this.getChart(name, this.checkList[name]);
|
||||||
this.getChart(name, this.checkList[name]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getChart(reportKey, checkList) {
|
getChart(reportKey, checkList) {
|
||||||
|
@ -259,57 +281,81 @@ export default {
|
||||||
this.$get("/performance/report/content/" + reportKey + "/" + this.id)
|
this.$get("/performance/report/content/" + reportKey + "/" + this.id)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
let data = res.data.data;
|
let data = res.data.data;
|
||||||
if (checkList) {
|
let allData = [];
|
||||||
data = data.filter(item => {
|
let checkAllOption = checkList.indexOf('ALL') > -1;
|
||||||
if (checkList.indexOf('ALL') > -1) {
|
if (checkAllOption) {
|
||||||
return true;
|
let result = groupBy(data, 'xAxis');
|
||||||
}
|
for (const xAxis in result) {
|
||||||
if (checkList.indexOf(item.groupName) > -1) {
|
let yAxis = result[xAxis].map(a => a.yAxis).reduce((a, b) => a + b, 0) / result[xAxis].length;
|
||||||
return true;
|
allData.push({
|
||||||
}
|
groupName: 'ALL',
|
||||||
});
|
xAxis: xAxis,
|
||||||
|
yAxis: yAxis
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
data = data.filter(item => {
|
||||||
|
if (checkList.indexOf(item.groupName) > -1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 选中了all
|
||||||
|
data = data.concat(allData);
|
||||||
|
|
||||||
|
|
||||||
// prefix
|
// prefix
|
||||||
data.forEach(item => {
|
data.forEach(item => {
|
||||||
item.groupName = this.$t('load_test.report.' + reportKey) + ': ' + item.groupName;
|
item.groupName = this.$t('load_test.report.' + reportKey) + ': ' + item.groupName;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chartData = this.chartData.concat(data);
|
let yAxisList = data.map(m => m.yAxis);
|
||||||
|
|
||||||
let yAxisList = data.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
|
|
||||||
let yAxisListMax = this._getChartMax(yAxisList);
|
let yAxisListMax = this._getChartMax(yAxisList);
|
||||||
|
if (this.baseOption.yAxis.length === 0) {
|
||||||
this.baseOption.yAxis = [
|
this.baseOption.yAxis.push({
|
||||||
{
|
name: this.$t('load_test.report.' + reportKey),
|
||||||
name: 'Value',
|
|
||||||
type: 'value',
|
type: 'value',
|
||||||
min: 0,
|
min: 0,
|
||||||
}
|
max: yAxisListMax,
|
||||||
];
|
position: 'left',
|
||||||
|
});
|
||||||
this.totalOption = this.generateOption(this.baseOption, this.chartData);
|
} else {
|
||||||
|
this.baseOption.yAxis.push({
|
||||||
|
name: this.$t('load_test.report.' + reportKey),
|
||||||
|
type: 'value',
|
||||||
|
min: 0,
|
||||||
|
max: yAxisListMax,
|
||||||
|
position: 'right',
|
||||||
|
nameRotate: 20,
|
||||||
|
offset: (this.baseOption.yAxis.length - 1) * 50,
|
||||||
|
});
|
||||||
|
this.baseOption.grid.right = (this.baseOption.yAxis.length - 1) * 5 + '%';
|
||||||
|
}
|
||||||
|
let yAxisIndex = this.baseOption.yAxis.length - 1;
|
||||||
|
this.totalOption = this.generateOption(this.baseOption, data, yAxisIndex);
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
this.totalOption = {};
|
this.totalOption = {};
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
generateOption(option, data) {
|
generateOption(option, data, yAxisIndex) {
|
||||||
let chartData = data;
|
let chartData = data;
|
||||||
let legend = [], series = {}, xAxis = [], seriesData = [];
|
let series = {}, xAxis = [];
|
||||||
chartData.forEach(item => {
|
chartData.forEach(item => {
|
||||||
if (!xAxis.includes(item.xAxis)) {
|
if (!xAxis.includes(item.xAxis)) {
|
||||||
xAxis.push(item.xAxis);
|
xAxis.push(item.xAxis);
|
||||||
}
|
}
|
||||||
xAxis.sort();
|
xAxis.sort();
|
||||||
let name = item.groupName;
|
let name = item.groupName;
|
||||||
if (!legend.includes(name)) {
|
if (!this.legend.includes(name)) {
|
||||||
legend.push(name);
|
this.legend.push(name);
|
||||||
series[name] = [];
|
series[name] = [];
|
||||||
}
|
}
|
||||||
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis.toFixed(2)]);
|
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis.toFixed(2)]);
|
||||||
});
|
});
|
||||||
this.$set(option.legend, "data", legend);
|
this.$set(option.legend, "data", this.legend);
|
||||||
this.$set(option.legend, "type", "scroll");
|
this.$set(option.legend, "type", "scroll");
|
||||||
this.$set(option.legend, "bottom", "10px");
|
this.$set(option.legend, "bottom", "10px");
|
||||||
this.$set(option.xAxis, "data", xAxis);
|
this.$set(option.xAxis, "data", xAxis);
|
||||||
|
@ -320,13 +366,14 @@ export default {
|
||||||
name: name,
|
name: name,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: d,
|
data: d,
|
||||||
|
yAxisIndex: yAxisIndex,
|
||||||
smooth: true,
|
smooth: true,
|
||||||
sampling: 'lttb',
|
sampling: 'lttb',
|
||||||
animation: !this.export,
|
animation: !this.export,
|
||||||
};
|
};
|
||||||
seriesData.push(items);
|
this.seriesData.push(items);
|
||||||
}
|
}
|
||||||
this.$set(option, "series", seriesData);
|
this.$set(option, "series", this.seriesData);
|
||||||
return option;
|
return option;
|
||||||
},
|
},
|
||||||
_getChartMax(arr) {
|
_getChartMax(arr) {
|
||||||
|
|
|
@ -650,10 +650,10 @@ export default {
|
||||||
set_default: 'Set to Default',
|
set_default: 'Set to Default',
|
||||||
unselect_all: 'Unselect All',
|
unselect_all: 'Unselect All',
|
||||||
ActiveThreadsChart: 'Users',
|
ActiveThreadsChart: 'Users',
|
||||||
TransactionsChart: 'Requests/Transactions',
|
TransactionsChart: 'Req/Trans',
|
||||||
ErrorsChart: 'Error',
|
ErrorsChart: 'Error',
|
||||||
ResponseTimeChart: 'Response Time',
|
ResponseTimeChart: 'Response',
|
||||||
ResponseTimePercentilesChart: 'Response time percentage',
|
ResponseTimePercentilesChart: 'Response percentage',
|
||||||
ResponseCodeChart: 'Response Code',
|
ResponseCodeChart: 'Response Code',
|
||||||
LatencyChart: 'Latency',
|
LatencyChart: 'Latency',
|
||||||
BytesThroughputChart: 'Bytes',
|
BytesThroughputChart: 'Bytes',
|
||||||
|
|
|
@ -650,10 +650,10 @@ export default {
|
||||||
ActiveThreadsChart: '用户数',
|
ActiveThreadsChart: '用户数',
|
||||||
TransactionsChart: '请求/事务数',
|
TransactionsChart: '请求/事务数',
|
||||||
ErrorsChart: '错误',
|
ErrorsChart: '错误',
|
||||||
ResponseTimeChart: '响应时间',
|
ResponseTimeChart: '响应',
|
||||||
ResponseTimePercentilesChart: '响应时间百分比',
|
ResponseTimePercentilesChart: '响应百分比',
|
||||||
ResponseCodeChart: '响应码',
|
ResponseCodeChart: '响应码',
|
||||||
LatencyChart: '延迟时间',
|
LatencyChart: '延迟',
|
||||||
BytesThroughputChart: '字节数',
|
BytesThroughputChart: '字节数',
|
||||||
Network: '网络',
|
Network: '网络',
|
||||||
},
|
},
|
||||||
|
|
|
@ -650,10 +650,10 @@ export default {
|
||||||
ActiveThreadsChart: '用戶數',
|
ActiveThreadsChart: '用戶數',
|
||||||
TransactionsChart: '請求/事務數',
|
TransactionsChart: '請求/事務數',
|
||||||
ErrorsChart: '錯誤',
|
ErrorsChart: '錯誤',
|
||||||
ResponseTimeChart: '響應時間',
|
ResponseTimeChart: '響應',
|
||||||
ResponseTimePercentilesChart: '響應時間百分比',
|
ResponseTimePercentilesChart: '響應百分比',
|
||||||
ResponseCodeChart: '響應碼',
|
ResponseCodeChart: '響應碼',
|
||||||
LatencyChart: '延遲時間',
|
LatencyChart: '延遲',
|
||||||
BytesThroughputChart: '字節數',
|
BytesThroughputChart: '字節數',
|
||||||
Network: '網絡',
|
Network: '網絡',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue