当前位置:首页 » 《随便一记》 » 正文

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

8 人参与  2023年04月16日 19:17  分类 : 《随便一记》  评论

点击全文阅读


文章目录

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

一、效果展示

先看一下展示的效果,无论是尺寸多宽的屏幕,都会将内容显示完整,做到了正正的响应式。唯一不足的是图表中的样例,会随着图表的缩放而变换位置,窗口尺寸变化过快会反应不过来,好在有节流函数,可以让浏览器计算量没有那么大。本篇博客不会直接拿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作为例子进行讲解<Panel  mychart="echart1"  :option="chartsList[0]"  title="柱形图 - 就业形式"></Panel>//这个标签控制一个图表,mychart是图表将要挂载的ref,option是图表的配置项,title是图表的标题。

Mainbox.vue整体布局

<template>  <div class="mainbox">    <!-- 左边的图形展示 -->    <div class="column">      <Panel        mychart="echart1"        :option="chartsList[0]"        title="柱形图 - 就业形式"      ></Panel>      <Panel        mychart="echart2"        :option="chartsList[2]"        title="曲线图-人员变化"      ></Panel>      <Panel        mychart="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">      <Panel        mychart="echart4"        :option="chartsList[1]"        title="技能占比-进度条"      ></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: "{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画图的,接下来一篇将会告诉大家如何画图。以及对图表进行响应式布局。如果大家有好的想法或者想要源码欢迎评论区留言。
在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/59694.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1