echart5.x地图下钻和地图标点(vue3+ts)

地图下钻的独立组件,引入即用
在echart地图上踩了太多坑了,记录下吧

使用:

<CityMap :list="mapList" @params="changeParams" />

// 地图标点
let mapList = [
  {
    FarmID: "337207bb-5abe-42ea-949c-e034a3ae6377",
    FarmName: "优然牧场一场",
    Long: 119.23944,
    Lati: 34.324724,
    Admin: "小王",
    Tel: "",
    Livestock: 7660,
    Address: "",
  },
];
let changeParams = (val: any) => {
  console.log("地图会传的数据:", val);
};

组件代码:

<template>
  <div class="cityMap">
    <div class="backMap" :class="{ notAllowed: !notAllowed }" @click="backMap">
      <span>返回</span>
    </div>
    <div class="tradeIn-cattle-map" ref="echartsRef"></div>
  </div>
</template>

<script setup lang="ts">
/**
 * 省市区-地图下钻
 */
import * as echarts from "echarts";
import {
  ref,
  onMounted,
  reactive,
  Ref,
  onUnmounted,
  nextTick,
  watch,
} from "vue";
import axios from "axios";
import { mapScatter } from "@/utils/youran";
// 本地测试用的地图json数据
const mapDatas = require("./320700_full.json");
const mapDatas2 = require("./320723.json");
const echartsRef: Ref = ref(null);

let notAllowed = ref<Boolean>(false);

let timeFn: any = null;

let myChart: any = null;

// 所有地图
let AllMap = reactive([
  {
    prefix: "",
    adcode: "",
    name: "",
  },
]);

onMounted(() => {
  initChart();
});

onUnmounted(() => {});

// 获取地图--和域名一样的地图(上线上上去,防跨域)
function GetMapGeoJson(cityCN: string, citylevel: string) {
  var uploadedDataURL = "";
  if (citylevel == "china") {
    //全国地图
    return "/YooHooMIS/Scripts/echarts/china/100000_full.json";
  }
  if (citylevel != "district" && (cityCN + "").substring(4) != "00")
    citylevel = "district";
  if (citylevel == "district") {
    uploadedDataURL =
      "/YooHooMIS/Scripts/echarts/china/district/" +
      cityCN +
      ".json";
  } else if (citylevel == "city") {
    uploadedDataURL =
      "/YooHooMIS/Scripts/echarts/china/city/" +
      cityCN +
      "_full.json";
  } else {
    uploadedDataURL =
      "/YooHooMIS/Scripts/echarts/china/province/" +
      cityCN +
      "_full.json";
  }
  return uploadedDataURL;
}

// 地图2--阿里云地图
function GetMapGeoJson2(cityCN: string, citylevel: string) {
  var uploadedDataURL = "";
  if (citylevel == "china") {
    //全国地图
    return "https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json";
  }
  if (citylevel != "district" && (cityCN + "").substring(4) != "00")
    citylevel = "district";
  if (citylevel == "district") {
    uploadedDataURL =
      "https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + ".json";
  } else if (citylevel == "city") {
    uploadedDataURL =
      "https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + "_full.json";
  } else {
    uploadedDataURL =
      "https://geo.datav.aliyun.com/areas_v3/bound/" + cityCN + "_full.json";
  }
  return uploadedDataURL;
}

// 向外传值
const emit = defineEmits(["params"]);

function returnParams(params: object) {
  emit("params", params);
}

const props = defineProps({
  funType: {
    type: Object,
    default: {},
  },
  list: {
    type: Array,
    default: [],
  },
});

//各省份的数据--本地图是标点图,所以不需要了,废弃了这里
let allData: any = reactive([]);
function initMapData() {
  // Api.getMapData({
  //   funType: props.funType.module,
  //   mapData: JSON.stringify(AllMap),
  //   range: props.funType.range,
  // }).then((res) => {
  // allData.length = 0;
  // allData.push(
  //   ...[
  //     {
  //       prefix: "district",
  //       adcode: "320703",
  //       name: "连云区",
  //       value: "0",
  //     },
  //     {
  //       prefix: "district",
  //       adcode: "320707",
  //       name: "赣榆区",
  //       value: "0",
  //     },
  //     {
  //       prefix: "district",
  //       adcode: "320722",
  //       name: "东海县",
  //       value: "0",
  //     },
  //     {
  //       prefix: "district",
  //       adcode: "320706",
  //       name: "海州区",
  //       value: "0",
  //     },
  //     {
  //       prefix: "district",
  //       adcode: "320723",
  //       name: "灌云县",
  //       value: "0",
  //     },
  //     {
  //       prefix: "district",
  //       adcode: "320724",
  //       name: "灌南县",
  //       value: "0",
  //     },
  //   ]
  // );
  // console.log("AllMap", AllMap);
  // console.log("各省份的数据allData", allData);

  setTimeout(() => {
    setOption();
  }, 1);
  // });
}

watch(
  [() => props, AllMap],
  (val, val2) => {
    initMapData();
  },
  {
    deep: true,
  }
);

// 激活地图栈

// 当前激活地图
let defaultMap = reactive({
  prefix: "",
  adcode: "",
  name: "",
});

//  初始化地图
initData();

function initData() {
  defaultMap = {
    prefix: "city",
    adcode: "320700",
    name: "连云港市",
  };
}

/**
 获取对应的json地图数据,然后向echarts注册该区域的地图,最后加载地图信息
 @params {String} mapCode:json数据的地址
 @params {String} name: 地图名称
 */
let mapStack: any[] = [];

function loadMap() {
  if (mapStack.length == 0) {
    mapStack.push(defaultMap);
  }
  let mapData = GetMapGeoJson2("320700", "city") || mapDatas;

  if (mapStack.length > 1) {
    mapData = GetMapGeoJson2(
      mapStack[mapStack.length - 1].adcode,
      mapStack[mapStack.length - 1].prefix
    );
  }
  AllMap = [
    {
      prefix: "district",
      adcode: "320703",
      name: "连云区",
    },
    {
      prefix: "district",
      adcode: "320707",
      name: "赣榆区",
    },
    {
      prefix: "district",
      adcode: "320722",
      name: "东海县",
    },
    {
      prefix: "district",
      adcode: "320706",
      name: "海州区",
    },
    {
      prefix: "district",
      adcode: "320723",
      name: "灌云县",
    },
    {
      prefix: "district",
      adcode: "320724",
      name: "灌南县",
    },
  ];
  // 注册当前激活地图
  // console.log("激活地图", mapStack[mapStack.length - 1].name, mapData);
  axios.get(mapData).then((geoJson: any) => {
    echarts.registerMap(mapStack[mapStack.length - 1].name, geoJson.data);
    nextTick(() => {
      setOption();
    });
  });
}

function setOption() {
  let option = {
    tooltip: {
      show: true,
      className: "CityMapChartTooltipBg",
      formatter: (params: any) => {
        if (params.componentSubType === "scatter") return params.name;
      },
    },
    geo: {
      map: mapStack[mapStack.length - 1].name || "连云港市",
      itemStyle: {
        normal: {
          areaColor: `#10359b`,
          borderColor: `#fff`,
          borderWidth: 1,
          shadowColor: `#94d9ff`,
          shadowOffsetX: -4,
          shadowOffsetY: 8,
          shadowBlur: 1,
        },
        emphasis: {
          label: {
            show: false,
          },
        },
      },
    },
    xAxis: [],
    yAxis: [],
    series: [
      {
        name: "MAP",
        type: "map",
        map: mapStack[mapStack.length - 1].name || "连云港市",
        selectedMode: "false", //是否允许选中多个区域
        label: {
          normal: {
            show: true,
            textStyle: {
              color: "#fff",
              fontSize: 16,
              fontFamily: "SourceHanSansCN",
            },
          },
        },

        itemStyle: {
          areaColor: "#0f18c2",
          borderColor: "#6becf5",
          borderWidth: 1.5,
          emphasis: {
            show: true,
            areaColor: "#55ade8", // 鼠标悬浮地图面的颜色
            shadowColor: "#94d9ff",
            shadowOffsetX: -2,
            shadowOffsetY: 2,
            shadowBlur: 5,
            label: {
              show: true,
              textStyle: {
                color: "#fff",
                fontSize: 16,
                fontFamily: "SourceHanSansCN",
              },
            },
          },
        },
        // data: allData,//各省的数据,鼠标放上显示,现在是标点图所以不显示
      },
    ],
  };
  addScatter(option);
  myChart.setOption(option);
}
// 加牧场坐标点
function addScatter(option: any) {
  let dataList: any = [];
  if (props.list.length > 0) {
    props.list.forEach((item: any) => {
      let name = `
      
${item.FarmName || ""} ${item.Livestock || 0}
负责人: ${item.Admin || ""}
地址: ${item.address || ""}
`
; dataList.push({ name: name, value: [item.Long, item.Lati], }); }); } option.series.push({ type: "scatter", coordinateSystem: "geo", symbol: "image://" + mapScatter, symbolSize: [66, 36], itemStyle: { normal: { color: "#1cedd4", shadowBlur: 10, shadowColor: "#333", }, }, zlevel: 2, data: dataList, }); } let initChart = () => { if (!myChart) { myChart = echarts.init(echartsRef.value); } loadMap(); //单击切换到省级地图,当mapCode有值,说明可以切换到下级地图 myChart.on("click", (params: any) => { notAllowed.value = true; clearTimeout(timeFn); //由于单击事件和双击事件冲突,故单击的响应事件延迟250毫秒执行 timeFn = setTimeout(() => { let clickMap = AllMap.find((item) => item.name == params.name); // if (!clickMap) { // alert("无此区域地图显示"); // return; // } // 向外传参 returnParams(clickMap || {}); // 只存3级 if (mapStack.length < 3) { mapStack.push(clickMap); } loadMap(); }, 250); }); // 绑定双击事件,返回全国地图 myChart.on("dblclick", (params: any) => { //当双击事件发生时,清除单击事件,仅响应双击事件 clearTimeout(timeFn); // 以防初始化双击丢栈 if (mapStack.length > 1) { mapStack.pop(); } let res = mapStack[mapStack.length - 1]; //返回参数 returnParams(res); loadMap(); }); }; let backMap = () => { notAllowed.value = false; //鼠标放上去的禁用状态 //当双击事件发生时,清除单击事件,仅响应双击事件 clearTimeout(timeFn); // 取当前默认地图 returnParams(defaultMap); mapStack.length = 0; // 地图栈 最后一个 loadMap(); }; </script> <style lang="less" scoped> .cityMap { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; position: relative; .backMap { position: absolute; top: 0; left: 40px; border: none; z-index: 9; span { display: block; font-size: 12px; border-radius: 7px; background-color: #06bcec; padding: 4px 6px; color: #fff; cursor: pointer; } &:focus { outline: none; } &:hover { background-size: 100% 100%; span { color: #ffffff; } } &.notAllowed { cursor: not-allowed; } } .tradeIn-cattle-map { width: 90%; height: 90%; } } </style>

效果图:

echart5.x地图下钻和地图标点(vue3+ts)_第1张图片

echart5.x地图下钻和地图标点(vue3+ts)_第2张图片

你可能感兴趣的:(vue,echarts,vue.js)