Vue使用Echarts实现大屏可视化布局示例详细讲解

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

一、效果展示

先看一下展示的效果,无论是尺寸多宽的屏幕,都会将内容显示完整,做到了正正的响应式。唯一不足的是图表中的样例,会随着图表的缩放而变换位置,窗口尺寸变化过快会反应不过来,好在有节流函数,可以让浏览器计算量没有那么大。本篇博客不会直接拿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画图的,接下来一篇将会告诉大家如何画图。以及对图表进行响应式布局

到此这篇关于Vue使用Echarts实现大屏可视化布局示例详细讲解的文章就介绍到这了,更多相关Vue大屏可视化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Vue Echarts简易实现仪表盘

    目录 前言 仪表盘的特点 仪表盘的基本实现 仪表盘的常见效果 前言 本篇来学习写仪表盘图 仪表盘的特点 可以更直观的表现出某个指标的进度或实际情况 仪表盘的基本实现 ECharts 最基本的代码结构 准备数据, 设置给 series 下的 data 在 series 下设置 type:gauge <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">

  • Vue ECharts简易实现雷达图

    目录 前言 雷达图特点 雷达图的基本实现 雷达图的常见效果 显示数值 区域面积 绘制类型 完整代码 前言 本篇来学习写雷达图 雷达图特点 可以用来分析多个维度的数据与标准数据的对比情况 雷达图的基本实现 ECharts 最基本的代码结构 定义各个维度的最大值 准备具体产品的数据 在 series 下设置 type:radar <!DOCTYPE html> <html lang="en"> <head> <meta charset="

  • Vue使用Echarts画柱状图详解

    目录 前言 柱状图实现步骤 柱状图常见效果 标记 显示 前言 本篇来学习下柱状图的实现 柱状图实现步骤 ECharts 最基本的代码结构 准备x轴的数据 准备 y 轴的数据 准备 option , 将 series 中的 type 的值设置为: bar <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="v

  • Vue echarts封装实现流程

    将echarts封装成组件,达到只要调用方法,传入数据和相应的参数就能生成图表的效果,避免在项目中编写大量重复和累赘的echarts的配置代码,实现的思路如下: 接口返回的一般是json数据,所以首先要将json数据进行处理,处理成echarts需要的数据形式 将echarts的配置代码封装在一个方法里,通过自定义的配置名进行调用 下面对我自己封装的组件 EchartsGenerate 逐步解释 首先看template <template> <div> <slot>&l

  • Vue ECharts设置主题实现方法介绍

    目录 前言 内置主题 自定义主题 前言 本篇来学习下ECharts中如何设置图表主题 内置主题 ECharts 中默认内置了两套主题: light dark var chart = echarts.init(dom, 'light') var chart = echarts.init(dom, 'dark') <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&qu

  • Vue Echarts实现图表轮播图以及图表组件封装和节流函数优化讲解

    目录 一.为什么要优雅的使用echarts 二.最初的表格组件 三.初步的封装 四.性能优化 一.为什么要优雅的使用echarts 为了提高代码的规范性.复用性,vue中最常用的就是将具有某些功能的代码封装到一个插件.如果没有对插件进行封装,在后期使用插件的时候效率会十分低下也不便于后期对程序的维护拓展,在优雅的使用echarts时,首先,我们考虑到多个地方需要用到echarts,就需要封装一个组件出来,由于每一个图中的属性均由配置项option进行控制,所以我们可以将option选项提取出来,

  • Vue使用Echarts实现大屏可视化布局示例详细讲解

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

  • vue+echarts+datav大屏数据展示及实现中国地图省市县下钻功能

    随着前端技术的飞速发展,大数据时代的来临,我们在开发项目时越来越多的客户会要求我们做一个数据展示的大屏,可以直观的展示用户想要的数据,同时炫酷的界面也会深受客户的喜欢. 大屏展示其实就是一堆的图表能够让人一目了然地看到该系统下的一些基本数据信息的汇总,也会有一些实时数据刷新,信息预警之类的.笔者在之前也做过一些大屏类的数据展示,但是由于都是一些图表类的,觉得没什么可说的,加之数据也都牵扯到公司,所以没有沉淀下来什么. 最近有朋友要做一个大屏,问了自己一个问题,自己也刚好做了一个简单的大屏数据展示

  • JavaScript实现echarts水球图百分比展示大屏可视化

    目录 前言: 示例: 简介: 代码实现 项目文件中引入 声明实例,设置参数,绘制水球图 设置缩放 总结: 前言: 掘友们,大家晚上好啊.今天突然的看到之前的同学,在宿舍群里询问关于echarts水球图的问题,刚好,小编在之前做大屏可视化的时候,关于电脑磁盘空间的存储量做了水球图的展示,我就简单的给他分享了制作过程. 示例: 水球图的应用场景很广泛,一般最多的就是应用于容量大小的展示,使用空间的多少.这里先编以自己的项目为例,向大家展示. 简介: echarts已经升级到了V5版本,但是我们从官方

  • React大屏可视化脚手架教程示例

    目录 使用 create-react-app 初始化 引入 antd UI库 使用 craco 插件来自定义配置 自定义 antd 主题,使用 less 作为 css 预处理器 修改 craco.config.js 文件 craco-less .module.less 模拟vue组件中style的scope 功能 配置 craco.config.js 文件 以上操作版本记录 使用 create-react-app 初始化 # 使用了 create-react-app 的 typescript 模

  • python可视化大屏库big_screen示例详解

    目录 big_screen 特点 安装环境 输入数据 本地运行 在线部署 对于从事数据领域的小伙伴来说,当需要阐述自己观点.展示项目成果时,我们需要在最短时间内让别人知道你的想法.我相信单调乏味的语言很难让别人快速理解.最直接有效的方式就是将数据如上图所示这样,进行可视化展现. 具体如下: big_screen 特点 便利性工具, 结构简单, 你只需传数据就可以实现数据大屏展示. 安装环境 pip install -i https://pypi.tuna.tsinghua.edu.cn/simp

  • Vue大屏数据展示示例

    高效实现需求,避免臃肿的组件库和重复造轮子,前段时间做了很多大屏展示类的项目,今天来跟大家分享一下,大屏的实践过程,最开始我是使用了dataview 这个组件库,然后发现是自己并不需要它太多的封装好的组件,而且在移动端,有样式错乱的问题.所以自己看了他的实现方式,搞了一个大屏自适应的组件.话不多说,直接上效果图: 效果图 需要适配所有尺寸的大型显示屏,并且在手机上,可以缩放查看效果.我这里添加了这样一段代码,通过缩放body的大小,进行等比例放大缩小,达到不变形,整体适配的效果. <script

  • SpringBoot+Thymeleaf+ECharts实现大数据可视化(基础篇)

    目录 0x01 新建SpringBoot项目 2. 编写HelloWorld程序代码 0x02 引入ECharts资源 1. 获取JQuery与ECharts资源 2. 新建ECharts模版html文件 3. 添加后台java代码 4. ECharts模版样式预览 0x03 SpringBoot整合Thymeleaf 1. 新建myECharts方法 2. 引入Thymeleaf 3. ECharts新样式预览 4. 模式升级 0xFF 总结 0x01 新建SpringBoot项目 1. 新建

  • echart实现大屏动效示例详解

    目录 1.通过dataZoom实现柱状图动态前移效果 2.叠加流光效果 3.柱状图光亮轮播 1.通过dataZoom实现柱状图动态前移效果 最近做大屏相关需求,产品说需要炫酷一点的效果,于是做了一些echart相关的动效 设置dataZoom当前缩放值,加定时器,实现轮播效果. 示例: option = { color: ['#1E90FF', '#FFA500'], tooltip: { trigger: 'axis', axisPointer: {} }, grid: { left: 20,

  • echarts大屏字体自适应的方法步骤

    用echarts做大屏可视化的时候会遇到不是用电脑投屏而是直接在大屏打开的情况,这时候大屏幕下固定的px为单位的字体就会显得很小.有一种解决方法就是采用rem为单位,根据屏幕的宽度调整html的font-size. 获取屏幕宽度并计算比例 function fontSize(res){ let docEl = document.documentElement, clientWidth = window.innerWidth||document.documentElement.clientWidt

  • Vue联动Echarts实现数据大屏展示

    目录 1.安装echarts.js 2.新建vue界面 3.引入 ECharts 4.创建Vue方法和图表信息 5.效果样式 6.通过官网查找自己喜欢的样式 7.组件重复使用 1.组件重复使用定义 2.当前页面数据传递子组件中 1.安装echarts.js npm install echarts --save 2.新建vue界面 <template> <!-- 定义echarts需要控制的dom元素 --> <div :style="{height:height,w

随机推荐