echarts 地图和柱状图结合(在地图上显示柱状图)

news2024/11/18 21:43:47

如图,需求要做一个在地图上显示柱状图的echarts图,但是百度了半天,发现很少有人发这种例子。这个代码也是借鉴的别人的文章,但需求肯定不完全一致,那我会根据我的需求把代码和注意事项发出来并解释。(如果有人发现了借鉴的那篇,请在评论区发一下链接,我找不到了,谢谢)

话不多说,先上代码

目录:

index.vue文件(也就是组件)

<template>
  <div class="ChinaEcharts">
    <div class="wrap">
      <div id="map" :style="'width:' + Width + ';height:' + Height">
        <div :style="'width:' + Width + ';height:' + Height" ref="myEchart"></div>
      </div>
    </div>
  </div>
</template>


<script>
import * as echarts from 'echarts'
import tangshan from "./tangshan.json";
import Options from "./optionConfig"; //地图配置
export default {
  name: "ChinaEcharts",
  props: {
    Width: {
      type: String,
      default() {
        return '100%';
      },
    },
    Height: {
      type: String,
      default() {
        return '360px';
      },
    },
    areaData: {
      type: Array,
      default() {
        return [];
      },
    },
    option: {
      type: Object,
      default() {
        return new Options();
      },
    },
    cityConfig: {
      type: Object,
      default() {
        return {};
      },
    },
    areaItems: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      wrap: null, //包裹框
      drawBar: null, // 柱状图
      barWrap: null,
      myChart: null,
      // 地区坐标
      selfAreaItems: {},
      selfAreaData: [],
      selfOption: new Options(),
      barColor: ''
    };
  },
  watch: {
    areaData: {
      deep: true,
      handler: function(newVal,oldVal) {
        this.initEcharts();
      }
    }
  },
  methods: {
    loadMap(mapName, data) {
      if (data) {
        console.log(mapName, data, "mapName, datamapName, data");
        this.echarts.registerMap(mapName, data);
      }
    },
    initEcharts() {
      this.echarts.registerMap("map", tangshan);
      this.selfAreaData = JSON.parse(JSON.stringify(this.areaData));
      this.selfOption = JSON.parse(JSON.stringify(this.option));
      this.myChart = this.echarts.init(this.$refs.myEchart);
      if (this.cityConfig.dataJson) {
        this.loadMap(this.cityConfig.name, this.cityConfig.dataJson);
      }
      this.selfAreaItems = JSON.parse(JSON.stringify(this.areaItems));
      window.onresize = this.myChart.resize;
      this.myChart.setOption(this.selfOption);
      // 拖拽跟缩放重置
      let throttledRenderEachCity = this.throttle(this.renderItems, 0);
      this.myChart.on("geoRoam", throttledRenderEachCity);
      this.renderItems();
    },
    // 缩放和拖拽
    throttle(fn, delay, debounce) {
      let currCall;
      let lastCall = 0;
      let lastExec = 0;
      let timer = null;
      let diff;
      let scope;
      let args;
      delay = delay || 0;
      function exec() {
        lastExec = new Date().getTime();
        timer = null;
        fn.apply(scope, args || []);
      }

      let cb = function () {
        currCall = new Date().getTime();
        scope = this;
        args = arguments;
        diff = currCall - (debounce ? lastCall : lastExec) - delay;

        clearTimeout(timer);

        if (debounce) {
          timer = setTimeout(exec, delay);
        } else {
          if (diff >= 0) {
            exec();
          } else {
            timer = setTimeout(exec, -diff);
          }
        }

        lastCall = currCall;
      };

      return cb;
    },
    // 填充 地图点位
    renderItems() {
      let option = Object.assign(this.selfOption, {
        xAxis: [],
        yAxis: [],
        grid: [],
        series: [],
        tooltip: {
          trigger: "item",
          axisPointer: {
            type: "none",
          },
        },
      });
      this.selfAreaData.forEach((item, idx) => {
        let nodeCoord = this.selfAreaItems[item.areaName];
        let coord = this.myChart.convertToPixel("geo", nodeCoord);
        let itemData = []
        itemData.push(Number(item.value));
        if(item.value >= 0 && item.value<=5) {
          this.barColor = '#58dabd';
        }else if(item.value > 5 && item.value<=10) {
          this.barColor = '#fec018';
        }else if(item.value > 10) {
          this.barColor = '#f75218';
        }
        if (coord) {
          option.xAxis.push({
            id: idx + item.areaName,
            gridId: idx + item.areaName,
            type: "category",
            // name: item.areaName,//是否显示柱状图文字
            nameLocation: "middle",
            nameGap: 3,
            splitLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              show: false,
            },
            axisLine: {
              show: false,
            },
            // data: titleItems,
            z: 100,
          });
          option.yAxis.push({
            id: idx + item.areaName,
            gridId: idx + item.areaName,
            type: "value",
            splitLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              show: false,
            },
            axisLine: {
              show: false,
              lineStyle: {
                color: "red",
              },
            },
            min: 0,
            max: "dataMax",
          });
          option.grid.push({
            id: idx + item.areaName,
            width: 15,
            height: 30,
            left: coord[0] - 15,
            top: coord[1] - 15,
            z: 10,
          });
          option.series.push({
            id: idx + item.areaName,
            type: "bar",
            xAxisId: idx + item.areaName,
            yAxisId: idx + item.areaName,
            barGap: 0,
            barCategoryGap: 0,
            data: itemData,
            barWidth: 8,
            z: 100,
            itemStyle: {
              normal: {
                color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{  
                  // 四个数字分别对应 数组中颜色的开始位置,分别为 右,下,左,上。例如(1,0,0,0 )代表从右边开始渐
                  // 变。offset取值为0~1,0代表开始时的颜色,1代表结束时的颜色,柱子表现为这两种颜色的渐变。
                  offset: 0,
                  color: '#ffffff'
                }, {
                  offset: 1,
                  color: this.barColor
                }]),
              },
              opacity: 0,
              emphasis: {
                label: {
                  show: false,
                },
              },
            },
          });
        }
      });
      this.myChart.setOption(option);
    },
  },
};
</script>

 optionConfig.js文件(这个是地图的配置项)


export default class Options {
  constructor() {
    return {
      tooltip: {},
      geo: {
        map: "map",
        roam: true,
        label: {
          show: false,
          normal: {
            show: true,
            textStyle: {
              color: "#8483c0",
              fontSize: 12,
            },
          },
          emphasis: {
            show: true,
            textStyle: {
              color: "black",
              fontSize: 12,
            },
          },
        },
        itemStyle: {
          // 普通样式。
          normal: {
            areaColor: '#fffefe',//背景颜色
            borderWidth: 2, //设置外层边框
            borderColor: '#8483c0'
          },
          emphasis: {// 也是选中样式
            areaColor: "#8483c0",
            shadowOffsetX: 0,
            shadowOffsetY: 0,
            shadowBlur: 20,
            borderWidth: 0,
            shadowColor: "rgba(0, 0, 0, 0.5)",
          }
        },
        clickable:false,

      },
      visualMap: {
        type:'piecewise',
        showLabel:true,
        pieces:[
          {min: 10,label:'>10'}, 
          {min: 6, max: 10,label:'5-10'},  
          {min: 0, max: 5,label:'0-5'},   
        ],
        inRange: {
          color: ['#56dabb','#fec52c','#f7551c']
        },
        seriesIndex: 999,
        left:35,
        bottom:35,
        textStyle: {
          color: "#8483c0",
        }
      },
    };
  }
}

tangshan.json文件(可以到下面的链接下载需要的地图json,下载的格式应该是geoJson,改成json文件就行了)

echarts-map最新实时geoJson文件下载_hxkj.vip_HashTang

组件的引入:

import chinaEcharts from '../components/ChinaEcharts/index.vue'
<china-echarts :areaData="areaData" :areaItems="areaItems"></china-echarts>

 areaData 是数组格式是

areaData: [
	 {
		areaName:'路南区',
		value: 9
	},
	{
		areaName:'路北区',
		value: 19
	},
	{
		areaName:'遵化市',
		value: 2
	},
	{
		areaName:'迁西县',
		value: 5
	},
	{
		areaName:'丰南区',
		value: 10
	},
],

areaItems 因为每个柱状图是遍历的 所以这个传入的配置项是地区对应的柱状图坐标(这个坐标可以在json文件找,我图省事就是用的center坐标,如果有更好的方法请告知我谢谢)

 代码放完了,接下来改说说注意事项是什么了

 第一个注意点(最重要!!!):调后台接口有数据但是没有图

        我们柱状图的数据肯定是要调后台接口的。但是会发现我们用假的数据,能正常显示柱状图,但是调了后台接口就显示不出来了。在模拟的数据和处理返回的数据格式都一致的情况下。那就是渲染的问题了。

       我们请求是异步的,所以客户端就没等服务端相应完就渲染了。所以会导致柱状图再渲染的时候,你传入的数据还是空的

        解决办法:

         用watch监听数据变化 在渲染柱状图(我这个是封装的组件,如果是在同一个页面就直接在请求接口的方法里面调用initEcharts方法就行了)。用假数据测试,initEcharts方法写在mounted里面就行。

watch: {
    areaData: {
      deep: true,
      handler: function(newVal,oldVal) {
        this.initEcharts();
      }
    }
  },

第二个注意点:柱状图渐变色的问题

        我的需求是根据传入的不同数值,显示不同的颜色,在index文件里面 renderItems()里面是写柱状图配置的。

        在series里面的itemStyle的normal 写color的配置

       renderItems ()里面写对颜色的判断

color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [{  
      // 四个数字分别对应 数组中颜色的开始位置,分别为 右,下,左,上。例如(1,0,0,0 )代表从右边开始渐
   // 变。offset取值为0~1,0代表开始时的颜色,1代表结束时的颜色,柱子表现为这两种颜色的渐变。
  offset: 0,
  color: '#ffffff'
 }, {
   offset: 1,
    color: this.barColor
]),

注意:offset 中间也可以加0.5,这样就可以三个颜色过渡了。

第三个注意点:visualMap会覆盖柱状图的渐变色

        echarts里面地图的示例配置是visualMap 不是 lengend

 导致会覆盖柱状图颜色的罪魁祸首就是seriesIndex,echarts官网说的很清楚了,因为我这块只是为了展示用,不做任何功能,所以就不用关联 设一个不可能的值就行了,这样就不会覆盖改好的柱状图颜色了。

 第四个注意点:一个地区渲染多个柱状条和名字

        在index文件中,传入的areaData里面的areaName就是每个柱状图的名字,不过我不需要,需要的把他打开就行了

 如果在一个地区渲染多个柱状条的话,itemData也就是areaData里面的value,这是一个数组,如果传入的数组长度是2,那就在一个区域会显示两个柱条,并且有高低变化。

第五个注意点:echarts引入方式

import * as echarts from 'echarts'

不管在哪引入echarts,要用* as的形式,官方推荐用法,直接用import from 可能报echarts undefined的错 

补充 :解决每个区域柱状图高度一直问题

        这个问题真的想了很久,甚至想过在数组里面加一个value,然后只显示一个柱条。但没想到咋改。突然茅塞顿开,既然让他给高度不一致,直接设置y轴刻度不就行了。一开始想的是把每组的最大值算出来赋给y轴刻度。然后想了一下不太好,如果数据很多总和加起来就很多了,那少的数据不就几乎看不见了。所以要算每个区域的最大值赋给y轴,话不多说,上代码

        

 在initEcharts方法里面获取最大值

// 遍历数组获取最大值
for(let i = 0;i<this.selfAreaData.length;i++) {
  if(this.maxValue<this.selfAreaData[i].value) {
    this.maxValue = this.selfAreaData[i].value
   }
}

        或者换一种更简便的方法,用reduce函数一行代码

this.maxValue = this.selfAreaData.reduce((pre, cur) => pre > cur?.value ? pre : cur?.value)

data里面定义一下maxValue

         

 在柱状图配置项里面的yAxis里面的max属性设置刻度就搞定了

 

 最后附效果图(柱条的样式可以根据需要修改)

 

 如有问题,请指出,谢谢!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ant-design-vue:基础使用

一、环境介绍 vue3tsant-design-vue 二、安装使用 2.1、安装脚手架工具 $ npm install -g vue/cli # OR $ yarn global add vue/cli 2.2、创建一个demo项目 2.2.1、创建项目 $ vue create antd-demo 2.2.2、 安装成功&#xff1a; 2.2.3、 项目目录及启动项目&#xff1a…

前端常见的几种布局方式,2分钟即可看完,全是干货。

前端常见的几种布局方式 提示&#xff1a;本篇文章不包含具体知识点&#xff0c;但是可以帮助小白了解到什么是布局 文章目录前端常见的几种布局方式前言参考文档一、前端常见的几种布局方式是什么&#xff1f;二、几大布局介绍1.浮动布局2.定位布局3.弹性布局4.栅格布局5.响应…

scss安装入门到使用高级语法

一.sass的基本概念 sass是css的"预处理器", 一门专门的css编程语言 增加了变量, 函数, 计算, 嵌套关系等用法,让css编写更简洁, 清晰. 二. scss的安装步骤 首先查询一下是否已经安装过sass, 在cmd中输入sass -v 或者 sass --version sass -vsass --version使用上…

【前端修炼之路】第一话 · 初识前端领域

写在前面 夏日炎炎&#xff0c;现在屋外的鸟儿叫的很欢&#xff0c;屋内刚刚组装完的主机风扇在轰轰作响&#xff0c;呜呜呜&#xff0c;怎么闻怎么看都不像是矿卡的显卡现在竟散发出阵阵甜味~哈哈哈哈开个玩笑&#xff0c;写个文章看个视频&#xff0c;这显卡的风扇应该都不带…

申请百度地图开发者AK和基本使用

前言 有需求就会有市场&#xff0c;百度地图也会开放一些免费的Api。来提供一些基本的地图服务。 今天我们讲解的是百度地图申请AK过程&#xff0c;和申请完之后基本的使用&#xff0c;方便大家日后有需要浏览。 AK-申请 1.首先我们学习一个技术最直接的是去看官方文档&…

ES6中新语法:解构

目录 解构 1.解构初了解 2.解构详细解析 2.1对象属性赋值形式 2.2变量的声明 2.3怎么解构 3.实践 3.1数组的解构 3.2对象的解构 3.3解构参数 4.总结 ☀️作者简介&#xff1a;大家好我是言不及行yyds &#x1f40b;个人主页&#xff1a;言不及行yyds的CSDN博客 &#…

Element-UI--<el-switch>的@change回调函数的参数用法

原文网址&#xff1a;Element-UI--&#xff1c;el-switch&#xff1e;的change回调函数的参数用法_IT利刃出鞘的博客-CSDN博客 简介 说明 本文介绍Element-UI的<el-switch>的change回调函数的参数用法。 需求 2个switch组件&#xff0c;用同一个回调函数switch组件状…

Flask 与 Django 框架对比

详细分析了两种 Python Web框架&#xff1a; Flask 与 Django。从开发难易度、应用架构、性能、可扩展性以及适用范围等方面进行了详细说明。 Django 中级教程在 B 站上线&#xff0c;深入解析 Django 体系架构&#xff0c;实现从入门到精通的跨越。在线教程 前言 基于 Gith…

H5呼起微信支付(个人实践总结)

H5呼起微信支付存在两种场景 第一种&#xff1a;其他浏览器呼起微信支付。 第二种&#xff1a;微信内部呼起微信支付。 项目说明&#xff1a; 我这边的项目要求的两种方式均要适用。 产品要求是当支付失败时或者未支付情况是停留在支付订单页面&#xff0c;可再次发起订单请…

Vue3下使用Vuex(store)实现响应式全局变量

Vue3下使用Vuex store1 安装2 编写vuex配置文件2.1 目录及文件结构2.2 index.js文件2.3 编写vuex模块级参数文件2.4 index.js中引入模块级参数3 引入4 使用5 持久化5.1 vuex值存储在sessionStorge中5.1 vuex值存储在localStorge中注意本文记录了如何使用vuex建立响应式全局变量…

Java后端Date类型返回给前端变为时间戳解决方法

今天在制作个人博客的分页功能时候&#xff0c;发现了这个问题 后端查询数据正确&#xff0c;2022-11-12 数据库MySQL5.7 用的date类型 因为写文章一般yyyy-MM-dd 类型就够用了 如果你需要yyyy-MM-dd HH-mm-SS 这种带时分秒的用datetime类型 数据存的也是2022-11-12 格式正确…

【JSP入门】只知道HTML却不知道JSP?

前言 今天我们继续来总结学习JSP相关知识&#xff0c;上一篇我们学习了Servlet的基础入门&#xff0c;如果你还对Servlet那么建议你先去看一下上篇博客再回来。 传送门&#xff1a;【Servlet入门】一篇文章让你从没听过到了熟于心 在之前我们已经学习了HTML&#xff0c;CSS&…

html静态登录、注册页面

登录 代码如下 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <style> body { background: url(https://cdn.pixabay.com/photo/2018/08/14/13/23/ocean-3605547_1280.j…

windows7安装node14版本及以上

前言&#xff1a; gitee上拉了一个项目&#xff0c;npm install一直报错。一直没有解决&#xff0c;就去gitee上看前端启动教程。作者说要运行在node14或者16上。我就去官网下载node14的msi。这个是不支持windows7的。我就百度&#xff0c;他们说要下载压缩包。 我之前走了好…

sourcemap文件泄露漏洞

最近进行渗透测试时&#xff0c;时常遇到xray扫出sourcemap文件&#xff0c;每次扫到都要百度&#xff0c;因此做个笔记。 漏洞原理 在日常测试时&#xff0c;经常会遇到以js.map为后缀的文件 这是jQuery中的一个新功能&#xff0c;支持Source Map 非常多Webpack打包的站点都…

Vue3: vue3 props接多个不同类型的参数,默认false

哪天的问题来着...嘶...(挠头)... 之所以会卡在这里&#xff0c;是因为在我的经验及认知里&#xff0c;封装组件中props的使用&#xff0c;接参时从来都是一个参数对应一个值&#xff0c;尤其是在ts中&#xff0c;还更为严格地设定了参数类型&#xff0c;所以我的业务需求不知道…

保姆级教程!如何在安卓手机上安装使用油猴脚本

浏览器插件成千上万&#xff0c;但是大家都有一个共识&#xff0c;那就是油猴无插件能敌&#xff0c;原因就在于它一个插件就可以实现众多插件的功能。 首先需要明确一点的是&#xff0c;油猴插件本身是没有任何功能的&#xff0c;它需要依靠脚本来实现功能。至于脚本&#xf…

红队web打点信息收集

目录 红蓝对抗 ICP备案查询—查询主域 主站域名一键查询 敏感信息收集 googlehack语法 目标邮箱号收集 子域名收集 被动信息收集 证书透明 fofa_viewer 在线子域名查询 第三方DNS服务 google语法 主动信息收集 oneforall Sylas—从burp历史记录中提取子域 Lay…

【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件

目录 前言 初识express 使用express创建基本的web服务器 初识express路由 路由匹配概念 路由模块化 中间件 中间件和路由的区别 定义中间件函数 中间件作用 局部生效中间价 中间件分类 1.应用级别中间件 2.路由级别的中间件 3.错误级别中间件 4.内置中间件 5.自定义…

带你深入理解js事件循环机制

同步任务和异步任务&#xff08;微任务和宏任务&#xff09; JavaScript是一门单线程语言 分为同步任务和异步任务 同步任务是指在主线程上排队执行的任务&#xff0c;只有前一个任务执行完毕&#xff0c;才能继续执行下一个任务。 异步任务指的是&#xff0c;不进入主线程…