Files
dvcp_v2_webapp/ui/dv/layout/AiDvSummary/components/processPie.vue
2024-04-12 10:22:47 +08:00

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>