大屏 环形图组件
This commit is contained in:
		| @@ -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 | ||||
|     }, | ||||
|   | ||||
							
								
								
									
										137
									
								
								project/dvui/layout/AiDvSummary/components/DonutChart.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								project/dvui/layout/AiDvSummary/components/DonutChart.vue
									
									
									
									
									
										Normal 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> | ||||
							
								
								
									
										127
									
								
								project/dvui/layout/AiDvSummary/components/Summary8.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								project/dvui/layout/AiDvSummary/components/Summary8.vue
									
									
									
									
									
										Normal 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> | ||||
		Reference in New Issue
	
	Block a user