Files
dvcp_v2_webapp/packages/bigscreen/dv/components/DonutChart.vue
2022-08-30 17:29:29 +08:00

134 lines
3.1 KiB
Vue

<template>
<div class="DonutChart" :id="id">
<canvas :id="canvasId"></canvas>
<div class="DonutChart-text">
<span>{{ ratio || 0 }}%</span>
<i>{{ text }}</i>
</div>
</div>
</template>
<script>
export default {
props: ['ratio', 'text'],
data () {
return {
id: `DonutChart-${Math.ceil(Math.random() * 10000)}`,
canvasId: `DonutChartCanvas-${Math.ceil(Math.random() * 10000)}`,
canvasWidth: 90,
canvasHeight: 90
}
},
mounted () {
this.$nextTick(() => {
this.init()
})
},
methods: {
drawLine(ctx, options) {
const { beginX, beginY, endX, endY, lineColor, lineWidth } = options
ctx.lineWidth = lineWidth
ctx.strokeStyle = lineColor
ctx.beginPath()
ctx.moveTo(beginX, beginY)
ctx.lineTo(endX, endY)
ctx.closePath()
ctx.stroke()
},
angle (a, i, ox, oy, or) {
var hudu = (2 * Math.PI / 360) * a * i
var x = ox + Math.sin(hudu) * or
var y = oy - Math.cos(hudu) * or
return x + '_' + y
},
mapColor (value) {
if (value < 25) {
return '#FFC139'
}
if (value < 50) {
return '#21E03E'
}
return '#05C8FF'
},
init () {
const ctx = document.querySelector(`#${this.canvasId}`).getContext('2d')
const canvasWidth = document.querySelector(`#${this.id}`).offsetWidth
const canvasHeight = document.querySelector(`#${this.id}`).offsetHeight
const angle = this.ratio / 100 * 2
let radian = 0
ctx.width = canvasWidth
ctx.height = canvasHeight
const x = canvasWidth / 2
const y = canvasHeight / 2
ctx.lineWidth = 2
ctx.strokeStyle = '#383f56'
ctx.beginPath();
ctx.arc(x, y, x - 3, 0, 2 * Math.PI)
ctx.stroke()
ctx.beginPath()
ctx.lineWidth = 4
ctx.strokeStyle = 'rgba(76, 202, 227, 1)'
if (this.ratio < 25) {
radian = 3 / 2 + angle
ctx.arc(x, y, x - 4, Math.PI + Math.PI / 2, Math.PI * radian, false)
} else if (this.ratio === 100) {
ctx.arc(x, y, x - 4, 0, Math.PI * 2)
} else {
radian = (this.ratio - 25) / 100 * 2
ctx.arc(x, y, x - 4, Math.PI + Math.PI / 2, Math.PI * radian, false)
}
ctx.stroke()
}
}
}
</script>
<style lang="scss" scoped>
.DonutChart {
position: relative;
width: 84px;
height: 84px;
overflow: hidden;
.DonutChart-text {
display: flex;
position: absolute;
align-items: center;
justify-content: center;
flex-direction: column;
top: 50%;
left: 50%;
z-index: 1;
width: 100%;
height: 100%;
line-height: 1;
transform: translate(-50%, -50%);
span {
margin-bottom: 8px;
font-size: 20px;
font-weight: bold;
color: #fff;
font-style: oblique;
}
i {
font-size: 12px;
font-style: normal;
color: rgba(42, 183, 209, 1);
}
}
}
</style>