基于VUE + Echarts 实现可视化数据大屏展示效果

中国(寿光)国际蔬菜科技博览会智慧农业系统 — LED拼接屏展示前端开发文档

上线后呈现效果:

 

 

 

 

一、开发需求及方案制定

1、确定现场led拼接屏的宽高比,按照1920px*1080px的分辨率,F11全屏后刚好占满整屏且无滚动条;

2、与产品设计确定页面相关功能:

  • 第一屏相关功能:实时时间、当地天气、菜博会基本信息、图表数据统计(近三日人流量、寿光最近价格行情、菜博会新品种/新技术/新模式)、展区监控、产品图展示、中间菜博会宣传视频+场馆分布介绍图切换展示、下一页;
  • 第二屏相关功能:实时时间、当地天气、大棚基本信息、彩椒种植模型、传感器数据展示、大棚监控、设备数据展示、报警记录和农事记录数据展示、中间大棚植物生长三维动画、返回;
  • 第一屏与第二屏无缝切换且循环;

3、确认拼接屏展示时远程投屏的浏览器,根据页面所要实现的功能,挑选兼容性最好的浏览器,最终选定:360极速浏览器的兼容模式(IE10);

4、页面模块划分,确定两屏切换方案,编写公共样式;

 

二、功能实现(不局限于此):

  • 编码工具:Visual Studio Code
  • js框架:vue
  • 接口对接:axios

 

1、两屏循环切换采用单页,v-show来指定显示和隐藏的模块,此处不用v-if是因为我们需要在第一屏数据获取完后就获取到第二屏的接口数据并渲染,给用户视觉体验效果更好;v-if和v-show的区别请移步vue官方:https://cn.vuejs.org/v2/guide/conditional.html

  • 第一屏切换至第二屏:监听视频的播放+图片显示,当视频播放完毕后显示图片,停留30s,然后切换第二屏,但是当用户点击下一页切换至第二屏时第一屏的视频停止播放;
  • 第二屏切换至第一屏:监听视频的播放,同理;

2、自适应:拼接屏是直接连接电脑投屏上去,不需要考虑自适应的问题,如需考虑自适应请用rem;

3、图表(百度开发的Echarts)曲线图、柱状图,雷达图,散点图;先获取数据然后再绘制,详细请移步echarts官方:https://echarts.baidu.com/option.html#title

  • 当前项目安装echarts依赖,npm install echarts -save
  • 全局引入/按需引入;
  • 全局:main.js

         import echarts from 'echarts'

         Vue.prototype.$echarts = echarts

  •  按需:page1.vue

         var echarts = require('echarts');

  • 页面使用;

例:寿光最新价格行情曲线图

<template>
    <div id="price-quotation" style="width: 6rem; height: 4rem"></div>
<template>

<script>
    var echarts = require('echarts');
    export default {
        data(){
            return{
                highPriceList: [], //寿光今日价格数据列表 - 高
                lowerPriceList: [], //寿光今日价格数据列表 - 低 
            }
        },
        created(){
            var that = this;
            // 先获取接口的价格数据
            that.getPrice();
            window.setInterval(() => {  //每小时请求一次接口
                  setTimeout(that.getPrice, 0)
            }, 360000)
        },
        mounted(){
            //绘制曲线图
            that.drawDataTable1();
        },
        methods:{
            drawDataTable1(){
                // 基于准备好的dom,初始化echarts实例
                let myChart1 = echarts.init(document.getElementById('price-quotation'))
                console.log('图表中获取价格列表====')
                console.log(this.highPriceList)
                // 绘制图表
                myChart1.setOption({
                  title: { text: '' },
                  grid: { 
                      left: '10%', 
                      right: '8%', 
                      top:'20%',
                  },  
                  legend: {
                      top: '3%',
                      textStyle: {color: '#fff'},
                      itemGap: 20,
                      itemHeight: 10,
                      data:[
                        {name: '最高价'}, 
                        {name: '最低价'}
                      ]
                  },
                  color:['#28F2A8','#28D8FF'],
                  xAxis: [
                      {
                          type: 'category',
                          data: ['大红柿子(精品)','贝贝小柿子','大龙茄子','红彩椒','黄彩椒'],
                          boundaryGap: false,
                          axisLabel: {
                              interval: 0,
                              textStyle: {
                                  color: '#fff'
                              },
                          lineHeight: 24
                      },
                      axisLine: { // 坐标轴线
                      lineStyle: {
                          color: 'rgba(85,85,85,0.4)'
                      },
                  },
                  axisTick: {  //刻度线
                      show: false,
                      lineStyle: {
                          color: 'rgba(85,85,85,0.4)'
                      }
                  }, 
                  axisPointer: {
                      type: 'shadow'
                  },                
              }
          ],
          yAxis: [
              {
                  type: 'value',
                  name: '元(斤)',
                  min: 0,
                  max: 10,
                  interval: 2.5,
                  nameTextStyle: {
                      color: '#fff',
                  },
                  axisLabel: {
                      formatter: '{value}',
                      textStyle: {
                          color: '#fff'
                      },
                  },
                  axisLine: {
                      lineStyle: {
                          color: 'rgba(85,85,85,0.4)'
                      }
                  },
                  axisTick: {
                      show: false,
                      lineStyle: {
                          color: 'rgba(85,85,85,0.4)'
                      }
                  },
                  splitLine:{ //去除网格线
                      show: true,
                      lineStyle: {
                          color: ['rgba(85,85,85,0.4)']
                      }
                  },   
              },
              {
                  type: 'value',
                  axisLine: {
                      lineStyle: {
                          color: 'rgba(85,85,85,0.4)'
                      }
                  }, 
              },
          ],
          series: [
              {
                  name: '最高价',
                  type : 'line',
                  label : {
                    show: true,
                    position: 'top',
                    color: '#fff',
                  },
                  itemStyle: {
                      normal: {
                          lineStyle: {
                              width:2, //调整 线条的宽度 
                              color : '#28F2A8' //线条颜色 - 绿色
                          }
                      }
                  },
                  // showSymbol: false,
                  smooth: true,
                  barWidth : '20%',
                  data: this.highPriceList,
              },  
              {
                  name: '最低价',
                  type : 'line',
                  label : {
                    show: true,
                    position: 'bottom',
                    color: '#fff',
                  },
                  itemStyle: {
                      normal: {
                          lineStyle: {
                              width:2, //调整 线条的宽度 
                              color : '#28D8FF' //线条颜色 - 蓝色
                          }
                      }
                  },
                  // showSymbol: false,
                  smooth: true,
                  barWidth : '20%',
                  data: this.lowerPriceList,
              },    
          ]
        });
      }
    }
}
</script>

 

4、展区监控,菜博会官方使用的海康的摄像头和录像机,且该监控只能内网访问,我们使用的是最简单的办法,将海康的demo放在他们投屏的电脑上,vue中内嵌iframe页面,然后调样式即可;

<div id="page1-rvm1">
    <iframe src="http://127.0.0.1/en/cbhs2.html" frameborder="0" wmode="opaque" scrolling="no"></iframe>
</div>

注意:

  • 海康的demoWeb 控件 V3.0 基于 ActiveX 和 NPAPI 开发,接口封装于 javascript 脚本,以 javascript 接口形式提供用户 集成,支持网页上实现预览、回放、云台控制等功能。该控件开发包仅支持 B/S 网页开发,不适用于 C/S 开发。
  • 安装activex控件,此处坑较多,我的电脑是windows10的系统,IE浏览器始终安装不成功,后再另一台windows7系统的IE10上成功安装了此控件,附上安装失败时的处理方式:https://www.nhxz.com/fanyi/18102974563ba21a90da13da.html

 

5、产品图展示,图片自动循环轮播,

  • npm install vue-awesome-swiper --save
    /*全局引入*/ 
    import VueAwesomeSwiper from 'vue-awesome-swiper' 
    import 'swiper/dist/css/swiper.css' //这里注意具体看使用的版本是否需要引入样式,以及具体位置
    Vue.use(VueAwesomeSwiper)

     

  • 页面中使用
    <swiper :options="swiperOption" ref="mySwiper">
       <!-- slides -->             
       <swiper-slide v-for="(item,index) in proImgList" :key="index">
           <img class="img-cover" :src="item">
       </swiper-slide>
    </swiper>

     

  • js中配置参数,详细请移步:https://www.swiper.com.cn/api/index.html

   data中:

swiperOption: {  //绿色果蔬的产品轮播   
        direction: "horizontal",
        observer:true,//修改swiper自己或子元素时,自动初始化swiper 
        observeParents:true,//修改swiper的父元素时,自动初始化swiper 
        autoplay: {
          delay: 1500,          
          stopOnLastSlide: false,          
          disableOnInteraction: false,          
        }, 
        loop: true,    
        loopedSlides: 0,      
        initialSlide: 0,
        slidesPerView: 2,
        spaceBetween: '3.33%',        
        speed: 800, 
},

 

监听:

computed: {
    swiper () {
      return this.$refs.mySwiper.swiper;
    }
},

 

6、植物的种植模型,当切到第二屏时调用该函数,每一个阶段显示一定时间切换,图片的淡入淡出用css3控制

  • 页面使用:
    <div class="growing">
       <div class="g-item" v-for="(item,index) in growingList" :key="index" :class="{active: currentIndex==index}">
         <div class="left-title">
              <div class="title-line"></div>
              <div class="flex">
                   <p class="step color-fff">{{item.id}}</p>
                   <div class="color-fff text">
                       <h3>{{item.period}}</h3>
                       <!-- <p>{{item.dataInfo}}</p> -->
                    </div>
               </div>
          </div>
          <img :src="item.imgSrc" alt="">
        </div>
    </div>   

     

  • js数组及函数

      data中:

growingList: [  //种植模型
  {id: '01', period: '缓苗期管理', dataInfo: '(定植后1周)', imgSrc: 'static/images/growing1.png'},
  {id: '02', period: '定植期管理', dataInfo: '(定植后2~4周)', imgSrc: 'static/images/growing2.png'},
  {id: '03', period: '开花坐果期管理', dataInfo: '(定植后5~8周)', imgSrc: 'static/images/growing3.png'},
  {id: '04', period: '果实膨大期和成熟期管理', dataInfo: '(定植后9~11周)', imgSrc: 'static/images/growing4.png'},
  {id: '05', period: '采收期管理', dataInfo: '(雌花开放后37~40天采收第一批瓜)', imgSrc: 'static/images/growing4.png'},
],

 

监听:

watch: {
    currentPage (newValue, oldValue) {
      console.log("currentPage: "+newValue, oldValue);
      if(newValue == 2){
        // 种植模型
        this.plantModelAnt()
        this.pageSwitch2()
      }else{
        // console.log(newValue, oldValue)
        this.pageSwitch1()
      }
    },
},

 

函数:

// 种植模型动画
plantModelAnt(){
  var that = this;
  setTimeout(() => {
    console.log("当前展示屏===" +that.currentPage)
    if(that.currentIndex < 4){
        that.currentIndex += 1
    }else{
        that.currentIndex = 0
    }
    console.log('currentIndex====' + that.currentIndex)
    that.plantModelAnt()
  },11000)    
  
},

 

7、大棚监控,使用的萤石云,在萤石的后台拿到对应的Rtmp流地址

  • 页面使用:
    <video id="myPlayer" playsInline webkit-playsinline autoplay>
         <source src="对应流地址" type="rtmp/flv" />
    </video>

     

  • 将EZuikit.js下载本地引入,修改下

import { EZuikit } from '../common/js/EZuikit.js'
mounted(){
    var player = new EZUIKit.EZUIPlayer('myPlayer');
}

 

如有不懂请咨询QQ:1294487763,非相关请勿扰,谢谢!
 

打个广告:

本人承接微信公众号/微信小程序/可视化大屏/企业官网/管理系统等项目,有需要Q我吧~ (#^.^#)

 

 

 

 

 

©️2022 CSDN 皮肤主题:技术黑板 设计师:CSDN官方博客 返回首页

打赏作者

刺鸟_前端

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值