vue 里怎么使用 echarts 实现地图自动轮播功能自定义 tooltip 悬浮位置提示自定义 label 标签位置样式?

Posted 凯小默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 里怎么使用 echarts 实现地图自动轮播功能自定义 tooltip 悬浮位置提示自定义 label 标签位置样式?相关的知识,希望对你有一定的参考价值。

要实现的功能

比如:我们要实现白云地图24镇街的常住人口统计展示,然后需要我们实现 1s 自动轮播一次地区,自定义标签样式,自定义悬浮样式。

准备工作

1、安装依赖

npm i echarts -s

2、准备 24 镇街的 geoJson 数据

关于怎么获取 24 镇街的 geoJson 数据,请参考我之前的一篇博客:怎么获取echarts需要的geoJson数据去渲染地图:以广州市白云区24镇街为例

3、准备一份配置 24 镇街的文件

我们新建文件 440111.config.js,在里面添加一些配置参数用于数据展示的方便,比如我配置了几个:

/**
 * 1)4个镇:江高镇、人和镇、太和镇、钟落潭镇;
 * 2)20个街:龙归街、大源街、三元里街、松洲街、景泰街、同德街、黄石街、棠景街、新市街、同和街、京溪街、永平街、嘉禾街、均禾街、石井街、金沙街、云城街、鹤龙街、白云湖街、石门街;
 * */ 

export const BAIYUN_CONFIG = [
  '江高镇',
  '人和镇',
  '太和镇',
  '钟落潭镇',
  '龙归街',
  '大源街',
  '三元里街',
  '松洲街',
  '景泰街',
  '同德街',
  '黄石街',
  '棠景街',
  '新市街',
  '同和街',
  '京溪街',
  '永平街',
  '嘉禾街',
  '均禾街',
  '石井街',
  '金沙街',
  '云城街',
  '鹤龙街',
  '白云湖街',
  '石门街'
];

/**
 * SUCCESS_STYLE:绿色样式:'江高镇','太和镇','景泰街','黄石街','棠景街','京溪街','永平街','均禾街','石井街','金沙街';
 * WARNING_STYLE:橙色样式:'人和镇','嘉禾街','三元里街','石门街','新市街','大源街','松洲街';
 * ERROR_STYLE:红色样式:'钟落潭镇','同德街','云城街','鹤龙街','白云湖街','龙归街','同和街';
 * */ 
export const SUCCESS_STYLE = ['江高镇','太和镇','景泰街','黄石街','棠景街','京溪街','永平街','均禾街','石井街','金沙街'];
export const WARNING_STYLE = ['人和镇','嘉禾街','三元里街','石门街','新市街','大源街','松洲街'];
export const ERROR_STYLE = ['钟落潭镇','同德街','云城街','鹤龙街','白云湖街','龙归街','同和街'];

// 测试数据
export const MapData = [

  id: "jianggao",
  name: "江高镇",
  value: 883945
,
  id: "renhe",
  name: "人和镇",
  value: 4567992
,
  id: "taihe",
  name: "太和镇",
  value: 4567323
,
  id: "zhongluotan",
  name: "钟落潭镇",
  value: 497863
,
  id: "longgui",
  name: "龙归街",
  value: 3486257
,
  id: "dayuan",
  name: "大源街",
  value: 897435
,
  id: "sanyuanli",
  name: "三元里街",
  value: 46809544
,
  id: "songzhou",
  name: "松洲街",
  value: 123403
,
  id: "jingtai",
  name: "景泰街",
  value: 342256677
,
  id: "tongde",
  name: "同德街",
  value: 234677
,
  id: "huangshi",
  name: "黄石街",
  value: 976542
,
  id: "tangjing",
  name: "棠景街",
  value: 33456
,
  id: "xinshi",
  name: "新市街",
  value: 3455602
,
  id: "tonghe",
  name: "同和街",
  value: 487654
,
  id: "jingxi",
  name: "京溪街",
  value: 3876735
,
  id: "yongping",
  name: "永平街",
  value: 6677544
,
  id: "jiahe",
  name: "嘉禾街",
  value: 34526784
,
  id: "junhe",
  name: "均禾街",
  value: 8756534
,
  id: "shijing",
  name: "石井街",
  value: 220232
,
  id: "jinsha",
  name: "金沙街",
  value: 3352256
,
  id: "yuncheng",
  name: "云城街",
  value: 335677
,
  id: "helong",
  name: "鹤龙街",
  value: 334225
,
  id: "baiyunhu",
  name: "白云湖街",
  value: 34556
,
  id: "shimen",
  name: "石门街",
  value: 1354667

];

4、准备工具方法添加千分位

新建文件 utils.js,添加千分位函数:

// 数字加千位分隔符
export function numToThsSprtr (num) 
  let res = num.toString().replace(/\\d+/, function (n)  // 先提取整数部分
    return n.replace(/(\\d)(?=(\\d3)+$)/g, function ($1) 
      return $1 + ',';
    );
  )
  return res;



代码实现

1、自定义标签

我们配置标签的相应样式,我们利用 formatter,以及 rich 去处理,具体可以参考:https://echarts.apache.org/zh/option.html#series-map.label.formatter,backgroundColor 可以使用背景图片。

label: 
  show: true,
  color: "#fff",
  textAlign: "center",
  // a:系列名。b:数据名。c:数据值。
  formatter: (params) => 
    let richName = "";
    if (SUCCESS_STYLE.includes(params.name)) 
      richName = "success";
     else if (WARNING_STYLE.includes(params.name)) 
      richName = "warning";
     else if (ERROR_STYLE.includes(params.name)) 
      richName = "error";
    
    return `$richName|$params.name`;
  ,
  rich: 
    success: 
      fontSize: "0.0729rem",
      padding: [4, 7],
      borderWidth: 2, // 图形描边的宽度。
      borderColor: "#fff", // 边框颜色
      backgroundColor: 'green', // 背景色
    ,
    warning: 
      fontSize: "0.0729rem",
      padding: [4, 7],
      borderWidth: 2, // 图形描边的宽度。
      borderColor: "#fff", // 边框颜色
      backgroundColor: 'orange', // 背景色
    ,
    error: 
      fontSize: "0.0729rem",
      padding: [4, 7],
      borderWidth: 2, // 图形描边的宽度。
      borderColor: "#fff", // 边框颜色
      backgroundColor: 'red', // 背景色
    ,
  ,
,

怎么处理标签名重叠问题?

如果大家出现下面这种标签名重叠的问题,那应该怎么去处理?

这里我们可以参考 github 上面 echarts 的问题 4379 进行相应的处理:中国地图,省份名称重叠 #4379

问题的描述:

两种方式处理重叠

第一种:在 geoJson 数据中添加 cp 属性数据。

"properties": 
  "name": "白云湖街",
  "cp": [113.23196411132812, 23.24386977767157]

第二种:echarts.getMap(‘china’) 后修改已经加载的地图的数据。

var chinaMapInfoObj = document.getElementById(‘mianid‘’);
var chinaMap = echarts.init(chinaMapInfoObj);
var chinaEchartsObj = echarts.getMap('china');
var geoJSONChina = chinaEchartsObj.geoJson;
var allDefProvince = geoJSONChina.features;
for(var i=0,len=allDefProvince.length; i<len; i++)
       var sglProvinceProperties = allDefProvince[i].properties;
       var sglProvinceName = sglProvinceProperties.name;
       switch(sglProvinceName)
              case '新疆':
                       sglProvinceProperties.cp[0]=87.617733;
                       sglProvinceProperties.cp[1]=41.792818;
                       break;
               case '青海'://def:101.778916,36.623178
                        sglProvinceProperties.cp[0]=97.617733;
                        sglProvinceProperties.cp[1]=36.623178;
                       break;
                 case '江苏'://def:118.767413,32.041544
                        sglProvinceProperties.cp[0]=119.767413;
                        sglProvinceProperties.cp[1]=33.041544;
                        break;
        

option.echarts.registerMap('china', geoJSONChina, );

怎么确定中心点的坐标

可以去查看这个我写的这一篇博客里的确定边界汇聚点部分,里面有介绍怎么处理。怎么获取 echarts 需要的 geoJson 数据去渲染地图:以广州市白云区24镇街为例

大致就是把矩形左上方的点放到新的位置中心,就可以得到大概的坐标。

得到坐标之后,可能有点不太精确,可以自己合适的调整数据,达到自己想要的位置就行。

比如:现在 松洲街同德街,挡住了,需要把它进行移动,

这里我们采用第一种方式,修改 geojson 数据,我们给松洲街添加 cp 坐标数据,我们发现就不会被遮住了,其他也是同样的原理

"properties": 
  "name": "松洲街",
  "cp": [113.21036999511719, 23.15851026498019]

2、自定义悬浮提示

这里我们主要需要处理的就是 position 跟样式 formatter。这里的位置需要计算一下 (point:鼠标位置) 跟(contentSize:dom 的尺寸),找到合适的显示位置。具体的可以参考:

tooltip: 
  show: true,
  trigger: "item",
  // point:鼠标位置 contentSize:dom 的尺寸
  position: (point, params, dom, rect, size) => 
    return [point[0] - 20, point[1] - size.contentSize[1] - 15];
  ,
  extraCssText: "box-shadow: none", // 额外样式
  formatter: (param) => 
    let data = `
      <div class="map-tooltips">
        <div class="name">$param.name常住人口</div>
        <div class="value">
         <span class="num">$numToThsSprtr(param.value || 0)</span>
         <span class="unit">人</span>
        </div>
      </div>
    `;
    return data;
  ,
,

3、自动轮播功能

我们可以通过 dispatchAction 实现轮播高亮提示效果。这里需要注意的就是轮播到最后一个时的状态处理。这里就不具体展开逻辑,看完整代码就行,有注释。

具体的配置参考:https://echarts.apache.org/zh/api.html#action

高亮指定的数据图形。

// 如果要高亮系列:
dispatchAction(
    type: 'highlight',

    // 用 index 或 id 或 name 来指定系列。
    // 可以使用数组指定多个系列。
    seriesIndex?: number | number[],
    seriesId?: string | string[],
    seriesName?: string | string[],

    // 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项
    dataIndex?: number | number[],
    // 可选,数据项名称,在有 dataIndex 的时候忽略
    name?: string | string[],
);

取消高亮指定的数据图形。

// 如果要取消高亮系列:
dispatchAction(
    type: 'downplay',

    // 用 index 或 id 或 name 来指定系列。
    // 可以使用数组指定多个系列。
    seriesIndex?: number | number[],
    seriesId?: string | string[],
    seriesName?: string | string[],

    // 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项
    dataIndex?: number | number[],
    // 可选,数据项名称,在有 dataIndex 的时候忽略
    name?: string | string[],
)

指定系列中的数据图形,根据 tooltip 的配置项显示提示框。

dispatchAction(
    type: 'showTip',
    // 系列的 index,在 tooltip 的 trigger 为 axis 的时候可选。
    seriesIndex?: number,
    // 数据项的 index,如果不指定也可以通过 name 属性根据名称指定数据项
    dataIndex?: number,
    // 可选,数据项名称,在有 dataIndex 的时候忽略
    name?: string,,
    // 本次显示 tooltip 的位置。只在本次 action 中生效。
    // 缺省则使用 option 中定义的 tooltip 位置。
    position: number[] | string | Function,
)

隐藏提示框。

dispatchAction(
    type: 'hideTip'
)

4、大屏自适应方案

这个可以参考我的另外一篇:使用 sass + rem + flexible.js 实现大屏自适应

完整代码

<template>
<div ref="geoTwoDimensionalMapChart" class="geo-two-dimensional-map-chart"></div>
</template>

<script>
import * as echarts from "echarts";
// 白云区 geojson 数据
import baiyunGeoJson from "@/assets/mapData/440111.json";
// 24 镇街数据
import 
  BAIYUN_CONFIG,
  SUCCESS_STYLE,
  WARNING_STYLE,
  ERROR_STYLE,
  MapData
 from "@/assets/mapData/440111.config.js";
// 工具方法
import 
  numToThsSprtr
 from "@/utils/utils.js";
export default 
  name: "geoTwoDimensionalMapChart",
  data() 
    return 
      myChart: null,
      interval: 1000, // 时间间隔毫秒数
      index: 0, // 播放所在下标
      timer: null,
      option: 
        series: [
          type: "map",
          map: "白云区",
          data: [],
          layoutCenter: ["50%", "50%"], // 属性定义地图中心在屏幕中的位置
          layoutSize: "99%", // 定义地图的大小
          label: 
            show: true,
            color: "#fff",
            textAlign: "center",
            // a:系列名。b:数据名。c:数据值。
            formatter: (params) => 
              let richName = "";
              if (SUCCESS_STYLE.includes(params.name)) 
                richName = "success";
               else if (WARNING_STYLE.includes(params.name)) 
                richName = "warning";
               else if (ERROR_STYLE.includes(params.name)) 
                richName = "error";
              
              return `$richName|$params.name`;
            ,
            rich: 
              success: 
                fontSize: "0.0729rem",
                padding: [4, 7],
                borderWidth: 2, // 图形描边的宽度。
                borderColor: "#fff", // 边框颜色
                backgroundColor: 'green', // 背景色
              ,
              warning: 
                fontSize: "0.0729rem",
                padding: [4, 7],
                borderWidth: 2, // 图形描边的宽度。
                borderColor: "#fff", // 边框颜色
                backgroundColor: 'orange', // 背景色
              ,
              error: 
                fontSize: "0.0729rem",
                padding: [4, 7],
                borderWidth: 2, // 图形描边的宽度。
                borderColor: "#fff", // 边框颜色
                backgroundColor: 'red', // 背景色
              ,
            ,
          ,
          itemStyle: 
            borderWidth: 2, // 图形描边的宽度。
            borderColor: echarts 实现数据(tooltip)自动轮播插件

菜鸟怎么在页面的div里引入echarts图标

echarts 2.1.8 模块化单文件引入map报错,请问怎么处理

echarts tooltip自动轮播 高亮显示

Vue使用Echarts展示地图

Vue使用Echarts展示地图