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