文章目录
- 一、效果展示
- 二、基本的布局
- 三、背景
- 四、代码
- 布局中遇到的一些问题
一、效果展示
先看一下展示的效果,无论是尺寸多宽的屏幕,都会将内容显示完整,做到了正正的响应式。唯一不足的是图表中的样例,会随着图表的缩放而变换位置,窗口尺寸变化过快会反应不过来,好在有节流函数,可以让浏览器计算量没有那么大。本篇博客不会直接拿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作为例子进行讲解
<Panelmychart="echart1":option="chartsList[0]"title="柱形图 - 就业形式"
></Panel>
//这个标签控制一个图表,mychart是图表将要挂载的ref,option是图表的配置项,title是图表的标题。
Mainbox.vue整体布局
<template><div class="mainbox"><!-- 左边的图形展示 --><div class="column"><Panelmychart="echart1":option="chartsList[0]"title="柱形图 - 就业形式"></Panel><Panelmychart="echart2":option="chartsList[2]"title="曲线图-人员变化"></Panel><Panelmychart="echart3":option="chartsList[4]"title="南丁格尔图-地区分布"></Panel></div><!-- 中间的图形展示 --><div class="column"><!-- 首页数字展示 --><div class="mainboxtop"><div class="tophd"><ul><li>999999999+</li><li>200+</li></ul></div><div class="topbd"><ul><li>前端需求人数</li><li>市场供应人数</li></ul></div></div><!-- 首页地图展示 --><div class="mainboxbody"><div ref="chinamap" class="chinamap"></div><!-- 背景地球 --><div class="map1"></div><!-- 正旋转 --><div class="map2"></div><!-- 逆旋转 --><div class="map3"></div></div></div><!-- 右边的图形展示 --><div class="column"><Panelmychart="echart4":option="chartsList[1]"title="技能占比-进度条"></Panel><Panelmychart="echart5":option="chartsList[3]"title="曲线图-播放量"></Panel><Panel mychart="echart6" :option="chartsList[5]" title="饼图"></Panel></div></div>
</template><script>
// 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 +"<br />" +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 <= 0 || 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);},
};
</script><style scoped>
.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%;
}</style>
Header.vue用于管理布局中的头部。
<template><div class="header"><h1>大屏数据可视化展示</h1><div class="showtime">时间</div></div>
</template><script>
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); //设定定时器,循环运行}},
};
</script><style scoped>
.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);
}
</style>
布局中遇到的一些问题
下面是在布局的时候遇到的一些问题,可以参考一下:
-
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画图的,接下来一篇将会告诉大家如何画图。以及对图表进行响应式布局。如果大家有好的想法或者想要源码欢迎评论区留言。