组件:随便取名字吧
配置:
dealRate: '89%', // 饼图圆环中心百分比数据 dealLabel: '处置率', // 饼图圆环中心名称 PieWidth: '135', // 旋转饼图的大小 labelImgWidth: '47', // label的图形大小 incidentTop: '19', // 右边tab距离顶部的高度: incident-box的margin-top labelSize: '14', // 右侧label字体样式的大小 labelMarginBottm: '10', // 右侧label字体距离下面字体的距离 numValue: '24', // 右侧Value字体的大小 // 右边小模块的数据数组 tabsList: [{ label: 'XX标题', value: '82554', icon: 'home/waitIncident',//图标icon color: '#FFB82F' },],
<template>
<div class="finish-statistis-container">
<div class="circle-box" :style="`width:` + datalist.PieWidth + `px;` + `height:` + datalist.PieWidth + `px`">
<div class="circle-img" />
<div class="circle-con">
<div class="num">{
{ datalist.dealRate }}</div>
<div class="label">{
{ datalist.dealLabel }}</div>
</div>
</div>
<div class="incident-box" :style="`margin-top:` + datalist.incidentTop + `px`">
<div v-for="item in datalist.tabsList" class="incident">
<img :style="'width:' + datalist.labelImgWidth + 'px;' + 'height:' + datalist.labelImgWidth + 'px'" :src="require(`@img/` + item.icon + `.png`)">
<div class="wait">
<div class="label" :style="`font-size:` + datalist.labelSize + 'px;' + 'margin-bottom:' + datalist.labelMarginBottm + 'px'">{
{ item.label }}</div>
<div class="num" :style="`color:${item.color}` + ';font-size:' + datalist.numValue + 'px;'">{
{ item.value }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
/**
* @param dealRate:饼图圆环中心百分比数据;dealLabel:饼图圆环中心名称;tabsList:右边小模块的数据数组
*
* */
export default {
name: 'PieRotationModel',
props: {
pieData: {
type: Object,
default: () => {}
}
},
data() {
return {
datalist: {
dealRate: '89%', // 饼图圆环中心百分比数据
dealLabel: '处置率', // 饼图圆环中心名称
PieWidth: '135', // 旋转饼图的大小
labelImgWidth: '47', // label的图形大小
incidentTop: '19', // 右边tab距离顶部的高度: incident-box的margin-top
labelSize: '14', // 右侧label字体样式的大小
labelMarginBottm: '10', // 右侧label字体距离下面字体的距离
numValue: '24', // 右侧Value字体的大小
// 右边小模块的数据数组
tabsList: [
{
label: 'XX事件',
value: '82554',
icon: 'home/waitIncident',
color: '#FFB82F'
},
{
label: 'XX事件',
value: '12952',
icon: 'home/finishIncident',
color: '#5DF4E0'
}
]
}
}
},
watch: {
pieData: {
handler(nVue) {
this.datalist.assign(this.pieData)
},
deep: true
}
},
mounted() {
this.datalist = this.pieData
}
}
</script>
<style lang="scss" scoped>
$imgPath: '~@assets/images/home/';
.finish-statistis-container {
display: flex;
padding: 0 20px;
height: calc(100% - 51px);
vertical-align: center;
// 动图样式
.circle-box {
position: relative;
margin-left: 35px;
background: url($imgPath + 'circle-background.png') no-repeat;
background-size: 100% 100%;
}
.circle-img,
.circle-con {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.circle-img {
z-index: 1;
background: url($imgPath + 'circle.png') no-repeat;
background-size: 100% 100%;
animation: rotate 4s linear infinite;
-webkit-animation: rotate 4s linear infinite;
}
.circle-con {
z-index: 2;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.num {
font-size: 24px;
font-weight: bold;
color: #5df4e0;
}
.label {
font-size: 14px;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
}
}
}
// 事件数量
.incident-box {
margin: 19px 0 0 20px;
.incident {
display: flex;
img {
width: 47px;
height: 47px;
}
&:first-child {
margin-bottom: 13px;
}
.finish,
.wait {
margin: 1px 0 0 12px;
}
.wait {
font-size: 24px;
color: #ffb82f;
line-height: 19px;
}
.finish {
font-size: 24px;
color: #5df4e0;
line-height: 19px;
}
.label {
font-size: 14px;
color: #fff;
font-weight: 400;
line-height: 19px;
margin-bottom: 10px;
}
}
}
}
</style>
另一个旋转饼图样式:
options:
options = {
color: color,
legend: {
right: '10%',
top: 'center',
icon: 'circle',
itemWidth: 8,
itemHeight: 8,
itemGap: 11,
color: color,
textStyle: {
color: '#ffffff',
fontsize: 12,
rich: {
title: {
fontSize: 12,
color: 'rgba(214, 244, 255, 1)',
width: 80
},
x: {
fontSize: 12,
color: 'rgba(214, 244, 255, 1)',
width: 10,
textAlign: 'right'
},
value0: {
fontSize: 12,
color: '#05A5FF',
fontWeight: 600
},
value1: {
fontSize: 12,
color: '#44FFA5',
fontWeight: 600
},
value2: {
fontSize: 12,
color: '#FFDD3C',
fontWeight: 600
},
value3: {
fontSize: 12,
color: '#00FFFF',
fontWeight: 600
},
value4: {
fontSize: 12,
color: '#FDE056',
fontWeight: 600
}
}
},
formatter: function(name) {
const item = legend.filter(item => item.name === name)[0]
return '{title|' + name + '} {value' + item.index + '|' + Utils.number.numberThousandFormat(item.nums) + '}' + '{x|' + ' 项' + '}'
}
},
tooltip: {
show: true,
trigger: 'item',
transitionDuration: 0 // 动画延迟
},
series: [
{ // 外线1
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
return {
type: 'arc',
shape: {
cx: api.getWidth() / 4,
cy: api.getHeight() / 1.9,
r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77,
startAngle: (0 + angle) * Math.PI / 180,
endAngle: (90 + angle) * Math.PI / 180
},
style: {
stroke: '#4EE9E6',
fill: 'transparent',
lineWidth: 1.5
},
silent: true
}
},
data: [0]
},
{ // 内线1
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
return {
type: 'arc',
shape: {
cx: api.getWidth() / 4,
cy: api.getHeight() / 1.9,
r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77,
startAngle: (180 + angle) * Math.PI / 180,
endAngle: (270 + angle) * Math.PI / 180
},
style: {
stroke: '#4EE9E6',
fill: 'transparent',
lineWidth: 1.5
},
silent: true
}
},
data: [0]
},
{ // 外线2
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
return {
type: 'arc',
shape: {
cx: api.getWidth() / 4.0,
cy: api.getHeight() / 1.9,
r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9,
startAngle: (270 + -angle) * Math.PI / 180,
endAngle: (40 + -angle) * Math.PI / 180
},
style: {
stroke: '#4EE9E6',
fill: 'transparent',
lineWidth: 1.5
},
silent: true
}
},
data: [0]
},
{ // 外线2
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
return {
type: 'arc',
shape: {
cx: api.getWidth() / 4.0,
cy: api.getHeight() / 1.9,
r: Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9,
startAngle: (90 + -angle) * Math.PI / 180,
endAngle: (220 + -angle) * Math.PI / 180
},
style: {
stroke: '#4EE9E6',
fill: 'transparent',
lineWidth: 1.5
},
silent: true
}
},
data: [0]
},
{ // 绿点1
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
const x0 = api.getWidth() / 4
const y0 = api.getHeight() / 1.9
const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9
const point = getCirlPoint(x0, y0, r, (90 + -angle))
return {
type: 'circle',
shape: {
cx: point.x,
cy: point.y,
r: 2
},
style: {
stroke: '#66FFFF', // 粉
fill: '#66FFFF'
},
silent: true
}
},
data: [0]
},
{ // 绿点2
name: '', // 绿点
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
const x0 = api.getWidth() / 4
const y0 = api.getHeight() / 1.9
const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.9
const point = getCirlPoint(x0, y0, r, (270 + -angle))
return {
type: 'circle',
shape: {
cx: point.x,
cy: point.y,
r: 2
},
style: {
stroke: '#66FFFF', // 粉
fill: '#66FFFF'
},
silent: true
}
},
data: [0]
},
{ // 绿点3
name: '',
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
const x0 = api.getWidth() / 4
const y0 = api.getHeight() / 1.92
const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77
const point = getCirlPoint(x0, y0, r, (90 + angle))
return {
type: 'circle',
shape: {
cx: point.x,
cy: point.y,
r: 2
},
style: {
stroke: '#66FFFF', // 粉
fill: '#66FFFF'
},
silent: true
}
},
data: [0]
},
{ // 绿点4
name: '', // 绿点
type: 'custom',
coordinateSystem: 'none',
animationEasing: 'cubicInOut',
renderItem: function(params, api) {
const x0 = api.getWidth() / 4
const y0 = api.getHeight() / 1.92
const r = Math.min(api.getWidth(), api.getHeight()) / 2 * 0.77
const point = getCirlPoint(x0, y0, r, (270 + angle))
return {
type: 'circle',
shape: {
cx: point.x,
cy: point.y,
r: 2
},
style: {
stroke: '#66FFFF', // 粉
fill: '#66FFFF'
},
silent: true
}
},
data: [0]
},
{ // 最外的圈
name: '',
type: 'pie',
clockWise: false,
animationEasing: 'cubicInOut',
radius: ['130%', '129%'],
hoverAnimation: false,
center: ['25%', '55%'],
top: 'center',
itemStyle: {
normal: {
label: {
show: false
}
}
},
data: data
},
{
type: 'pie',
top: 'center',
startAngle: 90,
clockwise: false,
animationEasing: 'cubicInOut',
center: ['25%', '55%'],
legendHoverLink: false,
hoverAnimation: false,
radius: ['129%', '55%'],
itemStyle: {
opacity: 0.15
},
label: {
show: false,
position: 'center'
},
labelLine: {
show: false
},
data: data2
},
{
name: '',
type: 'pie',
clockWise: false,
animationEasing: 'cubicInOut',
center: ['25%', '55%'],
radius: ['25.5%', '26%'],
hoverAnimation: false,
top: 'center',
itemStyle: {
normal: {
label: {
show: false
}
}
},
data: data
}
]
}
值的方法:配置或者data;angle:数字,this.data:值
var data = []
var data2 = []
const legend = [] // 图例
var trafficWay = this.data
let total = 0
this.data.forEach(item => { total += item.nums })
var color = ['#3cadfe', '#07fcd9', '#fff499', '#08deff', '#FDE056', '#4ED33C', '#FF8A26', '#FF5252', '#9689FF', '#CB00FF']
trafficWay.forEach((item, index) => {
legend.push({
nums: item.nums,
name: item.name,
index: index
})
data.push({
value: item.nums,
name: item.name,
itemStyle: {
normal: {
borderWidth: 5,
shadowBlur: 10,
borderRadius: 10,
borderColor: color[index],
shadowColor: color[index]
}
}
}, {
value: total * 0.02,
name: '',
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
},
color: 'rgba(0, 0, 0, 0)',
borderColor: 'rgba(0, 0, 0, 0)',
borderWidth: 0
}
}
})
data2.push({
value: item.nums,
name: item.name,
index: index
},
{
value: total * 0.02,
name: '',
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
},
color: 'rgba(0, 0, 0, 0)',
borderColor: 'rgba(0, 0, 0, 0)',
borderWidth: 0,
opacity: 0.2
}
}
})
})
// 获取圆上面某点的坐标(x0,y0表示坐标,r半径,angle角度)
const getCirlPoint = (x0, y0, r, angle) => {
const x1 = x0 + r * Math.cos(angle * Math.PI / 180)
const y1 = y0 + r * Math.sin(angle * Math.PI / 180)
return {
x: x1,
y: y1
}
}
this.data举例:
dataList: [
{ nums: 1275, name: 'XXXX况' },
{ nums: 1275, name: 'XXXX开' },
{ nums: 1275, name: 'XXXX开' },
{ nums: 1275, name: 'XXXX开' },
{ nums: 1275, name: 'XXXX开' }
],