Vue使用Echarts實(shí)現(xiàn)大屏可視化布局示例詳細(xì)講解
一、效果展示
先看一下展示的效果,無(wú)論是尺寸多寬的屏幕,都會(huì)將內(nèi)容顯示完整,做到了正正的響應(yīng)式。唯一不足的是圖表中的樣例,會(huì)隨著圖表的縮放而變換位置,窗口尺寸變化過快會(huì)反應(yīng)不過來(lái),好在有節(jié)流函數(shù),可以讓瀏覽器計(jì)算量沒有那么大。本篇博客不會(huì)直接拿echarts圖表下手,會(huì)先介紹一些這個(gè)大屏可視化的響應(yīng)式布局。后面會(huì)出一個(gè)專門的博客介紹echarts的使用。
二、基本的布局
大致的布局如下,整體分為頭部與body,頭部有標(biāo)題與時(shí)間兩部分,body分為三個(gè)子標(biāo)簽,使用flex布局分別占3\5\3份,然后在占3份的標(biāo)簽內(nèi)又分為三部分,占5份的標(biāo)簽內(nèi)分為兩部分。
寫入樣式之后就有了下面的樣子
此時(shí)需要將前面封裝的畫圖組件插入到指定的位置。得到下面的結(jié)果
三、背景
可以看出。這有一個(gè)在轉(zhuǎn)的地球,地球有一個(gè)比較亮的描邊,還有一些網(wǎng)格狀的東西罩在上面。
地球與網(wǎng)狀格格順時(shí)針旋轉(zhuǎn),光邊逆時(shí)針旋轉(zhuǎn),這種效果使用的是動(dòng)畫效果與過渡效果實(shí)現(xiàn),樣式代碼如下:
map1、map2、map3盒子的背景分別是地球、描邊、網(wǎng)格。
.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); } }
四、代碼
//以下面一個(gè)panel作為例子進(jìn)行講解 <Panel mychart="echart1" :option="chartsList[0]" title="柱形圖 - 就業(yè)形式" ></Panel> //這個(gè)標(biāo)簽控制一個(gè)圖表,mychart是圖表將要掛載的ref,option是圖表的配置項(xiàng),title是圖表的標(biāo)題。
Mainbox.vue整體布局
<template> <div class="mainbox"> <!-- 左邊的圖形展示 --> <div class="column"> <Panel mychart="echart1" :option="chartsList[0]" title="柱形圖 - 就業(yè)形式" ></Panel> <Panel mychart="echart2" :option="chartsList[2]" title="曲線圖-人員變化" ></Panel> <Panel mychart="echart3" :option="chartsList[4]" title="南丁格爾圖-地區(qū)分布" ></Panel> </div> <!-- 中間的圖形展示 --> <div class="column"> <!-- 首頁(yè)數(shù)字展示 --> <div class="mainboxtop"> <div class="tophd"> <ul> <li>999999999+</li> <li>200+</li> </ul> </div> <div class="topbd"> <ul> <li>前端需求人數(shù)</li> <li>市場(chǎng)供應(yīng)人數(shù)</li> </ul> </div> </div> <!-- 首頁(yè)地圖展示 --> <div class="mainboxbody"> <div ref="chinamap" class="chinamap"></div> <!-- 背景地球 --> <div class="map1"></div> <!-- 正旋轉(zhuǎn) --> <div class="map2"></div> <!-- 逆旋轉(zhuǎn) --> <div class="map3"></div> </div> </div> <!-- 右邊的圖形展示 --> <div class="column"> <Panel mychart="echart4" :option="chartsList[1]" title="技能占比-進(jìn)度條" ></Panel> <Panel mychart="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: "", }, }, 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", }, }, // 把中國(guó)地圖放大了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; // 節(jié)流函數(shù) 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() { // 移除窗口改變監(jiān)聽 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; } /* 以下是存放中國(guó)地圖的容器樣式 */ .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>大屏數(shù)據(jù)可視化展示</h1> <div class="showtime">時(shí)間</div> </div> </template> <script> export default { name: "Header", mounted() { var t = null; t = setTimeout(time, 1000); //開始運(yùn)行 function time() { clearTimeout(t); //清除定時(shí)器 let dt = new Date(); var y = dt.getFullYear(); var mt = dt.getMonth() + 1; var day = dt.getDate(); var h = dt.getHours(); //獲取時(shí) var m = dt.getMinutes(); //獲取分 var s = dt.getSeconds(); //獲取秒 document.querySelector(".showtime").innerHTML = y + "/" + mt + "/" + day + " -" + h + ":" + m + ":" + s; t = setTimeout(time, 1000); //設(shè)定定時(shí)器,循環(huán)運(yùn)行 } }, }; </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>
布局中遇到的一些問題
下面是在布局的時(shí)候遇到的一些問題,可以參考一下:
Echarts:There is a chart instance already initialized on the dom.//重復(fù)給一個(gè)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,一直報(bào)上面的錯(cuò)誤,后來(lái)改變用vue的ref獲取就可以了
使用document.getelementById()獲取也會(huì)報(bào)錯(cuò)
./src/components/Home.vue Module not found: Error: Can’t resolve ‘less-loader’ in 'C:\Users\123\Desk
//使用了less語(yǔ)法,沒有裝less相關(guān)插件,執(zhí)行npm install less-loader@5.0.0 -D
這篇博客是沒有提到如何使用echarts畫圖的,接下來(lái)一篇將會(huì)告訴大家如何畫圖。以及對(duì)圖表進(jìn)行響應(yīng)式布局
到此這篇關(guān)于Vue使用Echarts實(shí)現(xiàn)大屏可視化布局示例詳細(xì)講解的文章就介紹到這了,更多相關(guān)Vue大屏可視化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue elementUI 表單校驗(yàn)功能之?dāng)?shù)組多層嵌套
這篇文章主要介紹了vue elementUI 表單校驗(yàn)(數(shù)組多層嵌套)功能的實(shí)例代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-06-06詳解Vue+axios+Node+express實(shí)現(xiàn)文件上傳(用戶頭像上傳)
這篇文章主要介紹了詳解Vue+axios+Node+express實(shí)現(xiàn)文件上傳(用戶頭像上傳),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-08-08vue-baidu-map實(shí)現(xiàn)區(qū)域圈線和路徑的漸變色
這篇文章主要介紹了vue-baidu-map實(shí)現(xiàn)區(qū)域圈線和路徑的漸變色方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07el-tree使用獲取當(dāng)前選中節(jié)點(diǎn)的父節(jié)點(diǎn)數(shù)據(jù)
本文主要介紹了el-tree使用獲取當(dāng)前選中節(jié)點(diǎn)的父節(jié)點(diǎn)數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10vue3中配置文件vue.config.js不生效的解決辦法
這篇文章主要介紹了vue3中配置文件vue.config.js不生效的解決辦法,文中通過代碼示例講解的非常詳細(xì),對(duì)大家解決問題有一定的幫助,需要的朋友可以參考下2024-05-05vue實(shí)現(xiàn)把接口單獨(dú)存放在一個(gè)文件方式
這篇文章主要介紹了vue實(shí)現(xiàn)把接口單獨(dú)存放在一個(gè)文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧2020-08-08解決vue-cli項(xiàng)目開發(fā)運(yùn)行時(shí)內(nèi)存暴漲卡死電腦問題
最近開發(fā)一個(gè)vue項(xiàng)目時(shí)遇到電腦卡死問題,突然間系統(tǒng)就非???,然后卡著卡著就死機(jī)了,鼠標(biāo)也動(dòng)不了了,只能冷啟動(dòng)。這篇文章主要介紹了vue-cli項(xiàng)目開發(fā)運(yùn)行時(shí)內(nèi)存暴漲卡死電腦問題,需要的朋友可以參考下2019-10-10element-plus中如何實(shí)現(xiàn)按需導(dǎo)入與全局導(dǎo)入
本文主要介紹了element-plus中如何實(shí)現(xiàn)按需導(dǎo)入與全局導(dǎo)入,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11vue3+vite使用postcss-pxtorem、autoprefixer自適應(yīng)和自動(dòng)添加前綴
這篇文章主要介紹了vue3+vite使用postcss-pxtorem、autoprefixer自適應(yīng)和自動(dòng)添加前綴方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10