From 294508d80607f463b35379041ce2196e88f73789 Mon Sep 17 00:00:00 2001 From: ann Date: Wed, 10 Jan 2024 15:07:58 +0800 Subject: [PATCH] fix --- src/views/prometheusMonitor/province.vue | 237 +++++++++++++++-------- 1 file changed, 151 insertions(+), 86 deletions(-) diff --git a/src/views/prometheusMonitor/province.vue b/src/views/prometheusMonitor/province.vue index a26e70a..f8af51c 100644 --- a/src/views/prometheusMonitor/province.vue +++ b/src/views/prometheusMonitor/province.vue @@ -4,12 +4,9 @@ 返回
- -
-
-
数算中心 {{ count.ys }}
-
智算中心 {{ count.zs }}
-
超算中心 {{ count.cs }}
+
+ +
@@ -58,7 +55,7 @@ export default { }, data() { return { - count: { ys: 0, zs: 0, cs: 0 }, + selectedCity: '', allJSON: { guangdongJson, chuanyuJson, @@ -66,12 +63,16 @@ export default { guizhouJson, jingjinjiJson, neimengguJson, ningxiaJson, changsanjiaoJson, guangdongOutline, hunanJson, hunanOutline }, - // yscount: 0, - // zscount: 0, - // cscount: 0, + currentIndex: 0, + interval: undefined, + img: undefined, activeTab: '', scale: 1, geoCenter: {}, + offsetX: 0, + offsetY: 0, + eventType: '', + cursorFlag: false, mapMap: { 1: 'ningxia', 2: 'neimenggu', @@ -111,59 +112,94 @@ export default { mapType(val) { if (val) { this.getBoxArea() - this.initMap() + this.drawMap() } } }, mounted() { this.getBoxArea() - this.initOutline() - this.initMap() - this.setPoint() + this.$nextTick(() => { + this.img = new Image() + this.img.src = process.env.VUE_APP_PUBLIC_SOURCE_API + '/click-point.svg' + this.img.addEventListener('load', () => { + this.setDataRoll() + }) + const canvas = document.querySelector('#container') + + // 鼠标移动事件 + canvas.addEventListener('mousemove', (event) => { + this.offsetX = event.offsetX / 0.55 + this.offsetY = event.offsetY / 0.65 + this.eventType = 'mousemove' + this.drawMap() + }) + + // 鼠标点击事件 + canvas.addEventListener('click', (event) => { + this.offsetX = event.offsetX / 0.55 + this.offsetY = event.offsetY / 0.65 + this.eventType = 'click' + clearInterval(this.interval) + this.drawMap() + }) + }) }, methods: { + setDataRoll() { + clearInterval(this.interval) + this.interval = setInterval(() => { + this.currentIndex = (this.currentIndex + 1) % this.cluster.length// 更新当前索引 + this.drawMap() + }, 4000) + }, clickback() { this.dialogVisible = false }, - filterData(type) { - console.log(type) + filterData(data) { + this.selectedCity = data + if (data === '') { + this.setDataRoll() + } + this.$emit('selectedCity', data) + }, + drawMap() { + const canvas = document.querySelector('#container') + const ctx = canvas.getContext('2d') + ctx.clearRect(0, 0, window.innerWidth, window.innerHeight) + this.initOutline() + this.initMap() + this.setPoint() }, setPoint() { - var img = new Image() // 创建一个新的图像对象 - img.src = process.env.VUE_APP_PUBLIC_SOURCE_API + '/click-point.svg' // 设置图像源 - img.addEventListener('load', () => { - // 将图像绘制到Canvas上 - const canvas = document.querySelector('#container') - const ctx = canvas.getContext('2d') - const map = { - 'cloud': 'ys', - 'ai': 'zs', - 'hpc': 'cs' - } - if (this.cluster.length) { - this.cluster.forEach(e => { - const position = this.toScreenPosition(e.longitude, e.latitude) - // e.type - this.count[map[e.type || 'hpc']]++ - ctx.drawImage(img, position.x - 50, position.y - 55, 80, 80) - ctx.fillStyle = 'rgba(255, 197, 39, 1)' // 设置填充颜色为紫色 - ctx.font = '30px PangMenZhengDao' // 设置字体 - ctx.fillText(e.name, position.x - e.name.length / 2 * 35, position.y - 55) - }) + const canvas = document.querySelector('#container') + const ctx = canvas.getContext('2d') + ctx.beginPath() + this.cluster.forEach((e, i) => { + const position = this.toScreenPosition(e.longitude, e.latitude) + if (this.currentIndex === i) { + ctx.drawImage(this.img, position.x - 40, position.y - 55, 80, 80) + ctx.fillStyle = 'rgba(255, 197, 39, 1)' + ctx.font = '30px PangMenZhengDao' + ctx.fillText(e.name, position.x - e.name.length / 2 * 35, position.y - 55) + + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)' + ctx.fillRect(position.x + 20, position.y + 5, 300, 90) + ctx.strokeStyle = '#3EDFFC' + ctx.strokeRect(position.x + 20, position.y + 5, 300, 90) + ctx.fillStyle = '#FFFFFF' + ctx.font = '20px Arial' + ctx.fillText('名称:' + e.name, position.x + 20 + 20, position.y + 5 + 40) + ctx.fillText('地址:' + e.address || '-', position.x + 20 + 20, position.y + 5 + 70) } else { - const position = this.toScreenPosition(113, 28) - ctx.drawImage(img, position.x - 50, position.y - 55, 80, 80) - // ctx.beginPath() - // ctx.moveTo(position.x - 50, position.y + 20) - ctx.fillStyle = 'rgba(255, 197, 39, 1)' // 设置填充颜色为紫色 - ctx.font = '30px PangMenZhengDao' // 设置字体 - ctx.fillText('长沙', position.x - 40, position.y - 55) + ctx.beginPath() + ctx.arc(position.x, position.y, 5, 0, Math.PI * 2) // 画一个半径为5的圆 + ctx.fillStyle = '#ffffff' // 设置填充颜色 + ctx.fill() + ctx.closePath() } - // ctx.fillStyle = 'red' - // ctx.beginPath() - // ctx.arc(x, y, r, 0, 2 * Math.PI) - // ctx.fill()// x、y是图像在Canvas上的位置,w、h是图像的宽度和高度 }) + ctx.stroke() + ctx.restore() }, getBoxArea() { const canvasW = window.innerWidth @@ -173,7 +209,6 @@ export default { if (item.geometry.type === 'Polygon') { item.geometry.coordinates = [item.geometry.coordinates] } - // 取四个方向的极值 item.geometry.coordinates.forEach(area => { area[0].forEach(elem => { if (elem[0] < W) { @@ -191,34 +226,17 @@ export default { }) }) }) - // 计算包围盒的宽高 - var wScale = canvasW / Math.abs(E - W) - 20 - var hScale = canvasH / Math.abs(N - S) - 20 - // const width = Math.abs(E - W) - // const height = Math.abs(N - S) - // const wScale = canvasW / width / 3 - // const hScale = canvasH / height / 3 - // 计算地图缩放系数 - this.scale = wScale > hScale ? hScale : wScale - // 获取包围盒中心经纬度坐标 - // this.geoCenterX = (E + W) / 2 - // this.geoCenterY = (N + S) / 2 + var wScale = canvasW / Math.abs(E - W) + var hScale = canvasH / Math.abs(N - S) + this.scale = (wScale > hScale ? hScale : wScale) * 0.9 this.geoCenter = { W: W, N: N, xoffset: canvasW / 2 - Math.abs(E - W) / 2 * this.scale, yoffset: canvasH / 2 - Math.abs(N - S) / 2 * this.scale } - // this.geoCenterY = S - // console.log({ - // xoffset: width / 2.0 - width / 2 * this.scale, - // yoffset: height / 2.0 - height / 2 * this.scale - // }) }, toScreenPosition(longitude, latitude) { - // var xoffset=width/2.0-width/2*scale - // var yoffset=height/2.0-height/2*scale - return { x: (longitude - this.geoCenter.W) * this.scale + this.geoCenter.xoffset, y: (this.geoCenter.N - latitude) * this.scale + this.geoCenter.yoffset @@ -227,41 +245,53 @@ export default { initMap() { const canvas = document.querySelector('#container') const ctx = canvas.getContext('2d') + this.cursorFlag = false ctx.beginPath() ctx.strokeStyle = '#3EDFFC' ctx.lineWidth = 1 this.allJSON[this.mapMap[this.mapType] + 'Json'].features.forEach(elem => { const coordinates = elem.geometry.coordinates - // const centerX = canvasW / 2 - // const centerY = canvasH / 2 - ctx.save() - // ctx.beginPath() - // ctx.translate(centerX, centerY) coordinates.forEach(multiPolygon => { multiPolygon.forEach(polygon => { + ctx.save() + ctx.beginPath() + // ctx.translate(0, 0) for (let i = 0; i < polygon.length; i++) { - // console.log(polygon[i]) const position = this.toScreenPosition(polygon[i][0], polygon[i][1]) - // console.log(position) if (i === 0) { ctx.moveTo(position.x, position.y - 5) } else { ctx.lineTo(position.x, position.y - 5) } } + ctx.closePath() + ctx.strokeStyle = '#34CEE9' + ctx.lineWidth = 1 + if (ctx.isPointInPath(this.offsetX, this.offsetY)) { + this.cursorFlag = true + ctx.fillStyle = '#a2f7ff' + if (this.eventType === 'click') { + this.filterData(elem.properties.name) + // 输出市级名称 + } + } else { + if (this.eventType === 'mousemove' && this.selectedCity === '') ctx.fillStyle = 'transparent' + } + if (this.selectedCity === elem.properties.name) ctx.fillStyle = '#00eaff' + + ctx.fill() + ctx.stroke() + ctx.restore() }) }) }) - ctx.closePath() - var g = ctx.createRadialGradient(700, 600, 50, 1000, 600, 600) - g.addColorStop(0, '#29a0ee') - g.addColorStop(1, '#0b4eaf') - ctx.fillStyle = g - ctx.fill() - ctx.stroke() - ctx.restore() + if (this.cursorFlag) { + canvas.style.cursor = 'pointer' + } else { + canvas.style.cursor = 'default' + } }, initOutline() { const canvas = document.querySelector('#container') @@ -280,9 +310,7 @@ export default { coordinates.forEach(multiPolygon => { multiPolygon.forEach(polygon => { for (let i = 0; i < polygon.length; i++) { - // console.log(polygon[i]) const position = this.toScreenPosition(polygon[i][0], polygon[i][1]) - // console.log(position) if (i === 0) { ctx.moveTo(position.x, position.y + 5) } else { @@ -293,6 +321,12 @@ export default { }) }) ctx.closePath() + if (!ctx.isPointInPath(this.offsetX, this.offsetY)) { + if (this.eventType === 'click') { + this.filterData('') + // 输出市级名称 + } + } ctx.fillStyle = '#3edffc' var grd = ctx.createLinearGradient(0, 0, 1500, 0) for (let i = 0; i < 1000; i++) { @@ -307,6 +341,32 @@ export default { ctx.fill() ctx.stroke() ctx.restore() + + ctx.beginPath() + this.allJSON[this.mapMap[this.mapType] + 'Outline'].features.forEach(elem => { + const coordinates = elem.geometry.coordinates + ctx.save() + coordinates.forEach(multiPolygon => { + multiPolygon.forEach(polygon => { + for (let i = 0; i < polygon.length; i++) { + const position = this.toScreenPosition(polygon[i][0], polygon[i][1]) + if (i === 0) { + ctx.moveTo(position.x, position.y - 5) + } else { + ctx.lineTo(position.x, position.y - 5) + } + } + }) + }) + }) + ctx.closePath() + var g = ctx.createRadialGradient(700, 600, 50, 1000, 600, 600) + g.addColorStop(0, '#29a0ee') + g.addColorStop(1, '#0b4eaf') + ctx.fillStyle = g + ctx.fill() + ctx.stroke() + ctx.restore() } } } @@ -396,6 +456,11 @@ export default { background-size: 100% 100%; } } +.canvasBox{ + width: 100%; + height: 100%; + position: relative; +} #container { width: 55vw; height: 65vh;