梳理清楚的echarts地图下钻和标点信息组件

效果图

效果图

说明

默认数据没有就是全国地图,
$bus.off("onresize")是地图容器变化刷新地图适配的,可以你们自己写
getEchartsFontSize是适配字体大小的,getEchartsFontSize(0.12) === 12
mapScatter是base64图片就是图上那个标点的底图
GetMapGeoJson是获取地图json的,这里的是我公司的,可以用阿里云的代替
还有不明白的可以看是之前的文章,echart5.x地图下钻和地图标点(vue3+ts)

// 地图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;
}

使用

<!-- :defaultMap="defaultMap" -->
<mapChart :list="scatterList" @changeMapData="changeMapData" />

import mapChart from "@/views/universal-visuali/components/charts/map/mapChart.vue";

// 默认的地图数据
let defaultMap = {
  // prefix: "china",
  // adcode: "110000",
  // name: "全国",
  prefix: "province",
  adcode: "150000",
  name: "内蒙古自治区",
};
// 标点
let scatterList = ref<any>([
  {
    FarmName: "养殖场一场",
    Admin: "小王",
    Livestock: 10000,
    Address: "江苏省连云港市",
    Long: 109.494324,
    Lati: 19.598813,
  },
  {
    FarmName: "向东养殖户",
    Admin: "向东",
    Livestock: 0,
    Address: "长虹科技大厦",
    Long: 113.964139785699,
    Lati: 22.544018837551,
  },
  {
    FarmName: "牧养殖种植合作社",
    Admin: "马胜军",
    Livestock: 91,
    Address: "广东省云浮市新兴县",
    Long: 112.231496832189,
    Lati: 22.701890082606,
  },
  {
    FarmName: "苏垦牧场",
    Admin: "小刘",
    Livestock: 8080,
    Address: "江苏省连云港连云区农场",
    Long: 119.43188,
    Lati: 34.62367,
  },
]);
const changeMapData = (info: any) => {
  console.log(info);
};

mapChart 组件代码

<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 { ElMessage } from "element-plus";

import {
  ref,
  onMounted,
  reactive,
  Ref,
  onUnmounted,
  nextTick,
  watch,
} from "vue";
import axios from "axios";
import { getEchartsFontSize } from "@/utils/common";
import { mapScatter } from "@/utils/youran";
import $bus from "@/utils/bus";

const props = defineProps({
  list: {
    type: Array,
    default: [],
  },
  defaultMap: {
    type: Object,
    default: {
      prefix: "china",
      adcode: "110000",
      name: "全国",
    },
  },
});

// 坐标点
let scatterDataList = ref<any>([]);

// dom和注册的echart实例
let echartsRef: Ref = ref(null);
let myChart: any = null;
// 没有上一级了,和点击的防抖
let notAllowed = ref<Boolean>(false);
let timeFn: any = null;

// 当前激活地图
let defaultMap = ref<any>({
  prefix: "china",
  adcode: "110000",
  name: "全国",
});
if (props.defaultMap) {
  defaultMap.value = JSON.parse(JSON.stringify(props.defaultMap));
}

// 地图栈
let mapStack: any[] = [];

// 所有下级地图,下钻用
let AllMap = ref<any[]>([]);

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

onMounted(() => {
  // 如果容器大小变化
  $bus.on("onresize", () => {
    initChart();
    myChart.resize();
  });
  initChart();
});

onUnmounted(() => {
  $bus.off("onresize");
  if (timeFn) {
    clearTimeout(timeFn);
  }
});

watch(
  () => props,
  (val) => {
    nextTick(() => {
      if (props.defaultMap) {
        defaultMap.value = JSON.parse(JSON.stringify(props.defaultMap));
      }
      initChart();
    });
  },
  {
    deep: true,
  }
);

// 获取地图--和域名一样的地图(上线上上去,防跨域)
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;
}
// 创建地图实例
let initChart = () => {
  if (!myChart) {
    myChart = echarts.init(echartsRef.value);
  }
  loadMap();
};
// 注册地图
function loadMap() {
  // 当前地图
  if (mapStack.length <= 0) {
    mapStack.push(defaultMap.value);
  } else {
    defaultMap.value = mapStack[mapStack.length - 1];
  }

  let mapData = GetMapGeoJson(defaultMap.value.adcode, defaultMap.value.prefix);
  // 注册当前激活地图
  axios
    .get(mapData)
    .then((geoJson: any) => {
      AllMap.value = geoJson.data.features || [];
      echarts.registerMap(defaultMap.value.name, geoJson.data);
      setOption();
    })
    .catch((err: any) => {
      // 接口404没地图数据的情况
      ElMessage.error(`${defaultMap.value.name}的地图数据`);
      mapStack.pop();
      defaultMap.value = mapStack[mapStack.length - 1];
      if (mapStack && mapStack.length <= 1) {
        notAllowed.value = false;
      }
    });
}
// 加牧场坐标点
function addScatter() {
  scatterDataList.value = [];
  if (props.list && props.list.length > 0) {
    props.list.forEach((item: any) => {
      let name = `
      <div class="CityMapChartTooltipBgBox">
        <div class="list">
          <div class="item">
            <span>${item.FarmName || ""}:</span>
            <span>${item.Livestock || 0}头</span>
          </div>
          <div class="item">
            <span>负责人:</span>
            <span>${item.Admin || ""}</span>
          </div>
          <div class="item">
            <span>地址:</span>
            <span>${item.Address || ""}</span>
          </div>
        </div>
      </div>`;
      scatterDataList.value.push({
        name: name,
        value: [item.Long, item.Lati],
      });
    });
  }
}
// 创建地图
function setOption() {
  addScatter();
  let option = {
    tooltip: {
      show: true,
      className: "CityMapChartTooltipBg",
      formatter: (params: any) => {
        if (params.componentSubType === "scatter") return params.name;
      },
    },
    geo: {
      show: false,
      map: defaultMap.value.name || "全国",
    },
    series: [
      {
        name: "MAP",
        type: "map",
        map: defaultMap.value.name || "全国",
        selectedMode: "false", //是否允许选中多个区域
        aspectScale: 0.75,
        zoom: 1.2,
        zlevel: 1,
        label: {
          show: true,
          textStyle: {
            color: "#fff",
            // fontSize: getEchartsFontSize(0.14),
            fontFamily: "YouSheBiaoTiHei",
          },
        },
        itemStyle: {
          areaColor: new echarts.graphic.LinearGradient(0, 0, 1, 1, [
            {
              offset: 0,
              color: `#06236d`,
            },
            {
              offset: 1,
              color: `#1d46a1`,
            },
          ]),
          borderColor: "#6789d7",
          borderWidth: getEchartsFontSize(0.01),
          shadowColor: "#0156f2",
          shadowOffsetX: -getEchartsFontSize(0.03),
          shadowOffsetY: getEchartsFontSize(0.03),
          shadowBlur: getEchartsFontSize(0.02),
          emphasis: {
            show: true,
            areaColor: "#182e8f", // 鼠标悬浮地图面的颜色
            borderColor: "#fff",
            borderWidth: getEchartsFontSize(0.02),
            label: {
              show: true,
              textStyle: {
                color: "#fff",
                fontSize: getEchartsFontSize(0.16),
                fontFamily: "YouSheBiaoTiHei",
              },
            },
          },
        },
        data: [],
      },
      {
        type: "scatter",
        coordinateSystem: "geo",
        symbol: "image://" + mapScatter,
        symbolSize: [getEchartsFontSize(0.66), getEchartsFontSize(0.36)],
        itemStyle: {
          color: "#1cedd4",
          shadowBlur: getEchartsFontSize(0.1),
          shadowColor: "#333",
        },
        zlevel: 200,
        data: scatterDataList.value || [],
      },
    ],
  };
  // 地图数据的关系setOption有时会报错,暂时无解
  myChart.setOption(option);
  mapChartAddClick();
}
// 加点击事件
function mapChartAddClick() {
  // 清空之前的点击事件
  myChart.off("click");
  myChart.on("click", (params: any) => {
    if (timeFn) {
      clearTimeout(timeFn);
    }
    //由于单击事件和双击事件冲突,故单击的响应事件延迟250毫秒执行
    timeFn = setTimeout(() => {
      // 现在和点的是一个阻止
      if (params.name === mapStack[mapStack.length - 1].name) {
        return;
      }
      if (params.seriesType == "scatter") {
        // 点标点逻辑,传递标点信息
        emit("changeMapData", props.list[params.dataIndex]);
      } else {
        // 地图下钻逻辑
        if (AllMap.value && AllMap.value.length > 0) {
          let clickMap = AllMap.value.find(
            (item) => item.properties.name === params.name
          );
          if (!clickMap) {
            ElMessage.warning("无此区域地图显示");
            return;
          }
          mapStack.push({
            prefix: clickMap.properties.level,
            adcode: clickMap.properties.adcode,
            name: clickMap.properties.name,
          });
          notAllowed.value = true;
          loadMap();
        } else {
          ElMessage.warning("无下级地图数据");
        }
      }
    }, 250);
  });
  // 绑定双击事件,返回
  // myChart.on("dblclick", (params: any) => {
  //   backMap();
  // });
}
// 返回上一级
let backMap = () => {
  // 当双击事件发生时,清除单击事件,仅响应双击事件
  if (timeFn) {
    clearTimeout(timeFn);
  }
  // 删最后一个,跳上一个
  if (mapStack && mapStack.length > 1) {
    mapStack.pop();
    loadMap();
  }
  // 鼠标放上去的禁用状态
  if (mapStack && mapStack.length <= 1) {
    notAllowed.value = false;
  }
};
</script>

<style lang="less" scoped>
.cityMap {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;

  .backMap {
    position: absolute;
    top: 27px;
    left: 40px;
    border: none;
    z-index: 9;
    cursor: pointer;
    // width: 123px;
    // height: 44px;
    // background-image: url("../assets/common/top_icon_back_default.png");
    // background-size: 100% 100%;
    // padding-left: 50px;
    // padding-top: 10px;

    span {
      display: block;
      font-size: 12px;
      // margin-left: 40px;
      border-radius: 7px;
      background-color: #06bcec;
      padding: 4px 6px;
      color: #fff;
    }

    &:focus {
      outline: none;
    }

    &:hover {
      // opacity: 0.93;
      // background-image: url("../assets/common/top_icon_back_select.png");
      background-size: 100% 100%;

      span {
        color: #ffffff;
      }
    }

    &.notAllowed {
      cursor: not-allowed;
    }
  }

  .tradeIn-cattle-map {
    // height: 600px;
    width: 100%;
    height: 100%;
    // margin-top: 50px;
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/659781.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

理解多线程看这一篇就够了

一、基本概念与关系 程序 程序是含有指令和数据的文件&#xff0c;静态地存储在磁盘等存储设备上。它是软件的实体&#xff0c;但未被激活。 进程 进程是程序的一次执行过程&#xff0c;是系统运行程序的基本单位。当程序被操作系统加载并执行时&#xff0c;就成为一个进程&a…

SAP 消息号VF501科目确定期间出错

在销售开票VF02的时候&#xff0c;经常出现报错&#xff1a;“科目确定期间出错”&#xff0c;这个报错&#xff0c;目前检查步骤&#xff1a; 1、BP客户主数据&#xff0c;销售代码层数据&#xff08;销售与分销&#xff09;-开票-会计-客户科目分配组&#xff0c;要与销售订…

卷积计算过程详解(含图示和代码)

什么是卷积&#xff1f; 卷积是一种数学运算&#xff0c;通过两个函数f和g生成第三个函数&#xff0c;其本质是一种特殊的积分变换&#xff0c;表征函数f与g经过翻转和平移的重叠部分函数值乘积对重叠长度的积分。卷积在泛函分析中扮演重要角色&#xff0c;可以被看作是“滑动平…

【大数据】Hadoop 2.X和1.X升级优化对比

目录 1.前言 2.hadoop 1.X的缺点和优化方向 3.解决NameNode的局限性 3.1.Hadoop HA 3.2.Haddop federation 4.yarn 5.周边组件 1.前言 本文是作者大数据系列中的一文&#xff0c;专栏地址&#xff1a; https://blog.csdn.net/joker_zjn/category_12631789.html?spm10…

扎气球最高分-第13届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第74讲。 扎气球最高分&…

图片怎样在线改像素大小?电脑快速修改图片大小的方法

在设计图片的时候下载的图片尺寸一般会比较大&#xff0c;在网上使用经常会因为尺寸的问题导致无法正常上传&#xff0c;那么如何快速在线改图片大小呢&#xff1f;想要修改图片尺寸可以在直接选择网上的图片改大小工具的功能来快速完成修改&#xff0c;操作简单方便使用&#…

FreeRTOS学习笔记-基于stm32(7)任务状态查询与任务时间统计API函数

1、FreeRTOS任务相关API函数 函数描述uxTaskPriorityGet()查询某个任务的优先级vTaskPrioritySet()改变某个任务的任务优先级uxTaskGetSystemState()获取系统中任务状态vTaskGetInfo()获取某个任务信息xTaskGetApplicationTaskTag()获取某个任务的标签(Tag)值xTaskGetCurrentT…

0.25W 1.5KVDC~3KVDC 隔离超小型单输出 DC/DC 电源模块——TKE-W25系列

TKE-W25系列隔离超小型单输出 DC/DC 电源模块是一款超小型单输出电源模块&#xff0c;工业级环境温度&#xff0c;用于PCB安装的国际标准结构。此系列产品小巧&#xff0c;效率高&#xff0c;低输出纹波,用于需要电压转换和隔离的场合&#xff0c;封装有SIP和DIP可选。

MiniPCIe/SATA双用插槽无法识别minipcie模块怎么回事!

在计算机和嵌入式系统设计中,MiniPCIe/SATA双用插槽作为一种高度集成的解决方案,提供了极大的灵活性与扩展能力。它不仅能够支持MiniPCIe接口的无线网卡、固态硬盘控制器等模块,还能适应SATA接口的硬盘或固态存储设备,大大丰富了系统配置的可能性。尽管设计初衷良好,但在实…

Java—二分查找

介绍 二分查找&#xff08;Binary Search&#xff09;是一种在有序数组中查找特定元素的搜索算法。其基本思想是将目标值与数组中间的元素进行比较&#xff1a; 如果目标值等于中间元素&#xff0c;则查找成功。如果目标值小于中间元素&#xff0c;则在数组左半部分继续进行二…

汽车悬架分为哪几类

汽车悬架分为哪几类 1)汽车的悬架系统可根据结构分为两种:独立悬架和非独立悬架,独立悬架根据构造又可以分为CDC运动悬架(CDC电磁悬架系统)和空气悬架; 2)当前比较火热的空气悬架,是独立悬架的一种; 3)前轮主要使用麦弗逊式独立悬架 和 双叉臂悬架,后轮主要使用多…

基于 DCT 的图像滤波

需求分析 对于图像去噪这一需求&#xff0c;我们可以通过DCT&#xff08;离散余弦变换&#xff09;算法来实现。DCT是一种基于频域的变换技术&#xff0c;可以将图像从空间域转换为频域&#xff0c;然后通过滤波等处理方式进行去噪。 针对这一需求&#xff0c;我们需要进行以下…

香港优才计划申请时间要多久?各流程申请周期规划,再晚就来不及了!

香港优才计划申请时间要多久&#xff1f;各流程申请周期规划&#xff0c;再晚就来不及了&#xff01; 2024年是香港优才计划不限配额的最后一年&#xff0c;明年政策如何变化还未可知&#xff0c;但如果明年又设置限额了&#xff0c;那么今年最后的机会一定要抓住了。 在这里…

美业SaaS收银系统源码-美团/口碑核销时报错:该商品未在美团/口碑上架怎么办?

美业SaaS系统 连锁多门店美业收银系统源码 多门店管理 / 会员管理 / 预约管理 / 排班管理 / 商品管理 / 活动促销 PC管理后台、手机APP、iPad APP、微信小程序 1. 可能是门店未做映射 • 美团门店映射&#xff1a;需要在【PC运营后端】-【渠道商品】-【美团点评门店管理】&…

elementUI type=“selection“多选框选中 删除 回显 赋值问题 回显数组改变选中状态未改变

业务需求&#xff1a; 点击查询弹列表框 勾选列表选项保存 可删除可重新查询列表添加 遇到的问题&#xff1a;删除之后查询列表selection回显问题 解决&#xff1a;row-click配合:reserve-selection"true"使用 <el-tableref"refPlanTable":data"…

AI时代的服装设计师--AIGC

AI时代的服装设计师--AIGC AIGCAIGC设计能替代真正的设计师吗森马T恤设计AIGC优势、优化 本文记录于去年参加的一次森马T恤设计活动的感受。 AIGC 可以说&#xff0c;近期以来&#xff0c;随着ChatGPT的不断发展&#xff0c;从ChatGPT-3到ChatGPT-4的飞速发展&#xff0c;AIGC…

【Spring Cloud】分布式配置

目录 未来的开发场景为什么需要配置中心配置实时生效配置管理流程 开源配置中心基本介绍DisconfSpring Cloud ConfigApolloNacos Spring Cloud Config介绍配置管理工具体系 案例需求编写 Config Server1.创建配置文件2.创建项目3.添加依赖4.添加注解5.修改配置文件application.…

selenium web 网页测试自动化需要哪些技术?

引言&#xff1a; 在当今互联网时代&#xff0c;网页测试自动化成为了确保软件质量和提高效率的重要手段之一。Selenium是一种功能强大且广泛应用的工具&#xff0c;可用于实现网页测试自动化。本文将带您了解Selenium Web网页测试自动化所需的技术和步骤&#xff0c;以便您从零…

伦敦银和现货白银是一回事吗

伦敦银和现货白银不能直接完全地画上等号&#xff0c;但如果投资者所指指的是国际市场上的现货白银交易&#xff0c;那么二者应该是等同的——因为在国际贵金属投资市场上&#xff0c;现货白银的别称就是伦敦银&#xff0c;伦敦银和现货白银指的其实是同一回事。 因为早在很多个…