1.效果图:

2. 安装echarts:

npm install echarts --save

 3.引入中国地图JSONDataV.GeoAtlas地理小工具系列

4.代码如下:

<template>
  <div class="map-container">
    <div id="map-chart" class="map" tabindex="0"></div>
    <div class="input-card">
      <div class="mt5">
        <el-avatar
          :size="20"
          src="xxx"
        />
        一级代理店
      </div>
      <div class="mt5">
        <el-avatar
          :size="20"
          src="xx"
        />
        二级代理店
      </div>
      <div class="mt5">
        <el-avatar
          :size="20"
          src="xxx"
        />
        三级代理店
      </div>
    </div>
    <div class="info">
      <div class="input-item">
        <el-input
          v-model="addressInput"
          placeholder="请输入地址"
          @keyup.enter="handleSearch"
        >
          <template #append>
            <el-button @click="handleSearch" icon="search">查询</el-button>
          </template>
        </el-input>
      </div>
    </div>
  </div>
</template>

<script>
import { onMounted, ref, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
import "echarts/extension/bmap/bmap";
import chinaJson from "./china.json"; //中国地图(省份)自行下载

export default {
  name: "AgentMapEcharts",
  setup() {
    const addressInput = ref("");
    let chartInstance = null;
    let originalData = []; // 保存原始数据

    // 店铺类型配置
    const shopTypeConfig = {
      一级代理店: {
        color: "#fcb715",
        icon: "xxx",
        symbolSize: 18,
      },
      二级代理店: {
        color: "#00862b",
        icon: "xxx",
        symbolSize: 16,
      },
      三级代理店: {
        color: "#015aef",
        icon: "xxx",
        symbolSize: 16,
      },
    };

    // 初始化地图和图表
    const initMap = () => {
      chartInstance = echarts.init(document.getElementById("map-chart"));

      // 注册中国地图数据(核心修改)
      echarts.registerMap("china", chinaJson);

      // 初始配置 - 简化地图样式配置
      const option = {
        animation: true,
        tooltip: {
          trigger: "item",
          formatter: (params) => {
            if (params.data) {
              const data = params.data;
              return `
                <div style="padding: 5px; min-width: 150px; color: ${
                  shopTypeConfig[data.type]?.color || "#333"
                }">
                  <div>店号:${data.code || "无"}</div>
                  <div>店主:${data.name || "无"}</div>
                  <div>地址:${data.address || "无"}</div>
                  <div>类型:${data.type || "无"}</div>
                </div>
              `;
            }
            return "";
          },
        },
        geo: {
          // 替换原有的bmap配置
          map: "china",
          roam: true,
          zoom: 2,
          center: [104.114129, 37.550339], // 中国中心点坐标
          label: {
            show: true,
            color: "#333",
          },
          itemStyle: {
            areaColor: "#f0f8ff", // 浅蓝色背景
            borderColor: "#00868B", // 青色边框
          },
          emphasis: {
            itemStyle: {
              areaColor: "#e6f7ff", // 高亮时浅蓝色
            },
          },
        },
        series: [
          {
            name: "代理店",
            type: "scatter",
            coordinateSystem: "geo",
            data: [],
            symbolSize: function (val) {
              return shopTypeConfig[val.type]?.symbolSize || 10;
            },
            itemStyle: {
              color: function (val) {
                return shopTypeConfig[val.data?.type]?.color || "#333";
              },
            },
            emphasis: {
              itemStyle: {
                color: function (val) {
                  return shopTypeConfig[val.data?.type]?.color || "#333";
                },
                borderWidth: 2,
                borderColor: "#fff",
              },
            },
          },
        ],
      };

      chartInstance.setOption(option);

      loadAgentData(); 
    };
    
    // 加载代理店数据
    const loadAgentData = async () => { 
      try {
        let shops = [
          {
            FDLDName: "聂xx",
            FAdr: "内蒙古兴安盟乌兰浩特xxx",
            FDLDCode2: "0720",
            FType: "一级代理店",
            FLong: "122.0832190000",
            FLat: "46.0744950000",
            FId: 1749,
          },
          {
            FDLDName: "郑xx",
            FAdr: "河北省石家庄新乐市邯xxx",
            FDLDCode2: "2063",
            FType: "一级代理店",
            FLong: "114.7235690000",
            FLat: "38.3414250000",
            FId: 4993,
          },
          {
            FDLDName: "姚xx",
            FAdr: "xxx",
            FDLDCode2: "0071CD",
            FType: "二级代理店",
            FLong: "122.9915890000",
            FLat: "41.1202170000",
            FId: 1306,
          },
          {
            FDLDName: "任xx",
            FAdr: "辽宁省开原市八宝镇金xxx",
            FDLDCode2: "0002AF",
            FType: "二级代理店",
            FLong: "124.7318630000",
            FLat: "42.7378750000",
            FId: 1303,
          },
          {
            FDLDName: "梁xx",
            FAdr: "四川省西昌市宁远桥光xxx",
            FDLDCode2: "0376AO",
            FType: "二级代理店",
            FLong: "102.2518450000",
            FLat: "27.8949840000",
            FId: 1301,
          },
          {
            FDLDName: "史xx",
            FAdr: "河南省焦作市解放区上xxx",
            FDLDCode2: "0439AC",
            FType: "二级代理店",
            FLong: "113.2055600000",
            FLat: "35.2501130000",
            FId: 1302,
          },
          {
            FDLDName: "周xx",
            FAdr: "xxx",
            FDLDCode2: "0550AB",
            FType: "二级代理店",
            FLong: "122.1258080000",
            FLat: "40.8342490000",
            FId: 1299,
          },
          {
            FDLDName: "付xx",
            FAdr: "xxx",
            FDLDCode2: "0298AM",
            FType: "二级代理店",
            FLong: "103.4487120000",
            FLat: "30.6189520000",
            FId: 1300,
          },
          {
            FDLDName: "刘xx",
            FAdr: "xxx",
            FDLDCode2: "0572",
            FType: "二级代理店",
            FLong: "119.1280900000",
            FLat: "36.7201900000",
            FId: 1327,
          },
          {
            FDLDName: "甄xx",
            FAdr: "xxx",
            FDLDCode2: "0018AI",
            FType: "二级代理店",
            FLong: "125.8612620000",
            FLat: "42.6425390000",
            FId: 1329,
          },
          {
            FDLDName: "杜xx",
            FAdr: "xxx",
            FDLDCode2: "0018AH",
            FType: "二级代理店",
            FLong: "125.8612620000",
            FLat: "42.6425390000",
            FId: 1330,
          },
        ];

        // 转换数据格式
        originalData = shops
          .filter((shop) => {
            const lng = parseFloat(shop.FLong) || 0;
            const lat = parseFloat(shop.FLat) || 0;
            return lng !== 0 && lat !== 0;
          })
          .map((shop) => {
            const type = shop.FType || "一级代理店";
            return {
              name: shop.FDLDName,
              code: shop.FDLDCode2,
              address: shop.FAdr,
              type: type,
              value: [
                parseFloat(shop.FLong),
                parseFloat(shop.FLat),
                shop.FDLDName,
              ],
              symbol: `image://${shopTypeConfig[type]?.icon}`,
              symbolSize: shopTypeConfig[type]?.symbolSize || 10,
              itemStyle: {
                color: shopTypeConfig[type]?.color || "#333",
              },
              // 添加原始大小记录
              originalSize: shopTypeConfig[type]?.symbolSize || 10,
            };
          });

        // 更新图表数据
        updateChartData(originalData);
      } catch (error) {
        console.error("加载代理店数据失败:", error);
      }
    };

    // 更新图表数据
    const updateChartData = (data) => {
      chartInstance.setOption({
        series: [
          {
            data: data,
          },
        ],
      });
    };

    const handleSearch = async () => {
      if (!addressInput.value) {
        // 如果搜索框为空,恢复原始数据显示
        updateChartData(originalData);
        return;
      }

      // 创建新的数据数组
      const newData = originalData.map((shop) => {
        // 默认使用原始大小
        const size = shop.originalSize;

        // 如果地址匹配,放大图标
        if (shop.address && shop.address.includes(addressInput.value)) {
          return {
            ...shop,
            symbolSize: size * 5, // 放大5倍
          };
        }
        return shop;
      });

      // 查找匹配的店铺
      const foundShops = newData.filter(
        (shop) => shop.address && shop.address.includes(addressInput.value)
      );

      if (foundShops.length > 0) {
        // 定位到第一个匹配的店铺
        const firstShop = foundShops[0];
        chartInstance.setOption({
          geo: {
            center: firstShop.value.slice(0, 2),
            zoom: 12, // 适当的缩放级别
          },
          series: [
            {
              data: newData,
            },
          ],
        });
      } else {
        console.log("未找到匹配的店铺");
        // 可以添加提示
        updateChartData(originalData); // 恢复原始数据
      }
    };

    // 窗口大小变化时重新调整图表大小
    const handleResize = () => {
      if (chartInstance) {
        chartInstance.resize();
      }
    };

    onMounted(() => {
      initMap();
      window.addEventListener("resize", handleResize);
    });

    onBeforeUnmount(() => {
      window.removeEventListener("resize", handleResize);
      if (chartInstance) {
        chartInstance.dispose();
      }
    });

    return {
      handleSearch,
      addressInput,
    };
  },
};
</script>

<style>
.map-container {
  position: relative;
  height: 100vh;
  width: 100vw;
}

.map {
  height: 100%;
  width: 100%;
}

.input-card {
  position: absolute;
  bottom: 100px;
  right: 20px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
  z-index: 10;
}

.info {
  position: absolute;
  top: 20px;
  right: 20px;
  background: white;
  padding: 10px;
  border-radius: 4px;
  box-shadow: 0 2px 6px 0 rgba(114, 124, 245, 0.5);
  z-index: 10;
  width: 300px;
}

.input-item {
  margin-bottom: 10px;
}
</style>

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐