refactor: 默认使用svg渲染echart

This commit is contained in:
Captain.B 2020-08-26 16:23:31 +08:00
parent e483748b97
commit b653848594
8 changed files with 452 additions and 397 deletions

View File

@ -5,22 +5,22 @@
<el-row type="flex" justify="center" align="middle"> <el-row type="flex" justify="center" align="middle">
<el-row> <el-row>
<div class="metric-time"> <div class="metric-time">
<div class="value" style="margin-right: 50px">{{time}}</div> <div class="value" style="margin-right: 50px">{{ time }}</div>
</div> </div>
</el-row> </el-row>
<chart id="chart" ref="chart" :options="options" :autoresize="true"></chart> <ms-chart id="chart" ref="chart" :options="options" :autoresize="true"></ms-chart>
<el-row type="flex" justify="center" align="middle"> <el-row type="flex" justify="center" align="middle">
<i class="circle success"/> <i class="circle success"/>
<div class="metric-box"> <div class="metric-box">
<div class="value">{{content.success}}</div> <div class="value">{{ content.success }}</div>
<div class="name">{{$t('api_report.success')}}</div> <div class="name">{{ $t('api_report.success') }}</div>
</div> </div>
<div style="width: 40px"></div> <div style="width: 40px"></div>
<i class="circle fail"/> <i class="circle fail"/>
<div class="metric-box"> <div class="metric-box">
<div class="value">{{content.error}}</div> <div class="value">{{ content.error }}</div>
<div class="name">{{$t('api_report.fail')}}</div> <div class="name">{{ $t('api_report.fail') }}</div>
</div> </div>
</el-row> </el-row>
</el-row> </el-row>
@ -30,18 +30,18 @@
<el-row type="flex" justify="space-around" align="middle"> <el-row type="flex" justify="space-around" align="middle">
<div class="metric-icon-box"> <div class="metric-icon-box">
<i class="el-icon-warning-outline fail"></i> <i class="el-icon-warning-outline fail"></i>
<div class="value">{{fail}}</div> <div class="value">{{ fail }}</div>
<div class="name">{{$t('api_report.fail')}}</div> <div class="name">{{ $t('api_report.fail') }}</div>
</div> </div>
<div class="metric-icon-box"> <div class="metric-icon-box">
<i class="el-icon-document-checked assertions"></i> <i class="el-icon-document-checked assertions"></i>
<div class="value">{{assertions}}</div> <div class="value">{{ assertions }}</div>
<div class="name">{{$t('api_report.assertions_pass')}}</div> <div class="name">{{ $t('api_report.assertions_pass') }}</div>
</div> </div>
<div class="metric-icon-box"> <div class="metric-icon-box">
<i class="el-icon-document-copy total"></i> <i class="el-icon-document-copy total"></i>
<div class="value">{{this.content.total}}</div> <div class="value">{{ this.content.total }}</div>
<div class="name">{{$t('api_report.request')}}</div> <div class="name">{{ $t('api_report.request') }}</div>
</div> </div>
</el-row> </el-row>
</div> </div>
@ -50,203 +50,205 @@
</template> </template>
<script> <script>
export default { import MsChart from "@/business/components/common/chart/MsChart";
name: "MsMetricChart",
props: { export default {
content: Object, name: "MsMetricChart",
totalTime: Number components: {MsChart},
}, props: {
data() { content: Object,
return { totalTime: Number
hour:0, },
minutes: 0, data() {
seconds: 0, return {
time: 0 hour: 0,
minutes: 0,
seconds: 0,
time: 0,
}
},
created() {
this.initTime()
},
methods: {
initTime() {
this.time = this.totalTime
this.seconds = Math.floor(this.time / 1000)
if (this.seconds >= 1) {
if (this.seconds > 60) {
this.minutes = Math.round(this.time / 60)
this.seconds = Math.round(this.time % 60)
this.time = this.minutes + "min" + this.seconds + "s"
}
if (this.seconds > 60) {
this.minutes = Math.round(this.time / 60)
this.seconds = Math.round(this.time % 60)
this.time = this.minutes + "min" + this.seconds + "s"
}
if (this.minutes > 60) {
this.hour = Math.round(this.minutes / 60)
this.minutes = Math.round(this.minutes % 60)
this.time = this.hour + "hour" + this.minutes + "min" + this.seconds + "s"
}
this.time = (this.seconds) + "s"
} else {
this.time = this.totalTime + "ms"
} }
}, },
created() { },
this.initTime() computed: {
}, options() {
methods: { return {
initTime() { color: ['#67C23A', '#F56C6C'],
this.time = this.totalTime tooltip: {
this.seconds = Math.floor(this.time / 1000) trigger: 'item',
if (this.seconds >= 1) { formatter: '{b}: {c} ({d}%)'
if (this.seconds > 60) { },
this.minutes = Math.round(this.time / 60) title: [{
this.seconds = Math.round(this.time % 60) text: '{value|' + this.content.total + '}\n{name|' + this.$t('api_report.request') + '}',
this.time = this.minutes + "min" + this.seconds + "s" top: 'center',
} left: 'center',
if (this.seconds > 60) { textStyle: {
this.minutes = Math.round(this.time / 60) rich: {
this.seconds = Math.round(this.time % 60) align: 'center',
this.time = this.minutes + "min" + this.seconds + "s" value: {
} fontSize: 32,
if (this.minutes > 60) { fontWeight: 'bold',
this.hour = Math.round(this.minutes / 60) padding: [10, 0]
this.minutes = Math.round(this.minutes % 60) },
this.time = this.hour + "hour" + this.minutes + "min" + this.seconds + "s" name: {
} fontSize: 14,
fontWeight: 'normal',
this.time = (this.seconds) + "s" color: '#7F7F7F',
} else {
this.time = this.totalTime + "ms"
}
},
},
computed: {
options() {
return {
color: ['#67C23A', '#F56C6C'],
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)'
},
title: [{
text: '{value|' + this.content.total + '}\n{name|' + this.$t('api_report.request') + '}',
top: 'center',
left: 'center',
textStyle: {
rich: {
align: 'center',
value: {
fontSize: 32,
fontWeight: 'bold',
padding: [10, 0]
},
name: {
fontSize: 14,
fontWeight: 'normal',
color: '#7F7F7F',
}
} }
} }
}], }
series: [ }],
{ series: [
type: 'pie', {
radius: ['80%', '90%'], type: 'pie',
avoidLabelOverlap: false, radius: ['80%', '90%'],
hoverAnimation: false, avoidLabelOverlap: false,
itemStyle: { hoverAnimation: false,
normal: { itemStyle: {
borderColor: "#FFF", normal: {
shadowColor: '#E1E1E1', borderColor: "#FFF",
shadowBlur: 10 shadowColor: '#E1E1E1',
} shadowBlur: 10
}, }
labelLine: { },
show: false labelLine: {
}, show: false
data: [ },
{value: this.content.success}, data: [
{value: this.content.error}, {value: this.content.success},
] {value: this.content.error},
} ]
] }
}; ]
}, };
fail() {
return (this.content.error / this.content.total * 100).toFixed(0) + "%";
},
assertions() {
return this.content.passAssertions + " / " + this.content.totalAssertions;
}
}, },
}
fail() {
return (this.content.error / this.content.total * 100).toFixed(0) + "%";
},
assertions() {
return this.content.passAssertions + " / " + this.content.totalAssertions;
}
},
}
</script> </script>
<style scoped> <style scoped>
.metric-container { .metric-container {
padding: 20px; padding: 20px;
} }
.metric-container #chart { .metric-container #chart {
width: 140px; width: 140px;
height: 140px; height: 140px;
margin-right: 40px; margin-right: 40px;
} }
.metric-container .split { .metric-container .split {
margin: 20px; margin: 20px;
height: 100px; height: 100px;
border-left: 1px solid #D8DBE1; border-left: 1px solid #D8DBE1;
} }
.metric-container .circle { .metric-container .circle {
width: 12px; width: 12px;
height: 12px; height: 12px;
border-radius: 50%; border-radius: 50%;
box-shadow: 0 0 20px 1px rgba(200, 216, 226, .42); box-shadow: 0 0 20px 1px rgba(200, 216, 226, .42);
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
vertical-align: middle; vertical-align: middle;
} }
.metric-container .circle.success { .metric-container .circle.success {
background-color: #67C23A; background-color: #67C23A;
} }
.metric-container .circle.fail { .metric-container .circle.fail {
background-color: #F56C6C; background-color: #F56C6C;
} }
.metric-box { .metric-box {
display: inline-block; display: inline-block;
text-align: center; text-align: center;
} }
.metric-box .value { .metric-box .value {
font-size: 32px; font-size: 32px;
font-weight: 600; font-weight: 600;
letter-spacing: -.5px; letter-spacing: -.5px;
} }
.metric-time .value { .metric-time .value {
font-size: 25px; font-size: 25px;
font-weight: 400; font-weight: 400;
letter-spacing: -.5px; letter-spacing: -.5px;
} }
.metric-box .name { .metric-box .name {
font-size: 16px; font-size: 16px;
letter-spacing: -.2px; letter-spacing: -.2px;
color: #404040; color: #404040;
} }
.metric-icon-box { .metric-icon-box {
text-align: center; text-align: center;
margin: 0 10px; margin: 0 10px;
} }
.metric-icon-box .value { .metric-icon-box .value {
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
letter-spacing: -.4px; letter-spacing: -.4px;
line-height: 28px; line-height: 28px;
vertical-align: middle; vertical-align: middle;
} }
.metric-icon-box .name { .metric-icon-box .name {
font-size: 13px; font-size: 13px;
letter-spacing: 1px; letter-spacing: 1px;
color: #BFBFBF; color: #BFBFBF;
line-height: 18px; line-height: 18px;
} }
.metric-icon-box .fail { .metric-icon-box .fail {
color: #F56C6C; color: #F56C6C;
font-size: 40px; font-size: 40px;
} }
.metric-icon-box .assertions { .metric-icon-box .assertions {
font-size: 40px; font-size: 40px;
} }
.metric-icon-box .total { .metric-icon-box .total {
font-size: 40px; font-size: 40px;
} }
</style> </style>

View File

@ -0,0 +1,41 @@
<template>
<chart
:init-options="defaultInitOptions"
:options="options"
:theme="theme"
:group="group"
:watch-shallow="watchShallow"
:manual-update="manualUpdate"
:autoresize="autoresize"/>
</template>
<script>
export default {
name: "MsChart",
props: {
options: Object,
theme: [String, Object],
initOptions: Object,
group: String,
autoresize: Boolean,
watchShallow: Boolean,
manualUpdate: Boolean
},
data() {
return {
defaultInitOptions: this.initOptions
}
},
mounted() {
this.defaultInitOptions = this.defaultInitOptions || {};
// svg
if (!this.defaultInitOptions.renderer) {
this.defaultInitOptions.renderer = 'svg';
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,27 +1,29 @@
<template> <template>
<div> <div>
<chart :options="options"> <ms-chart :options="options">
</chart> </ms-chart>
</div> </div>
</template> </template>
<script> <script>
export default { import MsChart from "@/business/components/common/chart/MsChart";
name: "MsPieChart",
components: {}, export default {
mounted() { name: "MsPieChart",
this.getDataNamesByData(); components: {MsChart},
}, mounted() {
watch: { this.getDataNamesByData();
data() { },
this.getDataNamesByData(); watch: {
}
},
data() { data() {
return { this.getDataNamesByData();
}
},
data() {
return {
options: { options: {
title: { title: {
text: this.text, text: this.text,

View File

@ -1,194 +1,196 @@
<template> <template>
<chart :options="bar"></chart> <ms-chart :options="bar"></ms-chart>
</template> </template>
<script> <script>
import echarts from 'echarts' import echarts from 'echarts'
import MsChart from "@/business/components/common/chart/MsChart";
export default { export default {
name: "PerformanceChart", name: "PerformanceChart",
data() { components: {MsChart},
return { data() {
bar: { return {
bar: {
backgroundColor: '#394056', backgroundColor: '#394056',
title: { title: {
top: 20, top: 20,
text: 'Requests', text: 'Requests',
textStyle: { textStyle: {
fontWeight: 'normal', fontWeight: 'normal',
fontSize: 16, fontSize: 16,
color: '#F1F1F3' color: '#F1F1F3'
},
left: '1%'
}, },
tooltip: { left: '1%'
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#57617B'
}
}
},
legend: {
top: 20,
icon: 'rect',
itemWidth: 14,
itemHeight: 5,
itemGap: 13,
data: ['CMCC', 'CTCC', 'CUCC'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#F1F1F3'
}
},
grid: {
top: 100,
left: '2%',
right: '2%',
bottom: '2%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
}],
yAxis: [{
type: 'value',
name: '(%)',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: '#57617B'
}
}
}],
series: [{
name: 'CMCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(137, 189, 27, 0.3)'
}, {
offset: 0.8,
color: 'rgba(137, 189, 27, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(137,189,27)',
borderColor: 'rgba(137,189,2,0.27)',
borderWidth: 12
}
},
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
}, {
name: 'CTCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 136, 212, 0.3)'
}, {
offset: 0.8,
color: 'rgba(0, 136, 212, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(0,136,212)',
borderColor: 'rgba(0,136,212,0.2)',
borderWidth: 12
}
},
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
}, {
name: 'CUCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(219, 50, 51, 0.3)'
}, {
offset: 0.8,
color: 'rgba(219, 50, 51, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(219,50,51)',
borderColor: 'rgba(219,50,51,0.2)',
borderWidth: 12
}
},
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
}]
}, },
} tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
color: '#57617B'
}
}
},
legend: {
top: 20,
icon: 'rect',
itemWidth: 14,
itemHeight: 5,
itemGap: 13,
data: ['CMCC', 'CTCC', 'CUCC'],
right: '4%',
textStyle: {
fontSize: 12,
color: '#F1F1F3'
}
},
grid: {
top: 100,
left: '2%',
right: '2%',
bottom: '2%',
containLabel: true
},
xAxis: [{
type: 'category',
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#57617B'
}
},
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55']
}],
yAxis: [{
type: 'value',
name: '(%)',
axisTick: {
show: false
},
axisLine: {
lineStyle: {
color: '#57617B'
}
},
axisLabel: {
margin: 10,
textStyle: {
fontSize: 14
}
},
splitLine: {
lineStyle: {
color: '#57617B'
}
}
}],
series: [{
name: 'CMCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(137, 189, 27, 0.3)'
}, {
offset: 0.8,
color: 'rgba(137, 189, 27, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(137,189,27)',
borderColor: 'rgba(137,189,2,0.27)',
borderWidth: 12
}
},
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122]
}, {
name: 'CTCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(0, 136, 212, 0.3)'
}, {
offset: 0.8,
color: 'rgba(0, 136, 212, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(0,136,212)',
borderColor: 'rgba(0,136,212,0.2)',
borderWidth: 12
}
},
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150]
}, {
name: 'CUCC',
type: 'line',
smooth: true,
symbol: 'circle',
symbolSize: 5,
showSymbol: false,
lineStyle: {
normal: {
width: 1
}
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgba(219, 50, 51, 0.3)'
}, {
offset: 0.8,
color: 'rgba(219, 50, 51, 0)'
}], false),
shadowColor: 'rgba(0, 0, 0, 0.1)',
shadowBlur: 10
}
},
itemStyle: {
normal: {
color: 'rgb(219,50,51)',
borderColor: 'rgba(219,50,51,0.2)',
borderWidth: 12
}
},
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122]
}]
},
} }
} }
}
</script> </script>
<style scoped> <style scoped>

View File

@ -84,7 +84,7 @@
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<div class="title">{{ $t('load_test.pressure_prediction_chart') }}</div> <div class="title">{{ $t('load_test.pressure_prediction_chart') }}</div>
<chart class="chart-container" ref="chart1" :options="orgOptions" :autoresize="true"></chart> <ms-chart class="chart-container" ref="chart1" :options="orgOptions" :autoresize="true"></ms-chart>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -92,6 +92,7 @@
<script> <script>
import echarts from "echarts"; import echarts from "echarts";
import MsChart from "@/business/components/common/chart/MsChart";
const TARGET_LEVEL = "TargetLevel"; const TARGET_LEVEL = "TargetLevel";
const RAMP_UP = "RampUp"; const RAMP_UP = "RampUp";
@ -102,6 +103,7 @@ const RPS_LIMIT_ENABLE = "rpsLimitEnable";
export default { export default {
name: "MsPerformancePressureConfig", name: "MsPerformancePressureConfig",
components: {MsChart},
props: ['report'], props: ['report'],
data() { data() {
return { return {

View File

@ -59,28 +59,31 @@
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<chart ref="chart1" :options="loadOption" class="chart-config" :autoresize="true"></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">
<chart ref="chart2" :options="resOption" class="chart-config" :autoresize="true"></chart> <ms-chart ref="chart2" :options="resOption" class="chart-config" :autoresize="true"></ms-chart>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
</template> </template>
<script> <script>
export default { import MsChart from "@/business/components/common/chart/MsChart";
name: "TestOverview",
data() { export default {
return { name: "TestOverview",
maxUsers: "0", components: {MsChart},
avgThroughput: "0", data() {
errors: "0", return {
avgResponseTime: "0", maxUsers: "0",
responseTime90: "0", avgThroughput: "0",
avgBandwidth: "0", errors: "0",
loadOption: {}, avgResponseTime: "0",
resOption: {}, responseTime90: "0",
avgBandwidth: "0",
loadOption: {},
resOption: {},
id: '' id: ''
} }
}, },

View File

@ -99,7 +99,7 @@
</el-col> </el-col>
<el-col :span="14"> <el-col :span="14">
<div class="title">{{ $t('load_test.pressure_prediction_chart') }}</div> <div class="title">{{ $t('load_test.pressure_prediction_chart') }}</div>
<chart class="chart-container" ref="chart1" :options="orgOptions" :autoresize="true"></chart> <ms-chart class="chart-container" ref="chart1" :options="orgOptions" :autoresize="true"></ms-chart>
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
@ -107,6 +107,7 @@
<script> <script>
import echarts from "echarts"; import echarts from "echarts";
import MsChart from "@/business/components/common/chart/MsChart";
const TARGET_LEVEL = "TargetLevel"; const TARGET_LEVEL = "TargetLevel";
const RAMP_UP = "RampUp"; const RAMP_UP = "RampUp";
@ -117,6 +118,7 @@ const RPS_LIMIT_ENABLE = "rpsLimitEnable";
export default { export default {
name: "PerformancePressureConfig", name: "PerformancePressureConfig",
components: {MsChart},
props: { props: {
testPlan: { testPlan: {
type: Object type: Object

View File

@ -2,6 +2,7 @@ import ECharts from 'vue-echarts'
import 'echarts/lib/chart/line' import 'echarts/lib/chart/line'
import 'echarts/lib/chart/bar' import 'echarts/lib/chart/bar'
import 'echarts/lib/chart/pie' import 'echarts/lib/chart/pie'
import 'zrender/lib/svg/svg'
export default { export default {
install(Vue) { install(Vue) {