fix(测试跟踪): 修复测试计划报告导出时性能测试报告详情不显示的问题
--bug=1024105 --user=宋天阳 【测试跟踪】测试计划导出的报告-性能测试用例没有数据 https://www.tapd.cn/55049933/s/1350582
This commit is contained in:
parent
a295a39ecb
commit
2c1fe4c70b
|
@ -531,7 +531,7 @@ public class TestPlanLoadCaseService {
|
|||
}
|
||||
|
||||
public void buildLoadResponse(List<TestPlanLoadCaseDTO> cases) {
|
||||
if (!org.apache.commons.collections.CollectionUtils.isEmpty(cases)) {
|
||||
if (!CollectionUtils.isEmpty(cases)) {
|
||||
cases.forEach(item -> {
|
||||
LoadCaseReportRequest request = new LoadCaseReportRequest();
|
||||
String reportId = item.getLoadReportId();
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package io.metersphere.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class LoadTestExportJmx {
|
||||
private String name;
|
||||
private String jmx;
|
||||
|
||||
public LoadTestExportJmx(String name, String jmx) {
|
||||
this.name = name;
|
||||
this.jmx = jmx;
|
||||
}
|
||||
}
|
|
@ -2,14 +2,15 @@ package io.metersphere.dto;
|
|||
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanLoadCaseWithBLOBs;
|
||||
|
||||
import io.metersphere.plan.dto.ChartsData;
|
||||
import io.metersphere.plan.dto.Errors;
|
||||
import io.metersphere.plan.dto.ErrorsTop5;
|
||||
import io.metersphere.plan.dto.Statistics;
|
||||
import io.opentelemetry.sdk.metrics.data.MetricData;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import javax.management.monitor.Monitor;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -34,8 +35,7 @@ public class TestPlanLoadCaseDTO extends TestPlanLoadCaseWithBLOBs {
|
|||
private long startTime;
|
||||
private long endTime;
|
||||
private String fixLoadConfiguration;
|
||||
// private LoadTestExportJmx jmxContent;
|
||||
// private List<LoadTestExportJmx> fixJmxContent;
|
||||
private List<LoadTestExportJmx> fixJmxContent;
|
||||
private TestOverview testOverview;
|
||||
private List<ChartsData> loadChartData;
|
||||
private List<ChartsData> responseTimeChartData;
|
||||
|
@ -46,8 +46,8 @@ public class TestPlanLoadCaseDTO extends TestPlanLoadCaseWithBLOBs {
|
|||
private List<Errors> reportErrors;
|
||||
private List<ErrorsTop5> reportErrorsTop5;
|
||||
private List<LogDetailDTO> reportLogResource;
|
||||
// private List<Monitor> reportResource;
|
||||
// private List<MetricData> metricData;
|
||||
private List<Monitor> reportResource;
|
||||
private List<MetricData> metricData;
|
||||
private List<TestResourcePoolDTO> resourcePools;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,41 +1,101 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-row >
|
||||
<el-col :span="12">
|
||||
<ms-doughnut-pie-chart :name="$t('test_track.plan.test_plan_test_case_count')" :data="caseCharData" ref="functionChar"/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<ms-doughnut-pie-chart :name="$t('test_track.plan_view.issues_count')" :data="issueCharData"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<ms-doughnut-pie-chart
|
||||
:name="$t('test_track.plan.test_plan_test_case_count')"
|
||||
:data="caseCharData"
|
||||
ref="functionChar"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<ms-doughnut-pie-chart
|
||||
:name="$t('test_track.plan_view.issues_count')"
|
||||
:data="issueCharData"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsDoughnutPieChart from "metersphere-frontend/src/components/MsDoughnutPieChart";
|
||||
export default {
|
||||
name: "FunctionalResult",
|
||||
components: {MsDoughnutPieChart},
|
||||
components: { MsDoughnutPieChart },
|
||||
data() {
|
||||
return {
|
||||
caseDataMap: new Map([
|
||||
["Pass", {name: this.$t('test_track.plan_view.pass'), itemStyle: {color: '#67C23A'}}],
|
||||
["Failure", {name: this.$t('test_track.plan_view.failure'), itemStyle: {color: '#F56C6C'}}],
|
||||
["Blocking", {name: this.$t('test_track.plan_view.blocking'), itemStyle: {color: '#E6A23C'}}],
|
||||
["Skip", {name: this.$t('test_track.plan_view.skip'), itemStyle: {color: '#909399'}}],
|
||||
["Underway", {name: this.$t('test_track.plan.plan_status_running'), itemStyle: {color: 'lightskyblue'}}],
|
||||
["Prepare", {name: this.$t('test_track.plan.plan_status_prepare'), itemStyle: {color: '#DEDE10'}}]
|
||||
[
|
||||
"Pass",
|
||||
{
|
||||
name: this.$t("test_track.plan_view.pass"),
|
||||
itemStyle: { color: "#67C23A" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"Failure",
|
||||
{
|
||||
name: this.$t("test_track.plan_view.failure"),
|
||||
itemStyle: { color: "#F56C6C" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"Blocking",
|
||||
{
|
||||
name: this.$t("test_track.plan_view.blocking"),
|
||||
itemStyle: { color: "#E6A23C" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"Skip",
|
||||
{
|
||||
name: this.$t("test_track.plan_view.skip"),
|
||||
itemStyle: { color: "#909399" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"Underway",
|
||||
{
|
||||
name: this.$t("test_track.plan.plan_status_running"),
|
||||
itemStyle: { color: "lightskyblue" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"Prepare",
|
||||
{
|
||||
name: this.$t("test_track.plan.plan_status_prepare"),
|
||||
itemStyle: { color: "#DEDE10" },
|
||||
},
|
||||
],
|
||||
]),
|
||||
issueDataMap: new Map([
|
||||
["resolved", {name: this.$t('test_track.issue.status_resolved'), itemStyle: {color: '#67C23A'}}],
|
||||
["new", {name: this.$t('test_track.issue.status_new'), itemStyle: {color: '#F56C6C'}}],
|
||||
["closed", {name: this.$t('test_track.issue.status_closed'), itemStyle: {color: '#909399'}}],
|
||||
[
|
||||
"resolved",
|
||||
{
|
||||
name: this.$t("test_track.issue.status_resolved"),
|
||||
itemStyle: { color: "#67C23A" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"new",
|
||||
{
|
||||
name: this.$t("test_track.issue.status_new"),
|
||||
itemStyle: { color: "#F56C6C" },
|
||||
},
|
||||
],
|
||||
[
|
||||
"closed",
|
||||
{
|
||||
name: this.$t("test_track.issue.status_closed"),
|
||||
itemStyle: { color: "#909399" },
|
||||
},
|
||||
],
|
||||
]),
|
||||
caseCharData: [],
|
||||
issueCharData: [],
|
||||
isShow: true
|
||||
}
|
||||
isShow: true,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
functionResult: {
|
||||
|
@ -43,15 +103,15 @@ export default {
|
|||
default() {
|
||||
return {
|
||||
caseData: [],
|
||||
issueData: []
|
||||
}
|
||||
}
|
||||
}
|
||||
issueData: [],
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
functionResult() {
|
||||
this.getCaseCharData();
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.getCaseCharData();
|
||||
|
@ -59,7 +119,7 @@ export default {
|
|||
methods: {
|
||||
getCaseCharData() {
|
||||
let caseCharData = [];
|
||||
this.functionResult.caseData.forEach(item => {
|
||||
this.functionResult.caseData.forEach((item) => {
|
||||
let data = this.caseDataMap.get(item.status);
|
||||
data.value = item.count;
|
||||
caseCharData.push(data);
|
||||
|
@ -67,46 +127,51 @@ export default {
|
|||
this.caseCharData = caseCharData;
|
||||
|
||||
let issueCharData = [];
|
||||
let colors = ['#67C23A', '#E6A23C','#DEDE10',
|
||||
'#F56C6C','#909399'];
|
||||
let colors = ["#67C23A", "#E6A23C", "#DEDE10", "#F56C6C", "#909399"];
|
||||
let usedSet = new Set();
|
||||
|
||||
this.functionResult.issueData.forEach(item => {
|
||||
let status = item.status;
|
||||
let data = this.issueDataMap.get(status);
|
||||
if (!data) {
|
||||
data = {name: status, itemStyle: {color: null}};
|
||||
if (status === 'new' || status === '新' || status === '待办' || status === 'active' || status === 'created') {
|
||||
data.itemStyle.color = '#F56C6C';
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (status === '已拒绝' || status === 'reject') {
|
||||
data.itemStyle.color = '#909399';
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (status === '已关闭' || status === 'close') {
|
||||
data.itemStyle.color = '#67C23A';
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (!data.itemStyle.color) {
|
||||
for (let i = 0; i < colors.length; i++) {
|
||||
let color = colors[i];
|
||||
if (!usedSet.has(color)) {
|
||||
data.itemStyle.color = color;
|
||||
usedSet.add(data.itemStyle.color);
|
||||
break;
|
||||
if (this.functionResult.issueData) {
|
||||
this.functionResult.issueData.forEach((item) => {
|
||||
let status = item.status;
|
||||
let data = this.issueDataMap.get(status);
|
||||
if (!data) {
|
||||
data = { name: status, itemStyle: { color: null } };
|
||||
if (
|
||||
status === "new" ||
|
||||
status === "新" ||
|
||||
status === "待办" ||
|
||||
status === "active" ||
|
||||
status === "created"
|
||||
) {
|
||||
data.itemStyle.color = "#F56C6C";
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (status === "已拒绝" || status === "reject") {
|
||||
data.itemStyle.color = "#909399";
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (status === "已关闭" || status === "close") {
|
||||
data.itemStyle.color = "#67C23A";
|
||||
usedSet.add(data.itemStyle.color);
|
||||
}
|
||||
if (!data.itemStyle.color) {
|
||||
for (let i = 0; i < colors.length; i++) {
|
||||
let color = colors[i];
|
||||
if (!usedSet.has(color)) {
|
||||
data.itemStyle.color = color;
|
||||
usedSet.add(data.itemStyle.color);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
data.value = item.count;
|
||||
issueCharData.push(data);
|
||||
});
|
||||
data.value = item.count;
|
||||
issueCharData.push(data);
|
||||
});
|
||||
}
|
||||
this.issueCharData = issueCharData;
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -6,30 +6,30 @@
|
|||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
:default-sort="{prop: 'elementLabel'}"
|
||||
:default-sort="{ prop: 'elementLabel' }"
|
||||
>
|
||||
<el-table-column
|
||||
prop="errorType"
|
||||
label="Type of error"
|
||||
sortable>
|
||||
<el-table-column prop="errorType" label="Type of error" sortable>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
width="200"
|
||||
prop="errorNumber"
|
||||
label="Number of errors"
|
||||
sortable>
|
||||
sortable
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
width="200"
|
||||
prop="percentOfErrors"
|
||||
label="% in errors"
|
||||
sortable>
|
||||
sortable
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
width="200"
|
||||
prop="percentOfAllSamples"
|
||||
label="% in all samples"
|
||||
sortable>
|
||||
sortable
|
||||
>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
|
@ -41,75 +41,49 @@
|
|||
style="width: 100%"
|
||||
show-summary
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="samples" label="#Samples"/>
|
||||
<el-table-column prop="errorsAllSize" label="All Errors"/>
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="samples" label="#Samples" />
|
||||
<el-table-column prop="errorsAllSize" label="All Errors" />
|
||||
</el-table>
|
||||
|
||||
<span class="table-title">#1 Error</span>
|
||||
<el-table
|
||||
:data="errorTop1"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="error1" label="#1 Error"/>
|
||||
<el-table-column prop="error1Size" label="#1 Errors Count" width="200"/>
|
||||
<el-table :data="errorTop1" border stripe style="width: 100%">
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="error1" label="#1 Error" />
|
||||
<el-table-column prop="error1Size" label="#1 Errors Count" width="200" />
|
||||
</el-table>
|
||||
|
||||
<span class="table-title">#2 Error</span>
|
||||
<el-table
|
||||
:data="errorTop2"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="error2" label="#2 Error"/>
|
||||
<el-table-column prop="error2Size" label="#2 Errors Count" width="200"/>
|
||||
<el-table :data="errorTop2" border stripe style="width: 100%">
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="error2" label="#2 Error" />
|
||||
<el-table-column prop="error2Size" label="#2 Errors Count" width="200" />
|
||||
</el-table>
|
||||
|
||||
<span class="table-title">#3 Error</span>
|
||||
<el-table
|
||||
:data="errorTop3"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="error3" label="#3 Error"/>
|
||||
<el-table-column prop="error3Size" label="#3 Errors Count" width="200"/>
|
||||
<el-table :data="errorTop3" border stripe style="width: 100%">
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="error3" label="#3 Error" />
|
||||
<el-table-column prop="error3Size" label="#3 Errors Count" width="200" />
|
||||
</el-table>
|
||||
|
||||
<span class="table-title">#4 Error</span>
|
||||
<el-table
|
||||
:data="errorTop4"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="error4" label="#4 Error"/>
|
||||
<el-table-column prop="error4Size" label="#4 Errors Count" width="200"/>
|
||||
<el-table :data="errorTop4" border stripe style="width: 100%">
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="error4" label="#4 Error" />
|
||||
<el-table-column prop="error4Size" label="#4 Errors Count" width="200" />
|
||||
</el-table>
|
||||
|
||||
<span class="table-title">#5 Error</span>
|
||||
<el-table
|
||||
:data="errorTop5"
|
||||
border
|
||||
stripe
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column prop="sample" label="Sample"/>
|
||||
<el-table-column prop="error5" label="#5 Error"/>
|
||||
<el-table-column prop="error5Size" label="#5 Errors Count" width="200"/>
|
||||
<el-table :data="errorTop5" border stripe style="width: 100%">
|
||||
<el-table-column prop="sample" label="Sample" />
|
||||
<el-table-column prop="error5" label="#5 Error" />
|
||||
<el-table-column prop="error5Size" label="#5 Errors Count" width="200" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "ErrorLog",
|
||||
data() {
|
||||
|
@ -121,10 +95,13 @@ export default {
|
|||
errorTop3: [],
|
||||
errorTop4: [],
|
||||
errorTop5: [],
|
||||
id: ''
|
||||
id: "",
|
||||
};
|
||||
},
|
||||
props: ['report', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
props: ["report", "isShare", "shareId", "planReportTemplate"],
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
methods: {
|
||||
initTableData() {
|
||||
if (this.planReportTemplate) {
|
||||
|
@ -137,37 +114,61 @@ export default {
|
|||
return;
|
||||
}
|
||||
this.errorTop1 = data
|
||||
.map(e => {
|
||||
return {sample: e.sample, error1: e.error1, error1Size: e.error1Size};
|
||||
.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
error1: e.error1,
|
||||
error1Size: e.error1Size,
|
||||
};
|
||||
})
|
||||
.filter(e => e.error1Size > 0);
|
||||
.filter((e) => e.error1Size > 0);
|
||||
|
||||
this.errorTop2 = data
|
||||
.map(e => {
|
||||
return {sample: e.sample, error2: e.error2, error2Size: e.error2Size};
|
||||
.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
error2: e.error2,
|
||||
error2Size: e.error2Size,
|
||||
};
|
||||
})
|
||||
.filter(e => e.error2Size > 0);
|
||||
.filter((e) => e.error2Size > 0);
|
||||
|
||||
this.errorTop3 = data
|
||||
.map(e => {
|
||||
return {sample: e.sample, error3: e.error3, error3Size: e.error3Size};
|
||||
.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
error3: e.error3,
|
||||
error3Size: e.error3Size,
|
||||
};
|
||||
})
|
||||
.filter(e => e.error3Size > 0);
|
||||
.filter((e) => e.error3Size > 0);
|
||||
|
||||
this.errorTop4 = data
|
||||
.map(e => {
|
||||
return {sample: e.sample, error4: e.error4, error4Size: e.error4Size};
|
||||
.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
error4: e.error4,
|
||||
error4Size: e.error4Size,
|
||||
};
|
||||
})
|
||||
.filter(e => e.error4Size > 0);
|
||||
.filter((e) => e.error4Size > 0);
|
||||
|
||||
this.errorTop5 = data
|
||||
.map(e => {
|
||||
return {sample: e.sample, error5: e.error5, error5Size: e.error5Size};
|
||||
.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
error5: e.error5,
|
||||
error5Size: e.error5Size,
|
||||
};
|
||||
})
|
||||
.filter(e => e.error5Size > 0);
|
||||
.filter((e) => e.error5Size > 0);
|
||||
|
||||
this.errorSummary = data.map(e => {
|
||||
return {sample: e.sample, samples: e.samples, errorsAllSize: e.errorsAllSize};
|
||||
this.errorSummary = data.map((e) => {
|
||||
return {
|
||||
sample: e.sample,
|
||||
samples: e.samples,
|
||||
errorsAllSize: e.errorsAllSize,
|
||||
};
|
||||
});
|
||||
},
|
||||
initData() {
|
||||
|
@ -178,7 +179,7 @@ export default {
|
|||
this.errorTop4 = [];
|
||||
this.errorTop5 = [];
|
||||
this.errorSummary = [];
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
report: {
|
||||
|
@ -200,7 +201,7 @@ export default {
|
|||
this.errorSummary = [];
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -208,8 +209,8 @@ export default {
|
|||
this.initTableData();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -2,21 +2,30 @@
|
|||
<div>
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="4">
|
||||
<el-select v-model="currentInstance" placeholder="" size="small" style="width: 100%"
|
||||
@change="changeInstance(currentInstance)">
|
||||
<el-select
|
||||
v-model="currentInstance"
|
||||
placeholder=""
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
@change="changeInstance(currentInstance)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in resource"
|
||||
:key="item.resourceId"
|
||||
:label="item.resourceName"
|
||||
:value="item.resourceId">
|
||||
:value="item.resourceId"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<div class="logging-content" v-loading="loading">
|
||||
<ul class="infinite-list">
|
||||
<li class="infinite-list-item" v-for="(log, index) in logContent"
|
||||
:key="currentInstance+index">
|
||||
<li
|
||||
class="infinite-list-item"
|
||||
v-for="(log, index) in logContent"
|
||||
:key="currentInstance + index"
|
||||
>
|
||||
{{ log.content }}
|
||||
</li>
|
||||
</ul>
|
||||
|
@ -27,7 +36,6 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "LogDetails",
|
||||
data() {
|
||||
|
@ -35,14 +43,17 @@ export default {
|
|||
resource: [],
|
||||
logContent: [],
|
||||
result: {},
|
||||
id: '',
|
||||
id: "",
|
||||
page: 1,
|
||||
pageCount: 5,
|
||||
loading: false,
|
||||
currentInstance: ''
|
||||
currentInstance: "",
|
||||
};
|
||||
},
|
||||
props: ['report', 'export', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
props: ["report", "export", "isShare", "shareId", "planReportTemplate"],
|
||||
created() {
|
||||
this.getResource();
|
||||
},
|
||||
methods: {
|
||||
getResource() {
|
||||
if (this.planReportTemplate) {
|
||||
|
@ -66,9 +77,9 @@ export default {
|
|||
}
|
||||
this.loading = true;
|
||||
if (this.planReportTemplate) {
|
||||
let {reportLogResource} = this.planReportTemplate;
|
||||
let { reportLogResource } = this.planReportTemplate;
|
||||
if (reportLogResource && reportLogResource.length > 0) {
|
||||
let {reportLogs} = reportLogResource[0];
|
||||
let { reportLogs } = reportLogResource[0];
|
||||
if (reportLogs) {
|
||||
this.handleGetPlanTemplateLog(reportLogs);
|
||||
}
|
||||
|
@ -76,7 +87,7 @@ export default {
|
|||
}
|
||||
},
|
||||
handleGetPlanTemplateLog(data) {
|
||||
data.forEach(log => {
|
||||
data.forEach((log) => {
|
||||
if (this.logContent) {
|
||||
this.logContent.push(log);
|
||||
}
|
||||
|
@ -92,9 +103,9 @@ export default {
|
|||
},
|
||||
},
|
||||
watch: {
|
||||
'$route'(to) {
|
||||
$route(to) {
|
||||
if (to.name === "perReportView") {
|
||||
this.id = to.path.split('/')[4];
|
||||
this.id = to.path.split("/")[4];
|
||||
this.getResource();
|
||||
}
|
||||
},
|
||||
|
@ -109,7 +120,7 @@ export default {
|
|||
this.getResource();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -117,8 +128,8 @@ export default {
|
|||
this.getResource();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -134,11 +145,10 @@ export default {
|
|||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
overflow: auto
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.infinite-list-item {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -3,24 +3,30 @@
|
|||
<el-row>
|
||||
<el-col :span="4">
|
||||
<div>
|
||||
<el-select v-model="currentInstance" placeholder="" size="small" style="width: 100%"
|
||||
@change="getResource(currentInstance)">
|
||||
<el-select
|
||||
v-model="currentInstance"
|
||||
placeholder=""
|
||||
size="small"
|
||||
style="width: 100%"
|
||||
@change="getResource(currentInstance)"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in instances"
|
||||
:key="item.ip+item.port"
|
||||
:value="item.ip+':'+item.port">
|
||||
:key="item.ip + item.port"
|
||||
:value="item.ip + ':' + item.port"
|
||||
>
|
||||
{{ item.ip }} {{ item.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 10px">
|
||||
<el-checkbox-group v-model="checkList"
|
||||
@change="handleCheckListChange(currentInstance)">
|
||||
<div v-for="op in checkOptions"
|
||||
:key="op.key"
|
||||
:content="op.label">
|
||||
<el-checkbox :label="op.label"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList"
|
||||
@change="handleCheckListChange(currentInstance)"
|
||||
>
|
||||
<div v-for="op in checkOptions" :key="op.key" :content="op.label">
|
||||
<el-checkbox :label="op.label" />
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
@ -28,56 +34,31 @@
|
|||
<el-col :span="20">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<ms-chart v-if="showChart" ref="chart2" class="chart-config" @datazoom="changeDataZoom"
|
||||
:options="totalOption"
|
||||
:autoresize="true"></ms-chart>
|
||||
<ms-chart
|
||||
v-if="showChart"
|
||||
ref="chart2"
|
||||
class="chart-config"
|
||||
@datazoom="changeDataZoom"
|
||||
:options="totalOption"
|
||||
:autoresize="true"
|
||||
></ms-chart>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :offset="2" :span="20">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table :data="tableData" stripe border style="width: 100%">
|
||||
<el-table-column label="Label" align="center">
|
||||
<el-table-column
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
<el-table-column prop="label" label="Label" sortable>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="Aggregate" align="center">
|
||||
<el-table-column
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column prop="avg" label="Avg." width="100" sortable />
|
||||
<el-table-column prop="min" label="Min." width="100" sortable />
|
||||
<el-table-column prop="max" label="Max." width="100" sortable />
|
||||
</el-table-column>
|
||||
<el-table-column label="Range" align="center">
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column prop="startTime" label="Start" width="160" />
|
||||
<el-table-column prop="endTime" label="End" width="160" />
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
|
@ -88,31 +69,42 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
|
||||
const color = ['#60acfc', '#32d3eb', '#5bc49f', '#feb64d', '#ff7c7c', '#9287e7', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
|
||||
const checkList = ['CPU', 'Memory', 'Disk', 'Network In', 'Network Out'];
|
||||
const color = [
|
||||
"#60acfc",
|
||||
"#32d3eb",
|
||||
"#5bc49f",
|
||||
"#feb64d",
|
||||
"#ff7c7c",
|
||||
"#9287e7",
|
||||
"#ca8622",
|
||||
"#bda29a",
|
||||
"#6e7074",
|
||||
"#546570",
|
||||
"#c4ccd3",
|
||||
];
|
||||
const checkList = ["CPU", "Memory", "Disk", "Network In", "Network Out"];
|
||||
const checkOptions = [
|
||||
{key: 'cpu', label: 'CPU'},
|
||||
{key: 'memory', label: 'Memory'},
|
||||
{key: 'disk', label: 'Disk'},
|
||||
{key: 'netIn', label: 'Network In'},
|
||||
{key: 'netOut', label: 'Network Out'}
|
||||
{ key: "cpu", label: "CPU" },
|
||||
{ key: "memory", label: "Memory" },
|
||||
{ key: "disk", label: "Disk" },
|
||||
{ key: "netIn", label: "Network In" },
|
||||
{ key: "netOut", label: "Network Out" },
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "MonitorCard",
|
||||
props: ['report', 'export', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
components: {MsChart},
|
||||
props: ["report", "export", "isShare", "shareId", "planReportTemplate"],
|
||||
components: { MsChart },
|
||||
data() {
|
||||
return {
|
||||
activeNames: '0',
|
||||
activeNames: "0",
|
||||
result: {},
|
||||
id: '',
|
||||
id: "",
|
||||
init: false,
|
||||
loading: false,
|
||||
currentInstance: '',
|
||||
currentInstance: "",
|
||||
instances: [],
|
||||
data: [],
|
||||
tableData: [],
|
||||
|
@ -126,37 +118,40 @@ export default {
|
|||
},
|
||||
title: {},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
type: "cross",
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
y: 'top'
|
||||
y: "top",
|
||||
},
|
||||
xAxis: {type: 'category'},
|
||||
yAxis: [{
|
||||
name: 'Usage(%)',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: 100,
|
||||
}, {
|
||||
type: 'value',
|
||||
name: 'kb/s',
|
||||
min: 0,
|
||||
}],
|
||||
xAxis: { type: "category" },
|
||||
yAxis: [
|
||||
{
|
||||
name: "Usage(%)",
|
||||
type: "value",
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
{
|
||||
type: "value",
|
||||
name: "kb/s",
|
||||
min: 0,
|
||||
},
|
||||
],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 20
|
||||
}
|
||||
end: 20,
|
||||
},
|
||||
],
|
||||
series: []
|
||||
series: [],
|
||||
},
|
||||
totalOption: {},
|
||||
seriesData: [],
|
||||
|
@ -165,25 +160,35 @@ export default {
|
|||
created() {
|
||||
this.data = [];
|
||||
this.instances = [];
|
||||
this.getResource();
|
||||
},
|
||||
methods: {
|
||||
getResource(currentInstance) {
|
||||
// this.init = true;
|
||||
if (this.planReportTemplate) {
|
||||
this.instances = this.planReportTemplate.reportResource;
|
||||
this.currentInstance = currentInstance || this.instances[0]?.ip + ":" + this.instances[0]?.port;
|
||||
this.data = this.planReportTemplate.metricData;
|
||||
this.totalOption = this.getOption(this.currentInstance);
|
||||
if (this.instances) {
|
||||
this.currentInstance =
|
||||
currentInstance ||
|
||||
this.instances[0]?.ip + ":" + this.instances[0]?.port;
|
||||
}
|
||||
if (this.planReportTemplate.metricData) {
|
||||
this.data = this.planReportTemplate.metricData;
|
||||
this.totalOption = this.getOption(this.currentInstance);
|
||||
}
|
||||
}
|
||||
},
|
||||
handleChecked(id) {
|
||||
let curr = this.instances.filter(instance => id === instance.ip + ":" + instance.port)[0];
|
||||
let curr = this.instances.filter(
|
||||
(instance) => id === instance.ip + ":" + instance.port
|
||||
)[0];
|
||||
if (curr && curr.monitorConfig) {
|
||||
this.checkList = [];
|
||||
this.checkOptions = curr.monitorConfig.filter(mc => mc.value && mc.name)
|
||||
.map(mc => {
|
||||
this.checkOptions = curr.monitorConfig
|
||||
.filter((mc) => mc.value && mc.name)
|
||||
.map((mc) => {
|
||||
this.checkList.push(mc.name);
|
||||
return {key: mc.name, label: mc.name,};
|
||||
return { key: mc.name, label: mc.name };
|
||||
});
|
||||
if (this.checkList.length === 0) {
|
||||
this.checkList = checkList;
|
||||
|
@ -196,7 +201,7 @@ export default {
|
|||
this.totalOption = {};
|
||||
this.$nextTick(() => {
|
||||
this.totalOption = this.getOption(id);
|
||||
this.changeDataZoom({start: 0, end: 100});
|
||||
this.changeDataZoom({ start: 0, end: 100 });
|
||||
});
|
||||
},
|
||||
handleCheckListChange(id) {
|
||||
|
@ -205,7 +210,7 @@ export default {
|
|||
this.$nextTick(() => {
|
||||
this.showChart = true;
|
||||
this.totalOption = this.getOption(id);
|
||||
this.changeDataZoom({start: 0, end: 100});
|
||||
this.changeDataZoom({ start: 0, end: 100 });
|
||||
});
|
||||
},
|
||||
getOption(id) {
|
||||
|
@ -213,12 +218,12 @@ export default {
|
|||
let series = [];
|
||||
|
||||
for (const name of this.checkList) {
|
||||
let check = this.checkOptions.filter(op => op.label === name)[0].key;
|
||||
let check = this.checkOptions.filter((op) => op.label === name)[0].key;
|
||||
let yAxisIndex = 1;
|
||||
if (check === 'cpu' || check === 'memory' || check === 'disk') {
|
||||
if (check === "cpu" || check === "memory" || check === "disk") {
|
||||
yAxisIndex = 0;
|
||||
}
|
||||
this.data.forEach(d => {
|
||||
this.data.forEach((d) => {
|
||||
if (d.instance === id && d.seriesName === check) {
|
||||
if (legend.indexOf(name) > -1) {
|
||||
return;
|
||||
|
@ -226,7 +231,7 @@ export default {
|
|||
|
||||
this.baseOption.xAxis.data = d.timestamps;
|
||||
|
||||
let yAxis = d.values.map(v => v.toFixed(2));
|
||||
let yAxis = d.values.map((v) => v.toFixed(2));
|
||||
let data = [];
|
||||
for (let i = 0; i < d.timestamps.length; i++) {
|
||||
data.push([d.timestamps[i], yAxis[i]]);
|
||||
|
@ -236,10 +241,10 @@ export default {
|
|||
series.push({
|
||||
name: name,
|
||||
data: data,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
yAxisIndex: yAxisIndex,
|
||||
smooth: true,
|
||||
sampling: 'lttb',
|
||||
sampling: "lttb",
|
||||
showSymbol: false,
|
||||
});
|
||||
|
||||
|
@ -261,9 +266,15 @@ export default {
|
|||
|
||||
let tableData = [];
|
||||
for (let i = 0; i < this.seriesData.length; i++) {
|
||||
let sub = this.seriesData[i].data, label = this.seriesData[i].name;
|
||||
let sub = this.seriesData[i].data,
|
||||
label = this.seriesData[i].name;
|
||||
let len = 0;
|
||||
let min, avg, max, sum = 0, startTime, endTime;
|
||||
let min,
|
||||
avg,
|
||||
max,
|
||||
sum = 0,
|
||||
startTime,
|
||||
endTime;
|
||||
for (let j = 0; j < sub.length; j++) {
|
||||
let time = sub[j][0];
|
||||
let value = Number.parseFloat(sub[j][1]);
|
||||
|
@ -296,7 +307,7 @@ export default {
|
|||
}
|
||||
|
||||
avg = (sum / len).toFixed(2);
|
||||
tableData.push({label, min, max, avg, startTime, endTime});
|
||||
tableData.push({ label, min, max, avg, startTime, endTime });
|
||||
}
|
||||
this.tableData = tableData;
|
||||
},
|
||||
|
@ -318,7 +329,7 @@ export default {
|
|||
this.instances = [];
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -326,8 +337,8 @@ export default {
|
|||
this.getResource();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -342,7 +353,7 @@ export default {
|
|||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.el-checkbox__label ) {
|
||||
:deep(.el-checkbox__label) {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -8,35 +8,31 @@
|
|||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="Requests" min-width="150" align="center">
|
||||
<el-table-column
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable
|
||||
min-width="150">
|
||||
<template v-slot:header="{column}">
|
||||
<el-table-column prop="label" label="Label" sortable min-width="150">
|
||||
<template v-slot:header="{ column }">
|
||||
<span>Label</span>
|
||||
<i class="el-icon-search" style="margin-left: 8px;cursor: pointer;font-weight: bold;"
|
||||
@click="click(column)"></i>
|
||||
<el-input v-model="searchLabel"
|
||||
placeholder="请输入 Label 搜索"
|
||||
size="mini"
|
||||
class="search_input"
|
||||
style="width: 100px; margin-left: 5px"
|
||||
v-if="column.showSearch"
|
||||
clearable
|
||||
@clear="filterLabel"
|
||||
@keyup.enter.native="filterLabel"/>
|
||||
<i
|
||||
class="el-icon-search"
|
||||
style="margin-left: 8px; cursor: pointer; font-weight: bold"
|
||||
@click="click(column)"
|
||||
></i>
|
||||
<el-input
|
||||
v-model="searchLabel"
|
||||
placeholder="请输入 Label 搜索"
|
||||
size="mini"
|
||||
class="search_input"
|
||||
style="width: 100px; margin-left: 5px"
|
||||
v-if="column.showSearch"
|
||||
clearable
|
||||
@clear="filterLabel"
|
||||
@keyup.enter.native="filterLabel"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="Executions" align="center">
|
||||
<el-table-column
|
||||
prop="samples"
|
||||
label="Samples"
|
||||
sortable
|
||||
width="110"
|
||||
/>
|
||||
<el-table-column prop="samples" label="Samples" sortable width="110" />
|
||||
|
||||
<el-table-column
|
||||
prop="fail"
|
||||
|
@ -46,57 +42,17 @@
|
|||
min-width="60"
|
||||
/>
|
||||
|
||||
<el-table-column
|
||||
prop="error"
|
||||
label="Error%"
|
||||
sortable
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column prop="error" label="Error%" sortable align="center" />
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="Response Times(ms)" align="center">
|
||||
<el-table-column
|
||||
prop="average"
|
||||
label="Avg"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="Min"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="Max"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="median"
|
||||
label="Med"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tp90"
|
||||
label="90%"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tp95"
|
||||
label="95%"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="tp99"
|
||||
label="99%"
|
||||
sortable
|
||||
min-width="60"
|
||||
/>
|
||||
<el-table-column prop="average" label="Avg" sortable min-width="60" />
|
||||
<el-table-column prop="min" label="Min" sortable min-width="60" />
|
||||
<el-table-column prop="max" label="Max" sortable min-width="60" />
|
||||
<el-table-column prop="median" label="Med" sortable min-width="60" />
|
||||
<el-table-column prop="tp90" label="90%" sortable min-width="60" />
|
||||
<el-table-column prop="tp95" label="95%" sortable min-width="60" />
|
||||
<el-table-column prop="tp99" label="99%" sortable min-width="60" />
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="Throughput">
|
||||
|
@ -124,7 +80,6 @@
|
|||
width="100"
|
||||
/>
|
||||
</el-table-column>
|
||||
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -136,13 +91,16 @@ export default {
|
|||
return {
|
||||
tableData: [],
|
||||
originalData: [],
|
||||
id: '',
|
||||
searchLabel: '',
|
||||
id: "",
|
||||
searchLabel: "",
|
||||
showSearch: false,
|
||||
showBtn: true,
|
||||
}
|
||||
};
|
||||
},
|
||||
props: ["report", "isShare", "shareId", "planReportTemplate"],
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
props: ['report', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
methods: {
|
||||
initTableData() {
|
||||
if (this.planReportTemplate) {
|
||||
|
@ -152,16 +110,20 @@ export default {
|
|||
}
|
||||
},
|
||||
click(column) {
|
||||
this.searchLabel = '';
|
||||
this.searchLabel = "";
|
||||
this.tableData = this.originalData;
|
||||
this.$set(column, 'showSearch', !column.showSearch);
|
||||
this.$set(column, "showSearch", !column.showSearch);
|
||||
},
|
||||
filterLabel() {
|
||||
this.tableData = this.searchLabel ? this.originalData.filter(this.createFilter(this.searchLabel)) : this.originalData;
|
||||
this.tableData = this.searchLabel
|
||||
? this.originalData.filter(this.createFilter(this.searchLabel))
|
||||
: this.originalData;
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return item => {
|
||||
return (item.label.toLowerCase().indexOf(queryString.toLowerCase()) !== -1);
|
||||
return (item) => {
|
||||
return (
|
||||
item.label.toLowerCase().indexOf(queryString.toLowerCase()) !== -1
|
||||
);
|
||||
};
|
||||
},
|
||||
},
|
||||
|
@ -179,7 +141,7 @@ export default {
|
|||
this.tableData = [];
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -187,14 +149,14 @@ export default {
|
|||
this.initTableData();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
}
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search_input :deep( .el-input__inner ) {
|
||||
.search_input :deep(.el-input__inner) {
|
||||
border-radius: 50px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
<template>
|
||||
<el-tabs v-model="active">
|
||||
<el-tab-pane :label="$t('load_test.pressure_config')">
|
||||
<performance-pressure-config :is-read-only="true" :test="test" :report="report" :report-id="reportId"
|
||||
:is-share="isShare" :share-id="shareId" @fileChange="fileChange"/>
|
||||
<performance-pressure-config
|
||||
:is-read-only="true"
|
||||
:test="test"
|
||||
:report="defaultReport"
|
||||
:report-id="reportId"
|
||||
:is-share="isShare"
|
||||
:share-id="shareId"
|
||||
@fileChange="fileChange"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('load_test.advanced_config')">
|
||||
<performance-advanced-config :is-read-only="true" :report-id="reportId" :report="report" :is-share="isShare"
|
||||
:share-id="shareId" ref="advancedConfig"/>
|
||||
<performance-advanced-config
|
||||
:is-read-only="true"
|
||||
:report-id="reportId"
|
||||
:report="defaultReport"
|
||||
:is-share="isShare"
|
||||
:share-id="shareId"
|
||||
ref="advancedConfig"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
|
@ -17,11 +30,12 @@ import PerformanceAdvancedConfig from "../../../load/PerformanceAdvancedConfig";
|
|||
|
||||
export default {
|
||||
name: "TestConfiguration",
|
||||
components: {PerformancePressureConfig, PerformanceAdvancedConfig},
|
||||
components: { PerformancePressureConfig, PerformanceAdvancedConfig },
|
||||
data() {
|
||||
return {
|
||||
active: '0'
|
||||
}
|
||||
active: "0",
|
||||
defaultReport: {},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
test: Object,
|
||||
|
@ -30,26 +44,33 @@ export default {
|
|||
report: Object,
|
||||
isShare: Boolean,
|
||||
shareId: String,
|
||||
planReportTemplate: Object,
|
||||
},
|
||||
created() {
|
||||
if (this.planReportTemplate) {
|
||||
this.defaultReport = this.planReportTemplate;
|
||||
} else {
|
||||
this.defaultReport = this.report;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fileChange(threadGroups) {
|
||||
let csvSet = new Set;
|
||||
threadGroups.forEach(tg => {
|
||||
let csvSet = new Set();
|
||||
threadGroups.forEach((tg) => {
|
||||
if (tg.csvFiles) {
|
||||
tg.csvFiles.map(item => csvSet.add(item));
|
||||
tg.csvFiles.map((item) => csvSet.add(item));
|
||||
}
|
||||
});
|
||||
let csvFiles = [];
|
||||
for (const f of csvSet) {
|
||||
csvFiles.push({name: f, csvSplit: false, csvHasHeader: true});
|
||||
csvFiles.push({ name: f, csvSplit: false, csvHasHeader: true });
|
||||
}
|
||||
if (this.$refs.advancedConfig) {
|
||||
this.$refs.advancedConfig.csvFiles = csvFiles;
|
||||
}
|
||||
|
||||
this.$refs.advancedConfig.csvFiles = csvFiles;
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
|
|
@ -2,33 +2,49 @@
|
|||
<div>
|
||||
<el-row>
|
||||
<el-col :span="6">
|
||||
<div style="padding-bottom: 5px;">
|
||||
<el-link type="primary" @click="resetDefault()">{{ $t('load_test.report.set_default') }}</el-link>
|
||||
<div style="padding-bottom: 5px">
|
||||
<el-link type="primary" @click="resetDefault()">{{
|
||||
$t("load_test.report.set_default")
|
||||
}}</el-link>
|
||||
</div>
|
||||
<el-collapse v-model="activeNames" class="test-detail">
|
||||
<el-collapse-item name="users">
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.ActiveThreadsChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'ActiveThreadsChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.ActiveThreadsChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('ActiveThreadsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('ActiveThreadsChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('ActiveThreadsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['ActiveThreadsChart']"
|
||||
@change="handleChecked('ActiveThreadsChart')">
|
||||
<div v-for="name in checkOptions['ActiveThreadsChart']" :key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['ActiveThreadsChart']"
|
||||
@change="handleChecked('ActiveThreadsChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['ActiveThreadsChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
|
@ -36,27 +52,40 @@
|
|||
<el-collapse-item name="transactions">
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.TransactionsChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'TransactionsChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.TransactionsChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('TransactionsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('TransactionsChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('TransactionsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['TransactionsChart']" @change="handleChecked('TransactionsChart')">
|
||||
<div v-for="name in checkOptions['TransactionsChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['TransactionsChart']"
|
||||
@change="handleChecked('TransactionsChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['TransactionsChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
|
@ -64,26 +93,40 @@
|
|||
<el-collapse-item name="responseTime">
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.ResponseTimeChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'ResponseTimeChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.ResponseTimeChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('ResponseTimeChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('ResponseTimeChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('ResponseTimeChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['ResponseTimeChart']" @change="handleChecked('ResponseTimeChart')">
|
||||
<div v-for="name in checkOptions['ResponseTimeChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['ResponseTimeChart']"
|
||||
@change="handleChecked('ResponseTimeChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['ResponseTimeChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
|
@ -91,136 +134,212 @@
|
|||
<el-collapse-item name="responseTimePercentiles">
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.ResponseTimePercentilesChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'ResponseTimePercentilesChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{
|
||||
$t("load_test.report.ResponseTimePercentilesChart")
|
||||
}}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('ResponseTimePercentilesChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('ResponseTimePercentilesChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('ResponseTimePercentilesChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['ResponseTimePercentilesChart']"
|
||||
@change="handleChecked('ResponseTimePercentilesChart')">
|
||||
<div v-for="name in checkOptions['ResponseTimePercentilesChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['ResponseTimePercentilesChart']"
|
||||
@change="handleChecked('ResponseTimePercentilesChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['ResponseTimePercentilesChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('load_test.report.ResponseCodeChart')" name="responseCode">
|
||||
<el-collapse-item
|
||||
:title="$t('load_test.report.ResponseCodeChart')"
|
||||
name="responseCode"
|
||||
>
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.ResponseCodeChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'ResponseCodeChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.ResponseCodeChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('ResponseCodeChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('ResponseCodeChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('ResponseCodeChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['ResponseCodeChart']" @change="handleChecked('ResponseCodeChart')">
|
||||
<div v-for="name in checkOptions['ResponseCodeChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['ResponseCodeChart']"
|
||||
@change="handleChecked('ResponseCodeChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['ResponseCodeChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('load_test.report.LatencyChart')" name="latency">
|
||||
<el-collapse-item
|
||||
:title="$t('load_test.report.LatencyChart')"
|
||||
name="latency"
|
||||
>
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.LatencyChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'LatencyChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.LatencyChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('LatencyChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('LatencyChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('LatencyChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['LatencyChart']" @change="handleChecked('LatencyChart')">
|
||||
<div v-for="name in checkOptions['LatencyChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['LatencyChart']"
|
||||
@change="handleChecked('LatencyChart')"
|
||||
>
|
||||
<div v-for="name in checkOptions['LatencyChart']" :key="name">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('load_test.report.BytesThroughputChart')" name="bytes">
|
||||
<el-collapse-item
|
||||
:title="$t('load_test.report.BytesThroughputChart')"
|
||||
name="bytes"
|
||||
>
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.BytesThroughputChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'BytesThroughputChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.BytesThroughputChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('BytesThroughputChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('BytesThroughputChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('BytesThroughputChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['BytesThroughputChart']"
|
||||
@change="handleChecked('BytesThroughputChart')">
|
||||
<div v-for="name in checkOptions['BytesThroughputChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['BytesThroughputChart']"
|
||||
@change="handleChecked('BytesThroughputChart')"
|
||||
>
|
||||
<div
|
||||
v-for="name in checkOptions['BytesThroughputChart']"
|
||||
:key="name"
|
||||
>
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="$t('load_test.report.ErrorsChart')" name="errors">
|
||||
<el-collapse-item
|
||||
:title="$t('load_test.report.ErrorsChart')"
|
||||
name="errors"
|
||||
>
|
||||
<template v-slot:title>
|
||||
<div style="width: 100%">
|
||||
<span>{{ $t('load_test.report.ErrorsChart') }}</span>
|
||||
<span style="float:right;">
|
||||
<el-link type="primary" @click="selectAll( 'ErrorsChart', $event)">
|
||||
{{ $t('load_test.report.select_all') }}
|
||||
<span>{{ $t("load_test.report.ErrorsChart") }}</span>
|
||||
<span style="float: right">
|
||||
<el-link
|
||||
type="primary"
|
||||
@click="selectAll('ErrorsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.select_all") }}
|
||||
</el-link>
|
||||
/
|
||||
<el-link type="default" @click="unselectAll('ErrorsChart', $event)">
|
||||
{{ $t('load_test.report.unselect_all') }}
|
||||
<el-link
|
||||
type="default"
|
||||
@click="unselectAll('ErrorsChart', $event)"
|
||||
>
|
||||
{{ $t("load_test.report.unselect_all") }}
|
||||
</el-link>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-checkbox-group v-model="checkList['ErrorsChart']" @change="handleChecked('ErrorsChart')">
|
||||
<div v-for="name in checkOptions['ErrorsChart']"
|
||||
:key="name">
|
||||
<el-tooltip class="item" effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top">
|
||||
<el-checkbox :label="name"/>
|
||||
<el-checkbox-group
|
||||
v-model="checkList['ErrorsChart']"
|
||||
@change="handleChecked('ErrorsChart')"
|
||||
>
|
||||
<div v-for="name in checkOptions['ErrorsChart']" :key="name">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="name"
|
||||
:disabled="name.length < minLength"
|
||||
placement="top"
|
||||
>
|
||||
<el-checkbox :label="name" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-checkbox-group>
|
||||
|
@ -230,12 +349,14 @@
|
|||
<el-col :span="18" v-loading="result.loading">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<ms-chart ref="chart2"
|
||||
v-if="refresh"
|
||||
class="chart-config"
|
||||
:options="totalOption"
|
||||
@datazoom="changeDataZoom"
|
||||
:autoresize="true"/>
|
||||
<ms-chart
|
||||
ref="chart2"
|
||||
v-if="refresh"
|
||||
class="chart-config"
|
||||
:options="totalOption"
|
||||
@datazoom="changeDataZoom"
|
||||
:autoresize="true"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
|
@ -245,45 +366,20 @@
|
|||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column label="Label" align="center">
|
||||
<el-table-column
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
<el-table-column prop="label" label="Label" sortable>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="Aggregate" align="center">
|
||||
<el-table-column
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column prop="avg" label="Avg." width="100" sortable />
|
||||
<el-table-column prop="min" label="Min." width="100" sortable />
|
||||
<el-table-column prop="max" label="Max." width="100" sortable />
|
||||
</el-table-column>
|
||||
<el-table-column label="Range" align="center">
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column prop="startTime" label="Start" width="160" />
|
||||
<el-table-column prop="endTime" label="End" width="160" />
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-col>
|
||||
|
@ -296,7 +392,19 @@
|
|||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/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) {
|
||||
|
@ -306,24 +414,24 @@ const groupBy = function (xs, key) {
|
|||
};
|
||||
|
||||
const CHART_MAP = [
|
||||
'ActiveThreadsChart',
|
||||
'TransactionsChart',
|
||||
'ResponseTimeChart',
|
||||
'ResponseTimePercentilesChart',
|
||||
'ResponseCodeChart',
|
||||
'ErrorsChart',
|
||||
'LatencyChart',
|
||||
'BytesThroughputChart',
|
||||
"ActiveThreadsChart",
|
||||
"TransactionsChart",
|
||||
"ResponseTimeChart",
|
||||
"ResponseTimePercentilesChart",
|
||||
"ResponseCodeChart",
|
||||
"ErrorsChart",
|
||||
"LatencyChart",
|
||||
"BytesThroughputChart",
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "TestDetails",
|
||||
components: {MsChart},
|
||||
props: ['report', 'export', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
components: { MsChart },
|
||||
props: ["report", "export", "isShare", "shareId", "planReportTemplate"],
|
||||
data() {
|
||||
return {
|
||||
result: {},
|
||||
activeNames: 'users',
|
||||
activeNames: "users",
|
||||
minLength: 35,
|
||||
loadOption: {},
|
||||
resOption: {},
|
||||
|
@ -335,8 +443,8 @@ export default {
|
|||
}, {}),
|
||||
checkOptions: {},
|
||||
defaultProps: {
|
||||
children: 'children',
|
||||
label: 'label'
|
||||
children: "children",
|
||||
label: "label",
|
||||
},
|
||||
init: false,
|
||||
refresh: true,
|
||||
|
@ -349,9 +457,9 @@ export default {
|
|||
title: {},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
axisPointer: {
|
||||
type: 'cross'
|
||||
type: "cross",
|
||||
},
|
||||
confine: true,
|
||||
formatter: function (params, ticket, callback) {
|
||||
|
@ -369,41 +477,43 @@ export default {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
y: 'top',
|
||||
y: "top",
|
||||
},
|
||||
xAxis: {boundaryGap: false},
|
||||
xAxis: { boundaryGap: false },
|
||||
yAxis: [],
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
type: "inside",
|
||||
start: 0,
|
||||
end: 100
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 0,
|
||||
end: 20
|
||||
}
|
||||
end: 20,
|
||||
},
|
||||
],
|
||||
series: []
|
||||
series: [],
|
||||
},
|
||||
seriesData: [],
|
||||
legend: [],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
methods: {
|
||||
resetDefault() {
|
||||
|
||||
this.checkList['ActiveThreadsChart'] = ['ALL'];
|
||||
this.checkList['TransactionsChart'] = ['ALL'];
|
||||
this.checkList['ResponseTimeChart'] = ['ALL'];
|
||||
this.checkList["ActiveThreadsChart"] = ["ALL"];
|
||||
this.checkList["TransactionsChart"] = ["ALL"];
|
||||
this.checkList["ResponseTimeChart"] = ["ALL"];
|
||||
//
|
||||
this.checkList['ResponseTimePercentilesChart'] = [];
|
||||
this.checkList['ErrorsChart'] = [];
|
||||
this.checkList['LatencyChart'] = [];
|
||||
this.checkList['BytesThroughputChart'] = [];
|
||||
this.checkList["ResponseTimePercentilesChart"] = [];
|
||||
this.checkList["ErrorsChart"] = [];
|
||||
this.checkList["LatencyChart"] = [];
|
||||
this.checkList["BytesThroughputChart"] = [];
|
||||
|
||||
this.getTotalChart();
|
||||
},
|
||||
|
@ -437,7 +547,6 @@ export default {
|
|||
}
|
||||
},
|
||||
handleChecked(name) {
|
||||
|
||||
this.getTotalChart();
|
||||
|
||||
this.refresh = false;
|
||||
|
@ -463,9 +572,11 @@ export default {
|
|||
this.init = false;
|
||||
return;
|
||||
}
|
||||
let yAxisIndex0List = data.filter(m => m.yAxis2 === -1).map(m => m.groupName);
|
||||
let yAxisIndex0List = data
|
||||
.filter((m) => m.yAxis2 === -1)
|
||||
.map((m) => m.groupName);
|
||||
yAxisIndex0List = this._unique(yAxisIndex0List);
|
||||
this.checkOptions[reportKey] = ['ALL'].concat(yAxisIndex0List);
|
||||
this.checkOptions[reportKey] = ["ALL"].concat(yAxisIndex0List);
|
||||
},
|
||||
getTotalChart() {
|
||||
this.result.loading = true;
|
||||
|
@ -479,22 +590,24 @@ export default {
|
|||
let chars = [];
|
||||
for (let name in this.checkList) {
|
||||
let data = this.planReportTemplate.checkOptions[name];
|
||||
chars.push({data, 'reportKey': name});
|
||||
chars.push({ data, reportKey: name });
|
||||
}
|
||||
this.handleGetTotalChart(chars);
|
||||
} else {
|
||||
for (let name in this.checkList) {
|
||||
promises.push(this.getChart(name, this.checkList[name]));
|
||||
}
|
||||
Promise.all(promises).then((res) => {
|
||||
this.handleGetTotalChart(res);
|
||||
}).catch(() => {
|
||||
this.result.loading = false;
|
||||
});
|
||||
Promise.all(promises)
|
||||
.then((res) => {
|
||||
this.handleGetTotalChart(res);
|
||||
})
|
||||
.catch(() => {
|
||||
this.result.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
handleGetTotalChart(res) {
|
||||
res = res.filter(v => !!v);
|
||||
res = res.filter((v) => !!v);
|
||||
if (res.length === 0) {
|
||||
this.refresh = false;
|
||||
this.result.loading = false;
|
||||
|
@ -504,27 +617,27 @@ export default {
|
|||
for (let i = 0; i < res.length; i++) {
|
||||
if (i === 0) {
|
||||
this.baseOption.yAxis.push({
|
||||
name: this.$t('load_test.report.' + res[i].reportKey),
|
||||
type: 'value',
|
||||
name: this.$t("load_test.report." + res[i].reportKey),
|
||||
type: "value",
|
||||
min: 0,
|
||||
position: 'left',
|
||||
boundaryGap: [0, '100%']
|
||||
position: "left",
|
||||
boundaryGap: [0, "100%"],
|
||||
});
|
||||
} else {
|
||||
this.baseOption.yAxis.push({
|
||||
name: this.$t('load_test.report.' + res[i].reportKey),
|
||||
type: 'value',
|
||||
name: this.$t("load_test.report." + res[i].reportKey),
|
||||
type: "value",
|
||||
min: 0,
|
||||
position: 'right',
|
||||
position: "right",
|
||||
nameRotate: 20,
|
||||
offset: (i - 1) * 50,
|
||||
boundaryGap: [0, '100%']
|
||||
boundaryGap: [0, "100%"],
|
||||
});
|
||||
}
|
||||
this.totalOption = this.generateOption(this.baseOption, res[i].data, i);
|
||||
}
|
||||
this.totalOption.grid.right = (res.length - 1) * 5 + '%';
|
||||
this.changeDataZoom({start: 0, end: 100});
|
||||
this.totalOption.grid.right = (res.length - 1) * 5 + "%";
|
||||
this.changeDataZoom({ start: 0, end: 100 });
|
||||
this.result.loading = false;
|
||||
},
|
||||
getChart(reportKey, checkList) {
|
||||
|
@ -535,29 +648,31 @@ export default {
|
|||
},
|
||||
handleGetChart(data, reportKey, checkList) {
|
||||
let allData = [];
|
||||
let checkAllOption = checkList.indexOf('ALL') > -1;
|
||||
let checkAllOption = checkList.indexOf("ALL") > -1;
|
||||
if (checkAllOption) {
|
||||
let avgOpt = [
|
||||
'ResponseTimeChart',
|
||||
'ResponseTimePercentilesChart',
|
||||
'LatencyChart',
|
||||
"ResponseTimeChart",
|
||||
"ResponseTimePercentilesChart",
|
||||
"LatencyChart",
|
||||
];
|
||||
let result = groupBy(data, 'xAxis');
|
||||
let result = groupBy(data, "xAxis");
|
||||
for (const xAxis in result) {
|
||||
let yAxis = result[xAxis].map(a => a.yAxis).reduce((a, b) => a + b, 0);
|
||||
let yAxis = result[xAxis]
|
||||
.map((a) => a.yAxis)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
if (avgOpt.indexOf(reportKey) > -1) {
|
||||
yAxis = yAxis / result[xAxis].length;
|
||||
}
|
||||
allData.push({
|
||||
groupName: 'ALL',
|
||||
groupName: "ALL",
|
||||
xAxis: xAxis,
|
||||
yAxis: yAxis
|
||||
yAxis: yAxis,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
data = data.filter(item => {
|
||||
data = data.filter((item) => {
|
||||
if (checkList.indexOf(item.groupName) > -1) {
|
||||
return true;
|
||||
}
|
||||
|
@ -566,17 +681,18 @@ export default {
|
|||
// 选中了all
|
||||
data = data.concat(allData);
|
||||
|
||||
|
||||
// prefix
|
||||
data.forEach(item => {
|
||||
item.groupName = this.$t('load_test.report.' + reportKey) + ': ' + item.groupName;
|
||||
data.forEach((item) => {
|
||||
item.groupName =
|
||||
this.$t("load_test.report." + reportKey) + ": " + item.groupName;
|
||||
});
|
||||
return {data, reportKey};
|
||||
return { data, reportKey };
|
||||
},
|
||||
generateOption(option, data, yAxisIndex) {
|
||||
let chartData = data;
|
||||
let series = {}, xAxis = [];
|
||||
chartData.forEach(item => {
|
||||
let series = {},
|
||||
xAxis = [];
|
||||
chartData.forEach((item) => {
|
||||
if (!xAxis.includes(item.xAxis)) {
|
||||
xAxis.push(item.xAxis);
|
||||
}
|
||||
|
@ -587,9 +703,11 @@ export default {
|
|||
series[name] = [];
|
||||
}
|
||||
if (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", this.legend);
|
||||
this.$set(option.legend, "type", "scroll");
|
||||
|
@ -600,11 +718,11 @@ export default {
|
|||
d.sort((a, b) => a[0].localeCompare(b[0]));
|
||||
let items = {
|
||||
name: name,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
data: d,
|
||||
yAxisIndex: yAxisIndex,
|
||||
smooth: true,
|
||||
sampling: 'lttb',
|
||||
sampling: "lttb",
|
||||
showSymbol: false,
|
||||
animation: !this.export,
|
||||
};
|
||||
|
@ -623,9 +741,15 @@ export default {
|
|||
|
||||
let tableData = [];
|
||||
for (let i = 0; i < this.seriesData.length; i++) {
|
||||
let sub = this.seriesData[i].data, label = this.seriesData[i].name;
|
||||
let sub = this.seriesData[i].data,
|
||||
label = this.seriesData[i].name;
|
||||
let len = 0;
|
||||
let min, avg, max, sum = 0, startTime, endTime;
|
||||
let min,
|
||||
avg,
|
||||
max,
|
||||
sum = 0,
|
||||
startTime,
|
||||
endTime;
|
||||
for (let j = 0; j < sub.length; j++) {
|
||||
let time = sub[j][0];
|
||||
let value = Number.parseFloat(sub[j][1]);
|
||||
|
@ -658,7 +782,7 @@ export default {
|
|||
}
|
||||
|
||||
avg = (sum / len).toFixed(2);
|
||||
tableData.push({label, min, max, avg, startTime, endTime});
|
||||
tableData.push({ label, min, max, avg, startTime, endTime });
|
||||
}
|
||||
this.tableData = tableData;
|
||||
},
|
||||
|
@ -668,12 +792,12 @@ export default {
|
|||
},
|
||||
_unique(arr) {
|
||||
return Array.from(new Set(arr));
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'$route'(to) {
|
||||
$route(to) {
|
||||
if (to.name === "perReportView") {
|
||||
this.id = to.path.split('/')[4];
|
||||
this.id = to.path.split("/")[4];
|
||||
this.init = false;
|
||||
this.initTableData();
|
||||
}
|
||||
|
@ -694,7 +818,7 @@ export default {
|
|||
this.initTableData();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -704,10 +828,9 @@ export default {
|
|||
// this.getTotalChart();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -722,7 +845,7 @@ export default {
|
|||
overflow: auto;
|
||||
}
|
||||
|
||||
:deep(.el-checkbox__label ) {
|
||||
:deep(.el-checkbox__label) {
|
||||
font-size: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
<span class="ms-card-data-digital">{{ maxUsers }}</span>
|
||||
<span class="ms-card-data-unit"> VU</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">{{ $t('load_test.report.ActiveThreadsChart') }}</span>
|
||||
<span class="ms-card-desc">{{
|
||||
$t("load_test.report.ActiveThreadsChart")
|
||||
}}</span>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
|
@ -16,7 +18,9 @@
|
|||
<span class="ms-card-data-digital">{{ avgTransactions }}</span>
|
||||
<span class="ms-card-data-unit"> TPS</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">{{ $t('load_test.report.TransactionsChart') }}</span>
|
||||
<span class="ms-card-desc">{{
|
||||
$t("load_test.report.TransactionsChart")
|
||||
}}</span>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
|
@ -25,7 +29,9 @@
|
|||
<span class="ms-card-data-digital">{{ errors }}</span>
|
||||
<span class="ms-card-data-unit"> %</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">{{ $t('load_test.report.ErrorsChart') }}</span>
|
||||
<span class="ms-card-desc">{{
|
||||
$t("load_test.report.ErrorsChart")
|
||||
}}</span>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
|
@ -34,7 +40,9 @@
|
|||
<span class="ms-card-data-digital">{{ avgResponseTime }}</span>
|
||||
<span class="ms-card-data-unit"> s</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">{{ $t('load_test.report.ResponseTimeChart') }}</span>
|
||||
<span class="ms-card-desc">{{
|
||||
$t("load_test.report.ResponseTimeChart")
|
||||
}}</span>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
|
@ -43,7 +51,9 @@
|
|||
<span class="ms-card-data-digital">{{ responseTime90 }}</span>
|
||||
<span class="ms-card-data-unit"> s</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">90% {{ $t('load_test.report.ResponseTimeChart') }}</span>
|
||||
<span class="ms-card-desc"
|
||||
>90% {{ $t("load_test.report.ResponseTimeChart") }}</span
|
||||
>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
|
@ -52,17 +62,27 @@
|
|||
<span class="ms-card-data-digital">{{ avgBandwidth }}</span>
|
||||
<span class="ms-card-data-unit"> KiB/s</span>
|
||||
</span>
|
||||
<span class="ms-card-desc">{{ $t('load_test.report.Network') }}</span>
|
||||
<span class="ms-card-desc">{{ $t("load_test.report.Network") }}</span>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<ms-chart ref="chart1" :options="loadOption" class="chart-config" :autoresize="true"></ms-chart>
|
||||
<ms-chart
|
||||
ref="chart1"
|
||||
:options="loadOption"
|
||||
class="chart-config"
|
||||
:autoresize="true"
|
||||
></ms-chart>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<ms-chart ref="chart2" :options="resOption" class="chart-config" :autoresize="true"></ms-chart>
|
||||
<ms-chart
|
||||
ref="chart2"
|
||||
:options="resOption"
|
||||
class="chart-config"
|
||||
:autoresize="true"
|
||||
></ms-chart>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
@ -71,7 +91,19 @@
|
|||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/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) {
|
||||
|
@ -82,7 +114,7 @@ const groupBy = function (xs, key) {
|
|||
|
||||
export default {
|
||||
name: "TestOverview",
|
||||
components: {MsChart},
|
||||
components: { MsChart },
|
||||
data() {
|
||||
return {
|
||||
maxUsers: "0",
|
||||
|
@ -96,10 +128,13 @@ export default {
|
|||
resOption: {},
|
||||
errorOption: {},
|
||||
resCodeOption: {},
|
||||
id: ''
|
||||
id: "",
|
||||
};
|
||||
},
|
||||
props: ['report', 'export', 'isShare', 'shareId', 'planReportTemplate'],
|
||||
props: ["report", "export", "isShare", "shareId", "planReportTemplate"],
|
||||
created() {
|
||||
this.initTableData();
|
||||
},
|
||||
methods: {
|
||||
initTableData() {
|
||||
if (this.planReportTemplate) {
|
||||
|
@ -110,13 +145,13 @@ export default {
|
|||
this.getResChart();
|
||||
},
|
||||
buildInfo(data) {
|
||||
this.maxUsers = data ? data.maxUsers : '0';
|
||||
this.avgThroughput = data ? data.avgThroughput : '0';
|
||||
this.avgTransactions = data ? data.avgTransactions : '0';
|
||||
this.errors = data ? data.errors : '0';
|
||||
this.avgResponseTime = data ? data.avgResponseTime : '0';
|
||||
this.responseTime90 = data ? data.responseTime90 : '0';
|
||||
this.avgBandwidth = data ? data.avgBandwidth : '0';
|
||||
this.maxUsers = data ? data.maxUsers : "0";
|
||||
this.avgThroughput = data ? data.avgThroughput : "0";
|
||||
this.avgTransactions = data ? data.avgTransactions : "0";
|
||||
this.errors = data ? data.errors : "0";
|
||||
this.avgResponseTime = data ? data.avgResponseTime : "0";
|
||||
this.responseTime90 = data ? data.responseTime90 : "0";
|
||||
this.avgBandwidth = data ? data.avgBandwidth : "0";
|
||||
},
|
||||
getLoadChart() {
|
||||
if (this.planReportTemplate) {
|
||||
|
@ -131,63 +166,77 @@ export default {
|
|||
let loadOption = {
|
||||
color: color,
|
||||
title: {
|
||||
text: 'Load',
|
||||
left: 'center',
|
||||
text: "Load",
|
||||
left: "center",
|
||||
top: 20,
|
||||
textStyle: {
|
||||
color: '#65A2FF'
|
||||
color: "#65A2FF",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
// extraCssText: 'z-index: 999;',
|
||||
confine: true,
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
series: []
|
||||
series: [],
|
||||
};
|
||||
|
||||
let allData = [];
|
||||
let result = groupBy(data, 'xAxis');
|
||||
let result = groupBy(data, "xAxis");
|
||||
for (const xAxis in result) {
|
||||
let yAxis1 = result[xAxis].filter(a => a.yAxis2 === -1).map(a => a.yAxis).reduce((a, b) => a + b, 0);
|
||||
let yAxis2 = result[xAxis].filter(a => a.yAxis === -1).map(a => a.yAxis2).reduce((a, b) => a + b, 0);
|
||||
allData.push({
|
||||
groupName: 'users',
|
||||
xAxis: xAxis,
|
||||
yAxis: yAxis1,
|
||||
yAxis2: -1,
|
||||
yAxisIndex: 0,
|
||||
}, {
|
||||
groupName: 'transactions/s',
|
||||
xAxis: xAxis,
|
||||
yAxis: -1,
|
||||
yAxis2: yAxis2,
|
||||
yAxisIndex: 1,
|
||||
});
|
||||
let yAxis1 = result[xAxis]
|
||||
.filter((a) => a.yAxis2 === -1)
|
||||
.map((a) => a.yAxis)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
let yAxis2 = result[xAxis]
|
||||
.filter((a) => a.yAxis === -1)
|
||||
.map((a) => a.yAxis2)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
allData.push(
|
||||
{
|
||||
groupName: "users",
|
||||
xAxis: xAxis,
|
||||
yAxis: yAxis1,
|
||||
yAxis2: -1,
|
||||
yAxisIndex: 0,
|
||||
},
|
||||
{
|
||||
groupName: "transactions/s",
|
||||
xAxis: xAxis,
|
||||
yAxis: -1,
|
||||
yAxis2: yAxis2,
|
||||
yAxisIndex: 1,
|
||||
}
|
||||
);
|
||||
}
|
||||
let yAxisList = allData.filter(m => m.yAxis2 === -1).map(m => m.yAxis);
|
||||
let yAxis2List = allData.filter(m => m.yAxis === -1).map(m => m.yAxis2);
|
||||
let yAxisList = allData
|
||||
.filter((m) => m.yAxis2 === -1)
|
||||
.map((m) => m.yAxis);
|
||||
let yAxis2List = allData
|
||||
.filter((m) => m.yAxis === -1)
|
||||
.map((m) => m.yAxis2);
|
||||
let yAxisListMax = this._getChartMax(yAxisList);
|
||||
let yAxis2ListMax = this._getChartMax(yAxis2List);
|
||||
loadOption.yAxis = [{
|
||||
name: 'User',
|
||||
type: 'value',
|
||||
min: 0,
|
||||
max: yAxisListMax,
|
||||
splitNumber: 5,
|
||||
interval: yAxisListMax / 5
|
||||
},
|
||||
loadOption.yAxis = [
|
||||
{
|
||||
name: 'Transactions/s',
|
||||
type: 'value',
|
||||
name: "User",
|
||||
type: "value",
|
||||
min: 0,
|
||||
max: yAxisListMax,
|
||||
splitNumber: 5,
|
||||
interval: yAxisListMax / 5,
|
||||
},
|
||||
{
|
||||
name: "Transactions/s",
|
||||
type: "value",
|
||||
splitNumber: 5,
|
||||
min: 0,
|
||||
max: yAxis2ListMax,
|
||||
interval: yAxis2ListMax / 5
|
||||
}
|
||||
interval: yAxis2ListMax / 5,
|
||||
},
|
||||
];
|
||||
this.loadOption = this.generateOption(loadOption, allData);
|
||||
},
|
||||
|
@ -204,16 +253,16 @@ export default {
|
|||
let resOption = {
|
||||
color: color,
|
||||
title: {
|
||||
text: 'Response Time',
|
||||
left: 'center',
|
||||
text: "Response Time",
|
||||
left: "center",
|
||||
top: 20,
|
||||
textStyle: {
|
||||
color: '#99743C'
|
||||
color: "#99743C",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
// extraCssText: 'z-index: 999;',
|
||||
confine: true,
|
||||
formatter: function (params, ticket, callback) {
|
||||
|
@ -231,21 +280,24 @@ export default {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
series: []
|
||||
series: [],
|
||||
};
|
||||
|
||||
let allData = [];
|
||||
let result = groupBy(data, 'xAxis');
|
||||
let result = groupBy(data, "xAxis");
|
||||
for (const xAxis in result) {
|
||||
let yAxis1 = result[xAxis].filter(a => a.yAxis2 === -1).map(a => a.yAxis).reduce((a, b) => a + b, 0);
|
||||
let yAxis1 = result[xAxis]
|
||||
.filter((a) => a.yAxis2 === -1)
|
||||
.map((a) => a.yAxis)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
yAxis1 = yAxis1 / result[xAxis].length;
|
||||
|
||||
allData.push({
|
||||
groupName: 'response',
|
||||
groupName: "response",
|
||||
xAxis: xAxis,
|
||||
yAxis: -1,
|
||||
yAxis2: yAxis1,
|
||||
|
@ -253,16 +305,18 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
let yAxisList = allData.filter(m => m.yAxis === -1).map(m => m.yAxis2);
|
||||
let yAxisList = allData
|
||||
.filter((m) => m.yAxis === -1)
|
||||
.map((m) => m.yAxis2);
|
||||
let yAxisListMax = this._getChartMax(yAxisList);
|
||||
resOption.yAxis = [
|
||||
{
|
||||
name: 'Response Time',
|
||||
type: 'value',
|
||||
name: "Response Time",
|
||||
type: "value",
|
||||
min: 0,
|
||||
max: yAxisListMax,
|
||||
interval: yAxisListMax / 5
|
||||
}
|
||||
interval: yAxisListMax / 5,
|
||||
},
|
||||
];
|
||||
this.resOption = this.generateOption(resOption, allData);
|
||||
},
|
||||
|
@ -279,16 +333,16 @@ export default {
|
|||
let errorOption = {
|
||||
color: color,
|
||||
title: {
|
||||
text: 'Errors',
|
||||
left: 'center',
|
||||
text: "Errors",
|
||||
left: "center",
|
||||
top: 20,
|
||||
textStyle: {
|
||||
color: '#99743C'
|
||||
color: "#99743C",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
// extraCssText: 'z-index: 999;',
|
||||
confine: true,
|
||||
formatter: function (params, ticket, callback) {
|
||||
|
@ -306,36 +360,41 @@ export default {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
series: []
|
||||
series: [],
|
||||
};
|
||||
|
||||
let allData = [];
|
||||
let result = groupBy(data, 'xAxis');
|
||||
let result = groupBy(data, "xAxis");
|
||||
for (const xAxis in result) {
|
||||
let yAxis1 = result[xAxis].filter(a => a.yAxis2 === -1).map(a => a.yAxis).reduce((a, b) => a + b, 0);
|
||||
let yAxis1 = result[xAxis]
|
||||
.filter((a) => a.yAxis2 === -1)
|
||||
.map((a) => a.yAxis)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
|
||||
allData.push({
|
||||
groupName: 'errors',
|
||||
groupName: "errors",
|
||||
xAxis: xAxis,
|
||||
yAxis: -1,
|
||||
yAxis2: yAxis1,
|
||||
yAxisIndex: 0,
|
||||
});
|
||||
}
|
||||
let yAxisList = allData.filter(m => m.yAxis === -1).map(m => m.yAxis2);
|
||||
let yAxisList = allData
|
||||
.filter((m) => m.yAxis === -1)
|
||||
.map((m) => m.yAxis2);
|
||||
let yAxisListMax = this._getChartMax(yAxisList);
|
||||
errorOption.yAxis = [
|
||||
{
|
||||
name: 'No',
|
||||
type: 'value',
|
||||
name: "No",
|
||||
type: "value",
|
||||
min: 0,
|
||||
max: yAxisListMax,
|
||||
interval: yAxisListMax / 5
|
||||
}
|
||||
interval: yAxisListMax / 5,
|
||||
},
|
||||
];
|
||||
|
||||
this.errorOption = this.generateOption(errorOption, allData);
|
||||
|
@ -353,16 +412,16 @@ export default {
|
|||
let resCodeOption = {
|
||||
color: color,
|
||||
title: {
|
||||
text: 'Response code',
|
||||
left: 'center',
|
||||
text: "Response code",
|
||||
left: "center",
|
||||
top: 20,
|
||||
textStyle: {
|
||||
color: '#99743C'
|
||||
color: "#99743C",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
show: true,
|
||||
trigger: 'axis',
|
||||
trigger: "axis",
|
||||
// extraCssText: 'z-index: 999;',
|
||||
confine: true,
|
||||
formatter: function (params, ticket, callback) {
|
||||
|
@ -380,43 +439,52 @@ export default {
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {},
|
||||
series: []
|
||||
series: [],
|
||||
};
|
||||
|
||||
let allData = [];
|
||||
let result = groupBy(data, 'xAxis');
|
||||
let result = groupBy(data, "xAxis");
|
||||
for (const xAxis in result) {
|
||||
let yAxis1 = result[xAxis].filter(a => a.yAxis2 === -1).map(a => a.yAxis).reduce((a, b) => a + b, 0);
|
||||
let yAxis1 = result[xAxis]
|
||||
.filter((a) => a.yAxis2 === -1)
|
||||
.map((a) => a.yAxis)
|
||||
.reduce((a, b) => a + b, 0);
|
||||
|
||||
allData.push({
|
||||
groupName: 'codes',
|
||||
groupName: "codes",
|
||||
xAxis: xAxis,
|
||||
yAxis: -1,
|
||||
yAxis2: yAxis1,
|
||||
yAxisIndex: 0,
|
||||
});
|
||||
}
|
||||
let yAxisList = allData.filter(m => m.yAxis === -1).map(m => m.yAxis2);
|
||||
let yAxisList = allData
|
||||
.filter((m) => m.yAxis === -1)
|
||||
.map((m) => m.yAxis2);
|
||||
let yAxisListMax = this._getChartMax(yAxisList);
|
||||
resCodeOption.yAxis = [
|
||||
{
|
||||
name: 'No',
|
||||
type: 'value',
|
||||
name: "No",
|
||||
type: "value",
|
||||
min: 0,
|
||||
max: yAxisListMax,
|
||||
interval: yAxisListMax / 5
|
||||
}
|
||||
interval: yAxisListMax / 5,
|
||||
},
|
||||
];
|
||||
this.resCodeOption = this.generateOption(resCodeOption, allData);
|
||||
},
|
||||
generateOption(option, data) {
|
||||
let chartData = data;
|
||||
let legend = [], series = {}, xAxis = [], seriesData = [], yAxisIndex = {};
|
||||
chartData.forEach(item => {
|
||||
let legend = [],
|
||||
series = {},
|
||||
xAxis = [],
|
||||
seriesData = [],
|
||||
yAxisIndex = {};
|
||||
chartData.forEach((item) => {
|
||||
if (!xAxis.includes(item.xAxis)) {
|
||||
xAxis.push(item.xAxis);
|
||||
}
|
||||
|
@ -428,9 +496,15 @@ export default {
|
|||
series[name] = [];
|
||||
}
|
||||
if (item.yAxis === -1) {
|
||||
series[name].splice(xAxis.indexOf(item.xAxis), 0, [item.xAxis, item.yAxis2.toFixed(2)]);
|
||||
series[name].splice(xAxis.indexOf(item.xAxis), 0, [
|
||||
item.xAxis,
|
||||
item.yAxis2.toFixed(2),
|
||||
]);
|
||||
} else {
|
||||
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);
|
||||
|
@ -442,13 +516,13 @@ export default {
|
|||
d.sort((a, b) => a[0].localeCompare(b[0]));
|
||||
let items = {
|
||||
name: name,
|
||||
type: 'line',
|
||||
type: "line",
|
||||
data: d,
|
||||
smooth: true,
|
||||
sampling: 'lttb',
|
||||
sampling: "lttb",
|
||||
showSymbol: false,
|
||||
animation: !this.export,
|
||||
yAxisIndex: yAxisIndex[name]
|
||||
yAxisIndex: yAxisIndex[name],
|
||||
};
|
||||
seriesData.push(items);
|
||||
}
|
||||
|
@ -461,7 +535,7 @@ export default {
|
|||
},
|
||||
_unique(arr) {
|
||||
return Array.from(new Set(arr));
|
||||
}
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
report: {
|
||||
|
@ -474,20 +548,20 @@ export default {
|
|||
if (status === "Completed" || status === "Running") {
|
||||
this.initTableData();
|
||||
} else {
|
||||
this.maxUsers = '0';
|
||||
this.avgThroughput = '0';
|
||||
this.avgTransactions = '0';
|
||||
this.errors = '0';
|
||||
this.avgResponseTime = '0';
|
||||
this.responseTime90 = '0';
|
||||
this.avgBandwidth = '0';
|
||||
this.maxUsers = "0";
|
||||
this.avgThroughput = "0";
|
||||
this.avgTransactions = "0";
|
||||
this.errors = "0";
|
||||
this.avgResponseTime = "0";
|
||||
this.responseTime90 = "0";
|
||||
this.avgBandwidth = "0";
|
||||
this.loadOption = {};
|
||||
this.resOption = {};
|
||||
this.errorOption = {};
|
||||
this.resCodeOption = {};
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
deep: true,
|
||||
},
|
||||
planReportTemplate: {
|
||||
handler() {
|
||||
|
@ -495,14 +569,13 @@ export default {
|
|||
this.initTableData();
|
||||
}
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-card-data {
|
||||
text-align: left;
|
||||
display: block;
|
||||
|
@ -533,52 +606,51 @@ export default {
|
|||
}
|
||||
|
||||
.ms-card-index-2 .ms-card-data-digital {
|
||||
color: #65A2FF;
|
||||
color: #65a2ff;
|
||||
}
|
||||
|
||||
.ms-card-index-2 {
|
||||
border-left-color: #65A2FF;
|
||||
border-left-color: #65a2ff;
|
||||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.ms-card-index-3 .ms-card-data-digital {
|
||||
color: #E6113C;
|
||||
color: #e6113c;
|
||||
}
|
||||
|
||||
.ms-card-index-3 {
|
||||
border-left-color: #E6113C;
|
||||
border-left-color: #e6113c;
|
||||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.ms-card-index-4 .ms-card-data-digital {
|
||||
color: #99743C;
|
||||
color: #99743c;
|
||||
}
|
||||
|
||||
.ms-card-index-4 {
|
||||
border-left-color: #99743C;
|
||||
border-left-color: #99743c;
|
||||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.ms-card-index-5 .ms-card-data-digital {
|
||||
color: #99743C;
|
||||
color: #99743c;
|
||||
}
|
||||
|
||||
.ms-card-index-5 {
|
||||
border-left-color: #99743C;
|
||||
border-left-color: #99743c;
|
||||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.ms-card-index-6 .ms-card-data-digital {
|
||||
color: #3C9899;
|
||||
color: #3c9899;
|
||||
}
|
||||
|
||||
.ms-card-index-6 {
|
||||
border-left-color: #3C9899;
|
||||
border-left-color: #3c9899;
|
||||
border-left-width: 3px;
|
||||
}
|
||||
|
||||
.chart-config {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue