fix(报表统计): 优化饼状图的展示方式以及导出细节
--bug=1021171 --user=宋天阳 【报表统计】github#20870,测试用例统计图,报表展示数值重叠,导出后缺少图表 https://www.tapd.cn/55049933/s/1351691
This commit is contained in:
parent
1c7ef48abd
commit
1d124b57f4
|
@ -8,6 +8,14 @@ import {
|
|||
import i18n from "../i18n";
|
||||
import html2canvas from "html2canvas";
|
||||
import JsPDF from "jspdf";
|
||||
/**
|
||||
* 同一行的多个文本框高度保持一致
|
||||
* 同时支持 autosize 的功能
|
||||
* @param size 同一行中文本框的个数
|
||||
* @param index 编辑行的下标
|
||||
* 如果编辑某一行,则只调整某一行,提升效率
|
||||
*/
|
||||
import calcTextareaHeight from "element-ui/packages/input/src/calcTextareaHeight";
|
||||
|
||||
export function setCustomizeColor(color) {
|
||||
// 自定义主题风格
|
||||
|
@ -309,10 +317,10 @@ export function sizeToByte(size) {
|
|||
let k = 1024,
|
||||
sizeUnits = ["B", "K", "M", "G", "T", "P", "E", "Z", "Y"];
|
||||
let i = 1;
|
||||
for (i++; i < sizeUnits.length;) {
|
||||
for (i++; i < sizeUnits.length; ) {
|
||||
let unit = sizeUnits[i];
|
||||
if (size.indexOf(unit) !== -1) {
|
||||
return size.toString().replace(unit, "") * Math.pow(k, i)
|
||||
return size.toString().replace(unit, "") * Math.pow(k, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -325,15 +333,6 @@ export function getTypeByFileName(filename) {
|
|||
return type.toUpperCase();
|
||||
}
|
||||
|
||||
/**
|
||||
* 同一行的多个文本框高度保持一致
|
||||
* 同时支持 autosize 的功能
|
||||
* @param size 同一行中文本框的个数
|
||||
* @param index 编辑行的下标
|
||||
* 如果编辑某一行,则只调整某一行,提升效率
|
||||
*/
|
||||
import calcTextareaHeight from "element-ui/packages/input/src/calcTextareaHeight";
|
||||
|
||||
export function resizeTextarea(size = 2, index) {
|
||||
let textareaList = document.querySelectorAll(
|
||||
".sync-textarea .el-textarea__inner"
|
||||
|
@ -404,7 +403,7 @@ export function downloadPDF(ele, pdfName) {
|
|||
let scale = canvas.height / ((canvas.width / 592.28) * 841.89);
|
||||
scale = scale > 3 ? 1 : 2;
|
||||
context.translate(-eleOffsetLeft - abs, -eleOffsetTop);
|
||||
let scrollWidth = document.getElementById("apiTestReport").scrollWidth;
|
||||
let scrollWidth = ele.scrollWidth;
|
||||
html2canvas(ele, {
|
||||
scale: scale, // 背景灰色
|
||||
background: "#FFFFFF",
|
||||
|
|
|
@ -2,6 +2,7 @@ package io.metersphere.reportstatistics.service;
|
|||
|
||||
import io.metersphere.base.domain.CustomField;
|
||||
import io.metersphere.base.domain.User;
|
||||
import io.metersphere.commons.constants.MicroServiceName;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
import io.metersphere.i18n.Translator;
|
||||
|
@ -15,15 +16,16 @@ import io.metersphere.reportstatistics.service.remote.apitest.ScenarioRemoteServ
|
|||
import io.metersphere.reportstatistics.service.remote.performance.PerformanceRemoteService;
|
||||
import io.metersphere.reportstatistics.service.remote.projectmanagement.TestCaseTemplateRemoteService;
|
||||
import io.metersphere.reportstatistics.service.remote.track.TestCaseRemoteService;
|
||||
import io.metersphere.reportstatistics.utils.DiscoveryUtil;
|
||||
import io.metersphere.request.member.QueryMemberRequest;
|
||||
import io.metersphere.service.BaseUserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
|
@ -126,7 +128,6 @@ public class TestCaseCountService {
|
|||
} else if (StringUtils.equalsIgnoreCase(request.getTimeRangeUnit(), "year")) {
|
||||
dateCountType = Calendar.YEAR;
|
||||
}
|
||||
|
||||
if (dateCountType != 0 && request.getTimeRange() != 0) {
|
||||
long startTime = DateUtils.dateSum(new Date(), (0 - request.getTimeRange()), dateCountType).getTime();
|
||||
request.setStartTime(startTime);
|
||||
|
@ -246,7 +247,7 @@ public class TestCaseCountService {
|
|||
}
|
||||
|
||||
|
||||
if (yAxisSelectTestCase) {
|
||||
if (yAxisSelectTestCase && DiscoveryUtil.hasService(MicroServiceName.TEST_TRACK)) {
|
||||
functionCaseCountResult = testCaseRemoteService.countTestCaseByRequest(request);
|
||||
if (functionCaseCountResult.isEmpty() && StringUtils.equalsIgnoreCase(request.getXaxis(), "casetype")) {
|
||||
TestCaseCountChartResult result = new TestCaseCountChartResult();
|
||||
|
@ -255,7 +256,7 @@ public class TestCaseCountService {
|
|||
functionCaseCountResult.add(result);
|
||||
}
|
||||
}
|
||||
if (yAxisSelectApi) {
|
||||
if (yAxisSelectApi && DiscoveryUtil.hasService(MicroServiceName.API_TEST)) {
|
||||
Map<String, List<String>> apiCaseFilterList = new HashMap<>();
|
||||
if (MapUtils.isNotEmpty(request.getFilterSearchList())) {
|
||||
for (Map.Entry<String, List<String>> entry : request.getFilterSearchList().entrySet()) {
|
||||
|
@ -274,7 +275,7 @@ public class TestCaseCountService {
|
|||
apiCaseCountResult.add(result);
|
||||
}
|
||||
}
|
||||
if (yAxisSelectScenarioCase) {
|
||||
if (yAxisSelectScenarioCase && DiscoveryUtil.hasService(MicroServiceName.API_TEST)) {
|
||||
scenarioCaseCount = scenarioRemoteService.countTestCaseByRequest(request);
|
||||
if (scenarioCaseCount.isEmpty() && StringUtils.equalsIgnoreCase(request.getXaxis(), "casetype")) {
|
||||
TestCaseCountChartResult result = new TestCaseCountChartResult();
|
||||
|
@ -283,7 +284,7 @@ public class TestCaseCountService {
|
|||
scenarioCaseCount.add(result);
|
||||
}
|
||||
}
|
||||
if (yAxisSelectLoad) {
|
||||
if (yAxisSelectLoad && DiscoveryUtil.hasService(MicroServiceName.PERFORMANCE_TEST)) {
|
||||
Map<String, List<String>> loadCaseFilterMap = new HashMap<>();
|
||||
if (MapUtils.isNotEmpty(request.getFilterSearchList())) {
|
||||
for (Map.Entry<String, List<String>> entry : request.getFilterSearchList().entrySet()) {
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package io.metersphere.reportstatistics.utils;
|
||||
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.dto.ServiceDTO;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DiscoveryUtil {
|
||||
|
||||
public static boolean hasService(String serviceId) {
|
||||
return getServiceIdSet().contains(serviceId);
|
||||
}
|
||||
|
||||
public static Set<String> getServiceIdSet() {
|
||||
DiscoveryClient discoveryClient = CommonBeanFactory.getBean(DiscoveryClient.class);
|
||||
return discoveryClient.getServices()
|
||||
.stream()
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public static List<ServiceDTO> getServices() {
|
||||
DiscoveryClient discoveryClient = CommonBeanFactory.getBean(DiscoveryClient.class);
|
||||
return discoveryClient.getServices().stream()
|
||||
.map(service -> new ServiceDTO(service, discoveryClient.getInstances(service).get(0).getPort()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
|
@ -1,35 +1,55 @@
|
|||
<template>
|
||||
<div class="ms-header">
|
||||
<el-row>
|
||||
<div class="ms-div">{{ title }}
|
||||
<div class="ms-div">
|
||||
{{ title }}
|
||||
<span v-if="historyReportName" class="history-report-name">
|
||||
{{ historyReportName }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="ms-header-right">
|
||||
<el-button type="primary" v-if="isSaveAsButtonShow" size="mini" @click="handleSaveAs" :disabled="readOnly">
|
||||
{{ $t('commons.save_as') }}<i class="el-icon-files el-icon--right"></i></el-button>
|
||||
<el-button type="primary" v-if="isSaveButtonShow" size="mini" @click="handleSave" :disabled="readOnly">
|
||||
{{ $t('commons.save') }}<i class="el-icon-files el-icon--right"></i></el-button>
|
||||
<el-button type="" size="mini" @click="handleExport" :disabled="readOnly">{{ $t('report.export') }}<i
|
||||
class="el-icon-download el-icon--right"></i></el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="isSaveAsButtonShow"
|
||||
size="mini"
|
||||
@click="handleSaveAs"
|
||||
:disabled="readOnly"
|
||||
>
|
||||
{{ $t("commons.save_as") }}<i class="el-icon-files el-icon--right"></i
|
||||
></el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
v-if="isSaveButtonShow"
|
||||
size="mini"
|
||||
@click="handleSave"
|
||||
:disabled="readOnly"
|
||||
>
|
||||
{{ $t("commons.save") }}<i class="el-icon-files el-icon--right"></i
|
||||
></el-button>
|
||||
<el-button
|
||||
type=""
|
||||
size="mini"
|
||||
@click="handleExport"
|
||||
:disabled="readOnly"
|
||||
>{{ $t("report.export")
|
||||
}}<i class="el-icon-download el-icon--right"></i
|
||||
></el-button>
|
||||
<span class="ms-span">|</span>
|
||||
<i class="el-icon-close report-alt-ico" @click="close"/>
|
||||
<i class="el-icon-close report-alt-ico" @click="close" />
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {exportPdf,} from "metersphere-frontend/src/utils";
|
||||
import {hasPermission} from "metersphere-frontend/src/utils/permission";
|
||||
import html2canvas from 'html2canvas';
|
||||
import { hasPermission } from "metersphere-frontend/src/utils/permission";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
export default {
|
||||
name: "ReportHeader",
|
||||
components: {},
|
||||
data() {
|
||||
return {}
|
||||
return {};
|
||||
},
|
||||
props: {
|
||||
title: String,
|
||||
|
@ -37,20 +57,22 @@ export default {
|
|||
historyReportName: String,
|
||||
},
|
||||
watch: {
|
||||
historyReportName() {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
historyReportName() {},
|
||||
},
|
||||
created() {},
|
||||
computed: {
|
||||
readOnly() {
|
||||
return !hasPermission('PROJECT_REPORT_ANALYSIS:READ+EXPORT');
|
||||
return !hasPermission("PROJECT_REPORT_ANALYSIS:READ+EXPORT");
|
||||
},
|
||||
isSaveAsButtonShow() {
|
||||
if (!this.historyReportId || this.historyReportId === null || this.historyReportId === '') {
|
||||
if (
|
||||
!this.historyReportId ||
|
||||
this.historyReportId === null ||
|
||||
this.historyReportId === ""
|
||||
) {
|
||||
return false;
|
||||
} else {
|
||||
if (hasPermission('PROJECT_REPORT_ANALYSIS:READ+CREATE')) {
|
||||
if (hasPermission("PROJECT_REPORT_ANALYSIS:READ+CREATE")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -58,28 +80,23 @@ export default {
|
|||
}
|
||||
},
|
||||
isSaveButtonShow() {
|
||||
if (hasPermission('PROJECT_REPORT_ANALYSIS:READ+UPDATE')) {
|
||||
if (hasPermission("PROJECT_REPORT_ANALYSIS:READ+UPDATE")) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleExport() {
|
||||
let name = this.title;
|
||||
this.$nextTick(function () {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('reportAnalysis'), {
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
this.$emit("exportReport", this.title);
|
||||
},
|
||||
handleSave() {
|
||||
if (!this.historyReportId || this.historyReportId === null || this.historyReportId === '') {
|
||||
if (
|
||||
!this.historyReportId ||
|
||||
this.historyReportId === null ||
|
||||
this.historyReportId === ""
|
||||
) {
|
||||
this.$emit("selectAndSaveReport");
|
||||
} else {
|
||||
this.$emit("updateReport");
|
||||
|
@ -89,16 +106,16 @@ export default {
|
|||
this.$emit("selectAndSaveReport");
|
||||
},
|
||||
close() {
|
||||
this.$emit('closePage');
|
||||
this.$emit("closePage");
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-header {
|
||||
border-bottom: 1px solid #E6E6E6;
|
||||
background-color: #FFF;
|
||||
border-bottom: 1px solid #e6e6e6;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.ms-div {
|
||||
|
|
|
@ -2,56 +2,101 @@
|
|||
<div>
|
||||
<el-row type="flex">
|
||||
<p class="tip">
|
||||
<span class="ms-span">{{ $t('commons.report_statistics.name') }}</span>
|
||||
<el-select v-model="reportType" class="ms-col-type" size="mini" style="width: 120px">
|
||||
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in reportTypes"/>
|
||||
<span class="ms-span">{{ $t("commons.report_statistics.name") }}</span>
|
||||
<el-select
|
||||
v-model="reportType"
|
||||
class="ms-col-type"
|
||||
size="mini"
|
||||
style="width: 120px"
|
||||
>
|
||||
<el-option
|
||||
:key="t.id"
|
||||
:value="t.id"
|
||||
:label="t.name"
|
||||
v-for="t in reportTypes"
|
||||
/>
|
||||
</el-select>
|
||||
</p>
|
||||
</el-row>
|
||||
<transition>
|
||||
<keep-alive>
|
||||
<report-card @openCard="openCard"/>
|
||||
<report-card @openCard="openCard" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
|
||||
<!-- 测试用例趋势页面 -->
|
||||
<ms-drawer :visible="testCaseTrendDrawer" :size="100" @close="close" direction="right" :show-full-screen="false"
|
||||
:is-show-close="false" style="overflow: hidden">
|
||||
<ms-drawer
|
||||
:visible="testCaseTrendDrawer"
|
||||
:size="100"
|
||||
@close="close"
|
||||
direction="right"
|
||||
:show-full-screen="false"
|
||||
:is-show-close="false"
|
||||
style="overflow: hidden"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<report-header :title="$t('commons.report_statistics.test_case_analysis')" :history-report-id="historyReportId"
|
||||
:history-report-name="historyReportName"
|
||||
@closePage="close" @updateReport="updateReport"
|
||||
@selectAndSaveReport="openSaveReportDialog('saveAs')"/>
|
||||
<report-header
|
||||
:title="$t('commons.report_statistics.test_case_analysis')"
|
||||
:history-report-id="historyReportId"
|
||||
:history-report-name="historyReportName"
|
||||
@closePage="close"
|
||||
@updateReport="updateReport"
|
||||
@exportReport="exportReport"
|
||||
@selectAndSaveReport="openSaveReportDialog('saveAs')"
|
||||
/>
|
||||
</template>
|
||||
<test-analysis-container @initHistoryReportId="initHistoryReportId" ref="testAnalysisContainer"/>
|
||||
<test-analysis-container
|
||||
@initHistoryReportId="initHistoryReportId"
|
||||
ref="testAnalysisContainer"
|
||||
/>
|
||||
</ms-drawer>
|
||||
|
||||
<!-- 测试用例分析页面 -->
|
||||
<ms-drawer :visible="testCaseCountDrawer" :size="100" @close="close" direction="right" :show-full-screen="false"
|
||||
:is-show-close="false" style="overflow: hidden">
|
||||
<ms-drawer
|
||||
:visible="testCaseCountDrawer"
|
||||
:size="100"
|
||||
@close="close"
|
||||
direction="right"
|
||||
:show-full-screen="false"
|
||||
:is-show-close="false"
|
||||
style="overflow: hidden"
|
||||
>
|
||||
<template v-slot:header>
|
||||
<report-header :title="$t('commons.report_statistics.test_case_count')" :history-report-id="historyReportId"
|
||||
@closePage="close"
|
||||
:history-report-name="historyReportName"
|
||||
@updateReport="updateReport"
|
||||
@selectAndSaveReport="openSaveReportDialog('saveAs')"/>
|
||||
<report-header
|
||||
:title="$t('commons.report_statistics.test_case_count')"
|
||||
:history-report-id="historyReportId"
|
||||
@closePage="close"
|
||||
:history-report-name="historyReportName"
|
||||
@updateReport="updateReport"
|
||||
@exportReport="exportReport"
|
||||
@selectAndSaveReport="openSaveReportDialog('saveAs')"
|
||||
/>
|
||||
</template>
|
||||
<test-case-count-container @initHistoryReportId="initHistoryReportId" ref="testCaseCountContainer"/>
|
||||
<test-case-count-container
|
||||
@initHistoryReportId="initHistoryReportId"
|
||||
ref="testCaseCountContainer"
|
||||
/>
|
||||
</ms-drawer>
|
||||
|
||||
<el-dialog
|
||||
:title="$t('commons.save')"
|
||||
:visible.sync="dialogFormVisible"
|
||||
width="30%"
|
||||
:before-close="handleCloseSaveReportDialog">
|
||||
|
||||
:before-close="handleCloseSaveReportDialog"
|
||||
>
|
||||
<el-form :model="form" :rules="saveReportRules" ref="saveReportRuleForm">
|
||||
<el-form-item :label="$t('commons.input_name')" prop="reportName" label-width="120px">
|
||||
<el-form-item
|
||||
:label="$t('commons.input_name')"
|
||||
prop="reportName"
|
||||
label-width="120px"
|
||||
>
|
||||
<el-input v-model="form.reportName" autocomplete="off"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="saveReport">{{ $t('commons.confirm') }}</el-button>
|
||||
<el-button type="primary" @click="saveReport">{{
|
||||
$t("commons.confirm")
|
||||
}}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
@ -63,11 +108,17 @@ import TestAnalysisContainer from "@/business/projectstatistics/track/TestAnalys
|
|||
import MsDrawer from "metersphere-frontend/src/components/MsDrawer";
|
||||
import ReportHeader from "@/business/base/ReportHeader";
|
||||
import TestCaseCountContainer from "@/business/projectstatistics/casecount/TestCaseCountContainer";
|
||||
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
export default {
|
||||
name: "ReportAnalysis",
|
||||
components: {ReportCard, TestAnalysisContainer, MsDrawer, ReportHeader, TestCaseCountContainer},
|
||||
components: {
|
||||
ReportCard,
|
||||
TestAnalysisContainer,
|
||||
MsDrawer,
|
||||
ReportHeader,
|
||||
TestCaseCountContainer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
reportType: "track",
|
||||
|
@ -75,7 +126,7 @@ export default {
|
|||
testCaseCountDrawer: false,
|
||||
historyReportId: "",
|
||||
historyReportName: "",
|
||||
reportTypes: [{id: 'track', name: this.$t('test_track.test_track')}],
|
||||
reportTypes: [{ id: "track", name: this.$t("test_track.test_track") }],
|
||||
dialogFormVisible: false,
|
||||
form: {
|
||||
reportName: "",
|
||||
|
@ -83,19 +134,30 @@ export default {
|
|||
},
|
||||
saveReportRules: {
|
||||
reportName: [
|
||||
{required: true, message: this.$t('commons.input_name'), trigger: 'blur'},
|
||||
{min: 1, max: 20, message: '长度不大于20个字符', trigger: 'blur'}
|
||||
{
|
||||
required: true,
|
||||
message: this.$t("commons.input_name"),
|
||||
trigger: "blur",
|
||||
},
|
||||
{ min: 1, max: 20, message: "长度不大于20个字符", trigger: "blur" },
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
exportReport(title) {
|
||||
if (this.testCaseCountDrawer && this.$refs.testCaseCountContainer) {
|
||||
this.$refs.testCaseCountContainer.handleExport();
|
||||
} else if (this.testCaseTrendDrawer) {
|
||||
this.$refs.testAnalysisContainer.handleExport();
|
||||
}
|
||||
},
|
||||
openCard(type) {
|
||||
this.historyReportName = "";
|
||||
this.historyReportId = "";
|
||||
if (type === 'trackTestCase') {
|
||||
if (type === "trackTestCase") {
|
||||
this.testCaseTrendDrawer = true;
|
||||
} else if (type === 'countTestCase') {
|
||||
} else if (type === "countTestCase") {
|
||||
this.testCaseCountDrawer = true;
|
||||
}
|
||||
},
|
||||
|
@ -119,12 +181,18 @@ export default {
|
|||
}
|
||||
},
|
||||
saveReport() {
|
||||
this.$refs['saveReportRuleForm'].validate((valid) => {
|
||||
this.$refs["saveReportRuleForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.testCaseTrendDrawer) {
|
||||
this.$refs.testAnalysisContainer.saveAndSaveAsReport(this.form.reportName, this.form.saveType);
|
||||
this.$refs.testAnalysisContainer.saveAndSaveAsReport(
|
||||
this.form.reportName,
|
||||
this.form.saveType
|
||||
);
|
||||
} else if (this.testCaseCountDrawer) {
|
||||
this.$refs.testCaseCountContainer.saveAndSaveAsReport(this.form.reportName, this.form.saveType);
|
||||
this.$refs.testCaseCountContainer.saveAndSaveAsReport(
|
||||
this.form.reportName,
|
||||
this.form.saveType
|
||||
);
|
||||
}
|
||||
this.form.reportName = "";
|
||||
this.form.saveType = "";
|
||||
|
@ -142,14 +210,14 @@ export default {
|
|||
this.form.reportName = "";
|
||||
this.form.saveType = "";
|
||||
this.dialogFormVisible = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ms-span {
|
||||
margin: 10px 10px 0px
|
||||
margin: 10px 10px 0px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
|
|
|
@ -1,24 +1,53 @@
|
|||
<template>
|
||||
<div>
|
||||
<el-container v-loading="loading" :style="{ 'max-height': (h-50) + 'px', 'overflow': 'auto'}">
|
||||
<el-aside v-if="!isHide" :width="!isHide ?'235px':'0px'" :style="{ 'margin-left': '5px'}">
|
||||
<history-report-data report-type="TEST_CASE_COUNT"
|
||||
@selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId"
|
||||
ref="historyReport"/>
|
||||
<el-container
|
||||
v-loading="loading"
|
||||
:style="{ 'max-height': h - 50 + 'px', overflow: 'auto' }"
|
||||
>
|
||||
<el-aside
|
||||
v-if="!isHide"
|
||||
:width="!isHide ? '235px' : '0px'"
|
||||
:style="{ 'margin-left': '5px' }"
|
||||
>
|
||||
<history-report-data
|
||||
report-type="TEST_CASE_COUNT"
|
||||
@selectReport="selectReport"
|
||||
@removeHistoryReportId="removeHistoryReportId"
|
||||
ref="historyReport"
|
||||
/>
|
||||
</el-aside>
|
||||
<el-main class="ms-main" id="reportAnalysis" style="padding: 0px 5px 0px">
|
||||
<div>
|
||||
<test-case-count-chart @hidePage="hidePage" @orderCharts="orderCharts"
|
||||
ref="analysisChart" @updateChartType="updateChartType"
|
||||
:chart-width="chartWidth" :load-option="loadOption" :pie-option="pieOption"/>
|
||||
</div>
|
||||
<div class="ms-row" v-if="!isHide">
|
||||
<test-case-count-table :group-name="getGroupNameStr(options.xaxis)" :show-columns="options.yaxis"
|
||||
:tableData="tableData"/>
|
||||
<div id="testCaseCountPicDiv">
|
||||
<div>
|
||||
<test-case-count-chart
|
||||
@hidePage="hidePage"
|
||||
@orderCharts="orderCharts"
|
||||
ref="analysisChart"
|
||||
@updateChartType="updateChartType"
|
||||
:chart-width="chartWidth"
|
||||
:load-option="loadOption"
|
||||
:pie-option="pieOption"
|
||||
/>
|
||||
</div>
|
||||
<div class="ms-row">
|
||||
<test-case-count-table
|
||||
:group-name="getGroupNameStr(options.xaxis)"
|
||||
:show-columns="options.yaxis"
|
||||
ref="caseCountTable"
|
||||
:tableData="tableData"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-main>
|
||||
<el-aside v-if="!isHide" style="height: 100%" :width="!isHide ?'485px':'0px'">
|
||||
<test-case-count-filter @filterCharts="filterCharts" ref="countFilter"/>
|
||||
<el-aside
|
||||
v-if="!isHide"
|
||||
style="height: 100%"
|
||||
:width="!isHide ? '485px' : '0px'"
|
||||
>
|
||||
<test-case-count-filter
|
||||
@filterCharts="filterCharts"
|
||||
ref="countFilter"
|
||||
/>
|
||||
</el-aside>
|
||||
</el-container>
|
||||
</div>
|
||||
|
@ -28,16 +57,24 @@
|
|||
import TestCaseCountChart from "./chart/TestCaseCountChart";
|
||||
import TestCaseCountTable from "@/business/projectstatistics/casecount/table/TestCaseCountTable";
|
||||
import TestCaseCountFilter from "./filter/TestCaseCountFilter";
|
||||
import {exportPdf} from "metersphere-frontend/src/utils";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import html2canvas from 'html2canvas';
|
||||
import {getCountReport} from "@/api/report";
|
||||
import { getCurrentProjectID } from "metersphere-frontend/src/utils/token";
|
||||
import { downloadPDF } from "metersphere-frontend/src/utils";
|
||||
import { getCountReport } from "@/api/report";
|
||||
import HistoryReportData from "../../base/HistoryReportData";
|
||||
import {createHistoryReport, selectHistoryReportById, updateHistoryReport} from "@/api/history-report";
|
||||
import {
|
||||
createHistoryReport,
|
||||
selectHistoryReportById,
|
||||
updateHistoryReport,
|
||||
} from "@/api/history-report";
|
||||
|
||||
export default {
|
||||
name: "TestCaseCountContainer",
|
||||
components: {TestCaseCountChart, TestCaseCountTable, TestCaseCountFilter, HistoryReportData},
|
||||
components: {
|
||||
TestCaseCountChart,
|
||||
TestCaseCountTable,
|
||||
TestCaseCountFilter,
|
||||
HistoryReportData,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isHide: false,
|
||||
|
@ -52,7 +89,7 @@ export default {
|
|||
yAxis: {},
|
||||
label: {},
|
||||
tooltip: {},
|
||||
series: []
|
||||
series: [],
|
||||
},
|
||||
pieOption: {
|
||||
legend: {},
|
||||
|
@ -71,26 +108,29 @@ export default {
|
|||
this.chartType = value;
|
||||
},
|
||||
handleExport() {
|
||||
let name = this.$t('commons.report_statistics.test_case_analysis');
|
||||
this.hidePage(true);
|
||||
let name = this.$t("commons.report_statistics.test_case_count");
|
||||
this.$nextTick(function () {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('reportAnalysis'), {
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
});
|
||||
downloadPDF(
|
||||
document.getElementById("testCaseCountPicDiv"),
|
||||
name || "MeterSphere-report"
|
||||
);
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
|
||||
hidePage(isHide) {
|
||||
this.isHide = isHide;
|
||||
this.$refs.analysisChart.reCountWidth(isHide);
|
||||
this.$refs.caseCountTable.reCountWidth(isHide);
|
||||
},
|
||||
close() {
|
||||
this.$emit('closePage');
|
||||
this.$emit("closePage");
|
||||
},
|
||||
init(opt) {
|
||||
this.options = opt;
|
||||
this.loading = getCountReport(opt).then(response => {
|
||||
this.loading = getCountReport(opt).then((response) => {
|
||||
let data = response.data.barChartDTO;
|
||||
let pieData = response.data.pieChartDTO;
|
||||
let selectTableData = response.data.tableDTOs;
|
||||
|
@ -101,19 +141,18 @@ export default {
|
|||
if (!formatData) {
|
||||
return;
|
||||
}
|
||||
if (typeof (formatData.legend) === 'string') {
|
||||
if (typeof formatData.legend === "string") {
|
||||
formatData.legend = JSON.parse(formatData.legend);
|
||||
}
|
||||
if (typeof (formatData.xaxis) === 'string') {
|
||||
if (typeof formatData.xaxis === "string") {
|
||||
formatData.xaxis = JSON.parse(formatData.xaxis);
|
||||
}
|
||||
if (typeof (formatData.series) === 'string') {
|
||||
if (typeof formatData.series === "string") {
|
||||
formatData.series = JSON.parse(formatData.series);
|
||||
}
|
||||
if (typeof (formatData.title) === 'string') {
|
||||
if (typeof formatData.title === "string") {
|
||||
formatData.title = JSON.parse(formatData.title);
|
||||
}
|
||||
|
||||
},
|
||||
initPic(barData, pieData, selectTableData) {
|
||||
this.loading = true;
|
||||
|
@ -126,9 +165,9 @@ export default {
|
|||
this.loadOption.xaxis = barData.xaxis;
|
||||
this.loadOption.series = barData.series;
|
||||
this.loadOption.grid = {
|
||||
bottom: '75px',//距离下边距
|
||||
bottom: "75px", //距离下边距
|
||||
};
|
||||
this.loadOption.series.forEach(item => {
|
||||
this.loadOption.series.forEach((item) => {
|
||||
if (this.$refs.analysisChart) {
|
||||
item.type = this.$refs.analysisChart.chartType;
|
||||
}
|
||||
|
@ -141,14 +180,14 @@ export default {
|
|||
this.pieOption.series = pieData.series;
|
||||
this.pieOption.title = pieData.title;
|
||||
this.pieOption.grid = {
|
||||
bottom: '75px',//距离下边距
|
||||
bottom: "75px", //距离下边距
|
||||
};
|
||||
if (pieData.width) {
|
||||
this.pieOption.width = pieData.width;
|
||||
this.chartWidth = pieData.width;
|
||||
}
|
||||
if (this.pieOption.series) {
|
||||
this.pieOption.series.forEach(item => {
|
||||
this.pieOption.series.forEach((item) => {
|
||||
if (this.$refs.analysisChart) {
|
||||
item.type = this.$refs.analysisChart.chartType;
|
||||
}
|
||||
|
@ -158,7 +197,10 @@ export default {
|
|||
if (selectTableData) {
|
||||
this.tableData = selectTableData;
|
||||
}
|
||||
this.$refs.analysisChart.setPieOptionAndBarOption(this.loadOption, this.pieOption);
|
||||
this.$refs.analysisChart.setPieOptionAndBarOption(
|
||||
this.loadOption,
|
||||
this.pieOption
|
||||
);
|
||||
this.loading = false;
|
||||
this.$refs.analysisChart.generateOption(this.chartType);
|
||||
},
|
||||
|
@ -181,9 +223,9 @@ export default {
|
|||
chartType: this.chartType,
|
||||
};
|
||||
obj.dataOption = JSON.stringify(dataOptionObj);
|
||||
obj.reportType = 'TEST_CASE_COUNT';
|
||||
obj.reportType = "TEST_CASE_COUNT";
|
||||
updateHistoryReport(obj).then(() => {
|
||||
this.$alert(this.$t('commons.save_success'));
|
||||
this.$alert(this.$t("commons.save_success"));
|
||||
this.$refs.historyReport.initReportData();
|
||||
});
|
||||
},
|
||||
|
@ -199,9 +241,9 @@ export default {
|
|||
chartType: this.chartType,
|
||||
};
|
||||
obj.dataOption = JSON.stringify(dataOptionObj);
|
||||
obj.reportType = 'TEST_CASE_COUNT';
|
||||
obj.reportType = "TEST_CASE_COUNT";
|
||||
createHistoryReport(obj).then(() => {
|
||||
this.$alert(this.$t('commons.save_success'));
|
||||
this.$alert(this.$t("commons.save_success"));
|
||||
this.$refs.historyReport.initReportData();
|
||||
});
|
||||
},
|
||||
|
@ -210,54 +252,71 @@ export default {
|
|||
if (selectId) {
|
||||
this.loading = true;
|
||||
let paramObj = {
|
||||
id: selectId
|
||||
}
|
||||
selectHistoryReportById(paramObj).then((response) => {
|
||||
let reportData = response.data;
|
||||
if (reportData) {
|
||||
selectName = reportData.name;
|
||||
if (reportData.dataOption) {
|
||||
let dataOptionObj = JSON.parse(reportData.dataOption);
|
||||
if (dataOptionObj.chartType) {
|
||||
if (dataOptionObj.chartType === "\"bar\"") {
|
||||
this.chartType = "bar";
|
||||
} else if (dataOptionObj.chartType === "\"pie\"") {
|
||||
this.chartType = "pie";
|
||||
id: selectId,
|
||||
};
|
||||
selectHistoryReportById(paramObj).then(
|
||||
(response) => {
|
||||
let reportData = response.data;
|
||||
if (reportData) {
|
||||
selectName = reportData.name;
|
||||
if (reportData.dataOption) {
|
||||
let dataOptionObj = JSON.parse(reportData.dataOption);
|
||||
if (dataOptionObj.chartType) {
|
||||
if (dataOptionObj.chartType === '"bar"') {
|
||||
this.chartType = "bar";
|
||||
} else if (dataOptionObj.chartType === '"pie"') {
|
||||
this.chartType = "pie";
|
||||
} else {
|
||||
this.chartType = dataOptionObj.chartType;
|
||||
}
|
||||
} else {
|
||||
this.chartType = dataOptionObj.chartType;
|
||||
this.chartType = "bar";
|
||||
}
|
||||
} else {
|
||||
this.chartType = "bar";
|
||||
this.initPic(
|
||||
dataOptionObj.loadOption,
|
||||
dataOptionObj.pieOption,
|
||||
dataOptionObj.tableData
|
||||
);
|
||||
}
|
||||
this.initPic(dataOptionObj.loadOption, dataOptionObj.pieOption, dataOptionObj.tableData);
|
||||
}
|
||||
if (reportData.selectOption) {
|
||||
let selectOptionObj = JSON.parse(reportData.selectOption);
|
||||
this.$refs.countFilter.initSelectOption(selectOptionObj);
|
||||
if (reportData.selectOption) {
|
||||
let selectOptionObj = JSON.parse(reportData.selectOption);
|
||||
this.$refs.countFilter.initSelectOption(selectOptionObj);
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
this.$emit("initHistoryReportId", selectId, selectName);
|
||||
},
|
||||
(error) => {
|
||||
this.loading = false;
|
||||
this.removeHistoryReportId();
|
||||
}
|
||||
this.$emit('initHistoryReportId', selectId, selectName);
|
||||
}, (error) => {
|
||||
this.loading = false;
|
||||
this.removeHistoryReportId();
|
||||
});
|
||||
);
|
||||
}
|
||||
},
|
||||
removeHistoryReportId() {
|
||||
this.$emit('initHistoryReportId', "", "");
|
||||
this.$emit("initHistoryReportId", "", "");
|
||||
},
|
||||
getGroupNameStr(groupName) {
|
||||
if (groupName === 'creator') {
|
||||
return this.$t('commons.report_statistics.report_filter.select_options.creator');
|
||||
} else if (groupName === 'maintainer') {
|
||||
return this.$t('commons.report_statistics.report_filter.select_options.maintainer');
|
||||
} else if (groupName === 'casetype') {
|
||||
return this.$t('commons.report_statistics.report_filter.select_options.case_type');
|
||||
} else if (groupName === 'casestatus') {
|
||||
return this.$t('commons.report_statistics.report_filter.select_options.case_status');
|
||||
} else if (groupName === 'caselevel') {
|
||||
return this.$t('commons.report_statistics.report_filter.select_options.case_level');
|
||||
if (groupName === "creator") {
|
||||
return this.$t(
|
||||
"commons.report_statistics.report_filter.select_options.creator"
|
||||
);
|
||||
} else if (groupName === "maintainer") {
|
||||
return this.$t(
|
||||
"commons.report_statistics.report_filter.select_options.maintainer"
|
||||
);
|
||||
} else if (groupName === "casetype") {
|
||||
return this.$t(
|
||||
"commons.report_statistics.report_filter.select_options.case_type"
|
||||
);
|
||||
} else if (groupName === "casestatus") {
|
||||
return this.$t(
|
||||
"commons.report_statistics.report_filter.select_options.case_status"
|
||||
);
|
||||
} else if (groupName === "caselevel") {
|
||||
return this.$t(
|
||||
"commons.report_statistics.report_filter.select_options.case_level"
|
||||
);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -269,7 +328,7 @@ export default {
|
|||
yAxis: {},
|
||||
label: {},
|
||||
tooltip: {},
|
||||
series: []
|
||||
series: [],
|
||||
};
|
||||
this.pieOption = {
|
||||
legend: {},
|
||||
|
@ -286,12 +345,12 @@ export default {
|
|||
this.saveReport(reportName);
|
||||
},
|
||||
saveAndSaveAsReport(reportName, saveType) {
|
||||
if (saveType === 'save') {
|
||||
if (saveType === "save") {
|
||||
this.saveReport(reportName);
|
||||
} else if (saveType === 'saveAs') {
|
||||
} else if (saveType === "saveAs") {
|
||||
this.selectAndSaveReport(reportName);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -301,7 +360,7 @@ export default {
|
|||
padding-top: 5px;
|
||||
}
|
||||
|
||||
:deep(.el-main ) {
|
||||
:deep(.el-main) {
|
||||
padding: 0px 20px 0px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card class="ms-test-chart" :style="{ width: w+'px', height: h + 'px'}" ref="msDrawer">
|
||||
<el-card
|
||||
class="ms-test-chart"
|
||||
:style="{ width: w + 'px', height: h + 'px' }"
|
||||
ref="msDrawer"
|
||||
>
|
||||
<el-row class="ms-row">
|
||||
<p class="tip"><span style="margin-left: 5px"></span> {{ $t('commons.report_statistics.chart') }} </p>
|
||||
<p class="tip">
|
||||
<span style="margin-left: 5px"></span>
|
||||
{{ $t("commons.report_statistics.chart") }}
|
||||
</p>
|
||||
<div class="ms-test-chart-header" v-if="!readOnly">
|
||||
<el-dropdown @command="exportCommand" :hide-on-click="false">
|
||||
<span class="el-dropdown-link">
|
||||
{{ $t('commons.export') }}<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
{{ $t("commons.export")
|
||||
}}<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="jpg">JPG</el-dropdown-item>
|
||||
|
@ -14,26 +22,63 @@
|
|||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<span style="margin: 0px 10px 10px">|</span>
|
||||
<el-select v-model="chartType" class="ms-col-type" size="mini" style="width: 100px" @change="generateOption">
|
||||
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in charts"/>
|
||||
<el-select
|
||||
v-model="chartType"
|
||||
class="ms-col-type"
|
||||
size="mini"
|
||||
style="width: 100px"
|
||||
@change="generateOption"
|
||||
>
|
||||
<el-option
|
||||
:key="t.id"
|
||||
:value="t.id"
|
||||
:label="t.name"
|
||||
v-for="t in charts"
|
||||
/>
|
||||
</el-select>
|
||||
<span style="margin: 0px 10px 10px">|</span>
|
||||
<el-select v-model="order" class="ms-col-type" size="mini" style="width: 120px" @change="orderCharts">
|
||||
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in orders"/>
|
||||
<el-select
|
||||
v-model="order"
|
||||
class="ms-col-type"
|
||||
size="mini"
|
||||
style="width: 120px"
|
||||
@change="orderCharts"
|
||||
>
|
||||
<el-option
|
||||
:key="t.id"
|
||||
:value="t.id"
|
||||
:label="t.name"
|
||||
v-for="t in orders"
|
||||
/>
|
||||
</el-select>
|
||||
<span style="margin: 0px 10px 10px">|</span>
|
||||
<font-awesome-icon v-if="!isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'expand-alt']"
|
||||
size="lg" @click="fullScreen"/>
|
||||
<font-awesome-icon v-if="isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'compress-alt']"
|
||||
size="lg" @click="unFullScreen"/>
|
||||
<font-awesome-icon
|
||||
v-if="!isFullScreen && showFullScreen"
|
||||
class="report-alt-ico"
|
||||
:icon="['fa', 'expand-alt']"
|
||||
size="lg"
|
||||
@click="fullScreen"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
v-if="isFullScreen && showFullScreen"
|
||||
class="report-alt-ico"
|
||||
:icon="['fa', 'compress-alt']"
|
||||
size="lg"
|
||||
@click="unFullScreen"
|
||||
/>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div class="chart-style">
|
||||
<ms-chart ref="chart1" v-if="!loading" :options="dataOption"
|
||||
:style="{width: chartWidthNumber+'px', height: (h-70) + 'px'}" class="chart-config"
|
||||
:autoresize="true"
|
||||
id="picChart"/>
|
||||
<ms-chart
|
||||
ref="chart1"
|
||||
v-if="!loading"
|
||||
:options="dataOption"
|
||||
:style="{ width: chartWidthNumber + 'px', height: h - 70 + 'px' }"
|
||||
class="chart-config"
|
||||
:autoresize="true"
|
||||
id="picChart"
|
||||
/>
|
||||
</div>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
@ -42,10 +87,11 @@
|
|||
|
||||
<script>
|
||||
import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
||||
import html2canvas from "html2canvas";
|
||||
|
||||
export default {
|
||||
name: "TestCaseCountChart",
|
||||
components: {MsChart},
|
||||
components: { MsChart },
|
||||
props: {
|
||||
chartWidth: Number,
|
||||
needFullScreen: Boolean,
|
||||
|
@ -68,24 +114,28 @@ export default {
|
|||
type: Boolean,
|
||||
default() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},
|
||||
charts: [
|
||||
{id: 'bar', name: this.$t('commons.report_statistics.bar')},
|
||||
{id: 'pie', name: this.$t('commons.report_statistics.pie')}
|
||||
{ id: "bar", name: this.$t("commons.report_statistics.bar") },
|
||||
{ id: "pie", name: this.$t("commons.report_statistics.pie") },
|
||||
],
|
||||
order: "",
|
||||
orders: [{id: '', name: this.$t('commons.sort_default')}, {
|
||||
id: 'desc',
|
||||
name: this.$t('commons.report_statistics.desc')
|
||||
}, {
|
||||
id: 'asc',
|
||||
name: this.$t('commons.report_statistics.asc')
|
||||
}],
|
||||
orders: [
|
||||
{ id: "", name: this.$t("commons.sort_default") },
|
||||
{
|
||||
id: "desc",
|
||||
name: this.$t("commons.report_statistics.desc"),
|
||||
},
|
||||
{
|
||||
id: "asc",
|
||||
name: this.$t("commons.report_statistics.asc"),
|
||||
},
|
||||
],
|
||||
loading: false,
|
||||
options: {},
|
||||
chartType: "bar",
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.dataOption = this.loadOption;
|
||||
|
@ -104,32 +154,109 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
reCountWidth(isHideOther) {
|
||||
if (isHideOther) {
|
||||
this.w = document.documentElement.clientWidth - 50;
|
||||
} else {
|
||||
this.w = document.documentElement.clientWidth - 760;
|
||||
}
|
||||
this.generateOption(this.chartType);
|
||||
this.countChartWidth();
|
||||
this.reload();
|
||||
},
|
||||
countChartWidth() {
|
||||
if (this.chartWidth === 0 || this.chartType === 'bar') {
|
||||
if (this.chartWidth === 0 || this.chartType === "bar") {
|
||||
this.chartWidthNumber = this.w;
|
||||
} else if (
|
||||
this.chartType === "pie" &&
|
||||
this.dataOption.width &&
|
||||
this.dataOption.width > 0
|
||||
) {
|
||||
this.chartWidthNumber = this.dataOption.width;
|
||||
} else {
|
||||
this.chartWidthNumber = this.chartWidth;
|
||||
}
|
||||
},
|
||||
orderCharts() {
|
||||
this.$emit('orderCharts', this.order);
|
||||
this.$emit("orderCharts", this.order);
|
||||
},
|
||||
generateOption(chartTypeParam) {
|
||||
if (chartTypeParam) {
|
||||
this.chartType = chartTypeParam;
|
||||
}
|
||||
if (this.chartType === 'pie') {
|
||||
this.dataOption = this.pieOption;
|
||||
if (this.chartType === "pie") {
|
||||
this.dataOption = this.formatPieOption(this.pieOption);
|
||||
} else {
|
||||
this.dataOption = this.loadOption;
|
||||
}
|
||||
if (this.dataOption.series) {
|
||||
this.dataOption.series.forEach(item => {
|
||||
item.type = this.chartType;
|
||||
this.dataOption.series.forEach((item) => {
|
||||
item.type = chartTypeParam;
|
||||
});
|
||||
}
|
||||
this.reload();
|
||||
},
|
||||
formatPieOption(reformatPieOption) {
|
||||
let finalPieOption = reformatPieOption;
|
||||
/**
|
||||
* 根据现有的 width,动态计算饼图各个模块的位置。
|
||||
* 假设饼图共n个, 一行为c,一共r行
|
||||
* 则 r 取 200 + 350 * c <= width 的最大值。
|
||||
* 高度为: n/r 进一法取整数, height = 200*n
|
||||
* 第一行
|
||||
* 第一个饼图位置(center属性)为:"center": ["200", "150"],title位置:"left": "200","top": "200",
|
||||
* 第二个饼图位置(center属性)为:"center": ["550", "150"],title位置:"left": "550","top": "200",
|
||||
* 第二行
|
||||
* 第一个饼图位置(center属性)为:"center": ["200", "350"],title位置:"left": "200","top": "400",
|
||||
* 第二个饼图位置(center属性)为:"center": ["550", "350"],title位置:"left": "550","top": "400",
|
||||
*/
|
||||
this.h = document.documentElement.clientHeight * 0.5;
|
||||
// "series" "title"
|
||||
if (
|
||||
finalPieOption.series &&
|
||||
finalPieOption.title &&
|
||||
finalPieOption.series.length > 0 &&
|
||||
finalPieOption.series.length === finalPieOption.title.length
|
||||
) {
|
||||
let cNum = 0;
|
||||
let rNum = 0;
|
||||
let countWidth = this.w;
|
||||
let countHeight = 0;
|
||||
let allPieCount = finalPieOption.series.length;
|
||||
if (countWidth >= 550) {
|
||||
countWidth = countWidth - 200;
|
||||
do {
|
||||
cNum++;
|
||||
countWidth = countWidth - 350;
|
||||
} while (countWidth > 350);
|
||||
if (cNum > 0) {
|
||||
rNum = Math.ceil(allPieCount / cNum);
|
||||
countHeight = 200 * rNum + 100;
|
||||
if (countHeight > this.h) {
|
||||
this.h = countHeight;
|
||||
}
|
||||
let pieRowIndex = 1; //饼状图起始行
|
||||
for (let pieIndex = 0; pieIndex < allPieCount; pieIndex++) {
|
||||
if (pieIndex >= cNum * pieRowIndex) {
|
||||
pieRowIndex++;
|
||||
}
|
||||
let pieInRow = pieIndex;
|
||||
if (pieIndex >= cNum) {
|
||||
pieInRow = pieIndex % cNum;
|
||||
}
|
||||
finalPieOption.series[pieIndex].center = [
|
||||
200 + 350 * pieInRow,
|
||||
200 * pieRowIndex - 60,
|
||||
];
|
||||
finalPieOption.title[pieIndex].left = 200 + 350 * pieInRow;
|
||||
finalPieOption.title[pieIndex].top = 200 * pieRowIndex;
|
||||
}
|
||||
finalPieOption.width = this.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
return finalPieOption;
|
||||
},
|
||||
setPieOptionAndBarOption(barOption, pieOption) {
|
||||
if (barOption) {
|
||||
this.loadOption = barOption;
|
||||
|
@ -139,33 +266,32 @@ export default {
|
|||
}
|
||||
},
|
||||
reload() {
|
||||
this.loading = true
|
||||
this.loading = true;
|
||||
this.$nextTick(() => {
|
||||
this.loading = false;
|
||||
})
|
||||
});
|
||||
},
|
||||
fullScreen() {
|
||||
this.originalW = this.w;
|
||||
this.originalH = this.h;
|
||||
this.w = document.body.clientWidth - 50;
|
||||
this.h = document.body.clientHeight;
|
||||
this.isFullScreen = true;
|
||||
this.$emit('hidePage', true);
|
||||
this.$emit("hidePage", true);
|
||||
},
|
||||
unFullScreen() {
|
||||
this.w = this.originalW;
|
||||
this.h = this.originalH;
|
||||
this.isFullScreen = false;
|
||||
this.$emit('hidePage', false);
|
||||
this.$emit("hidePage", false);
|
||||
},
|
||||
getImages(command) {
|
||||
let imageType = 'image/png';
|
||||
if (command === 'jpg') {
|
||||
imageType = 'image/jpg';
|
||||
let imageType = "image/png";
|
||||
if (command === "jpg") {
|
||||
imageType = "image/jpg";
|
||||
}
|
||||
let returnImageData = "";
|
||||
if (document.getElementById('picChart')) {
|
||||
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0];
|
||||
if (document.getElementById("picChart")) {
|
||||
let chartsCanvas = document
|
||||
.getElementById("picChart")
|
||||
.querySelectorAll("canvas")[0];
|
||||
if (chartsCanvas) {
|
||||
// toDataURL()是canvas对象的一种方法,用于将canvas对象转换为base64位编码
|
||||
returnImageData = chartsCanvas && chartsCanvas.toDataURL(imageType);
|
||||
|
@ -175,46 +301,50 @@ export default {
|
|||
return returnImageData;
|
||||
},
|
||||
exportCommand(command) {
|
||||
let fileName = 'report_pic.' + command;
|
||||
if (document.getElementById('picChart')) {
|
||||
let chartsCanvas = document.getElementById('picChart').querySelectorAll('canvas')[0]
|
||||
let mime = 'image/png';
|
||||
if (command === 'jpg') {
|
||||
mime = 'image/jpg';
|
||||
let fileName = "report_pic." + command;
|
||||
if (document.getElementById("picChart")) {
|
||||
let chartsCanvas = document
|
||||
.getElementById("picChart")
|
||||
.querySelectorAll("canvas")[0];
|
||||
let mime = "image/png";
|
||||
if (command === "jpg") {
|
||||
mime = "image/jpg";
|
||||
}
|
||||
if (chartsCanvas) {
|
||||
// toDataURL()是canvas对象的一种方法,用于将canvas对象转换为base64位编码
|
||||
let imageUrl = chartsCanvas && chartsCanvas.toDataURL(mime)
|
||||
if (navigator.userAgent.indexOf('Trident') > -1) {
|
||||
let imageUrl = chartsCanvas && chartsCanvas.toDataURL(mime);
|
||||
if (navigator.userAgent.indexOf("Trident") > -1) {
|
||||
// IE11
|
||||
let arr = imageUrl.split(',')
|
||||
let arr = imageUrl.split(",");
|
||||
// atob() 函数对已经使用base64编码编码的数据字符串进行解码
|
||||
let bstr = atob(arr[1])
|
||||
let bstrLen = bstr.length
|
||||
let bstr = atob(arr[1]);
|
||||
let bstrLen = bstr.length;
|
||||
// Uint8Array, 开辟 8 位无符号整数值的类型化数组。内容将初始化为 0
|
||||
let u8arr = new Uint8Array(bstrLen)
|
||||
let u8arr = new Uint8Array(bstrLen);
|
||||
while (bstrLen--) {
|
||||
// charCodeAt() 方法可返回指定位置的字符的 Unicode 编码
|
||||
u8arr[bstrLen] = bstr.charCodeAt(bstrLen)
|
||||
u8arr[bstrLen] = bstr.charCodeAt(bstrLen);
|
||||
}
|
||||
// msSaveOrOpenBlob 方法允许用户在客户端上保存文件,方法如同从 Internet 下载文件,这是此类文件保存到“下载”文件夹的原因
|
||||
window.navigator.msSaveOrOpenBlob(new Blob([u8arr], {type: mime}), fileName);
|
||||
window.navigator.msSaveOrOpenBlob(
|
||||
new Blob([u8arr], { type: mime }),
|
||||
fileName
|
||||
);
|
||||
} else {
|
||||
// 其他浏览器
|
||||
let $a = document.createElement('a')
|
||||
$a.setAttribute('href', imageUrl)
|
||||
$a.setAttribute('download', fileName)
|
||||
$a.click()
|
||||
let $a = document.createElement("a");
|
||||
$a.setAttribute("href", imageUrl);
|
||||
$a.setAttribute("download", fileName);
|
||||
$a.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-test-chart-header {
|
||||
z-index: 999;
|
||||
width: 380px;
|
||||
|
@ -234,7 +364,7 @@ export default {
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
:deep(.echarts ) {
|
||||
:deep(.echarts) {
|
||||
height: calc(100vh / 1.95);
|
||||
}
|
||||
|
||||
|
@ -258,8 +388,7 @@ export default {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-card__body ) {
|
||||
:deep(.el-card__body) {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,46 +1,63 @@
|
|||
<template>
|
||||
<div v-loading="loading" class="ms-div">
|
||||
<el-card :style="{ width: w+'px'}">
|
||||
<el-card :style="{ width: w + 'px' }">
|
||||
<el-row style="padding-top: 10px">
|
||||
<p class="tip"><span style="margin-left: 5px"></span>{{ $t('commons.report_statistics.excel') }} </p>
|
||||
<p class="tip">
|
||||
<span style="margin-left: 5px"></span
|
||||
>{{ $t("commons.report_statistics.excel") }}
|
||||
</p>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-table
|
||||
:data="tableData"
|
||||
:max-height="tableHeight"
|
||||
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
row-key="id"
|
||||
border
|
||||
class="ms-table">
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="groupName">
|
||||
</el-table-column>
|
||||
class="ms-table"
|
||||
>
|
||||
<el-table-column prop="name" :label="groupName"> </el-table-column>
|
||||
<el-table-column
|
||||
prop="allCount"
|
||||
:label="$t('commons.report_statistics.count')">
|
||||
:label="$t('commons.report_statistics.count')"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="testCaseCount"
|
||||
:label="$t('api_test.home_page.failed_case_list.table_value.case_type.functional')"
|
||||
:label="
|
||||
$t(
|
||||
'api_test.home_page.failed_case_list.table_value.case_type.functional'
|
||||
)
|
||||
"
|
||||
v-if="isShowColumn('testCase')"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="apiCaseCount"
|
||||
:label="$t('api_test.home_page.failed_case_list.table_value.case_type.api')"
|
||||
:label="
|
||||
$t(
|
||||
'api_test.home_page.failed_case_list.table_value.case_type.api'
|
||||
)
|
||||
"
|
||||
v-if="isShowColumn('apiCase')"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="scenarioCaseCount"
|
||||
:label="$t('api_test.home_page.failed_case_list.table_value.case_type.scene')"
|
||||
:label="
|
||||
$t(
|
||||
'api_test.home_page.failed_case_list.table_value.case_type.scene'
|
||||
)
|
||||
"
|
||||
v-if="isShowColumn('scenarioCase')"
|
||||
>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="loadCaseCount"
|
||||
:label="$t('api_test.home_page.failed_case_list.table_value.case_type.load')"
|
||||
:label="
|
||||
$t(
|
||||
'api_test.home_page.failed_case_list.table_value.case_type.load'
|
||||
)
|
||||
"
|
||||
v-if="isShowColumn('loadCase')"
|
||||
>
|
||||
</el-table-column>
|
||||
|
@ -62,15 +79,15 @@ export default {
|
|||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableHeight: "100px",
|
||||
w: document.documentElement.clientWidth - 760,
|
||||
loading: false,
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getTableHeight();
|
||||
|
@ -79,25 +96,30 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
reCountWidth(isHideOther) {
|
||||
if (isHideOther) {
|
||||
this.w = document.documentElement.clientWidth - 50;
|
||||
} else {
|
||||
this.w = document.documentElement.clientWidth - 760;
|
||||
}
|
||||
},
|
||||
isShowColumn(type) {
|
||||
if (this.showColumns) {
|
||||
return this.showColumns.findIndex(item => item === type) >= 0;
|
||||
return this.showColumns.findIndex((item) => item === type) >= 0;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
getTableHeight() {
|
||||
let countNumber = document.documentElement.clientHeight * 0.4 / 1 - 140;
|
||||
let countNumber = (document.documentElement.clientHeight * 0.4) / 1 - 140;
|
||||
countNumber = Math.ceil(countNumber);
|
||||
this.tableHeight = countNumber + 'px';
|
||||
}
|
||||
this.tableHeight = countNumber + "px";
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.tip {
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
|
@ -115,8 +137,7 @@ export default {
|
|||
margin: 20px;
|
||||
}
|
||||
|
||||
:deep( .el-card__body ) {
|
||||
:deep(.el-card__body) {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,23 +1,36 @@
|
|||
<template>
|
||||
<div :style="{ height: h + 'px'}">
|
||||
<div :style="{ height: h + 'px' }">
|
||||
<el-container v-loading="loading" style="overflow: scroll">
|
||||
<el-container class="ms-row">
|
||||
<el-aside :width="!isHide ?'235px':'0px'" style="margin-left: 5px; max-height: 843px">
|
||||
<history-report-data report-type="TEST_CASE_ANALYSIS"
|
||||
@selectReport="selectReport" @removeHistoryReportId="removeHistoryReportId"
|
||||
ref="historyReport"/>
|
||||
<el-aside
|
||||
:width="!isHide ? '235px' : '0px'"
|
||||
style="margin-left: 5px; max-height: 843px"
|
||||
>
|
||||
<history-report-data
|
||||
report-type="TEST_CASE_ANALYSIS"
|
||||
@selectReport="selectReport"
|
||||
@removeHistoryReportId="removeHistoryReportId"
|
||||
ref="historyReport"
|
||||
/>
|
||||
</el-aside>
|
||||
<el-main class="ms-main" id="reportAnalysis">
|
||||
<div>
|
||||
<test-analysis-chart @hidePage="hidePage" @orderCharts="orderCharts" ref="analysisChart"
|
||||
:load-option="loadOption"/>
|
||||
<test-analysis-chart
|
||||
@hidePage="hidePage"
|
||||
@orderCharts="orderCharts"
|
||||
ref="analysisChart"
|
||||
:load-option="loadOption"
|
||||
/>
|
||||
</div>
|
||||
<div class="ms-row" v-if="!isHide">
|
||||
<test-analysis-table :tableData="tableData"/>
|
||||
<test-analysis-table :tableData="tableData" />
|
||||
</div>
|
||||
</el-main>
|
||||
<el-aside :width="!isHide ?'485px':'0px'">
|
||||
<test-analysis-filter @filterCharts="filterCharts" ref="analysisFilter"/>
|
||||
<el-aside :width="!isHide ? '485px' : '0px'">
|
||||
<test-analysis-filter
|
||||
@filterCharts="filterCharts"
|
||||
ref="analysisFilter"
|
||||
/>
|
||||
</el-aside>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
@ -28,16 +41,25 @@
|
|||
import TestAnalysisChart from "./chart/TestAnalysisChart";
|
||||
import TestAnalysisTable from "./table/TestAnalysisTable";
|
||||
import TestAnalysisFilter from "./filter/TestAnalysisFilter";
|
||||
import {getCurrentProjectID} from "metersphere-frontend/src/utils/token";
|
||||
import {exportPdf} from "metersphere-frontend/src/utils";
|
||||
import {getAnalysisReport} from "@/api/report";
|
||||
import html2canvas from 'html2canvas';
|
||||
import { getCurrentProjectID } from "metersphere-frontend/src/utils/token";
|
||||
import { exportPdf } from "metersphere-frontend/src/utils";
|
||||
import { getAnalysisReport } from "@/api/report";
|
||||
import html2canvas from "html2canvas";
|
||||
import HistoryReportData from "../../base/HistoryReportData";
|
||||
import {createHistoryReport, selectHistoryReportById, updateHistoryReport} from "@/api/history-report";
|
||||
import {
|
||||
createHistoryReport,
|
||||
selectHistoryReportById,
|
||||
updateHistoryReport,
|
||||
} from "@/api/history-report";
|
||||
|
||||
export default {
|
||||
name: "TestAnalysisContainer",
|
||||
components: {TestAnalysisChart, TestAnalysisTable, TestAnalysisFilter, HistoryReportData},
|
||||
components: {
|
||||
TestAnalysisChart,
|
||||
TestAnalysisTable,
|
||||
TestAnalysisFilter,
|
||||
HistoryReportData,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isHide: false,
|
||||
|
@ -49,35 +71,41 @@ export default {
|
|||
yAxis: {},
|
||||
label: {},
|
||||
tooltip: {},
|
||||
series: []
|
||||
series: [],
|
||||
},
|
||||
tableData: [],
|
||||
h: document.documentElement.clientHeight - 40,
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleExport() {
|
||||
let name = this.$t('commons.report_statistics.test_case_analysis');
|
||||
this.hidePage(true);
|
||||
let name = this.$t("commons.report_statistics.test_case_analysis");
|
||||
this.$nextTick(function () {
|
||||
setTimeout(() => {
|
||||
html2canvas(document.getElementById('reportAnalysis'), {
|
||||
scale: 2
|
||||
}).then(function (canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
});
|
||||
html2canvas(document.getElementById("reportAnalysis"), {
|
||||
scale: 2,
|
||||
})
|
||||
.then(function (canvas) {
|
||||
exportPdf(name, [canvas]);
|
||||
})
|
||||
.then(() => {
|
||||
this.hidePage(false);
|
||||
});
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
hidePage(isHide) {
|
||||
this.isHide = isHide;
|
||||
this.$refs.analysisChart.reCountWidth(isHide);
|
||||
},
|
||||
close() {
|
||||
this.$emit('closePage');
|
||||
this.$emit("closePage");
|
||||
},
|
||||
init(opt) {
|
||||
this.loading = true;
|
||||
this.options = opt;
|
||||
getAnalysisReport(opt).then(response => {
|
||||
getAnalysisReport(opt).then((response) => {
|
||||
let data = response.data.chartDTO;
|
||||
let tableDTOs = response.data.tableDTOs;
|
||||
this.initPic(data, tableDTOs);
|
||||
|
@ -102,9 +130,9 @@ export default {
|
|||
tableData: this.tableData,
|
||||
};
|
||||
obj.dataOption = JSON.stringify(dataOptionObj);
|
||||
obj.reportType = 'TEST_CASE_ANALYSIS';
|
||||
obj.reportType = "TEST_CASE_ANALYSIS";
|
||||
updateHistoryReport(obj).then(() => {
|
||||
this.$alert(this.$t('commons.save_success'));
|
||||
this.$alert(this.$t("commons.save_success"));
|
||||
this.$refs.historyReport.initReportData();
|
||||
});
|
||||
},
|
||||
|
@ -119,9 +147,9 @@ export default {
|
|||
tableData: this.tableData,
|
||||
};
|
||||
obj.dataOption = JSON.stringify(dataOptionObj);
|
||||
obj.reportType = 'TEST_CASE_ANALYSIS';
|
||||
obj.reportType = "TEST_CASE_ANALYSIS";
|
||||
createHistoryReport(obj).then(() => {
|
||||
this.$alert(this.$t('commons.save_success'));
|
||||
this.$alert(this.$t("commons.save_success"));
|
||||
this.$refs.historyReport.initReportData();
|
||||
});
|
||||
},
|
||||
|
@ -132,11 +160,11 @@ export default {
|
|||
this.loadOption.xAxis = loadOptionParam.xaxis;
|
||||
this.loadOption.series = loadOptionParam.series;
|
||||
this.loadOption.grid = {
|
||||
bottom: '75px',//距离下边距
|
||||
}
|
||||
this.loadOption.series.forEach(item => {
|
||||
bottom: "75px", //距离下边距
|
||||
};
|
||||
this.loadOption.series.forEach((item) => {
|
||||
item.type = this.$refs.analysisChart.chartType;
|
||||
})
|
||||
});
|
||||
}
|
||||
if (tableData) {
|
||||
this.tableData = tableData;
|
||||
|
@ -148,32 +176,37 @@ export default {
|
|||
if (selectId) {
|
||||
this.loading = true;
|
||||
let paramObj = {
|
||||
id: selectId
|
||||
}
|
||||
selectHistoryReportById(paramObj).then(response => {
|
||||
let reportData = response.data;
|
||||
if (reportData) {
|
||||
selectName = reportData.name;
|
||||
if (reportData.dataOption) {
|
||||
let dataOptionObj = JSON.parse(reportData.dataOption);
|
||||
this.initPic(dataOptionObj.loadOption, dataOptionObj.pieOption, dataOptionObj.tableData);
|
||||
id: selectId,
|
||||
};
|
||||
selectHistoryReportById(paramObj)
|
||||
.then((response) => {
|
||||
let reportData = response.data;
|
||||
if (reportData) {
|
||||
selectName = reportData.name;
|
||||
if (reportData.dataOption) {
|
||||
let dataOptionObj = JSON.parse(reportData.dataOption);
|
||||
this.initPic(
|
||||
dataOptionObj.loadOption,
|
||||
dataOptionObj.pieOption,
|
||||
dataOptionObj.tableData
|
||||
);
|
||||
}
|
||||
if (reportData.selectOption) {
|
||||
let selectOptionObj = JSON.parse(reportData.selectOption);
|
||||
this.$refs.analysisFilter.initSelectOption(selectOptionObj);
|
||||
}
|
||||
}
|
||||
if (reportData.selectOption) {
|
||||
let selectOptionObj = JSON.parse(reportData.selectOption);
|
||||
this.$refs.analysisFilter.initSelectOption(selectOptionObj);
|
||||
}
|
||||
}
|
||||
this.$emit('initHistoryReportId', selectId, selectName);
|
||||
this.loading = false;
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
this.removeHistoryReportId();
|
||||
});
|
||||
|
||||
this.$emit("initHistoryReportId", selectId, selectName);
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
this.removeHistoryReportId();
|
||||
});
|
||||
}
|
||||
},
|
||||
removeHistoryReportId() {
|
||||
this.$emit('initHistoryReportId', "", "");
|
||||
this.$emit("initHistoryReportId", "", "");
|
||||
},
|
||||
selectAndSaveReport(reportName) {
|
||||
let opt = this.$refs.analysisFilter.getOption();
|
||||
|
@ -181,14 +214,14 @@ export default {
|
|||
this.saveReport(reportName);
|
||||
},
|
||||
saveAndSaveAsReport(reportName, saveType) {
|
||||
if (saveType === 'save') {
|
||||
if (saveType === "save") {
|
||||
this.saveReport(reportName);
|
||||
} else if (saveType === 'saveAs') {
|
||||
} else if (saveType === "saveAs") {
|
||||
this.selectAndSaveReport(reportName);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -196,7 +229,7 @@ export default {
|
|||
padding-top: 10px;
|
||||
}
|
||||
|
||||
:deep(.el-main ) {
|
||||
:deep(.el-main) {
|
||||
padding: 0px 20px 0px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,25 +1,69 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card class="ms-test-chart" :style="{ width: w+'px', height: h + 'px'}" ref="msDrawer">
|
||||
<el-card
|
||||
class="ms-test-chart"
|
||||
:style="{ width: w + 'px', height: h + 'px' }"
|
||||
ref="msDrawer"
|
||||
>
|
||||
<el-row class="ms-row">
|
||||
<p class="tip"><span style="margin-left: 5px"></span> {{ $t('commons.report_statistics.chart') }} </p>
|
||||
<p class="tip">
|
||||
<span style="margin-left: 5px"></span>
|
||||
{{ $t("commons.report_statistics.chart") }}
|
||||
</p>
|
||||
<div class="ms-test-chart-header">
|
||||
<el-select v-model="chartType" class="ms-col-type" size="mini" style="width: 100px" @change="generateOption">
|
||||
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in charts"/>
|
||||
<el-select
|
||||
v-model="chartType"
|
||||
class="ms-col-type"
|
||||
size="mini"
|
||||
style="width: 100px"
|
||||
@change="generateOption"
|
||||
>
|
||||
<el-option
|
||||
:key="t.id"
|
||||
:value="t.id"
|
||||
:label="t.name"
|
||||
v-for="t in charts"
|
||||
/>
|
||||
</el-select>
|
||||
<span style="margin: 0px 10px 10px">|</span>
|
||||
<el-select v-model="order" class="ms-col-type" size="mini" style="width: 120px" @change="orderCharts">
|
||||
<el-option :key="t.id" :value="t.id" :label="t.name" v-for="t in orders"/>
|
||||
<el-select
|
||||
v-model="order"
|
||||
class="ms-col-type"
|
||||
size="mini"
|
||||
style="width: 120px"
|
||||
@change="orderCharts"
|
||||
>
|
||||
<el-option
|
||||
:key="t.id"
|
||||
:value="t.id"
|
||||
:label="t.name"
|
||||
v-for="t in orders"
|
||||
/>
|
||||
</el-select>
|
||||
<span style="margin: 0px 10px 10px">|</span>
|
||||
<font-awesome-icon v-if="!isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'expand-alt']" size="lg"
|
||||
@click="fullScreen"/>
|
||||
<font-awesome-icon v-if="isFullScreen && showFullScreen" class="report-alt-ico" :icon="['fa', 'compress-alt']" size="lg"
|
||||
@click="unFullScreen"/>
|
||||
<font-awesome-icon
|
||||
v-if="!isFullScreen && showFullScreen"
|
||||
class="report-alt-ico"
|
||||
:icon="['fa', 'expand-alt']"
|
||||
size="lg"
|
||||
@click="fullScreen"
|
||||
/>
|
||||
<font-awesome-icon
|
||||
v-if="isFullScreen && showFullScreen"
|
||||
class="report-alt-ico"
|
||||
:icon="['fa', 'compress-alt']"
|
||||
size="lg"
|
||||
@click="unFullScreen"
|
||||
/>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<ms-chart ref="chart1" :options="loadOption" class="chart-config" :autoresize="true"/>
|
||||
<ms-chart
|
||||
ref="chart1"
|
||||
:options="loadOption"
|
||||
class="chart-config"
|
||||
:autoresize="true"
|
||||
/>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
|
@ -32,7 +76,7 @@ import MsChart from "metersphere-frontend/src/components/chart/MsChart";
|
|||
|
||||
export default {
|
||||
name: "TestAnalysisChart",
|
||||
components: {MsChart},
|
||||
components: { MsChart },
|
||||
props: {
|
||||
loadOption: {},
|
||||
},
|
||||
|
@ -49,35 +93,50 @@ export default {
|
|||
type: Boolean,
|
||||
default() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
},
|
||||
// 头部部分
|
||||
chartType: "line",
|
||||
charts: [{id: 'line', name: this.$t('commons.report_statistics.line')}, {id: 'bar', name: this.$t('commons.report_statistics.bar')}],
|
||||
charts: [
|
||||
{ id: "line", name: this.$t("commons.report_statistics.line") },
|
||||
{ id: "bar", name: this.$t("commons.report_statistics.bar") },
|
||||
],
|
||||
order: "",
|
||||
orders: [{id: '', name: this.$t('commons.sort_default')}, {id: 'desc', name: this.$t('commons.report_statistics.desc')}, {
|
||||
id: 'asc',
|
||||
name: this.$t('commons.report_statistics.asc')
|
||||
}],
|
||||
orders: [
|
||||
{ id: "", name: this.$t("commons.sort_default") },
|
||||
{ id: "desc", name: this.$t("commons.report_statistics.desc") },
|
||||
{
|
||||
id: "asc",
|
||||
name: this.$t("commons.report_statistics.asc"),
|
||||
},
|
||||
],
|
||||
loading: false,
|
||||
options: {},
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
reCountWidth(isHideOther) {
|
||||
if (isHideOther) {
|
||||
this.w = document.documentElement.clientWidth - 20;
|
||||
} else {
|
||||
this.w = document.documentElement.clientWidth - 760;
|
||||
}
|
||||
this.reload();
|
||||
},
|
||||
orderCharts() {
|
||||
this.$emit('orderCharts', this.order);
|
||||
this.$emit("orderCharts", this.order);
|
||||
},
|
||||
generateOption() {
|
||||
this.loadOption.series.forEach(item => {
|
||||
this.loadOption.series.forEach((item) => {
|
||||
item.type = this.chartType;
|
||||
})
|
||||
});
|
||||
this.reload();
|
||||
},
|
||||
reload() {
|
||||
this.loading = true
|
||||
this.loading = true;
|
||||
this.$nextTick(() => {
|
||||
this.loading = false
|
||||
})
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
fullScreen() {
|
||||
this.originalW = this.w;
|
||||
|
@ -85,23 +144,22 @@ export default {
|
|||
this.w = document.body.clientWidth - 50;
|
||||
this.h = document.body.clientHeight;
|
||||
this.isFullScreen = true;
|
||||
this.$emit('hidePage', true);
|
||||
this.$emit("hidePage", true);
|
||||
},
|
||||
unFullScreen() {
|
||||
this.w = this.originalW;
|
||||
this.h = this.originalH;
|
||||
this.isFullScreen = false;
|
||||
this.$emit('hidePage', false);
|
||||
this.$emit("hidePage", false);
|
||||
},
|
||||
getOptions() {
|
||||
return this.loadOption;
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.ms-test-chart-header {
|
||||
z-index: 999;
|
||||
width: 320px;
|
||||
|
@ -121,7 +179,7 @@ export default {
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
:deep(.echarts ) {
|
||||
:deep(.echarts) {
|
||||
height: calc(100vh / 1.95);
|
||||
}
|
||||
|
||||
|
@ -141,8 +199,7 @@ export default {
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
:deep(.el-card__body ) {
|
||||
:deep(.el-card__body) {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue