138 lines
3.3 KiB
Vue
138 lines
3.3 KiB
Vue
<script>
|
|
export default {
|
|
name: "processPie",
|
|
props: {
|
|
data: Object
|
|
},
|
|
computed: {
|
|
percentage: v => Math.floor(v.data.v1 / v.data.total * 100),
|
|
legend: v => {
|
|
const {totalLabel, label, v1, total} = v.data
|
|
return [
|
|
{label: totalLabel, value: total},
|
|
{label, value: v1},
|
|
]
|
|
}
|
|
},
|
|
mounted() {
|
|
const svg = this.$el.querySelector("svg")
|
|
const path = this.$el.querySelector(".el-progress-circle__path")
|
|
const gradient = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
|
|
gradient.setAttribute('id', 'gradient');
|
|
gradient.setAttribute('x1', '0%');
|
|
gradient.setAttribute('y1', '0%');
|
|
gradient.setAttribute('x2', '100%');
|
|
gradient.setAttribute('y2', '0%');
|
|
|
|
const stop1 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
|
|
stop1.setAttribute('offset', '0%');
|
|
stop1.setAttribute('style', 'stop-color:#2C96E7;stop-opacity:1');
|
|
gradient.appendChild(stop1);
|
|
|
|
const stop2 = document.createElementNS('http://www.w3.org/2000/svg', 'stop');
|
|
stop2.setAttribute('offset', '100%');
|
|
stop2.setAttribute('style', 'stop-color:#5CFFF3;stop-opacity:1');
|
|
gradient.appendChild(stop2);
|
|
svg.insertBefore(gradient, path);
|
|
path.setAttribute('stroke', 'url(#gradient)');
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<section class="processPie flex">
|
|
<div class="progress">
|
|
<el-progress type="circle" :percentage="percentage" :stroke-width="7" define-back-color="#66798a66"
|
|
:show-text="false" :width="106"/>
|
|
<div class="label">
|
|
<div class="percentage" v-text="`${percentage}%`"/>
|
|
<div v-text="data.name"/>
|
|
</div>
|
|
</div>
|
|
<div class="fill">
|
|
<div class="item flex" v-for="(item, i) in legend" :key="i">
|
|
<div class="label fill" v-text="item.label"/>
|
|
<div class="value" v-text="item.value"/>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.processPie {
|
|
.progress {
|
|
position: relative;
|
|
height: initial;
|
|
margin-right: 60px;
|
|
flex-shrink: 0;
|
|
|
|
:deep(.el-progress) {
|
|
display: block;
|
|
}
|
|
|
|
.label {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-weight: 400;
|
|
font-size: 12px;
|
|
color: #FFFFFF;
|
|
white-space: nowrap;
|
|
width: 82px;
|
|
height: 82px;
|
|
border-radius: 50%;
|
|
border: 2px solid #66798a66;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.percentage {
|
|
font-weight: 700;
|
|
font-size: 22px;
|
|
color: #02FEFF;
|
|
letter-spacing: 0;
|
|
text-align: right;
|
|
line-height: 23px;
|
|
font-family: DINAlternate;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item {
|
|
margin-bottom: 25px;
|
|
height: 32px;
|
|
|
|
&:last-of-type {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.label {
|
|
margin-right: 25px;
|
|
font-weight: 400;
|
|
font-size: 18px;
|
|
color: #9BB7D4;
|
|
letter-spacing: 0;
|
|
|
|
&:before {
|
|
content: "●";
|
|
color: #66798a66;
|
|
margin-right: 8px;
|
|
}
|
|
}
|
|
|
|
&:first-of-type > .label:before {
|
|
color: #5AF9F0;
|
|
}
|
|
|
|
.value {
|
|
font-weight: 600;
|
|
font-size: 20px;
|
|
color: #FFFFFF;
|
|
letter-spacing: 0;
|
|
text-align: right;
|
|
}
|
|
}
|
|
}
|
|
</style> |