Skip to content
索引

地图

实现步骤

  1. 定义一个有宽高的html元素
  2. 获取相应地图的json
  3. 在echarts的registerMap方法注册地图json
  4. 获取那个有宽高的html元素,使用echarts的init方法初始化echarts
  5. 设置好echarts的option
  6. 使用init返回的echarts实例的setOption方法设置option

获取地图json

全国-省-市-区的地图json数据可以直接去阿里云官网复制

入门实例

vue3+typescript中使用

vue
<script setup lang="ts">
import { init, registerMap, EChartsOption } from "echarts"
import chinaMap from "./assets/china.json" // 2.获取相应地图的json,可去相应网站直接复制
import { ref, nextTick } from "vue"
const chart = ref<HTMLElement | null>(null)
// 5.设置好echarts的option
const option:EChartsOption = {
  series: [
    {
      type: "map",
      map: "chinamap", // 注意,这里的map值要与registerMap的第一个参数一致
    }
  ]
}

nextTick(() => {
  registerMap("chinamap", chinaMap) // 3.在echarts的registerMap方法注册地图json
  const echart = init(chart.value as HTMLElement) // 4.获取echart元素,使用echarts的init方法初始化echarts
  echart.setOption(option) // 6.使用init返回的echarts实例的setOption方法设置option
})
</script>

<template>
  <!-- 1.定义一个有宽高的html元素 -->
  <div ref="chart" id="chart"></div>
</template>

<style>
#chart {
  width: 1200px;
  height: 800px;
}
</style>
<script setup lang="ts">
import { init, registerMap, EChartsOption } from "echarts"
import chinaMap from "./assets/china.json" // 2.获取相应地图的json,可去相应网站直接复制
import { ref, nextTick } from "vue"
const chart = ref<HTMLElement | null>(null)
// 5.设置好echarts的option
const option:EChartsOption = {
  series: [
    {
      type: "map",
      map: "chinamap", // 注意,这里的map值要与registerMap的第一个参数一致
    }
  ]
}

nextTick(() => {
  registerMap("chinamap", chinaMap) // 3.在echarts的registerMap方法注册地图json
  const echart = init(chart.value as HTMLElement) // 4.获取echart元素,使用echarts的init方法初始化echarts
  echart.setOption(option) // 6.使用init返回的echarts实例的setOption方法设置option
})
</script>

<template>
  <!-- 1.定义一个有宽高的html元素 -->
  <div ref="chart" id="chart"></div>
</template>

<style>
#chart {
  width: 1200px;
  height: 800px;
}
</style>

react+typescript中使用

tsx
import { useRef, useEffect } from "react"
import styled from "styled-components"
import { Link } from "react-router-dom"
import { init, registerMap, EChartsOption } from "echarts"
import mapData from "../assets/mapData.json" // 2.获取相应地图的json,可去相应网站直接复制
// 5.设置好echarts的option
const option: EChartsOption = {
  series: [
    {
      type: "map",
      map: "china" // 注意,这里的map值要与registerMap的第一个参数一致
    }
  ]
}
function Map() {
  const chartDom = useRef(null)
  useEffect(() => {
    registerMap("china", mapData as any) // 3.在echarts的registerMap方法注册地图json
    const chart = init(chartDom.current as unknown as HTMLElement) // 4.获取echart元素,使用echarts的init方法初始化echarts
    chart.setOption(option) // 6.使用init返回的echarts实例的setOption方法设置option
  }, [])
  return (
    <>
      <StyleContainer>
        <!-- 1.定义一个有宽高的html元素 -->
        <div className="chart" ref={chartDom}></div>
      </StyleContainer>
    </>
  )
}
const StyleContainer = styled.section`
  .chart {
    width: 800px;
    height: 600px;
  }
`
export default Map
import { useRef, useEffect } from "react"
import styled from "styled-components"
import { Link } from "react-router-dom"
import { init, registerMap, EChartsOption } from "echarts"
import mapData from "../assets/mapData.json" // 2.获取相应地图的json,可去相应网站直接复制
// 5.设置好echarts的option
const option: EChartsOption = {
  series: [
    {
      type: "map",
      map: "china" // 注意,这里的map值要与registerMap的第一个参数一致
    }
  ]
}
function Map() {
  const chartDom = useRef(null)
  useEffect(() => {
    registerMap("china", mapData as any) // 3.在echarts的registerMap方法注册地图json
    const chart = init(chartDom.current as unknown as HTMLElement) // 4.获取echart元素,使用echarts的init方法初始化echarts
    chart.setOption(option) // 6.使用init返回的echarts实例的setOption方法设置option
  }, [])
  return (
    <>
      <StyleContainer>
        <!-- 1.定义一个有宽高的html元素 -->
        <div className="chart" ref={chartDom}></div>
      </StyleContainer>
    </>
  )
}
const StyleContainer = styled.section`
  .chart {
    width: 800px;
    height: 600px;
  }
`
export default Map

注意点

series中的map名要与 registerMap的第一个参数一致

json
const option = {
 ...
 series: [
    {
      type: "map",
      map: "nanjing", 
      ...
    }
  ]  
}
nextTick(() => {
  registerMap("nanjing",chinaMap as any)
  ...
})
const option = {
 ...
 series: [
    {
      type: "map",
      map: "nanjing", 
      ...
    }
  ]  
}
nextTick(() => {
  registerMap("nanjing",chinaMap as any)
  ...
})

option常用属性简介

对于常用属性有一个基本的认识

属性说明
map使用 registerMap 注册的地图名称
label设置文字相关
itemStyle设置背景颜色,边框颜色等
emphasis设置悬浮高亮相关
select设置选中相关
roam设置是否放大缩小放大
scaleLimit设置放大缩小的限制
selectedMode设置选中的模式,单选还是多选
left设置地图组件在容器中的左位置
right设置地图组件在容器中的右位置

获取坐标

可以使用百度地图的拾取坐标系统,左上角可以搜索,点击地图后可以在右上角复制坐标

更改地图文字位置

手动修改地图json文件来改变地图文字位置

  • properties的cp属性控制地图上文字的显示位置
  • 一般来说默认的地图json文件是没有这个属性的,需要手动添加
  • 该属性值可以先设置成properties的center值,然后再微调
json
"features": [
    {
      "type": "Feature",
      "properties": {
        "adcode": 320302,
        "name": "鼓楼区",
        "cp": [117.29, 34.31],
        "center": [117.192941, 34.269397],
        "centroid": [117.140874, 34.308857],
        "childrenNum": 0,
        "level": "district",
        "parent": { "adcode": 320300 },
        "subFeatureIndex": 0,
        "acroutes": [100000, 320000, 320300]
      },
    ...
]
"features": [
    {
      "type": "Feature",
      "properties": {
        "adcode": 320302,
        "name": "鼓楼区",
        "cp": [117.29, 34.31],
        "center": [117.192941, 34.269397],
        "centroid": [117.140874, 34.308857],
        "childrenNum": 0,
        "level": "district",
        "parent": { "adcode": 320300 },
        "subFeatureIndex": 0,
        "acroutes": [100000, 320000, 320300]
      },
    ...
]

设置散点图

series中加入effectScatter组件

js
series: [
  ...
  {
    type: "effectScatter",
    coordinateSystem: "geo",
    symbolSize: 20, // 散点图标大小
    // 散点图标颜色
    itemStyle: {
       color: "#ffffff"
    },
    // 散点图标坐标,需要与地图json文件中的properties的name对应
    data: [
        { name: "鼓楼区", value: [117.2, 34.31] },
        { name: "云龙区", value: [117.29, 34.2] },
        { name: "贾汪区", value: [117.450212, 34.441642] },
        { name: "泉山区", value: [117.16, 34.25] },
        { name: "铜山区", value: [117.52, 34.19288] },
        { name: "丰县", value: [116.6, 34.75] },
        { name: "睢宁县", value: [117.9, 34.02] },
        { name: "沛县", value: [116.9, 34.77] },
        { name: "新沂市", value: [118.345828, 34.32] },
        { name: "邳州市", value: [117.89, 34.39] }
    ]
  }
]
series: [
  ...
  {
    type: "effectScatter",
    coordinateSystem: "geo",
    symbolSize: 20, // 散点图标大小
    // 散点图标颜色
    itemStyle: {
       color: "#ffffff"
    },
    // 散点图标坐标,需要与地图json文件中的properties的name对应
    data: [
        { name: "鼓楼区", value: [117.2, 34.31] },
        { name: "云龙区", value: [117.29, 34.2] },
        { name: "贾汪区", value: [117.450212, 34.441642] },
        { name: "泉山区", value: [117.16, 34.25] },
        { name: "铜山区", value: [117.52, 34.19288] },
        { name: "丰县", value: [116.6, 34.75] },
        { name: "睢宁县", value: [117.9, 34.02] },
        { name: "沛县", value: [116.9, 34.77] },
        { name: "新沂市", value: [118.345828, 34.32] },
        { name: "邳州市", value: [117.89, 34.39] }
    ]
  }
]

geo属性地图下方第二个地图

js
option = {
  geo: {
    map: "taizhouMap",
    itemStyle: {
      areaColor: "#43C1B5",
      shadowColor: "#F0FAF5",
      shadowOffsetX: 0,
      shadowOffsetY: 20,
      shadowBlur: 30
    },
    silent: true,
    layoutSize: 360,
    layoutCenter: ["50%", "50.5%"]
  }
  ...
} 
option = {
  geo: {
    map: "taizhouMap",
    itemStyle: {
      areaColor: "#43C1B5",
      shadowColor: "#F0FAF5",
      shadowOffsetX: 0,
      shadowOffsetY: 20,
      shadowBlur: 30
    },
    silent: true,
    layoutSize: 360,
    layoutCenter: ["50%", "50.5%"]
  }
  ...
} 

拖拽缩放

js
 roam: false
 roam: false

实战案例

vue
<script setup lang="ts">
import { init, registerMap } from "echarts"
import chinaMap from "./assets/china.json"

const chart = ref<HTMLElement | null>(null)
var option = {
  tooltip: {
    //鼠标hover是提示信息
    show: true, //不显示提示标签
    formatter: "{b}", //提示标签格式
    backgroundColor: "#ff7f50", //提示标签背景颜色
    textStyle: {
      color: "#fff",
      fontSize: "20"
    } //提示标签字体颜色
  },
  visualMap: {
    //视觉映射组件()
    type: "continuous", //连续型
    min: 0,
    max: 150,
    left: 990,
    top: 800,
    text: ["150", "0"], // 文本,默认为数值文本
    textGap: 10, //文本与图形之间的距离
    itemWidth: 40, //图形的宽
    itemHeight: 200, //突刺是哪个的高
    calculable: true, //是否显示拖动手柄
    textStyle: {
      color: "#fff",
      fontSize: 25
    }, //省份标签字体颜色
    //align:"left",
    //inverse: true, //反向
    inRange: {
      //地图颜色变化
      color: ["#3246FB", "#24DD57", "#FDD52C"]
    }
    // outOfRange:{
    // 	symbolSize: [100, 100]
    // }
  },
  series: [
    {
      type: "map",
      color: "red",
      mapType: "china",
      roam: "false", //是否开启缩放平移
      label: {
        //标签字体样式
        position: "inside",
        normal: {
          //正常情况下显示效果
          show: true, //显示省份标签
          textStyle: {
            color: "#fff",
            fontSize: 20
          } //省份标签字体颜色
        },
        emphasis: {
          //对应的鼠标悬浮效果
          show: true,
          textStyle: {
            color: "#800080"
          }
        }
      },
      itemStyle: {
        normal: {
          borderWidth: 2, //区域边框宽度
          borderColor: "#fff", //区域边框颜色
          //areaColor: "#ffefd5", //区域颜色
          fontSize: "30"
        },
        emphasis: {
          borderWidth: 2,
          borderColor: "#3246FB"
          //areaColor: "red",
        }
      },
      data: [
        {
          name: "北京",
          value: 2500
        },
        {
          name: "天津",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "上海",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "重庆",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "河北",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "河南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "云南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "辽宁",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "黑龙江",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "湖南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "安徽",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "山东",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "新疆",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "江苏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "浙江",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "江西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "湖北",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "广西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "甘肃",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "山西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "内蒙古",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "陕西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "吉林",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "福建",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "贵州",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "广东",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "青海",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "西藏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "四川",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "宁夏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "海南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "台湾",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "香港",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "澳门",
          value: Math.round(Math.random() * 100)
        }
      ]
    }
  ]
}
nextTick(() => {
  registerMap(
    "china",
    { geoJSON: chinaMap  as GeoJSONSourceInput},
    {
      妈祖: {
        // 左上角经度
        left: 120.178644,
        // 左上角纬度
        top: 24.84237,
        // 经度横跨的范围
        width: 0.21
      },
      金门: {
        left: 119.847492,
        top: 24.270233,
        width: 0.21
      }
    }
  )
  const echart = init(chart.value as HTMLElement)
  echart.setOption(option)
})
</script>

<template>
  <div ref="chart" id="chart"></div>
</template>

<style>
#chart {
  width: 1200px;
  height: 800px;
}
</style>
<script setup lang="ts">
import { init, registerMap } from "echarts"
import chinaMap from "./assets/china.json"

const chart = ref<HTMLElement | null>(null)
var option = {
  tooltip: {
    //鼠标hover是提示信息
    show: true, //不显示提示标签
    formatter: "{b}", //提示标签格式
    backgroundColor: "#ff7f50", //提示标签背景颜色
    textStyle: {
      color: "#fff",
      fontSize: "20"
    } //提示标签字体颜色
  },
  visualMap: {
    //视觉映射组件()
    type: "continuous", //连续型
    min: 0,
    max: 150,
    left: 990,
    top: 800,
    text: ["150", "0"], // 文本,默认为数值文本
    textGap: 10, //文本与图形之间的距离
    itemWidth: 40, //图形的宽
    itemHeight: 200, //突刺是哪个的高
    calculable: true, //是否显示拖动手柄
    textStyle: {
      color: "#fff",
      fontSize: 25
    }, //省份标签字体颜色
    //align:"left",
    //inverse: true, //反向
    inRange: {
      //地图颜色变化
      color: ["#3246FB", "#24DD57", "#FDD52C"]
    }
    // outOfRange:{
    // 	symbolSize: [100, 100]
    // }
  },
  series: [
    {
      type: "map",
      color: "red",
      mapType: "china",
      roam: "false", //是否开启缩放平移
      label: {
        //标签字体样式
        position: "inside",
        normal: {
          //正常情况下显示效果
          show: true, //显示省份标签
          textStyle: {
            color: "#fff",
            fontSize: 20
          } //省份标签字体颜色
        },
        emphasis: {
          //对应的鼠标悬浮效果
          show: true,
          textStyle: {
            color: "#800080"
          }
        }
      },
      itemStyle: {
        normal: {
          borderWidth: 2, //区域边框宽度
          borderColor: "#fff", //区域边框颜色
          //areaColor: "#ffefd5", //区域颜色
          fontSize: "30"
        },
        emphasis: {
          borderWidth: 2,
          borderColor: "#3246FB"
          //areaColor: "red",
        }
      },
      data: [
        {
          name: "北京",
          value: 2500
        },
        {
          name: "天津",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "上海",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "重庆",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "河北",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "河南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "云南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "辽宁",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "黑龙江",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "湖南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "安徽",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "山东",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "新疆",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "江苏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "浙江",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "江西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "湖北",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "广西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "甘肃",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "山西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "内蒙古",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "陕西",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "吉林",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "福建",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "贵州",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "广东",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "青海",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "西藏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "四川",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "宁夏",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "海南",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "台湾",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "香港",
          value: Math.round(Math.random() * 100)
        },
        {
          name: "澳门",
          value: Math.round(Math.random() * 100)
        }
      ]
    }
  ]
}
nextTick(() => {
  registerMap(
    "china",
    { geoJSON: chinaMap  as GeoJSONSourceInput},
    {
      妈祖: {
        // 左上角经度
        left: 120.178644,
        // 左上角纬度
        top: 24.84237,
        // 经度横跨的范围
        width: 0.21
      },
      金门: {
        left: 119.847492,
        top: 24.270233,
        width: 0.21
      }
    }
  )
  const echart = init(chart.value as HTMLElement)
  echart.setOption(option)
})
</script>

<template>
  <div ref="chart" id="chart"></div>
</template>

<style>
#chart {
  width: 1200px;
  height: 800px;
}
</style>

Released under the MIT License.