| | |
| | | <template> |
| | | <div class="map-container"> |
| | | <!-- 地图容器 --> |
| | | <div class="map-container" :class="{ loading: isLoading }"> |
| | | <!-- echarts地图渲染区域 --> |
| | | <div class="chart" ref="myMap" /> |
| | | <!-- 新增加载提示 --> |
| | | <div v-if="isLoading" class="loading-tip">地图加载中...</div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | // import "echarts-gl"; |
| | | export default { |
| | | name: 'Map', |
| | | data() { |
| | | return { |
| | | mapBg: null // 地图背景图片 |
| | | // 导入防抖函数 |
| | | import _ from 'lodash'; |
| | | |
| | | // 导入地图相关的背景和图标资源 |
| | | import mapBg from "@/assets/map/mapBg.png"; // 地图背景图片 |
| | | import tooltipBg from "@/assets/map/tooltipBg.png"; // 提示框背景图片 |
| | | import tooltipBlue from "@/assets/map/tooltipBlue.png"; // 蓝色标记图标 |
| | | import tooltipOrange from "@/assets/map/tooltipOrange.png"; // 橙色标记图标 |
| | | |
| | | // 定义地图常量配置 |
| | | const MAP_CONSTANTS = { |
| | | // 阴影相关配置 |
| | | SHADOW: { |
| | | COLOR: "#00eaff", |
| | | BLUR: 25, |
| | | OFFSET: 0 |
| | | }, |
| | | // 标记点相关配置 |
| | | MARKER: { |
| | | SIZE: [20, 30], |
| | | OFFSET: [0, -15], |
| | | Z_INDEX: 20, |
| | | COLORS: { |
| | | BLUE: '#00eaff', |
| | | ORANGE: '#ff8e3a' |
| | | } |
| | | }, |
| | | // 提示框相关配置 |
| | | TOOLTIP: { |
| | | OFFSET: [-100, -160], |
| | | WIDTH: '211px', |
| | | FONT_FAMILY: 'pangmenzhengdao' |
| | | }, |
| | | // 地图图层配置 |
| | | LAYERS: { |
| | | 1: { // 最底层 |
| | | top: "15%", |
| | | bottom: "10%", |
| | | borderColor: "#00A0F5", |
| | | borderWidth: 1 |
| | | }, |
| | | 2: { // 中间层 |
| | | top: "16%", |
| | | bottom: "9%", |
| | | borderColor: "#0C93C5", |
| | | borderWidth: 1 |
| | | }, |
| | | 3: { // 最顶层 |
| | | top: "17%", |
| | | bottom: "8%", |
| | | borderColor: "#0A5C83", |
| | | borderWidth: 2 |
| | | } |
| | | } |
| | | }; |
| | | |
| | | export default { |
| | | name: 'Map', |
| | | // 接收父组件传递的数据 |
| | | props: { |
| | | data: { |
| | | type: Object, |
| | | default: () => ({}), |
| | | // 新增:数据格式验证 |
| | | validator(value) { |
| | | if (!value.mapResponses) return true; |
| | | return Array.isArray(value.mapResponses) && |
| | | value.mapResponses.every(item => |
| | | item.street && |
| | | typeof item.householdCount === 'number' && |
| | | typeof item.personCount === 'number' |
| | | ); |
| | | } |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | mapBg: null, // 地图背景图片实例 |
| | | mapPoints: [], // 存储处理后的地图标记点数据 |
| | | chart: null, // echarts实例 |
| | | isLoading: false, // 新增:加载状态标志 |
| | | errorMessage: '' // 新增:错误信息 |
| | | } |
| | | }, |
| | | |
| | | // 新增:计算属性 |
| | | computed: { |
| | | // 检查数据是否有效 |
| | | hasValidData() { |
| | | return this.data && this.data.mapResponses && this.data.mapResponses.length > 0; |
| | | } |
| | | }, |
| | | |
| | | mounted() { |
| | | this.initMapBg(); |
| | | this.initMap(); |
| | | // 组件挂载后初始化地图 |
| | | this.initEventListeners(); // 新增:初始化事件监听 |
| | | this.$nextTick(() => { |
| | | if (this.hasValidData) { |
| | | this.initMap(); |
| | | } |
| | | }); |
| | | }, |
| | | methods: { |
| | | // 初始化地图背景图片 |
| | | initMapBg() { |
| | | // 创建一个 canvas 来生成背景图案 |
| | | const canvas = document.createElement('canvas'); |
| | | const ctx = canvas.getContext('2d'); |
| | | canvas.width = 8; |
| | | canvas.height = 8; |
| | | |
| | | // 设置渐变 |
| | | const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height); |
| | | gradient.addColorStop(0, 'rgba(0,24,106,0.8)'); |
| | | gradient.addColorStop(1, 'rgba(0,24,106,0.9)'); |
| | | |
| | | // 绘制背景 |
| | | ctx.fillStyle = gradient; |
| | | ctx.fillRect(0, 0, canvas.width, canvas.height); |
| | | |
| | | // 添加网格效果 |
| | | ctx.strokeStyle = 'rgba(0,234,255,0.1)'; |
| | | ctx.lineWidth = 0.5; |
| | | ctx.beginPath(); |
| | | ctx.moveTo(0, canvas.height / 2); |
| | | ctx.lineTo(canvas.width, canvas.height / 2); |
| | | ctx.moveTo(canvas.width / 2, 0); |
| | | ctx.lineTo(canvas.width / 2, canvas.height); |
| | | ctx.stroke(); |
| | | |
| | | // 保存为base64图片 |
| | | this.mapBg = canvas.toDataURL(); |
| | | // 新增:初始化事件监听器 |
| | | initEventListeners() { |
| | | window.addEventListener('resize', this.handleResize); |
| | | // 新增:错误监听 |
| | | window.addEventListener('error', this.handleGlobalError, true); |
| | | }, |
| | | initMap() { |
| | | // json地图数据-需要根据需求下载引入对应名称文件 |
| | | let mapJson = require("@/utils/map/chongzhou.json"); |
| | | let myChart = this.$echarts.init(this.$refs.myMap); |
| | | myChart.showLoading(); |
| | | myChart.hideLoading(); |
| | | this.$echarts.registerMap("myMap", mapJson); |
| | | |
| | | let option = { |
| | | tooltip: { |
| | | trigger: "none", // 关闭提示框 |
| | | // 新增:全局错误处理 |
| | | handleGlobalError(event) { |
| | | if (event.target.tagName === 'SCRIPT') { |
| | | this.handleError(new Error('地图资源加载失败'), '资源加载'); |
| | | } |
| | | }, |
| | | |
| | | // 统一的错误处理方法 |
| | | handleError(error, context) { |
| | | console.error(`地图组件错误 - ${context}:`, error); |
| | | this.errorMessage = `加载失败: ${error.message}`; |
| | | this.isLoading = false; |
| | | // 可以添加错误上报逻辑 |
| | | }, |
| | | |
| | | // 处理窗口大小变化,使用防抖优化 |
| | | handleResize: _.debounce(function () { |
| | | if (this.chart) { |
| | | this.chart.resize(); |
| | | } |
| | | }, 300), |
| | | |
| | | // 处理地图数据,将原始数据转换为echarts可用的格式 |
| | | processMapData() { |
| | | if (!this.data.mapResponses) return; |
| | | |
| | | // 获取地图JSON数据 |
| | | const mapJson = require("@/utils/map/chongzhou.json"); |
| | | |
| | | // 遍历处理每个地点数据 |
| | | this.mapPoints = this.data.mapResponses.map(point => { |
| | | // 在地图JSON中查找对应的地理信息 |
| | | const feature = mapJson.features.find(f => f.properties.name === point.street); |
| | | |
| | | if (!feature) { |
| | | console.warn(`未找到街道: ${point.street} 的坐标`); |
| | | return null; |
| | | } |
| | | |
| | | // 判断是街道还是乡镇,用于显示不同的图标 |
| | | const isStreet = point.street.includes('街道'); |
| | | |
| | | // 获取中心点坐标 |
| | | let center; |
| | | if (feature.properties.center) { |
| | | // 优先使用预设的中心点坐标 |
| | | center = feature.properties.center; |
| | | } else if (feature.geometry && feature.geometry.coordinates) { |
| | | // 否则根据地理数据计算中心点 |
| | | if (feature.geometry.type === 'Polygon') { |
| | | // 处理单个多边形 |
| | | const coordinates = feature.geometry.coordinates[0]; |
| | | center = this.calculateCenter(coordinates); |
| | | } else if (feature.geometry.type === 'MultiPolygon') { |
| | | // 处理多个多边形 |
| | | const coordinates = feature.geometry.coordinates[0][0]; |
| | | center = this.calculateCenter(coordinates); |
| | | } |
| | | } |
| | | |
| | | if (!center) { |
| | | console.warn(`无法获取 ${point.street} 的中心点坐标`); |
| | | return null; |
| | | } |
| | | |
| | | // 返回处理后的标记点数据 |
| | | return { |
| | | name: point.street, |
| | | value: center, |
| | | type: isStreet ? 'orange' : 'blue', // 街道使用橙色,乡镇使用蓝色 |
| | | symbolSize: 32, |
| | | householdCount: point.householdCount, // 安置户数 |
| | | personCount: point.personCount // 安置人数 |
| | | }; |
| | | }).filter(Boolean); // 过滤掉无效的数据 |
| | | }, |
| | | |
| | | // 计算多边形的中心点坐标 |
| | | calculateCenter(coordinates) { |
| | | if (!coordinates || coordinates.length === 0) return null; |
| | | |
| | | // 计算所有顶点的平均值作为中心点 |
| | | let sumX = 0; |
| | | let sumY = 0; |
| | | let count = coordinates.length; |
| | | |
| | | coordinates.forEach(coord => { |
| | | sumX += coord[0]; |
| | | sumY += coord[1]; |
| | | }); |
| | | |
| | | return [sumX / count, sumY / count]; |
| | | }, |
| | | |
| | | // 新增:检查地图实例状态 |
| | | checkChartStatus() { |
| | | if (!this.chart) { |
| | | throw new Error('地图实例未初始化'); |
| | | } |
| | | return true; |
| | | }, |
| | | |
| | | // 初始化地图方法优化 |
| | | initMap: _.debounce(async function () { |
| | | try { |
| | | if (!this.$refs.myMap) { |
| | | throw new Error('地图DOM元素未准备好'); |
| | | } |
| | | |
| | | this.isLoading = true; |
| | | this.errorMessage = ''; |
| | | |
| | | // 新增:等待资源加载 |
| | | await this.loadMapResources(); |
| | | |
| | | this.processMapData(); |
| | | |
| | | if (this.chart) { |
| | | this.chart.dispose(); |
| | | } |
| | | |
| | | this.chart = this.$echarts.init(this.$refs.myMap); |
| | | this.chart.showLoading(); |
| | | |
| | | const mapJson = require("@/utils/map/chongzhou.json"); |
| | | this.$echarts.registerMap("myMap", mapJson); |
| | | |
| | | // 设置配置项 |
| | | this.chart.setOption(this.getMapOption()); |
| | | this.chart.hideLoading(); |
| | | |
| | | this.isLoading = false; |
| | | } catch (error) { |
| | | this.handleError(error, '初始化地图'); |
| | | } |
| | | }, 300), |
| | | |
| | | // 新增:加载地图资源 |
| | | async loadMapResources() { |
| | | try { |
| | | const mapImage = new Image(); |
| | | mapImage.src = mapBg; |
| | | await new Promise((resolve, reject) => { |
| | | mapImage.onload = resolve; |
| | | mapImage.onerror = reject; |
| | | }); |
| | | this.mapBg = mapImage; |
| | | } catch (error) { |
| | | throw new Error('地图背景图片加载失败'); |
| | | } |
| | | }, |
| | | |
| | | // 生成标记点系列的配置 |
| | | getMarkerSeries(type) { |
| | | return { |
| | | name: type === "blue" ? "蓝色标记" : "橙色标记", |
| | | type: "scatter", |
| | | coordinateSystem: "geo", |
| | | geoIndex: 0, |
| | | data: this.mapPoints.filter(point => point.type === type), |
| | | symbol: `image://${type === "blue" ? tooltipBlue : tooltipOrange}`, |
| | | symbolSize: MAP_CONSTANTS.MARKER.SIZE, |
| | | symbolOffset: MAP_CONSTANTS.MARKER.OFFSET, |
| | | z: MAP_CONSTANTS.MARKER.Z_INDEX, |
| | | |
| | | label: { |
| | | show: false // 禁用标签显示 |
| | | }, |
| | | // 设置多层级地图实现立体效果 |
| | | geo: [ |
| | | { |
| | | map: "myMap", // 使用注册的地图名称 |
| | | aspectScale: 1, // 地图长宽比 |
| | | zoom: 1, // 地图缩放比例 |
| | | top: "15%", // 距离容器顶部距离 |
| | | bottom: "10%", // 距离容器底部距离 |
| | | roam: false, // 禁用地图平移缩放 |
| | | z: 5, // 图层层级,数值大的在上层 |
| | | itemStyle: { |
| | | areaColor: "transparent", // 区域透明 |
| | | borderColor: "#00eaff", // 边框颜色 |
| | | borderWidth: 1 // 边框宽度 |
| | | }, |
| | | select: { |
| | | disabled: true // 禁用选中状态 |
| | | }, |
| | | tooltip: { |
| | | show: false, // 关闭提示框 |
| | | }, |
| | | }, |
| | | { |
| | | map: "myMap", // 第二层地图 |
| | | aspectScale: 1, |
| | | zoom: 1, |
| | | top: "16%", // 比第一层低一点 |
| | | bottom: "9%", |
| | | roam: false, |
| | | z: 4, // 层级比第一层低 |
| | | itemStyle: { |
| | | areaColor: "transparent", |
| | | borderColor: "#00eaff", |
| | | borderWidth: 1 |
| | | }, |
| | | select: { |
| | | disabled: true |
| | | }, |
| | | tooltip: { |
| | | show: false, |
| | | }, |
| | | }, |
| | | { |
| | | map: "myMap", // 第三层地图 |
| | | aspectScale: 1, |
| | | zoom: 1, |
| | | top: "17%", // 最底层 |
| | | bottom: "8%", |
| | | roam: false, |
| | | z: 3, // 最底层层级 |
| | | itemStyle: { |
| | | areaColor: "transparent", |
| | | borderColor: "#00eaff", |
| | | borderWidth: 1 |
| | | }, |
| | | select: { |
| | | disabled: true |
| | | }, |
| | | tooltip: { |
| | | show: false, |
| | | }, |
| | | }, |
| | | ], |
| | | |
| | | // 修复tooltip配置 |
| | | tooltip: { |
| | | show: true, |
| | | trigger: 'item', |
| | | backgroundColor: 'transparent', |
| | | borderWidth: 0, |
| | | padding: 0, |
| | | className: 'map-tooltip', |
| | | position: function (point) { |
| | | // 固定偏移量 |
| | | return [point[0] - 100, point[1] - 160]; |
| | | }, |
| | | formatter: function (params) { |
| | | const { name, data } = params; |
| | | return ` |
| | | <div style=" |
| | | background: url(${tooltipBg}) no-repeat center center; |
| | | background-size: 100% 100%; |
| | | width: 211px; |
| | | padding: 20px 0; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | "> |
| | | <div style="color: #fff; font-size: 16px; margin-bottom: 16px; font-weight: bold;">${name}</div> |
| | | <div style="display: flex; justify-content: space-around; width: 100%; padding: 0 20px;"> |
| | | <div style="text-align: center;"> |
| | | <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.householdCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置户数(户)</div> |
| | | </div> |
| | | <div style="text-align: center;"> |
| | | <div style="color: #66ffff; font-size: 20px; font-family: 'pangmenzhengdao'; margin-bottom: 8px;">${data.personCount}</div> |
| | | <div style="color: #fff; font-size: 12px;">安置人数(人)</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | `; |
| | | } |
| | | }, |
| | | |
| | | emphasis: { |
| | | scale: true, |
| | | scaleSize: 1.2, |
| | | itemStyle: { |
| | | shadowBlur: 10, |
| | | shadowColor: type === "blue" ? MAP_CONSTANTS.SHADOW.COLOR : '#ff8e3a' |
| | | } |
| | | } |
| | | }; |
| | | }, |
| | | |
| | | // 生成地图图层的配置 |
| | | // 参数 index: 图层索引(1-3),用于创建三层叠加的立体效果 |
| | | getGeoLayers(index) { |
| | | // 定义每层的具体配置 |
| | | const layerConfig = { |
| | | 1: { // 最底层 |
| | | top: "15%", // 距顶部距离 |
| | | bottom: "10%", // 距底部距离 |
| | | borderColor: "#00A0F5", // 边框颜色 |
| | | borderWidth: 1 // 边框宽度 |
| | | }, |
| | | 2: { // 中间层 |
| | | top: "16%", |
| | | bottom: "9%", |
| | | borderColor: "#0C93C5", |
| | | borderWidth: 1 |
| | | }, |
| | | 3: { // 最顶层 |
| | | top: "17%", |
| | | bottom: "8%", |
| | | borderColor: "#0A5C83", |
| | | borderWidth: 2 |
| | | } |
| | | }; |
| | | |
| | | const config = layerConfig[index]; |
| | | return { |
| | | map: "myMap", // 使用注册的地图名称 |
| | | aspectScale: 1, // 地图长宽比 |
| | | zoom: 1, // 缩放级别 |
| | | roam: false, // 是否开启鼠标缩放和平移漫游 |
| | | top: config.top, // 距容器顶部距离 |
| | | bottom: config.bottom, // 距容器底部距离 |
| | | z: index, // 图层层级,值越大越靠前 |
| | | |
| | | // 地图区域的样式设置 |
| | | itemStyle: { |
| | | areaColor: "transparent", // 区域填充色为透明 |
| | | borderColor: config.borderColor, // 边框颜色 |
| | | borderWidth: config.borderWidth, // 边框宽度 |
| | | // 仅在最顶层添加阴影效果 |
| | | ...(index === 3 ? { |
| | | shadowColor: "#00eaff", // 阴影颜色 |
| | | shadowBlur: 25, // 阴影模糊大小 |
| | | shadowOffsetX: 0, // 阴影水平偏移 |
| | | shadowOffsetY: 0, // 阴影垂直偏移 |
| | | opacity: 1 // 不透明度 |
| | | } : {}) |
| | | }, |
| | | |
| | | // 高亮状态配置 |
| | | emphasis: { |
| | | disabled: true // 禁用高亮效果 |
| | | }, |
| | | |
| | | // 选中状态配置 |
| | | select: { |
| | | disabled: true // 禁用选中状态 |
| | | }, |
| | | |
| | | // 提示框配置 |
| | | tooltip: { |
| | | show: false // 禁用提示框 |
| | | }, |
| | | |
| | | silent: true // 禁用鼠标事件响应 |
| | | }; |
| | | }, |
| | | |
| | | // 新增:获取地图完整配置项 |
| | | getMapOption() { |
| | | return { |
| | | // 关闭默认的tooltip |
| | | tooltip: { |
| | | show: false |
| | | }, |
| | | // geo组件配置,用于地图的三层叠加效果 |
| | | geo: [ |
| | | this.getGeoLayers(1), // 最底层 |
| | | this.getGeoLayers(2), // 中间层 |
| | | this.getGeoLayers(3) // 最顶层 |
| | | ], |
| | | // 系列列表 |
| | | series: [ |
| | | { |
| | | type: "map", // 地图类型 |
| | | name: "地图", // 系列名称 |
| | | selectedMode: false, // 禁用选中模式 |
| | | aspectScale: 1, // 长宽比 |
| | | zoom: 1, // 缩放比例 |
| | | roam: false, // 禁用平移缩放 |
| | | regionHeight: 2, // 三维地图的厚度 |
| | | map: "myMap", // 使用的地图 |
| | | z: 10, // 最顶层 |
| | | top: "14%", // 主图层位置 |
| | | bottom: "11%", |
| | | viewControl: { // 视角控制 |
| | | distance: 115, // 视角距离主体的距离 |
| | | alpha: 40, // 视角绕 x 轴,即上下旋转的角度 |
| | | rotateSensitivity: [0, 0], // 禁用旋转 |
| | | beta: 0, // 视角绕 y 轴,即左右旋转的角度 |
| | | }, |
| | | label: { // 标签样式 |
| | | normal: { |
| | | show: true, // 显示标签 |
| | | textStyle: { |
| | | color: "#fff", // 标签文字颜色 |
| | | fontSize: 16, // 文字大小 |
| | | fontWeight: "normal", // 文字粗细 |
| | | textShadowColor: "rgba(0,234,255,0.8)", // 文字阴影颜色 |
| | | textShadowBlur: 10, // 文字阴影模糊 |
| | | opacity: 1, // 文字透明度 |
| | | }, |
| | | type: "map", // 图表类型为地图 |
| | | name: "地图", // 系列名称 |
| | | selectedMode: false, // 禁用选中模式 |
| | | aspectScale: 1, // 地图长宽比 |
| | | zoom: 1, // 地图缩放比例 |
| | | roam: false, // 禁用地图平移缩放 |
| | | regionHeight: 2, // 三维地图的高度 |
| | | map: "myMap", // 使用注册的地图名称 |
| | | z: 10, // 图层的层级 |
| | | top: "14%", // 距离容器顶部的距离 |
| | | bottom: "11%", // 距离容器底部的距离 |
| | | |
| | | // 地图区域的样式 |
| | | itemStyle: { |
| | | areaColor: { // 区域填充样式 |
| | | type: 'pattern', // 使用图案填充 |
| | | image: mapBg, // 背景图片 |
| | | repeat: 'no-repeat', // 图片不重复 |
| | | imageSize: '100%', // 图片大小 |
| | | patternSize: [815, 534], // 图案大小 |
| | | patternPosition: [0, 0] // 图案位置 |
| | | }, |
| | | emphasis: { |
| | | color: "#fff", // 悬浮时文字颜色 |
| | | }, |
| | | borderColor: "#324D6B", // 边框颜色 |
| | | borderWidth: 2, // 边框宽度 |
| | | }, |
| | | itemStyle: { // 主图层样式 |
| | | areaColor: { |
| | | image: this.mapBg, // 使用背景图片 |
| | | repeat: 'repeat' // 平铺模式 |
| | | }, |
| | | borderColor: "#00eaff", // 边框颜色 |
| | | borderWidth: 2, // 边框宽度 |
| | | borderType: 'solid', |
| | | shadowColor: "#00eaff", // 阴影颜色 |
| | | shadowOffsetX: 0, |
| | | shadowOffsetY: 0, |
| | | shadowBlur: 20, |
| | | opacity: 1 |
| | | }, |
| | | |
| | | // 高亮状态的配置 |
| | | emphasis: { |
| | | disabled: true // 禁用悬浮效果 |
| | | disabled: false, // 启用高亮效果 |
| | | label: { |
| | | show: true, // 显示标签 |
| | | color: "#fff", // 文字颜色 |
| | | fontSize: 10, // 文字大小 |
| | | fontWeight: "normal", // 文字粗细 |
| | | opacity: 1 // 不透明度 |
| | | }, |
| | | itemStyle: { |
| | | areaColor: { // 区域填充,保持与正常状态相同的背景 |
| | | type: 'pattern', |
| | | image: mapBg, |
| | | repeat: 'no-repeat', |
| | | imageSize: '100%', |
| | | patternSize: [815, 534], |
| | | patternPosition: [0, 0] |
| | | }, |
| | | borderColor: MAP_CONSTANTS.SHADOW.COLOR, // 高亮时的边框颜色 |
| | | borderWidth: 2, // 高亮时的边框宽度 |
| | | shadowColor: 'rgba(0, 234, 255, 0.8)', // 阴影颜色,添加透明度 |
| | | shadowBlur: 40, // 增大阴影模糊半径 |
| | | shadowOffsetX: 0, // 保持阴影水平偏移为0 |
| | | shadowOffsetY: 0, // 保持阴影垂直偏移为0 |
| | | glow: { |
| | | width: 20, // 发光宽度 |
| | | color: 'rgba(0, 234, 255, 0.2)' // 发光颜色 |
| | | }, |
| | | opacity: 0.9 // 略微降低不透明度,增强光晕效果 |
| | | } |
| | | }, |
| | | |
| | | // 选中状态配置 |
| | | select: { |
| | | disabled: true |
| | | disabled: true // 禁用选中状态 |
| | | }, |
| | | light: { // 光照相关的设置 |
| | | main: { // 主光源 |
| | | color: "#00eaff", // 光照颜色 |
| | | intensity: 1.2, // 增加光照强度 |
| | | shadow: true, // 是否显示阴影 |
| | | shadowQuality: "high", // 阴影质量 |
| | | alpha: 40, |
| | | beta: 0, |
| | | }, |
| | | ambient: { // 环境光 |
| | | color: "#00eaff", // 环境光颜色 |
| | | intensity: 0.3, // 减弱环境光以突出主光源 |
| | | }, |
| | | |
| | | // 标签配置 |
| | | label: { |
| | | show: true, // 显示标签 |
| | | color: "#fff", // 文字颜色 |
| | | fontSize: 10, // 文字大小 |
| | | fontWeight: "normal", // 文字粗细 |
| | | opacity: 1 // 不透明度 |
| | | }, |
| | | |
| | | tooltip: { |
| | | show: false // 禁用该系列的tooltip |
| | | }, |
| | | silent: false // 允许鼠标事件 |
| | | }, |
| | | ], |
| | | // 添加蓝色和橙色标记点系列 |
| | | this.getMarkerSeries("blue"), // 蓝色标记点系列 |
| | | this.getMarkerSeries("orange") // 橙色标记点系列 |
| | | ] |
| | | }; |
| | | myChart.setOption(option); |
| | | }, |
| | | }, |
| | | watch: { |
| | | // 监听数据变化,更新地图 |
| | | data: { |
| | | handler(newVal) { |
| | | if (this.hasValidData) { |
| | | this.$nextTick(() => { |
| | | this.initMap(); |
| | | }); |
| | | } |
| | | }, |
| | | immediate: false // 不立即执行,等待mounted |
| | | } |
| | | }, |
| | | beforeDestroy() { |
| | | // 组件销毁前清理echarts实例 |
| | | window.removeEventListener('resize', this.handleResize); |
| | | window.removeEventListener('error', this.handleGlobalError, true); |
| | | if (this.chart) { |
| | | this.chart.dispose(); |
| | | this.chart = null; |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | <style lang="less" scoped> |
| | | /* 地图容器样式 */ |
| | | .map-container { |
| | | position: relative; |
| | | width: 815px; |
| | | height: 534px; |
| | | position: relative; |
| | | |
| | | // 加载状态样式 |
| | | &.loading { |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | bottom: 0; |
| | | background: rgba(0, 0, 51, 0.6); |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | } |
| | | } |
| | | |
| | | // 新增:加载提示样式 |
| | | .loading-tip { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | color: #fff; |
| | | font-size: 14px; |
| | | z-index: 10; |
| | | } |
| | | |
| | | // 新增:错误提示样式 |
| | | .error-message { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | color: #ff4d4f; |
| | | font-size: 14px; |
| | | z-index: 10; |
| | | } |
| | | } |
| | | |
| | | /* 图表容器样式 */ |
| | | .chart { |
| | | width: 100%; |
| | | height: 100%; |
| | | transition: all 0.3s ease; |
| | | } |
| | | </style> |