195 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script>
 | |
| import AiDvMap from "./AiDvMap.vue";
 | |
| import AiDvSummary from "./layout/AiDvSummary/AiDvSummary.vue";
 | |
| import {DvCompData} from "./index";
 | |
| 
 | |
| export default {
 | |
|   name: "AiLinkageMap",
 | |
|   components: {AiDvSummary, AiDvMap},
 | |
|   props: {
 | |
|     instance: Function,
 | |
|     config: {default: () => ({})},
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       geoData: [],
 | |
|       mapOptions: {
 | |
|         visualMap: {
 | |
|           left: "right",
 | |
|           type: "piecewise",
 | |
|           splitNumber: 8,
 | |
|           min: 0,
 | |
|           max: 8000,
 | |
|           maxOpen: true,
 | |
|           inRange: {
 | |
|             color: [
 | |
|               "#25EDF4",
 | |
|               "rgba(12,222,233,0.9)",
 | |
|               "rgba(11,208,218,0.81)",
 | |
|               "rgba(11,193,213,0.72)",
 | |
|               "rgba(11,172,193,0.63)",
 | |
|               "rgba(9,147,174,0.54)",
 | |
|               "rgba(7,108,136,0.45)",
 | |
|               "rgba(6,78,107,0.36)",
 | |
|               "rgba(5,66,97,0.27)"].reverse()
 | |
|           },
 | |
|           outOfRange: {color: "#25EDF4"},
 | |
|           textStyle: {
 | |
|             color: "#fff"
 | |
|           },
 | |
|           calculable: true
 | |
|         },
 | |
|       },
 | |
|       dialog: false,
 | |
|       detail: [],
 | |
|       dialogPos: {},
 | |
|       compData: null
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     dialog(v) {
 | |
|       if (!v) {
 | |
|         this.detail = []
 | |
|         this.dialogPos = {}
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     sta: v => v.config.summaryConfigs || [],
 | |
|     mapData: v => v.geoData.map(e => ({name: e.name.replace(/([市县区])/g, ""), value: parseInt(e.低风险纠纷) + parseInt(e.中风险纠纷) + parseInt(e.高风险纠纷)}))
 | |
|   },
 | |
|   methods: {
 | |
|     getData(type = "530300000000") {
 | |
|       return this.compData.getData({type}).then(res => {
 | |
|         const json = JSON.parse(res.param)
 | |
|         if (type == "530300000000") {
 | |
|           this.geoData = json.map
 | |
|           this.$refs.map.chart?.setOption({series: {data: this.mapData}})
 | |
|         }
 | |
|         this.config.summaryConfigs = json.sta?.map((e, i) => ({pos: ["rt", "lb", 'lt', 'rb'][i % 4], display: "summary20", ...e})) || []
 | |
|       })
 | |
|     },
 | |
|     handleMapClick(evt) {
 | |
|       const {name, event: {offsetX, offsetY}, info: {code} = {}} = evt
 | |
|       this.dialog = true
 | |
|       this.detail = []
 | |
|       const item = this.geoData.find(e => e.name.includes(name))
 | |
|       this.$refs.map.chart.showLoading({
 | |
|         text: "数据加载中...", textColor: "#fff",
 | |
|         maskColor: 'rgba(0, 0, 0, 0)'
 | |
|       })
 | |
|       this.getData(String(code).padEnd(12, '0')).finally(() => {
 | |
|         this.$refs.map.chart.hideLoading()
 | |
|       })
 | |
|       for (const k in item) {
 | |
|         if ('name' != k) {
 | |
|           this.detail.push({
 | |
|             label: k, value: item[k], color: {
 | |
|               高风险纠纷: "#FF6868",
 | |
|               中风险纠纷: "#FFAB68",
 | |
|               低风险纠纷: "#7FE89E",
 | |
|             }[k]
 | |
|           })
 | |
|         }
 | |
|       }
 | |
|       this.dialogPos = {left: offsetX + 'px', top: offsetY + 'px'}
 | |
|     },
 | |
|     dotStyle(color) {
 | |
|       return {
 | |
|         background: color,
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.compData = new DvCompData(this.config, this.instance)
 | |
|     this.getData()
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <template>
 | |
|   <section class="AiLinkageMap">
 | |
|     <ai-dv-map ref="map" :geo-json="config.geoJson" :data="mapData" :ops="mapOptions" @click="handleMapClick" @globalout="dialog=false,getData()"/>
 | |
|     <ai-dv-summary class="abs" v-for="(item,i) in sta" :key="i" :class="item.pos" :type="item.display" :data="item.data"/>
 | |
|     <div class="dialog" v-if="dialog" :style="dialogPos">
 | |
|       <div v-for="item in detail" :key="item.name" class="flex">
 | |
|         <div class="dot" :style="dotStyle(item.color)"/>
 | |
|         <div class="label fill" v-text="item.label"/>
 | |
|         <div v-text="item.value"/>
 | |
|       </div>
 | |
|     </div>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <style scoped lang="scss">
 | |
| .AiLinkageMap {
 | |
|   width: 100%;
 | |
|   height: 100%;
 | |
|   position: relative;
 | |
| 
 | |
|   .abs {
 | |
|     position: absolute;
 | |
|     width: auto;
 | |
|     height: auto;
 | |
| 
 | |
|     &.lt {
 | |
|       left: 0;
 | |
|       top: 0;
 | |
|     }
 | |
| 
 | |
|     &.rt {
 | |
|       right: 0;
 | |
|       top: 0;
 | |
|     }
 | |
| 
 | |
|     &.lb {
 | |
|       left: 0;
 | |
|       bottom: 0;
 | |
|     }
 | |
| 
 | |
|     &.rb {
 | |
|       right: 0;
 | |
|       bottom: 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .dialog {
 | |
|     position: absolute;
 | |
|     transform: translate(-50%, -120%);
 | |
|     z-index: 20240327926;
 | |
|     padding: 16px 16px 24px;
 | |
|     background-color: rgba(9, 48, 69, 0.8);
 | |
|     backdrop-filter: blur(5px);
 | |
|     color: #fff;
 | |
|     font-size: 14px;
 | |
|     min-width: 200px;
 | |
|     border: 1px solid #02C6DC;
 | |
| 
 | |
|     &:after {
 | |
|       position: absolute;
 | |
|       bottom: 0;
 | |
|       left: 50%;
 | |
|       transform: translate(-50%, 50%) rotate(-135deg);
 | |
|       content: " ";
 | |
|       width: 10px;
 | |
|       height: 10px;
 | |
|       background: inherit;
 | |
|       border: inherit;
 | |
|       clip-path: polygon(0 0, 100% 0, 0 100%);
 | |
|     }
 | |
| 
 | |
|     .dot {
 | |
|       width: 14px;
 | |
|       height: 14px;
 | |
|       border-radius: 50%;
 | |
|       margin-right: 8px;
 | |
|       border: 3px solid rgba(9, 48, 69, .4);
 | |
|     }
 | |
| 
 | |
|     .label {
 | |
|       color: #9BB7D4;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </style>
 |