大屏 环形图组件

This commit is contained in:
yanran200730
2022-05-11 16:47:05 +08:00
parent e4d1e85156
commit f9d5e51222
5 changed files with 277 additions and 10 deletions

View File

@@ -403,7 +403,7 @@
value: '0'
}],
images: [],
summaryList: ['summary0', 'summary1', 'summary2', 'summary3', 'summary4', 'summary5', 'summary7', 'summary9', 'summary10'],
summaryList: ['summary0', 'summary1', 'summary2', 'summary3', 'summary4', 'summary6', 'summary5', 'summary7', 'summary8', 'summary9', 'summary10'],
borderList: ['border0', 'border1', 'border2', 'border3', 'border4', 'border5']
}
},

View File

@@ -222,15 +222,6 @@
.render-element {
::v-deep .dvScrollBoard1 {
.index {
color: #fff;
text-shadow: none;
background: transparent;
background-color: #BD4921!important;
-webkit-background-clip: inherit;
-webkit-text-fill-color: #fff;
}
.header {
background: rgba(0, 0, 0, 0.1)!important;
@@ -251,9 +242,19 @@
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
& > div:nth-of-type(2n) {
background: rgba(0, 0, 0, 0.1)!important;
}
.index {
color: #fff;
text-shadow: none;
background: transparent;
background-color: #BD4921!important;
-webkit-background-clip: inherit;
-webkit-text-fill-color: #fff;
}
}
}
}

View File

@@ -13,6 +13,7 @@
import Summary5 from './components/Summary5'
import Summary6 from './components/Summary6'
import Summary7 from './components/Summary7'
import Summary8 from './components/Summary8'
import Summary9 from './components/Summary9'
import Summary10 from './components/Summary10'
@@ -28,6 +29,7 @@
Summary5,
Summary6,
Summary7,
Summary8,
Summary9,
Summary10
},

View File

@@ -0,0 +1,137 @@
<template>
<div class="DonutChart" :id="id">
<canvas :id="canvasId"></canvas>
<div class="DonutChart-text">
<span>{{ ratio }}</span>
<i>%</i>
</div>
</div>
</template>
<script>
export default {
props: ['ratio'],
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 = 4
ctx.strokeStyle = 'rgba(250, 140, 22, 0.5)'
ctx.beginPath();
ctx.arc(x, y, x - 8, 0, 2 * Math.PI)
ctx.stroke()
ctx.beginPath()
ctx.lineWidth = 8
ctx.strokeStyle = 'rgba(255, 225, 94, 1)'
if (this.ratio < 25) {
radian = 3 / 2 + angle
ctx.arc(x, y, x - 8, Math.PI + Math.PI / 2, Math.PI * radian, false)
} else if (this.ratio === 100) {
ctx.arc(x, y, x - 8, 0, Math.PI * 2)
} else {
radian = (this.ratio - 25) / 100 * 2
ctx.arc(x, y, x - 8, Math.PI + Math.PI / 2, Math.PI * radian, false)
}
ctx.stroke()
}
}
}
</script>
<style lang="scss" scoped>
.DonutChart {
position: relative;
width: 90px;
height: 90px;
overflow: hidden;
.DonutChart-text {
display: flex;
position: absolute;
justify-content: center;
top: 50%;
left: 50%;
z-index: 1;
transform: translate(-50%, -50%);
span {
font-size: 26px;
font-weight: bold;
color: #CEE1FF;
text-shadow: 0px 2px 4px rgba(117, 9, 9, 0.1);
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
i {
position: relative;
bottom: -8px;
font-size: 16px;
font-style: normal;
font-weight: bold;
color: #CEE1FF;
text-shadow: 0px 2px 4px rgba(117, 9, 9, 0.1);
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<div class="Summary8">
<div class="summary5-item" v-for="(item, index) in arr" :key="index">
<div class="left">
<DonutChart :ratio="item.ratio"></DonutChart>
</div>
<div class="right">
<h2>{{ item[keys] }}</h2>
<p>{{ item[value] }}</p>
</div>
</div>
</div>
</template>
<script>
import DonutChart from './DonutChart'
export default {
name: 'Summary8',
components: {
DonutChart
},
props: {
data: {
type: Array,
default: () => []
},
keys: {
type: String,
default: 'key'
},
value: {
type: String,
default: 'value'
}
},
watch: {
data: {
handler (v) {
if (!v.length) return []
let sum = 0
v.forEach(x => {
sum = x[this.value] + sum
})
this.arr = v.map(v => {
console.log(v[this.value] / sum)
return {
...v,
ratio: Number((v[this.value] / sum).toFixed(2)) * 100
}
})
console.log(this.arr)
},
immediate: true,
deep: true
}
},
data () {
return {
arr: []
}
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.Summary8 {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
width: 100%;
height: 100%;
div {
box-sizing: border-box;
}
.summary5-item {
display: flex;
position: relative;
align-items: center;
.right {
min-width: 90px;
}
.left {
display: flex;
position: relative;
align-items: center;
justify-content: center;
margin-right: 20px;
width: 90px;
height: 90px;
}
h2 {
margin-bottom: 12px;
color: #fff;
font-size: 16px;
font-weight: normal;
}
p {
font-size: 26px;
font-weight: bold;
color: #CEE1FF;
text-shadow: 0px 2px 4px rgba(117, 9, 9, 0.1);
background: linear-gradient(180deg, #FFF6C7 0%, #FF9A02 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
}
</style>