接上一条地图预警区域通过adcode来传区域 地图整个背景颜色设置为#062D4A 区县分割线颜色设置为#09CFD2 在warningData 里面的存在的区域数据显示市县名称 其他区域则不显示名称
时间: 2025-07-31 16:43:14 浏览: 10
<think>根据用户需求,我们需要在之前实现的四川地图预警系统基础上,调整地图样式和区域显示控制。具体要求如下:
1. 使用adcode传递区域信息(在之前的实现中,我们使用的是区县名称,现在需要改为adcode)
2. 设置地图背景颜色为#062D4A
3. 设置区县分割线颜色为#09CFD2
4. 根据warningData数据显示市县名称,其他区域不显示名称
实现步骤:
1. **数据格式调整**:将之前使用区县名称作为标识改为使用adcode。需要获取四川省各区县的adcode,并更新warningData数据结构。
2. **地图样式调整**:
- 背景色:通过backgroundColor设置
- 分割线:通过itemStyle.borderColor设置
3. **标签显示控制**:使用label.formatter函数,根据warningData中是否存在该区域的数据来决定是否显示标签。
具体修改如下:
### 1. 准备adcode数据
我们需要一个映射关系,将区县名称映射到adcode。可以从GeoJSON数据中提取,也可以在代码中维护一个映射表。
在`sichuan.json`文件中,每个区县的特征(feature)都包含properties,其中应有adcode属性。我们可以利用这个属性。
### 2. 修改SichuanMap.vue组件
#### 数据调整
将warningData的数据结构从`{ '区县名': 等级 }`改为`{ 'adcode': 等级 }`。
同时,我们需要一个区县名称到adcode的映射表(如果GeoJSON中已经包含名称和adcode,我们可以直接使用)。
#### 地图配置调整
- 背景色:在option中设置`backgroundColor: '#062D4A'`
- 分割线颜色:在series的itemStyle中设置`borderColor: '#09CFD2'`
- 标签显示:在label配置中,使用formatter函数,根据该区域的adcode是否在warningData中来决定是否显示名称
### 代码修改示例
**src/components/SichuanMap.vue**
```vue
<script setup>
// ...其他代码保持不变
// 模拟预警数据(使用adcode作为键)
const warningData = ref({
// 示例:成都市锦江区 adcode 510104
'510104': 1,
'510105': 2, // 青羊区
'510106': 3, // 金牛区
// ...其他区县
});
// 从GeoJSON中提取名称和adcode的映射(假设sichuanMapData已经导入)
// 注意:由于GeoJSON的结构,我们需要遍历所有区县
const areaMap = ref({});
if (sichuanMapData) {
sichuanMapData.features.forEach(feature => {
const name = feature.properties.name;
const adcode = feature.properties.adcode;
areaMap.value[adcode] = name; // adcode到名称的映射
// 也可以建立名称到adcode的映射,但这里我们主要用adcode
});
}
onMounted(() => {
initChart();
// ...其他代码
});
const initChart = () => {
// ...注册地图等代码不变
const option = {
backgroundColor: '#062D4A', // 设置背景色
// ...其他配置
series: [{
// ...其他配置
label: {
show: true,
fontSize: 10,
color: '#fff', // 文字颜色设为白色,在深色背景下更清晰
formatter: function(params) {
// 根据adcode判断该区域是否有预警数据
const adcode = params.data ? params.data.adcode : null;
// 如果有预警数据,则显示名称,否则不显示
if (adcode && warningData.value[adcode] !== undefined) {
return areaMap.value[adcode] || params.name;
}
return ''; // 没有预警数据的区域不显示名称
}
},
emphasis: {
// ...其他配置
},
data: Object.keys(warningData.value).map(adcode => ({
adcode: adcode,
name: areaMap.value[adcode] || '', // 这里name用于tooltip显示
value: warningData.value[adcode]
})),
itemStyle: {
borderColor: '#09CFD2', // 设置分割线颜色
borderWidth: 1
}
}]
};
// ...设置option和事件监听
};
</script>
```
### 3. 调整右侧面板
右侧面板中的表格之前使用的是区县名称,现在需要改为使用adcode映射到名称显示。我们同样使用之前构建的areaMap映射。
**src/views/MapView.vue**
```vue
<script setup>
// ...其他代码
// 模拟预警数据(使用adcode)
const warningData = ref({
'510104': 1,
'510105': 2,
// ...其他区县
});
// 映射表(从SichuanMap组件中获取或单独定义,建议抽离为公共数据)
const areaMap = ref({
'510104': '锦江区',
'510105': '青羊区',
// ...其他区县
});
// 过滤后的预警数据(表格使用)
const filteredWarningData = computed(() => {
return Object.entries(warningData.value)
.filter(([adcode]) => {
// 根据搜索文本过滤(搜索的是区县名称)
const areaName = areaMap.value[adcode] || '';
return areaName.includes(searchText.value);
})
.map(([adcode, level]) => ({
adcode,
area: areaMap.value[adcode] || adcode, // 显示名称
level
}));
});
// 在显示详情和更新预警等级时,也要注意使用adcode
const showDetail = (adcode) => {
selectedAdcode.value = adcode;
selectedLevel.value = warningData.value[adcode];
detailVisible.value = true;
};
const updateWarningLevel = () => {
warningData.value[selectedAdcode.value] = selectedLevel.value;
detailVisible.value = false;
};
</script>
```
### 4. 样式微调
由于背景色变深,可能需要调整其他元素的颜色以保证可读性。
### 注意事项
1. **adcode来源**:确保GeoJSON数据中包含adcode属性。如果没有,需要手动添加或使用其他唯一标识符。
2. **映射表维护**:如果区县较多,建议将名称与adcode的映射表单独维护为一个JSON文件,避免在代码中硬编码。
3. **性能优化**:当区县数量很多时,在formatter函数中频繁查询可能会影响性能。可以考虑预先处理数据,将需要显示标签的区域单独标记。
### 相关问题
1. 如何获取中国所有区县的adcode?
2. 在ECharts中如何实现动态更新地图数据?
3. 如何优化大量区域标签显示的性能?
4. 深色背景下如何选择合适的地图元素配色?
5. 如何实现地图区域点击后的高亮效果?
以上修改实现了用户需求的地图样式和标签显示控制。地图背景变为深蓝色(#062D4A),区县分割线为青色(#09CFD2),并且只显示有预警数据的区县名称。</think># Vue3 + Element Plus 四川地图预警系统(增强版)
我将根据您的需求增强地图样式,实现以下功能:
- 使用adcode传递区域信息
- 设置地图背景颜色为#062D4A
- 设置区县分割线颜色为#09CFD2
- 根据预警数据显示市县名称,其他区域不显示名称
下面是完整的实现方案:
## 增强功能实现
### 1. 修改地图组件
**src/components/SichuanMap.vue**
```vue
<template>
<div class="map-container">
<div ref="mapChart" class="map-chart"></div>
<!-- 图例卡片 -->
<el-card class="legend-card">
<div class="legend">
<div v-for="(level, index) in warningLevels" :key="index" class="legend-item">
<div class="color-box" :style="{ backgroundColor: level.color }"></div>
<span>{{ level.name }}</span>
</div>
</div>
</el-card>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import * as echarts from 'echarts';
import sichuanMapData from '@/assets/sichuan.json'; // 四川省GeoJSON数据
const props = defineProps({
warningData: {
type: Object,
required: true
}
});
const mapChart = ref(null);
let chartInstance = null;
// 预警等级配置
const warningLevels = ref([
{ name: '无预警', value: 0, color: '#dcdfe6' },
{ name: '一级预警', value: 1, color: '#e6f7ff' },
{ name: '二级预警', value: 2, color: '#bae7ff' },
{ name: '三级预警', value: 3, color: '#91d5ff' },
{ name: '四级预警', value: 4, color: '#69c0ff' },
{ name: '五级预警', value: 5, color: '#40a9ff' },
{ name: '特级预警', value: 6, color: '#1890ff' }
]);
// 创建地图数据
const createMapData = () => {
return Object.entries(props.warningData).map(([adcode, level]) => ({
adcode,
value: level
}));
};
onMounted(() => {
initChart();
window.addEventListener('resize', resizeChart);
});
onBeforeUnmount(() => {
window.removeEventListener('resize', resizeChart);
if (chartInstance) {
chartInstance.dispose();
}
});
// 监听预警数据变化
watch(() => props.warningData, () => {
if (chartInstance) {
const option = chartInstance.getOption();
option.series[0].data = createMapData();
chartInstance.setOption(option);
}
}, { deep: true });
const initChart = () => {
if (!mapChart.value) return;
// 注册四川地图
echarts.registerMap('sichuan', sichuanMapData);
chartInstance = echarts.init(mapChart.value);
const option = {
backgroundColor: '#062D4A', // 设置深蓝色背景
title: {
text: '四川省预警地图',
subtext: '实时监控各区县预警状态',
left: 'center',
textStyle: {
color: '#fff', // 白色文字
fontSize: 18
}
},
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(6, 45, 74, 0.8)',
borderColor: '#09CFD2',
textStyle: {
color: '#fff'
},
formatter: function(params) {
const adcode = params.data ? params.data.adcode : '';
const level = props.warningData[adcode] || 0;
const levelInfo = warningLevels.value.find(l => l.value === level);
// 从GeoJSON中获取区域名称
const areaFeature = sichuanMapData.features.find(f => f.properties.adcode == adcode);
const areaName = areaFeature ? areaFeature.properties.name : '未知区域';
return `
<div style="font-weight:bold;color:#09CFD2">${areaName}</div>
<div>预警等级: ${levelInfo.name}</div>
<div>更新时间: ${new Date().toLocaleTimeString()}</div>
`;
}
},
visualMap: {
type: 'piecewise',
pieces: warningLevels.value.map(level => ({
value: level.value,
label: level.name,
color: level.color
})),
textStyle: {
color: '#fff'
},
orient: 'horizontal',
left: 'center',
bottom: 10
},
series: [{
name: '预警等级',
type: 'map',
map: 'sichuan',
roam: true,
zoom: 1.2,
label: {
show: true,
fontSize: 10,
color: '#fff',
// 只显示有预警数据的区域名称
formatter: function(params) {
const adcode = params.data ? params.data.adcode : '';
// 如果有预警数据才显示名称
if (props.warningData[adcode] !== undefined) {
// 从GeoJSON中获取区域名称
const areaFeature = sichuanMapData.features.find(f => f.properties.adcode == adcode);
return areaFeature ? areaFeature.properties.name : '';
}
return '';
}
},
emphasis: {
label: {
color: '#fff',
fontSize: 12
},
itemStyle: {
areaColor: '#ffd04b'
}
},
data: createMapData(),
itemStyle: {
borderColor: '#09CFD2', // 设置分割线颜色
borderWidth: 1
}
}]
};
chartInstance.setOption(option);
// 添加点击事件
chartInstance.on('click', (params) => {
if (params.data) {
console.log('点击区域adcode:', params.data.adcode);
// 实际项目中可以跳转到详情页面
}
});
};
const resizeChart = () => {
chartInstance && chartInstance.resize();
};
</script>
<style scoped>
.map-container {
position: relative;
width: 100%;
height: 600px;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
}
.map-chart {
width: 100%;
height: 100%;
}
.legend-card {
position: absolute;
top: 20px;
right: 20px;
z-index: 10;
width: 180px;
background-color: rgba(6, 45, 74, 0.7);
border: 1px solid #09CFD2;
}
.legend {
display: flex;
flex-direction: column;
gap: 8px;
}
.legend-item {
display: flex;
align-items: center;
gap: 8px;
color: #fff;
}
.color-box {
width: 20px;
height: 20px;
border-radius: 4px;
border: 1px solid #dcdfe6;
}
</style>
```
### 2. 更新主页面组件
**src/views/MapView.vue**
```vue
<template>
<div class="map-view">
<el-page-header @back="goBack" title="返回">
<template #content>
<span class="text-large font-600 mr-3" style="color: #fff">四川省预警地图系统</span>
</template>
</el-page-header>
<el-row :gutter="20" class="mt-4">
<el-col :span="18">
<sichuan-map ref="mapRef" :warning-data="warningData" />
</el-col>
<el-col :span="6">
<el-card class="info-card">
<template #header>
<div class="card-header">
<span>预警数据管理</span>
<el-button type="primary" size="small" @click="refreshData">
<el-icon><Refresh /></el-icon> 刷新数据
</el-button>
</div>
</template>
<el-table :data="filteredWarningData" height="400" stripe style="width: 100%">
<el-table-column prop="area" label="行政区划" width="120" />
<el-table-column prop="level" label="预警等级">
<template #default="{ row }">
<el-tag :type="getTagType(row.level)" effect="dark">
{{ getLevelName(row.level) }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template #default="{ row }">
<el-button type="primary" size="small" @click="showDetail(row.adcode)">
详情
</el-button>
</template>
</el-table-column>
</el-table>
<div class="filter-area mt-4">
<el-input
v-model="searchText"
placeholder="搜索行政区划..."
clearable
>
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
</div>
</el-card>
</el-col>
</el-row>
<!-- 详情对话框 -->
<el-dialog v-model="detailVisible" :title="`${selectedAreaName} - 预警详情`" width="500">
<div class="detail-content">
<div class="level-display">
<span>当前预警等级:</span>
<el-tag :type="getTagType(selectedLevel)" size="large" effect="dark">
{{ getLevelName(selectedLevel) }}
</el-tag>
</div>
<el-divider />
<div class="level-control">
<span>调整预警等级:</span>
<el-slider
v-model="selectedLevel"
:max="6"
:step="1"
:marks="warningMarks"
show-stops
/>
</div>
<el-divider />
<div class="action-buttons">
<el-button type="primary" @click="updateWarningLevel">确认修改</el-button>
<el-button @click="detailVisible = false">取消</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { Refresh, Search } from '@element-plus/icons-vue';
import SichuanMap from '@/components/SichuanMap.vue';
import sichuanMapData from '@/assets/sichuan.json'; // 导入地图数据以获取区域名称
// 创建adcode到名称的映射
const adcodeToNameMap = {};
sichuanMapData.features.forEach(feature => {
adcodeToNameMap[feature.properties.adcode] = feature.properties.name;
});
// 模拟预警数据(使用adcode作为键)
const warningData = ref({
// 成都市
'510104': 1, // 锦江区
'510105': 2, // 青羊区
'510106': 3, // 金牛区
'510107': 4, // 武侯区
'510108': 5, // 成华区
'510112': 0, // 龙泉驿区
'510113': 1, // 青白江区
'510114': 2, // 新都区
'510115': 3, // 温江区
// 绵阳市
'510703': 4, // 涪城区
'510704': 5, // 游仙区
'510705': 6, // 安州区
// 自贡市
'510302': 2, // 自流井区
'510303': 3, // 贡井区
'510304': 4, // 大安区
'510311': 1, // 沿滩区
// 攀枝花市
'510402': 5, // 东区
'510403': 6, // 西区
'510411': 3 // 仁和区
});
const searchText = ref('');
const detailVisible = ref(false);
const selectedAdcode = ref('');
const selectedLevel = ref(0);
const selectedAreaName = computed(() =>
selectedAdcode.value ? adcodeToNameMap[selectedAdcode.value] : ''
);
// 预警等级标记
const warningMarks = ref({
0: '无预警',
1: '一级',
2: '二级',
3: '三级',
4: '四级',
5: '五级',
6: '特级'
});
// 过滤后的预警数据(用于表格显示)
const filteredWarningData = computed(() => {
return Object.entries(warningData.value)
.filter(([adcode]) => {
const areaName = adcodeToNameMap[adcode] || '';
return areaName.includes(searchText.value);
})
.map(([adcode, level]) => ({
adcode,
area: adcodeToNameMap[adcode] || adcode,
level
}));
});
// 获取预警等级名称
const getLevelName = (level) => {
const levels = ['无预警', '一级预警', '二级预警', '三级预警', '四级预警', '五级预警', '特级预警'];
return levels[level] || '未知';
};
// 获取标签类型
const getTagType = (level) => {
const types = ['info', '', 'success', 'warning', 'danger', 'danger', 'danger'];
return types[level] || 'info';
};
// 刷新数据
const refreshData = () => {
// 实际项目中应调用API获取最新数据
console.log('刷新预警数据...');
};
// 显示详情
const showDetail = (adcode) => {
selectedAdcode.value = adcode;
selectedLevel.value = warningData.value[adcode];
detailVisible.value = true;
};
// 更新预警等级
const updateWarningLevel = () => {
warningData.value[selectedAdcode.value] = selectedLevel.value;
detailVisible.value = false;
};
// 返回上一页
const goBack = () => {
console.log('返回上一页');
// 实际项目中应使用路由返回
};
</script>
<style scoped>
.map-view {
padding: 20px;
background-color: #062D4A; /* 深蓝色背景 */
min-height: 100vh;
color: #fff;
}
.info-card {
height: 100%;
border-radius: 8px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
background-color: rgba(6, 45, 74, 0.7);
border: 1px solid #09CFD2;
color: #fff;
}
:deep(.el-card__header) {
border-bottom: 1px solid #09CFD2;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
color: #fff;
}
.detail-content {
padding: 0 20px;
color: #333; /* 对话框内使用深色文字 */
}
.level-display {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 20px;
}
.level-control {
display: flex;
flex-direction: column;
gap: 15px;
margin-bottom: 20px;
}
.action-buttons {
display: flex;
justify-content: flex-end;
gap: 15px;
margin-top: 20px;
}
.filter-area {
margin-top: 15px;
}
/* 调整表格样式 */
:deep(.el-table) {
--el-table-border-color: #09CFD2;
--el-table-header-bg-color: rgba(6, 45, 74, 0.8);
--el-table-tr-bg-color: rgba(6, 45, 74, 0.6);
--el-table-text-color: #fff;
--el-table-header-text-color: #09CFD2;
--el-table-row-hover-bg-color: rgba(9, 207, 210, 0.2);
}
:deep(.el-table th) {
background-color: rgba(6, 45, 74, 0.9);
}
:deep(.el-table tr) {
background-color: rgba(6, 45, 74, 0.7);
}
:deep(.el-table__body tr:hover>td) {
background-color: rgba(9, 207, 210, 0.3) !important;
}
</style>
```
### 3. 获取四川省地图数据(含adcode)
1. 访问阿里云DataV获取GeoJSON数据:http://datav.aliyun.com/portal/school/atlas/area_selector
2. 选择四川省,下载GeoJSON格式的地图数据
3. 确保下载的数据包含adcode字段(通常包含在properties中)
4. 将下载的文件保存为 `src/assets/sichuan.json`
### 4. 样式增强说明
1. **深色背景**:
- 地图背景设置为 `#062D4A`
- 整个页面背景也设置为深蓝色主题
- 文字颜色调整为白色或浅色,确保可读性
2. **分割线样式**:
- 区县分割线颜色设置为 `#09CFD2`(青色)
- 边框宽度保持为1px
3. **区域名称显示**:
- 使用 `label.formatter` 函数控制标签显示
- 只显示有预警数据的区域名称
- 使用GeoJSON中的区域名称确保准确性
4. **adcode传递**:
- 所有区域数据使用adcode作为唯一标识
- 通过adcode在GeoJSON中查找对应的区域名称
- 表格和对话框中使用adcode与名称的映射
5. **深色主题适配**:
- 调整表格、卡片等组件的样式适配深色背景
- 使用半透明效果增强视觉层次感
- 添加青色边框增强科技感
## 技术要点
1. **adcode的使用**:
- adcode是中国行政区划的标准编码,确保区域标识的唯一性
- 从GeoJSON的properties中提取adcode和名称的映射关系
- 使用adcode作为数据传递的核心标识符
2. **地图标签控制**:
```javascript
label: {
formatter: function(params) {
const adcode = params.data ? params.data.adcode : '';
if (props.warningData[adcode] !== undefined) {
const areaFeature = sichuanMapData.features.find(f =>
f.properties.adcode == adcode
);
return areaFeature ? areaFeature.properties.name : '';
}
return '';
}
}
```
3. **深色主题实现**:
```css
.map-view {
background-color: #062D4A;
color: #fff;
}
.info-card {
background-color: rgba(6, 45, 74, 0.7);
border: 1px solid #09CFD2;
}
```
4. **响应式数据更新**:
```javascript
watch(() => props.warningData, () => {
if (chartInstance) {
const option = chartInstance.getOption();
option.series[0].data = createMapData();
chartInstance.setOption(option);
}
}, { deep: true });
```
## 相关问题
1. 如何获取中国其他省份的adcode数据?
2. 在深色地图背景下如何优化标签的可读性?
3. 如何实现地图区域的下钻功能(省->市->区县)?
4. 当区域数据量很大时,如何优化地图渲染性能?
5. 如何将地图预警系统集成到现有的监控平台中?
6. 如何实现地图数据的实时更新(WebSocket)?
7. 在Element Plus中如何创建自定义深色主题?
以上实现满足了您的所有需求:使用adcode传递区域信息、深蓝色背景(#062D4A)、青色分割线(#09CFD2),以及根据预警数据显示区域名称的功能。系统现在具有科技感十足的深色主题,同时保持了良好的用户体验和交互性。
阅读全文
相关推荐











