一文教会你从零开始画echarts地图

目录
  • echarts地图制作
  • 基础配置
  • 数据渲染
  • 嵌入文字
  • 地图下钻
  • 结合水印制作级联效果
  • visualMap
  • 总结

echarts地图制作

离线地图下载地址https://datav.aliyun.com/tools/atlas/index.html

echarts文档地址https://echarts.apache.org/zh/option.html

基于VUE编写,其他框架请自行转换,大同小异

基础配置

先让地图内容出来,npm安装步骤省略,请参考官方文档,创建的div必须设置宽度和高度,关于图表的宽高自适应,参考我的另一篇文章

<template>
  <div class="content">
    <div ref="charts" style="width: 1000px; height: 800px"></div>
  </div>
</template>

<script>
import * as echarts from "echarts";
import zhongguo from "@/assets/mapJson/data-city.json"
export default {
  created () {
    this.$nextTick(() => {
      this.initCharts();
    })
  },
  methods: {
    initCharts() {
      const charts = echarts.init(this.$refs["charts"]);
      const option = {
        // 背景颜色
        backgroundColor: "#404a59",
        // 提示浮窗样式
        tooltip: {
          show: true,
          trigger: "item",
          alwaysShowContent: false,
          backgroundColor: "#0C121C",
          borderColor: "rgba(0, 0, 0, 0.16);",
          hideDelay: 100,
          triggerOn: "mousemove",
          enterable: true,
          textStyle: {
            color: "#DADADA",
            fontSize: "12",
            width: 20,
            height: 30,
            overflow: "break",
          },
          showDelay: 100
        },
        // 地图配置
        geo: {
          map: "china",
          label: {
            // 通常状态下的样式
            normal: {
              show: true,
              textStyle: {
                color: "#fff",
              },
            },
            // 鼠标放上去的样式
            emphasis: {
              textStyle: {
                color: "#fff",
              },
            },
          },
          // 地图区域的样式设置
          itemStyle: {
            normal: {
              borderColor: "rgba(147, 235, 248, 1)",
              borderWidth: 1,
              areaColor: {
                type: "radial",
                x: 0.5,
                y: 0.5,
                r: 0.8,
                colorStops: [
                  {
                    offset: 0,
                    color: "rgba(147, 235, 248, 0)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(147, 235, 248, .2)", // 100% 处的颜色
                  },
                ],
                globalCoord: false, // 缺省为 false
              },
              shadowColor: "rgba(128, 217, 248, 1)",
              shadowOffsetX: -2,
              shadowOffsetY: 2,
              shadowBlur: 10,
            },
            // 鼠标放上去高亮的样式
            emphasis: {
              areaColor: "#389BB7",
              borderWidth: 0,
            },
          },
        },
      };
      // 地图注册,第一个参数的名字必须和option.geo.map一致
      echarts.registerMap("china",zhongguo)
      charts.setOption(option);
    },
  },
};
</script>

这是最基础的配置,外加了一些我自己写的样式,使地图美观一些,如果你完全的复制,并且china.json文件也引入了,那么你会看到如下的内容

这其中比较有意思的是,如果你注册地图时,还有option.geo.map的名字用的是china,南海诸岛会如上图以缩略图展示,但是以此之外来命名地图,则不会展示缩略图。

再次声明,如果二者名字不一致,将会导致异常,致使地图无法显示

数据渲染

实际开发中,往往需要将后台的数据渲染到地图里,我们在option里添加series属性,以下是我的两个示例,仅做参考:

series: [
    {
        type: "scatter",
        coordinateSystem: "geo",
        symbol: "pin",
        legendHoverLink: true,
        symbolSize: [60, 60],
        // 这里渲染标志里的内容以及样式
        label: {
            show: true,
            formatter(value) {
                return value.data.value[2];
            },
            color: "#fff",
        },
        // 标志的样式
        itemStyle: {
            normal: {
                color: "rgba(255,0,0,.7)",
                shadowBlur: 2,
                shadowColor: "D8BC37",
            },
        },
        // 数据格式,其中name,value是必要的,value的前两个值是数据点的经纬度,其他的数据格式可以自定义
        // 至于如何展示,完全是靠上面的formatter来自己定义的
        data: [
            { name: "西藏", value: [91.23, 29.5, 2333] },
            { name: "黑龙江", value: [128.03, 47.01, 1007] },
        ],
        showEffectOn: "render",
        rippleEffect: {
            brushType: "stroke",
        },
        hoverAnimation: true,
        zlevel: 1,
    },
    // {
    //   type: "effectScatter",
    //   coordinateSystem: "geo",
    //   effectType: "ripple",
    //   showEffectOn: "render",
    //   rippleEffect: {
    //     period: 10,
    //     scale: 10,
    //     brushType: "fill",
    //   },

    //   hoverAnimation: true,
    //   itemStyle: {
    //     normal: {
    //       color: "rgba(255, 235, 59, .7)",
    //       shadowBlur: 10,
    //       shadowColor: "#333",
    //     },
    //   },
    //   zlevel: 1,
    //   data: [
    //     { name: "西藏", value: [91.23, 29.5, 2333] },
    //     { name: "黑龙江", value: [128.03, 47.01, 1007] },
    //   ],
    // },
],

两种渲染方式如下:

使用备注的部分时,需要在option.tooltip里添加formatter属性,我写的如下:

const option = {
    // ...
    tooltip: {
    // ...
        formatter(params) {
            return `地区:${params.name}</br>数值:${params.value[2]}`;
        }
    }
}

更多的方式还要自己多试验,这是个费时且需要耐心的活,你甚至可以将柱状图放上去。有更花里胡哨的效果,也请分享给我。

嵌入文字

使用option.graphic可以实现简单的水印效果

const option = {
    // ...
    graphic:{
        // 水印类型
        type: 'text',
        // 相对于容器的位置
        left:'10%',
        top: '10%',
        // 样式设置
        style: {
            // 文本内容
            text: "create by cRack_cLick",
            // 字体粗细、大小、字体
            font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',
            // 字体颜色
            fill: "#fff"
        }
    }
}

效果如下:

利用graphic的type=“group”,还可以组合出一些有意思的效果(抄官方文档的效果):

        graphic: {
          type: "group",
          rotation: Math.PI / 4,
          bounding: "raw",
          left: 110,
          top: 110,
          z: 100,
          children: [
            {
              type: "rect",
              left: "center",
              top: "center",
              z: 100,
              shape: {
                width: 400,
                height: 50,
              },
              style: {
                fill: "rgba(0,0,0,0.3)",
              },
            },
            {
              type: "text",
              left: "center",
              top: "center",
              z: 100,
              style: {
                fill: "#ddd",
                text: "create by cRack_cLick",
                font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',
              },
            },
          ],
        },

地图下钻

往往还有一种需求,在我们点击一个省的时候,需要切换到这个省的详细地图,甚至还可以下钻到市、县等等。

为了试下点击下钻,我们需要先了解echarts中的点击事件,文档参考

以目前的功能来说,我们暂时不需要加入其它的业务逻辑以及省级的数据渲染,仅仅只做地图的切换,所以点击事件里我们需要实现获取点击的省份名称,然后根据省份名称,来选择地图的JSON文件,最后重新渲染echarts图表,下面是我的简单示例:

// 新增加北京的地图JSON文件
import beijing from "@/assets/mapJson/data-beijing.json";
// ...

initCharts(){
    const charts = echarts.init(this.$refs["charts"]);
// ...
// 注意这里是echarts的实例对象,而不是echarts组件本身。
    charts.on('click', ({name}) => {
        if (name === "北京") {
            // 修改option的配置,可以继续自定义
            option.geo.zoom = 0.8
            // 就像上面提到的,这里必须要和注册地图时的名字一致
            option.geo.map = "beijing"
            // 注册地图
            echarts.registerMap("beijing", beijing)
            // 重新渲染
            charts.setOption(option, true)
        }
    })
}

需要注意的是,在重新setOption的时候,我们加入了第二个参数,按照官方文档的说法:

参数:

调用方式:

chart.setOption(option, notMerge, lazyUpdate);

或者

chart.setOption(option, {
    notMerge: ...,
    lazyUpdate: ...,
    silent: ...
});
  • option

图表的配置项和数据。

  • notMerge

可选,是否不跟之前设置的 option 进行合并,默认为 false,即合并。

  • lazyUpdate

可选,在设置完 option 后是否不立即更新图表,默认为 false,即立即更新。

  • silent

可选,阻止调用 setOption 时抛出事件,默认为 false,即抛出事件。

第二个从参数设置为true来让图表重新渲染,而不合并配置,当然,这一点具体需要看你显示开发的需求,我在这里仅是为了演示。绝不是偷懒

另外在echarts v3.x的版本里,切换地图默认是有过渡动画的,而v4.x和v5.x的版本里则没有过渡动画,如果知道怎么加上的,可以私信我。

上面虽然可以实现地图切换,但很显然开发中这么写要被打死。下钻三十多个地图要写三十多个if,显然是一种不理智的开发方式。一种方式我们可以通过axios或者ajax异步请求,但是这样需要你在生产环境和运维协商好,否则会导致请求不到JSON文件。

下面是我在前端写的一个简单的工具方法,仅供参考:

import zhongguo from "@/assets/mapJson/data-city.json";
import neimenggu from "@/assets/mapJson/data-neimenggu.json";
import beijing from "@/assets/mapJson/data-beijing.json";
// ...

const mapDict = {
  "北京": "beijing",
  "内蒙古": "neimenggu",
  // ...
}

const mapData = {
  beijing,
  neimenggu,
  // ...
}

export function getMap(mapName) {
  const cityName = mapDict[mapName]
  if(cityName){
    return [cityName, mapData[cityName]]
  }
  return ['china', zhongguo]
}

需要建立两个字典,一个是汉字和拼音的对照映射,一个是拼音和JSON文件的映射,这个可灵活配置,并非唯一。

优化一下上面的的代码:

// 删除地图json文件的引用,修改为上面的工具方法
import { getMap } from "./maputil";
methods: {
    initCharts() {
        const charts = echarts.init(this.$refs["charts"]);
        const option = {
            // ...
        };
        // 不传name默认会返回中国地图
        const [mapName, mapJson] = getMap();
        option.geo.map = mapName;
        // 地图注册,第一个参数的名字必须和option.geo.map一致
        echarts.registerMap(mapName, mapJson);

        charts.setOption(option);

        charts.on("click", ({ name }) => {
            // 这里和上面一样,其实还可以再优化一下。为了方便阅读,这里不再封装。
            const [mapName, mapJson] = getMap(name);
            option.geo.zoom = 0.8;
            option.geo.map = mapName;
            echarts.registerMap(mapName, mapJson);
            charts.setOption(option, true);
        });
    }
}

效果如下:

结合水印制作级联效果

现在的地图可以下钻了,但是似乎操作起来还有些别扭。

我们现在想要的效果是:我们需要每下钻一层,水印部分就会加上当前地区的名称。点击水印地区的名称,就会跳转到当前地区的地图,我们要来改造一下echarts示例的click事件。

首先option.graphic的默认值修改为中国地图,这里为了方便阅读,仅使用text格式演示:

// ...
graphic: [
    {
        type: "text",
        left: "10%",
        top: "10%",
        style: {
            text: "中国",
            font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',
            fill: "#fff",
        },
    },
],

以数组的形势编写后,思路就明显了,只要在click事件的时候,将下钻地图的信息push进来,并且为了防止重合,稍微移动一下定位即可,我的示例如下:

charts.on("click", ({ name }) => {
    const [mapName, mapJson] = getMap(name);
    option.geo.zoom = 0.8;
    option.geo.map = mapName;
    // 为了重新定位,这里使用了length
    const idx = option.graphic.length + 1;
    option.graphic.push({
        type: "text",
        left: `${idx * 10}%`,
        top: "10%",
        style: {
            text: name,
            font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',
            fill: "#fff",
        },
    });
    echarts.registerMap(mapName, mapJson);
    charts.setOption(option, true);
});

点击后效果如下:

现在还有问题,就是点击地区名字没有响应,所以我们还要为option.graphic子元素加上click事件

这个click事件功能也类似,获取地图名称,获取地图数据,重新渲染。但是这个click事件需要注意,比如我点击了北京,那么在数组里是需要将密云区的元素删除掉的,同理,点击中国,则后面的元素都要删除。在这里我就不把相同的部分抽离出来了:

// 防止graph里频繁添加click事件,在添加click事件之前先全部清空掉。
charts.off()
charts.on("click", ({name}) => {
    // 如果option.graphic里已经有了城市名称,则不进行任何操作,防止频繁点击
    const index = option.graphic.findIndex(i => i.style.text === name);
    if (!name || index !== -1) return
    const [mapName, mapJson] = getMap(name);
    option.geo.zoom = 0.8;
    option.geo.map = mapName;
    // 为了重新定位,这里使用了length
    const idx = option.graphic.length + 1;
    option.graphic.push({
        type: "text",
        left: `${idx * 10}%`,
        top: "10%",
        style: {
            text: name,
            font: 'bolder 1.5rem "Microsoft YaHei", sans-serif',
            fill: "#fff",
        },
        onclick: () => {
            // 利用函数的作用域,可以直接拿上面的name来用
            const [grahpName, graphJson] = getMap(name);
            const index = option.graphic.findIndex(i => i.style.text === name);
            // 点击元素之后的所有元素全部删除
            option.graphic.splice(index + 1);
            // 很多操作重复了,你可以将公共部分抽离出来
            option.geo.map = mapName;
            echarts.registerMap(grahpName, graphJson);
            charts.setOption(option, true);
        },
    });
    echarts.registerMap(mapName, mapJson);
    charts.setOption(option, true);
});

这里会有个坑,在给graph添加click事件后,点击时会同时触发我们上面charts.on的click事件,想了很久也没有找到好一点的方式来解决这个事件冲突,最后只好判断了一下name是否为空来暂时解决。如果有更好的办法,也请留言。最终效果如下:

至此绘制地图已经完毕,更多是依靠自己的业务需求来进行更灵活的配置和渲染,它的API没有什么太复杂的,只是我们缺少了一点耐心去实验。

visualMap

首先来看效果

增加visualMap来让地图的数据渲染更有层次感,实现起来也很简单,只需要在option里增加visualMap配置即可:

const option = {
    // ...
    visualMap: {
        // 是否展示左下角,即是是false,也仅是不显示,不影响数据的映射
        show: true,
        // 上下端文字
        text: ["高", "低"],
        // 最小值和最大值,必须指定
        min: 0,
        max: 6000,
        // 位置
        left: "10%",
        bottom: "10%",
        // 是否展示滑块
        calculable: true,
        // 指定映射的数据,对应的是option.series,这里根据自己的实际需要进行配置
        seriesIndex: [0],
        // 从下到上的颜色
        inRange: {
            color: ['#00467F', '#A5CC82'],
        },
        //字体颜色
        textStyle: {
            color: "#fff",
            map: "china",
        },
    }
}

如果你的代码是跟着我从上面一直写下来的,那么此时你应该发现只是定位的图标变了,相应的地图区域并未变色,所以我们还要把地图的数据映射上去,所以在option.series里再加一个元素,使其type=“map”,内容与geo一致即可,但是要多加data属性,渲染的数据和定位图标一致。并将seriesIndex的索引做好映射,即可实现。

const option = {
    // ...
    visualMap: {
        // 是否展示左下角,即是是false,也仅是不显示,不影响数据的映射
        show: true,
        // 上下端文字
        text: ["高", "低"],
        // 最小值和最大值,必须指定
        min: 0,
        max: 6000,
        // 位置
        left: "10%",
        bottom: "10%",
        // 是否展示滑块
        calculable: true,
        // 指定映射的数据,对应的是option.series,这里根据自己的实际需要进行配置
        seriesIndex: [0],
        // 从下到上的颜色
        inRange: {
            color: ['#00467F', '#A5CC82'],
        },
        //字体颜色
        textStyle: {
            color: "#fff",
            map: "china",
        },
    }
}

如果你的代码是跟着我从上面一直写下来的,那么此时你应该发现只是定位的图标变了,相应的地图区域并未变色,所以我们还要把地图的数据映射上去,所以在option.series里再加一个元素,使其type=“map”,内容与geo一致即可,但是要多加data属性,渲染的数据和定位图标一致。并将seriesIndex的索引做好映射,即可实现。

如果出现了缩放重影,说明生成了两个地图组件,需要在新的series里加上geoIndex属性,值是geo里的索引,这样就只会共享一个组件,不会出现缩放重影的问题了

以下为源文档

默认情况下,map series 会自己生成内部专用的 geo 组件。但是也可以用这个 geoIndex 指定一个 geo组件。这样的话,map 和 其他 series(例如散点图)就可以共享一个 geo组件了。并且,geo组件的颜色也可以被这个 map series 控制,从而用 visualMap来更改。

当设定了 geoIndex 后,series-map.map属性,以及 series-map.itemStyle等样式配置不再起作用,而是采用 geo中的相应属性。

总结

到此这篇关于画echarts地图的文章就介绍到这了,更多相关echarts绘制地图内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • echarts实现地图定时切换散点与多图表级联联动详解

    1.  摘要 最近做项目遇到个统计相关需求,一个页面中大概四个或更多图形统计,百度地图.饼图.柱状图.线型图.百度地图上显示所有店面在全国各地大概位置,目前暂定每省一个,在地图上显示散点.如默认显示郑州散点闪动,其他图形显示郑州相关数据:5秒切换下一个区域点,其他的图表数据对应改变.先上个图,各位有需要的可以再接着往下 2.  引入ECharts以及地图相关json ECharts 3 开始不再强制使用 AMD 的方式按需引入,代码里也不再内置 AMD 加载器.因此引入方式简单了很多,只需要像普

  • echarts3 使用总结(绘制各种图表,地图)

    由于项目需要自学了echarts,下面将学到的东西总结如下,如果有哪里写的不好,请批评指正 一.前期准备 1.使用echarts之前先要引入echarts.js,js可以到官网下载 2.写一个div容器用来装echarts内容,这个容器必须有高度,不然看不到内容. 3.在script中获取div容器的id,根据需要写option中的参数(也许你现在还不知道option是干嘛用的,不要着急往下看),使用setoption生成图表. (代码如下)注:后面将不再对引入js,获取id,调用option生

  • echarts设置图例颜色和地图底色的方法实例

    前言 本来想写echarts初始化函数的,但最近因为要写一个地图与柱状图的混合方式,也就是每个省的地图上要有柱状图显示.于是仔细使用了一下地图. 1.地图的一些基本属性就不介绍了,还是那些style 2.地图数据的获取以及Series的加载和其他没有什么大的差异.地图数据都在map.js中,都可以自己看,也可以自己根据格式获取响应的数据. 这里主要想处理的是图例颜色与地图底图颜色怎么设置的问题. 1.图例的颜色代码 refresh: function (newOption) { if (newO

  • ECharts地图绘制和钻取简易接口详解

    1.地图绘制过程原理 给定范围边界经纬度数据,再给它个名字就构成了绘制地图的基础.也就是说,你可以绘制任意形状的地图版块. 2.地图数据生成 中国以及省市县等地图的基础数据可以从这里生成与下载. http://datav.aliyun.com/tools/atlas 有了地图范围数据,在 echarts 中通过 registerMap 给这块注册个名字,即可为后续绘制使用,以下代码以最简形式绘制一幅中国地图. $.getJSON('https://geo.datav.aliyun.com/are

  • 一篇文章搞定echarts地图轮播高亮

    目录 前言 toDoList just do it 准备一个地图 保存实例备用 设置定时器轮播 加入鼠标事件 总结 前言 这两天忙着做公司的超级数据大屏,实在挤不出时间连续更文. 但是更文活动都坚持这么久了也不想停止更新,那我就分享一下在工作中经常用到的echarts地图轮播高亮吧. 技术栈用的是vue2.x 相信效果大家已经清楚了那我们就开干吧. toDoList 简单的准备一个地图 保存实例备用 设置定时器 设置鼠标移入移出事件 just do it 准备一个地图 首先准备一个简简单单的地图

  • Echarts地图添加引导线效果(labelLine)

    最近有粉丝问我能不能出个案例:地图上的地区文字,或其他标示类的图层,因为区块面积相对太小,想放在地图之外,通过labelLine连接到对应的区块上.今天就分享一个类似简单的案例,铺设散点形式铺设label,部分地区用线连接,地图以广州地图为例: 如果需要地图geojson或js文件的话,可以到我的个人 github 上自取:https://github.com/zhangqian00/echarts3-mapFile 1.初始化地图: 2. 声明label数据: 配置需要铺设的label,val

  • 一文教会你从零开始画echarts地图

    目录 echarts地图制作 基础配置 数据渲染 嵌入文字 地图下钻 结合水印制作级联效果 visualMap 总结 echarts地图制作 离线地图下载地址https://datav.aliyun.com/tools/atlas/index.html echarts文档地址https://echarts.apache.org/zh/option.html 基于VUE编写,其他框架请自行转换,大同小异 基础配置 先让地图内容出来,npm安装步骤省略,请参考官方文档,创建的div必须设置宽度和高度

  • 如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)

    ECharts地图主要用于地理区域数据的可视化,展示不同区域的数据分布信息.ECharts官网提供了中国地图.世界地图等地图数据下载,通过js引入或异步加载json文件的形式调用地图. 效果演示      源码下载 本文将结合实例讲解如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据,我们以中国地图为例,展示去年(2015年)我国各省份GDP数据.通过异步请求php,读取mysql中的数据,然后展示在地图上,因此本文除了你掌握前端知识外,还需要你了解PHP以及MySQL方

  • vue2项目中封装echarts地图的优雅方法

    目录 前言 能学到的知识 效果图 注意 1.vue中echarts 5.x以下版本和5.x以上版本引入的区别 2.记得在vue.config.js中开启运行时编译功能 实现 数据准备 echarts地图模块封装 页面调用 接口数据处理 代码总览 代码 总结 参考资料 前言 以前写过 vue项目中封装echarts的比较优雅的方式,大屏可视化里面,除了数据图表很常用,显示省市地图区域也是很常用到的,这是姐妹篇. 区域地图选区域时,需要弹窗展示数据,样式是各种各样的,各种排列的数据.图文混搭.视频.

  • echarts地图设置背景图片及海岸线实例代码

    目录 1.地图设置背景图片 2.地图外部多层轮廓线 3.地图海岸线 4.地图中高亮显示有数据的城市 5.滚动高亮轮播 总结 1.地图设置背景图片 // data domImg: require('@/assets/images/largescreen/nation/map_bg.png'), // js 渲染地图之前 var domImg = document.createElement("img"); domImg.style.height = domImg.height = dom

  • Python应用之利用pyecharts画中国地图

    目录 1.安装 pycharts包的安装 在绘制地图时,需要导入相应的地图文件包 2.绘制地图 pyecharts的坑---“画图不显示“ 下面为大家举个例子 原因如下 这段时间在爬取了杭州某网站发布的二手房信息,在作图的时候发现在地图呈现上还是有欠缺,这里就把用到的贴出来,提升一下记忆. 之前有接触用Basemap绘制地图,但是在涉及到中国行政划分上感觉不是很方便.Echarts在数据可视化上应用比较广泛,这里采用pyecharts生成echarts风格的图表. 环境:pycharm:pyth

  • 一文教你利用Python画花样图

    目录 前言 地球仪加线 地图上加线 最后的福利-3D图鉴赏 总结 前言 在之前的一篇文章Python可视化神器-Plotly动画展示展现了可视化神器-Plotly的动画的基本应用,本文介绍如何在Python中使用 Plotly 创建地图并在地图上标相应的线. 地球仪加线 根据地球仪的区域显示在相应的位置图形上加上线条,完美的线性地球仪详细代码如下: `import plotly.express as px df = px.data.gapminder.query("year == 2007&qu

  • 详解angular中使用echarts地图

    目录 echart的初始化 app-base-chart组件 html css 使用app-base-chart组件 总结 在angular中使用echart的时候,只需要在对应的组件生命周期中调用echart的api就可以了 echart的初始化 在component的ngOnInit事件中进行echarts的初始化,配置option,然后echarts图表就生成了 app-base-chart组件 html <div #chart [ngClass]="'chart-box ' + (

随机推荐