前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >echarts画中国地图及省份切换

echarts画中国地图及省份切换

作者头像
windliang
发布2022-09-23 13:19:16
3.9K0
发布2022-09-23 13:19:16
举报
文章被收录于专栏:windliang的博客windliang的博客

最近用 ehcarts 写了一个有关中国地图的需求,这篇文章来总结下基本的原理和用法。

Geojson

首先了解一下 GeoJSON ,看下 维基百科 的定义:

★**GeoJSON **是一种基于 JSON 的地理空间数据交换格式,它定义了几种类型 JSON 对象以及它们组合在一起的方法,以表示有关地理要素、属性和它们的空间范围的数据。 2015年,互联网工程任务组(IETF)与原始规范作者组建了一个 GeoJSON 工作组,一起规范 GeoJSON 标准。在2016年8月,推出了最新的GeoJSON数据格式标准规范(RFC 7946)。 GeoJSON 使用唯一地理坐标参考系统 WGS1984 和十进制度单位,一个 GeoJSON 对象可以是 Geometry, Feature 或者FeatureCollection. 其几何对象包括有点(表示地理位置)、线(表示街道、公路、边界)、多边形(表示国家、省、领土),以及由以上类型组合成的复合几何图形。 ”

简单说就是通过坐标系来描述点、线、面,看几个例子就明白它们是什么了。

单个点:"type": "Point"

image-20220510095405517

多个点,"type": "MultiPoint"

image-20220510095158715

多个线:"type": "MultiLineString"

image-20220510095241321

多个面:"type": "MultiPolygon"

image-20220510095257874

地图 Geojson

中国地图和省份的 geoJson 可以在 echarts-map 或者阿里的 数据可视化中心 进行下载。

image-20220510101045037

echarts 4.x 的版本自带了一些 Geojson 的数据,在 node_modules/echarts/map/json 目录,但可能考虑到一些省区数据不能及时更新,echarts 5 版本就没有自带数据了。

让我们看一下全国地图中山西省的 geoJson 长什么样子。

代码语言:javascript
复制
{
    "type": "FeatureCollection",
    "features": [
       ...
        {
          ...
        }
        {
            "type": "Feature",
            "properties": {
                "adcode": 140000,
                "name": "山西省",
                "center": [112.549248, 37.857014],
                "centroid": [112.304436, 37.618179],
                "childrenNum": 11,
                "level": "province",
                "parent": { "adcode": 100000 },
                "subFeatureIndex": 3,
                "acroutes": [100000]
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [110.379257, 34.600612],
                            [110.424837, 34.588295],
                            [110.488279, 34.610956],
                            [110.533242, 34.583368],
                            [110.610851, 34.607508],
                            [110.710017, 34.605045],
                            [110.749437, 34.65232],
                            [110.791937, 34.649858],
                            [110.824582, 34.615881],
                            [110.883712, 34.64395],
                            [110.903422, 34.669056],
                            [110.920052, 34.730068],
                            ...
                        ]
                    ]
                ]
            }
        },
    {
          ...
        }
        ...
    ]
}

整体是一个 "type": "FeatureCollection" ,然后有一个 features 数组保存所有省份,每一个都是 "type": "Feature" ,代表单个省份。包含 properties 属性和 geometry 属性。geometry 属性就是所有的坐标信息。

根据坐标信息,计算最大值和最小值的差值,按比例映射到 canvas 上的坐标,然后就可以画出来了,细节的话可以参考 b 站 的这个视频。

echarts 画地图

安装 vueecharts ,先来个简单的正方形。

代码语言:javascript
复制
{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "name": "正方形"
            },
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [100.0, 0.0],
                            [101.0, 0.0],
                            [101.0, 1.0],
                            [100.0, 1.0],
                            [100.0, 0.0]
                        ]
                    ]
                ]
            }
        }
    ]
}

然后用 echarts 做引入我们的 json 文件、通过 echarts.registerMap 注册 json 文件、设置 opitonsseries 属性。

代码语言:javascript
复制
<template>
    <div id="main" style="width: 600px; height: 600px"></div>
</template>

<script>
import * as echarts from "echarts";
import test from '../data/test'
export default {
    name: "HelloWorld",
    props: {
    },
    mounted() {
        var myChart = echarts.init(document.getElementById("main"));
        echarts.registerMap('mapName', test); // 注册地图
        let option = {
            series: [
                {
                    type: "map",
                    map: 'mapName', // 引入地图数据
                },
            ],
        };
        myChart.setOption(option);
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

image-20220511080857038

然后我们只需要到阿里的 数据可视化中心 把中国地图的 Geojson 数据下载下来,替换上边的 test.json 即可。

值得注意的是,如果我们设置注册的名字为 chinaecharts 会自动给我们加上南沙群岛的放大图:

代码语言:javascript
复制
import * as echarts from "echarts";
import china from '../data/china'
export default {
    name: "HelloWorld",
    props: {
    },
    mounted() {
        var myChart = echarts.init(document.getElementById("main"));
        echarts.registerMap('china', china);
        let option = {
            series: [
                {
                    type: "map",
                    map: 'china', // 引入地图数据
                },
            ],
        };
        myChart.setOption(option);
    },
};

可能会用到的 options 属性

地图画出来以后,接下来可以照着 echarts 官网 变身为「echarts 配置工程师」了,记得注意一下自己当前的 eharts 版本。

设置悬浮上的数据

我们在 series 中引入 data ,加一点随机数据,其中 name 值是 json 数据中的 properties 对应的 name ,名字一定要一致。

代码语言:javascript
复制
const option = {
 ...
 series: [
   {
     type: "map",
     map: "china", // 引入地图数据
     name: "省份随机数据",
     data: [
       {
         name: "北京市",
         value: 21,
       },
       {
         name: "天津市",
         value: 12,
       },
       {
         name: "上海市",
         value: 99,
       },
       {
         name: "重庆市",
         value: 98,
       },
       {
         name: "河北省",
         value: 99,
       },
       {
         name: "河南省",
         value: 29,
       },
       {
         name: "云南省",
         value: 79,
       },
       {
         name: "辽宁省",
         value: 38,
       },
       {
         name: "黑龙江省",
         value: 4,
       },
       {
         name: "湖南省",
         value: 32,
       },
       {
         name: "安徽省",
         value: 84,
       },
       {
         name: "山东省",
         value: 72,
       },
       {
         name: "新疆维吾尔自治区",
         value: 99,
       },
       {
         name: "江苏省",
         value: 70,
       },
       {
         name: "浙江省",
         value: 85,
       },
       {
         name: "江西省",
         value: 11,
       },
       {
         name: "湖北省",
         value: 62,
       },
       {
         name: "广西壮族自治区",
         value: 13,
       },
       {
         name: "甘肃省",
         value: 74,
       },
       {
         name: "山西省",
         value: 78,
       },
       {
         name: "内蒙古自治区",
         value: 74,
       },
       {
         name: "陕西省",
         value: 40,
       },
       {
         name: "吉林省",
         value: 9,
       },
       {
         name: "福建省",
         value: 90,
       },
       {
         name: "贵州省",
         value: 57,
       },
       {
         name: "广东省",
         value: 6,
       },
       {
         name: "青海省",
         value: 52,
       },
       {
         name: "西藏自治区",
         value: 10,
       },
       {
         name: "四川省",
         value: 98,
       },
       {
         name: "宁夏回族自治区",
         value: 11,
       },
       {
         name: "海南省",
         value: 25,
       },
       {
         name: "台湾省",
         value: 86,
       },
       {
         name: "香港特别行政区",
         value: 8,
       },
       {
         name: "澳门特别行政区",
         value: 50,
       },
     ],
   },
 ],
 ...
}

再补上 tooltip 选项。

代码语言:javascript
复制
const option = {
  ...
  tooltip: {
    trigger: "item",
  },
  ...
}

视觉映射

我们可以通过 visualMap 选项,将数据分组。

代码语言:javascript
复制
const option = {
  ...
  visualMap: {
    left: "right",
    min: 0,
    max: 100,
    inRange: {
      color: [
        "#313695",
        "#4575b4",
        "#74add1",
        "#abd9e9",
        "#e0f3f8",
        "#ffffbf",
        "#fee090",
        "#fdae61",
        "#f46d43",
        "#d73027",
        "#a50026",
      ],
    },
    text: ["High", "Low"],
    calculable: true,
  },
  ...
}

设置后之后,我们可以滑动右下角的范围来选取不同的省份。

除了滑块的映射,还支持分区间的,类似下边这种。

image-20220512084908512

其他选项

其他选项这里就不介绍了,可以参考 官网 和 社区 的样例,然后结合自己的需求进行配置即可。

贴几张社区上炫酷的地图:

image-20220512085159589

省份切换

下边再实现一下点击省份切换到对应的省份地图的功能。

知道了上边的东西,思路其实很简单了,我们只需要把所有省份的 Geojson 数据全部下载下来,然后监听 echarts 的点击事件去显示省份即可。

为了逻辑之间的解耦,我们可以再新建一个组件,专门展示省份的数据。

代码语言:javascript
复制
<template>
  <div>
  <div id="province" style="width: 600px; height: 600px"></div>
</div>
</template>

<script>
    import * as echarts from "echarts";

export default {
  name: "Province",
  props: {
    fileName: String,
  },
  data() {
    return {
      option: {
        series: [
          {
            name: "省份数据",
            type: "map",
            map: "province",
            data: [],
          },
        ],
      },
    };
  },
  mounted() {
    this.initData();
  },
  methods: {
    initData() {
      try {
        const provinceJSON = require("../data/province/" +
                                     this.fileName);
        const myChart = echarts.init(
          document.getElementById("province")
        );
        echarts.registerMap("province", provinceJSON);
        myChart.setOption(this.option);
      } catch (e) {
        alert(`暂无${this.fileName}数据`);
        this.$emit("toMap");
      }
    },
  },
};
</script>

<style scoped rel="stylesheet/scss" lang="scss"></style>

我们把省份数据都放到 "../data/province" 目录中,这里简单演示,只下载了两个省份的地图:

image-20220512091724599

通过外部传进来文件的 fileName 注册地图。这里直接通过 require("../data/province" + this.fileName) 来动态引入 Geojson,一定要加上 "../data/province" 前缀来限制文件的位置,关于 webpack 的动态引入的更多细节可以参考 Webpack 打包 commonjs 和 esmodule 动态引入模块的产物对比。

我们增加一个 ProvinceMap 组件来调度两个组件的显示隐藏。

代码语言:javascript
复制
<template>
    <div>
        <Province
            v-if="showProvince"
            :fileName="fileName"
            @toMap="toMap"
        ></Province>

        <Map v-else @toProvince="toProvince"></Map>
    </div>
</template>

<script>
import Province from "./Province.vue";
import Map from "./Map.vue";

export default {
    name: "HelloWorld",
    components: {
        Province,
        Map,
    },
    data() {
        return {
            showProvince: false,
            fileName: null,
        };
    },
    methods: {
       // 显示省份数据
        toProvince({ fileName } = {}) {
            this.fileName = fileName;
            this.showProvince = true;
        },
      // 显示全国地图
        toMap() {
            this.showProvince = false;
        },
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>

Map 组件中监听省份的 click ,传递给 ProvinceMap 组件。

代码语言:javascript
复制
initData() {
  var myChart = echarts.init(document.getElementById("main"));
  echarts.registerMap("china", china);
  const option =  ....;
  myChart.setOption(option);
  myChart.on("click", (params) =>
             this.$emit("toProvince", { fileName: params.name })
            );
},

Province 组件中监听 click,传递给 ProvinceMap 组件。

代码语言:javascript
复制
initData() {
  try {
    const provinceJSON = require("../data/province/" +
                                 this.fileName);
    const myChart = echarts.init(
      document.getElementById("province")
    );
    echarts.registerMap("province", provinceJSON);
    myChart.setOption(this.option);
    myChart.on("click", () => this.$emit("toMap"));
  } catch (e) {
    alert(`暂无${this.fileName}数据`);
    this.$emit("toMap");
  }
},

最后看一下实现的效果:

Kapture 2022-05-12 at 10.06.29

通过 GeoJSONecharts ,知道大致的原理,然后其他配置项参考 官网 和 社区 的例子比对上 配置项 慢慢配置即可,文章的整体代码放到了 github,需要的同学可以参考。

ECharts 最初由百度团队开源,并于 2018 年初捐赠给Apache 基金会,2021126 日晚,Apache 基金会官方宣布 ECharts 项目正式毕业,成为 Apache 顶级项目。

平时开发 Echarts ,我们就可以从「切图仔」变成「echarts 配置工程师了」,手动狗头。

文章涉及到的一些外链:

echarts-map: https://github.com/echarts-maps

阿里云 Geojson: https://datav.aliyun.com/portal/school/atlas/area_selector

eharts 官方示例:https://echarts.apache.org/examples/zh/index.html#chart-type-map

echarts 社区示例:https://www.makeapie.cn/echarts_1.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 windliang 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Geojson
  • 地图 Geojson
  • echarts 画地图
  • 可能会用到的 options 属性
    • 设置悬浮上的数据
      • 视觉映射
        • 其他选项
        • 省份切换
        相关产品与服务
        图数据库 KonisGraph
        图数据库 KonisGraph(TencentDB for KonisGraph)是一种云端图数据库服务,基于腾讯在海量图数据上的实践经验,提供一站式海量图数据存储、管理、实时查询、计算、可视化分析能力;KonisGraph 支持属性图模型和 TinkerPop Gremlin 查询语言,能够帮助用户快速完成对图数据的建模、查询和可视化分析。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档