feat(性能测试): 测试报告支持自定义图表,多坐标轴

This commit is contained in:
Captain.B 2021-06-08 17:50:49 +08:00 committed by 刘瑞斌
parent ec77cd42ff
commit b469bc5365
4 changed files with 93 additions and 46 deletions

View File

@ -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) {

View File

@ -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',

View File

@ -650,10 +650,10 @@ export default {
ActiveThreadsChart: '用户数', ActiveThreadsChart: '用户数',
TransactionsChart: '请求/事务数', TransactionsChart: '请求/事务数',
ErrorsChart: '错误', ErrorsChart: '错误',
ResponseTimeChart: '响应时间', ResponseTimeChart: '响应',
ResponseTimePercentilesChart: '响应时间百分比', ResponseTimePercentilesChart: '响应百分比',
ResponseCodeChart: '响应码', ResponseCodeChart: '响应码',
LatencyChart: '延迟时间', LatencyChart: '延迟',
BytesThroughputChart: '字节数', BytesThroughputChart: '字节数',
Network: '网络', Network: '网络',
}, },

View File

@ -650,10 +650,10 @@ export default {
ActiveThreadsChart: '用戶數', ActiveThreadsChart: '用戶數',
TransactionsChart: '請求/事務數', TransactionsChart: '請求/事務數',
ErrorsChart: '錯誤', ErrorsChart: '錯誤',
ResponseTimeChart: '響應時間', ResponseTimeChart: '響應',
ResponseTimePercentilesChart: '響應時間百分比', ResponseTimePercentilesChart: '響應百分比',
ResponseCodeChart: '響應碼', ResponseCodeChart: '響應碼',
LatencyChart: '延遲時間', LatencyChart: '延遲',
BytesThroughputChart: '字節數', BytesThroughputChart: '字節數',
Network: '網絡', Network: '網絡',
}, },