【Vue中使用Echarts】大屏可视化项目整体布局(pink老师vue 版)

文章目录

  • 一、效果展示
  • 二、基本的布局
  • 三、背景
  • 四、代码
  • 布局中遇到的一些问题

一、效果展示

先看一下展示的效果,无论是尺寸多宽的屏幕,都会将内容显示完整,做到了正正的响应式。唯一不足的是图表中的样例,会随着图表的缩放而变换位置,窗口尺寸变化过快会反应不过来,好在有节流函数,可以让浏览器计算量没有那么大。本篇博客不会直接拿echarts图表下手,会先介绍一些这个大屏可视化的响应式布局。后面会出一个专门的博客介绍echarts的使用。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

二、基本的布局

大致的布局如下,整体分为头部与body,头部有标题与时间两部分,body分为三个子标签,使用flex布局分别占3\5\3份,然后在占3份的标签内又分为三部分,占5份的标签内分为两部分。

在这里插入图片描述

请添加图片描述

写入样式之后就有了下面的样子

请添加图片描述

此时需要将前面封装的画图组件插入到指定的位置。得到下面的结果

请添加图片描述

三、背景

可以看出。这有一个在转的地球,地球有一个比较亮的描边,还有一些网格状的东西罩在上面。

地球与网状格格顺时针旋转,光边逆时针旋转,这种效果使用的是动画效果与过渡效果实现,样式代码如下:

map1、map2、map3盒子的背景分别是地球、描边、网格。

.map1,
.map2,
.map3 {
  position: absolute;
  top: 50%;
  left: 50%;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  transform: translate(-50%, -50%);
  width: 6.475rem;
  height: 6.475rem;
  opacity: 0.3;
}
.map1 {
  background-image: url(../../public/images/map.png);

  animation: rotate 15s linear infinite;
}
.map2 {
  width: 8.0375rem;
  height: 8.0375rem;
  background-image: url(../../public/images/lbx.png);

  opacity: 0.8;
  animation: rotate 5s linear infinite;
  z-index: 2;
}
.map3 {
  width: 7.075rem;
  height: 7.075rem;
  background-image: url(../../public/images/jt.png);

  animation: rotate1 10s linear infinite;
}
@keyframes rotate {
  from {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}
@keyframes rotate1 {
  from {
    transform: translate(-50%, -50%) rotate(0deg);
  }
  to {
    transform: translate(-50%, -50%) rotate(-360deg);
  }
}

在这里插入图片描述

四、代码

//以下面一个panel作为例子进行讲解

//这个标签控制一个图表,mychart是图表将要挂载的ref,option是图表的配置项,title是图表的标题。

Mainbox.vue整体布局

  
    
    
      
      
      
    

    
    
      
      
        
          
  • 999999999+
  • 200+
  • 前端需求人数
  • 市场供应人数
// import MyEcharts from "./MyEcharts.vue"; // import "../../node_modules/echarts/dist/china.js"; import "../../node_modules/echarts/map/js/china.js"; // import "../config/chinamap.js"; // import "../config/china.js"; import * as echarts from "echarts"; import Panel from "./Panel.vue"; var yearData = [ ]; var geoCoordMap = { }; var XAData = [ ]; var XNData = [ ]; var YCData = [ ]; var planePath = "path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z"; //var planePath = 'arrow'; var convertData = function (data) { var res = []; for (var i = 0; i < data.length; i++) { var dataItem = data[i]; var fromCoord = geoCoordMap[dataItem[0].name]; var toCoord = geoCoordMap[dataItem[1].name]; if (fromCoord && toCoord) { res.push({ fromName: dataItem[0].name, toName: dataItem[1].name, coords: [fromCoord, toCoord], value: dataItem[1].value, }); } } return res; }; var color = ["#a6c84c", "#ffa022", "#46bee9"]; //航线的颜色 var series = []; [ ["西安", XAData], ["西宁", XNData], ["银川", YCData], ].forEach(function (item, i) { series.push( { name: item[0] + " Top3", type: "lines", zlevel: 1, effect: { show: true, period: 6, trailLength: 0.7, color: "red", //arrow箭头的颜色 symbolSize: 3, }, lineStyle: { normal: { color: color[i], width: 0, curveness: 0.2, }, }, data: convertData(item[1]), }, { name: item[0] + " Top3", type: "lines", zlevel: 2, symbol: ["none", "arrow"], symbolSize: 10, effect: { show: true, period: 6, trailLength: 0, symbol: planePath, symbolSize: 15, }, lineStyle: { normal: { color: color[i], width: 1, opacity: 0.6, curveness: 0.2, }, }, data: convertData(item[1]), }, { name: item[0] + " Top3", type: "effectScatter", coordinateSystem: "geo", zlevel: 2, rippleEffect: { brushType: "stroke", }, label: { normal: { show: true, position: "right", formatter: "{b}", }, }, symbolSize: function (val) { return val[2] / 8; }, itemStyle: { normal: { color: color[i], }, emphasis: { areaColor: "#2B91B7", }, }, data: item[1].map(function (dataItem) { return { name: dataItem[1].name, value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value]), }; }), } ); }); var option = { tooltip: { trigger: "item", formatter: function (params, ticket, callback) { if (params.seriesType == "effectScatter") { return "线路:" + params.data.name + "" + params.data.value[2]; } else if (params.seriesType == "lines") { return ( params.data.fromName + ">" + params.data.toName + "
" + params.data.value ); } else { return params.name; } }, }, legend: { orient: "vertical", top: "bottom", left: "right", data: ["西安 Top3", "西宁 Top3", "银川 Top3"], textStyle: { color: "#fff", }, selectedMode: "multiple", }, geo: { map: "china", label: { emphasis: { show: true, color: "#fff", }, }, // 把中国地图放大了1.2倍 zoom: 1.2, roam: true, itemStyle: { normal: { // 地图省份的背景颜色 areaColor: "rgba(20, 41, 87,0.6)", borderColor: "#195BB9", borderWidth: 1, }, emphasis: { areaColor: "#2B91B7", }, }, }, series: series, }; export default { components: { Panel }, name: "MainBox", data() { return { //这里存放图表 chartsList: [], mycharts: null, chartFun: null, }; }, mounted() { // this.$refs.echart1.setOption(this.chartsList[0]); // this.$refs.echart2.setOption(this.chartsList[0]); if (this.mycharts) { this.mycharts.dispose(); } // this.mycharts = echarts.init(document.getElementsByClassName("chinamap")); this.mycharts = echarts.init(this.$refs.chinamap); this.mycharts.setOption(option); let chart = this.mycharts; // 节流函数 function throttle(func, wait, options) { let time, context, args, result; let previous = 0; if (!options) options = {}; let later = function () { previous = options.leading === false ? 0 : new Date().getTime(); time = null; func.apply(context, args); if (!time) context = args = null; }; let throttled = function () { let now = new Date().getTime(); if (!previous && options.leading === false) previous = now; let remaining = wait - (now - previous); context = this; args = arguments; if (remaining wait) { if (time) { clearTimeout(time); time = null; } previous = now; func.apply(context, args); if (!time) context = args = null; } else if (!time && options.trailing !== false) { time = setTimeout(later, remaining); } }; return throttled; } this.chartFun = throttle(function () { chart.resize(); }, 10); window.addEventListener("resize", this.chartFun); }, beforeDestroy() { // 移除窗口改变监听 window.removeEventListener("resize", this.chartFun); }, }; .mainbox { display: flex; /* background-color: pink; */ padding: 0.125rem 0.125rem 0; } .column { /* height: 10rem; */ /* background-color: red; */ flex: 3; } .mainbox .column:nth-child(2) { /* background-color: blue; */ padding: 0 0.125rem 0.1875rem; /* background-color: blue; */ flex: 5; } /* 以下是存放中国地图的容器样式 */ .mainboxtop { background-color: rgba(101, 132, 226, 0.1); padding: 0.1875rem; } .tophd { position: relative; border: 1px solid rgba(25, 186, 139, 0.17); } @font-face { font-family: electronicFont; src: url(../../public/font/DS-DIGIT.TTF); } .tophd > ul, .topbd > ul { display: flex; } .tophd > ul > li { flex: 1; display: inline-block; height: 1rem; color: #ffeb7b; font-size: 0.875rem; font-family: electronicFont; } .tophd > ul::after { position: absolute; right: 50%; width: 0.0125rem; height: 50%; top: 25%; background-color: rgba(255, 255, 255, 0.2); content: ""; } .tophd::before, .tophd::after { position: absolute; content: ""; width: 0.375rem; height: 0.125rem; } .tophd::before { top: 0; left: 0; border-top: 2px solid #02a6b5; border-left: 2px solid #02a6b5; } .tophd::after { bottom: 0; right: 0; border-bottom: 2px solid #02a6b5; border-right: 2px solid #02a6b5; } .topbd > ul > li { flex: 1; height: 0.5rem; line-height: 0.5rem; color: rgba(255, 255, 255, 0.7); font-size: 0.225rem; padding-top: 0.125rem; } .mainboxbody { position: relative; width: 100%; height: 10.125rem; /* background-color: pink; */ } .chinamap { position: absolute; top: 0; left: 0; z-index: 5; height: 10.125rem; width: 100%; }

Header.vue用于管理布局中的头部。

  
    

大屏数据可视化展示

时间 export default { name: "Header", mounted() { var t = null; t = setTimeout(time, 1000); //開始运行 function time() { clearTimeout(t); //清除定时器 let dt = new Date(); var y = dt.getFullYear(); var mt = dt.getMonth() + 1; var day = dt.getDate(); var h = dt.getHours(); //获取时 var m = dt.getMinutes(); //获取分 var s = dt.getSeconds(); //获取秒 document.querySelector(".showtime").innerHTML = y + "/" + mt + "/" + day + " -" + h + ":" + m + ":" + s; t = setTimeout(time, 1000); //设定定时器,循环运行 } }, }; .header { position: relative; width: 100%; height: 1.25rem; /* background-color: pink; */ background: url(../../public/images/head_bg.png) no-repeat; background-position: top center; background-size: cover; } h1 { color: #fff; text-align: center; line-height: 1rem; font-size: 0.475rem; } .showtime { overflow: hidden; width: 4.5625rem; height: 1rem; position: absolute; top: 0; right: 0.375rem; line-height: 0.9375rem; font-size: 0.25rem; color: rgba(255, 255, 255, 0.7); }

布局中遇到的一些问题

下面是在布局的时候遇到的一些问题,可以参考一下:

  • Echarts:There is a chart instance already initialized on the dom.//重复给一个dom元素画图

  • echarts警告:Can‘t get DOM width or height. Please check dom.clientWidth and dom.clientHeight. …//没有给盒子宽高

  • Uncaught TypeError: Cannot read properties of undefined (reading ‘echarts’)//没有找到echarts中的china.js

    将china.js文件放入echarts.js所在的目录

  • Error in mounted hook: “TypeError: this.dom.getContext is not a function”

    一开始是使用jQuery获取dom,一直报上面的错误,后来改变用vue的ref获取就可以了

    使用document.getelementById()获取也会报错

  • ./src/components/Home.vue Module not found: Error: Can’t resolve ‘less-loader’ in ‘C:\Users\123\Desk

    //使用了less语法,没有装less相关插件,执行npm install less-loader@5.0.0 -D


这篇博客是没有提到如何使用echarts画图的,接下来一篇将会告诉大家如何画图。以及对图表进行响应式布局。如果大家有好的想法或者想要源码欢迎评论区留言。

在这里插入图片描述

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/5501483ae0.html