用three.js+echarts给公司写了一个站点数据大屏系统经验总结

news2024/12/28 21:21:05

时间过的好快,参加公司的新项目研发快一年了,五一机器人项目首秀,我们遇到了高并发集中下单情景,然后海量数据处理场景来了,给我在后端领域的高并发实践业务上画上了漂亮的一笔经验。人都是在磨练中成长,我很感谢这次给我的机会,虽然有点累,但也有点小成就。正好现在有空,我先聊聊首秀后给领导们做的大屏数据展示吧,领导等着看漂亮数据呢!

大屏重点是贼啦炫酷的动态特效加持

业务核心运营场景:各大地上地下停车场

这里我用的是three.js去实现的实际业务场景的场站模拟三维图,废话不多说,直接上图吧!先说一下,这里截图是看起来像2维,但实际是3维的,可以滑动翻转地图的。

截屏2024-05-07 18.35.07.png

如图所示,这是p4停车场的全景图,整个停车场的鸟瞰图一览无余,可以滚动鼠标放大看====》

这是我用three.js渲染的每个停车位的车位标记,这里记录了这个车场的每个车位的坐标点,方便后期,观察我们投放的100台机器人智能驾驶实时模拟。听起来是不是很牛逼plus?我告诉你,事情没那么简单!由于数据太多,既要有3D-map,也要有实时动态数据滚动展示和各种echarts图表,比如:

4A71FC88-CCB1-4DD4-82B9-612DE98328B8.png
ps:不好意思,本人还要严格遵守劳动合同执行公司数据保密,相关数据已经打码。

然后一堆实时数据数据和图上来后,不出意外的意外来了,性能出现了问题,我遇到了内存泄漏的情况。这还怎么继续二期的机器人动态运行场景研发呢?别慌,一步一步排查代码。

1.先介绍下大屏顶部的总数统计动态数字翻牌器

这里我用了第三方插件:动态数字翻牌器vue-count-to,只要有数据变化,就会实时看到动态增长的效果

首先要在框架中安装npm install vue-count-to,并在项目入口文件中引入

import CountTo from 'vue-count-to';
Vue.use(CountTo)
new Vue({
   
  el: '#app',
  router,
  store,
  render: h => h(App)
})

实际业务开发模块中代码:

                <count-to
                    class="count-to"
                    :startVal="0" //开始数值
                    :endVal="687573.74" //结束数值
                    :duration="500000" //动态变化的时间设定
                    :decimals="1"  //每次动态增长的数量
                ></count-to>

2.然后在大屏的左侧,我写了一个实时从下到上无限滚动的动态订单列表,可以让领导看到最新的订单情况。


<template>
    <div class="scrolling-list" :style="{ transform: `translate(0px,-${scrollTop}px)` }">
      <ul ref="scrollItemBox">
        <li v-for="(item, index) in items" :key="index" class="item-li">
            <div><span class="name">订单编号:</span><span class="content"><i class="el-icon-receiving">  {
   {
    item.order_id }}</i></span></div>
            <div><span class="name">订单金额:</span><span class="content"><i class="el-icon-s-finance" style="color:#1989fa" >  {
   {
    item.pre_total_amount }}</i></span><span class="name">手机号:</span><span class="content"><i class="el-icon-mobile-phone" style="color:#1989fa">  {
   {
    item.phone }}</i></span></div>
            <div><span class="name">车牌号:</span><span class="content"> <i class="el-icon-truck" style="color:#1989fa">  {
   {
    item.vehicle_no }}</i></span><span class="name">车位号:</span><span class="content"><i class="el-icon-map-location" style="color:#1989fa">  {
   {
    item.target_slot_no }}</i></span></div>
            <div><span class="name">订单来源:</span><span class="content">{
   {
    item.order_from == 1 ? '小程序' : 'APP' }}</span><span class="name">下单时间:</span><span class="content"><i class="el-icon-time">  {
   {
    item.created_at }}</i></span></div>
        </li>
      </ul>
      <div v-html="copyHtml"></div>
    </div>
</template>
<script>
  
  export default {
   
    
  data() {
   
      return {
   
        name: "InfiniteScroll",
        scrollTop: 0, //列表滚动高度
        speed: 15, //滚动的速度
        copyHtml: '',
        items:[],
        intervalId: null
      };
    },
  mounted() {
   
    this.initScroll()
  },
  beforeDestroy() {
   
    // 清除定时任务
      clearInterval(this.intervalId);
    },
  methods: {
   
     initScroll() {
   
            this.$nextTick(() => {
   
                this.copyHtml = this.$refs.scrollItemBox.innerHTML
                this.startScroll()
            })
      },
      // 开始滚动
      startScroll() {
   
          setInterval(this.scroll, this.speed);
      },
      // 滚动处理方法
      scroll() {
   
            this.scrollTop++
            // 获取需要滚动的盒子的高度
            let scrollItemBox = this.$refs.scrollItemBox?.offsetHeight || 1000
            // 当判断滚动的高度大于等于盒子高度时,从头开始滚动
            if (this.scrollTop >= scrollItemBox) {
   
                this.scrollTop = 0
            }
      }
    }
  };
  </script>

3.然后在大屏的右侧,用echarts写了两个饼图和折线图表,可以直观的的看到数据统计


export const timeStaticsOption = (xData,tipsArr) => {
   
  return {
   
    title: {
   
      text: '',
      subtext:'当天时间段充电订单数',
      subtextStyle:{
   
        color:'#fff',
      }
    },
    tooltip: {
   
      trigger: 'axis',
      axisPointer: {
   
        type: 'cross'
      }
    },
    xAxis: {
   
      type: 'category',
      data: xData,
      boundaryGap: false,
      axisLine: {
   
        show: false,
        lineStyle: {
   
          color: '#73B131',
          type: 'dashed'
        }
      },
    },
    yAxis: {
   
      type: 'value',
      axisPointer: {
   
        snap: true
      }
    },
    series: [
      {
   
        name: '时间段充电订单数',
        type: 'line',
        smooth: true,
        data: tipsArr,
      }
    ]
  }
}
export const botDataPieEcharts = (total,a,b)=>{
   
  console.log(total,a,b)
  return {
   
    title: {
   
      text: '',
      subtext: "Bot总数:"+ total+ '台',
      left: 'center',
      subtextStyle:{
   
        color:'#fff',
      }
    },
    tooltip: {
   
      trigger: 'item'
    },
    // legend: {
   
    //   orient: 'vertical',
    //   left: 'left'
    // },
    series: [
      {
   
        name: 'Bot数量',
        type: 'pie',
        radius: '50%',
        data: [
          {
    value: a, name: '在线:'+ a +'台' },
          {
    value: b, name: '空闲:'+ b +'台'},
        ],
        emphasis: {
   
          itemStyle: {
   
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  }
}

4.最后也是最耗性能的部分,用three.js写的停车场模拟实景鸟瞰图,3d-map

这里我直接把相关的方法和类,全部封装好,单独引入文件,用到以下文件,

import '../public/threejs/controls/OrbitControls.js'; 
import '../public/threejs/lines/LineSegmentsGeometry.js';
import '../public/threejs/lines/LineGeometry.js';
import '../public/threejs/lines/LineMaterial.js';
import '../public/threejs/lines/LineSegments2.js';
import '../public/threejs/lines/Line2.js';

在业务中相关代码写好工具方法,

import myWorker from './map.worker';
import FONT_JSON_DATA from './helvetiker_bold.typeface.json';
class basicThree {
   
    constructor(props) {
   
        this.from = props.from
        this.callbackSlotNo = props.callback
        console.log(props, 'props')
        this.LineGeometry
        // three 3要素
        this.renderer; //渲染器
        this.camera; //摄像头
        this.scene; //场景
        //光源
        this.ambientLight; //环境光
        this.pointLight; //平行光
        this.DirectionalLight
        //触屏开始时间
        this.touchTime = 0
        //摄像头控制
        this.controls;
        this.init()
        this.onmousedbclick = this.onMouseDblclick.bind(this);
        this.selectObject
        this.rawOption
        this.materialLine = Object()
        this.box = document.createElement("div")

        this.donX
        this.donY
        this.dataNumber
        this.originX; // 偏移量x坐标
        this.originZ; // 偏移量z坐标
        this.thinLine;
        this.wideLine;

        // 定义模型组
        this.initModalGroup();

        this.mapParams;

        this.drawModalFunc = {
   
            '0': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 0
            },
            '1': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 0
            },
            '2': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 2
            },
            '3': {
   
                'func': this.initNoAndArea.bind(this),
                'group': null,
                'z': 3
            },
            '4': {
   
                'func': this.basicWall.bind(this),
                'group': 'barrier_group',
                'z': 3
            },
            '5': {
   
                'func': this.initSlotLine.bind(this),
                'group': 'initSlotLine_group',
                'z': 3
            },
            '6': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 3
            },
            '7': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 3
            },
            '8': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 3
            },
            '9': {
   
                'func': this.initSlotLine.bind(this),
                'group': 'initSlotLine_group',
                'z': 3
            },
            '10': {
   
                'func': this.initSlotLine.bind(this),
                'group': 'initSlotLine_group',
                'z': 3
            },
            '11': {
   
                'func': this.RoadLineSigns.bind(this),
                'group': 'RoadLineSigns_group',
                'z': 3
            },
            '13': {
   
                'func': this.initSlotLine.bind(this),
                'group': 'initSlotLine_group',
        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1697952.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker 上面安装 Nginx 以及设置访问 IP 就可以访问前端工程

docker 运行 Nginx 第一步&#xff1a;搜索下镜像 首先可以使用 docker search nginx 搜索 nginx 服务 docker search nginx相关控制台输出&#xff1a; NAME DESCRIPTION STARS OFFICIAL…

电子商务网站(网上商店PetShop)

PetShop是一个范例&#xff0c;微软用它来展示.Net企业系统开发的能力。PetShop随着版本的不断更新&#xff0c;至现在基于.Net2.0的PetShop 4.0为止&#xff0c;整个设计逐渐变得成熟而优雅&#xff0c;有很多可以借鉴之处。PetShop是一个小型的项目&#xff0c;系统架构与代码…

统计信号处理基础 习题解答10-2

题目 两个随机变量x和y&#xff0c;如果联合PDF分解为&#xff1a; 那么称他们为条件独立的。在上式中z是条件随机变量。 我们观察 其中, , 是相互独立的。证明和是条件独立的。给出条件变量是A。和是无条件独立么&#xff1f;也就是 成立么&#xff1f;为了回答这个问题&…

flutter项目运行报错Exception: Gradle task assembleDebug failed with exit code 1各种报错合集

1.报错 Launching lib/main.dart on sdk gphone64 arm64 in debug mode... Running Gradle task assembleDebug... Exception in thread "main" java.net.ConnectException: Operation timed out at java.base/sun.nio.ch.Net.connect0(Native Method) at j…

【模版方法设计模式】

文章目录 模板方法设计模式模板方法的设计原则模板方法设计模式组成部分代码实现抽象类实现具体实现类执行 模板方法设计模式 模版方法设计模式&#xff08;Template Method Pattern&#xff09;是一种行为设计模式&#xff0c;它定义了一个操作中的算法骨架&#xff0c;而将一…

欢乐钓鱼大师游戏攻略:自动钓鱼技巧!

《欢乐钓鱼大师》是一款极具趣味性和挑战性的钓鱼模拟游戏&#xff0c;为玩家提供了一个体验钓鱼乐趣的虚拟世界。从湖泊到河流&#xff0c;再到广袤的海洋&#xff0c;游戏中的各种钓场让人流连忘返。无论是新手钓友&#xff0c;还是经验丰富的老钓手&#xff0c;都可以在游戏…

VMware虚拟机安装Windows server 2022超详细教程

文章目录 ISO下载安装步骤总结 ISO下载 链接&#xff1a;https://pan.baidu.com/s/19Z2q9KFKZq0pLisPZLn7_g 提取码&#xff1a;3pgn 安装步骤 安装完打开虚拟机后发现引导程序无法正常执行 解决方法见我的上一篇文章&#xff1a;http://t.csdnimg.cn/PzfOz 问题解决完后正常…

Dbs封装_连接池

1.Dbs封装 每一个数据库都对应着一个dao 每个dao势必存在公共部分 我们需要将公共部分抽取出来 封装成一个工具类 保留个性化代码即可 我们的工具类一般命名为xxxs 比如Strings 就是字符串相关的工具类 而工具类 我们将其放置于util包中我们以是否有<T>区分泛型方法和非泛…

如何恢复未保存或丢失的Word文档?

许多用户会遇到Word文档未保存而关闭的问题。实际上&#xff0c;您不会立即丢失未保存的文档数据。请不要对文档进行进一步的更改&#xff0c;例如修改并再次保存。您仍然有机会恢复未保存的Word文档。有一些方法可以帮助您恢复未保存的 Word 文档。 如果您不幸遇到这样的问题…

C#基础语言

​​​​ 目录 一个c# 程序主要包括以下部分&#xff1a;​​​​​​​ 标识符 C# 关键字 C# 数据类型 值类型&#xff08;Value types&#xff09; 引用类型&#xff08;Reference types&#xff09; 对象&#xff08;Object&#xff09;类型 动态&#xff08;Dynam…

手撕C语言题典——消失的数字

目录 前言 一&#xff0c;思路 1)排序查找 2&#xff09;数据求和&#xff0c;依次减去中值 3&#xff09; 异或 二&#xff0c;异或的代码实现 前言 依旧是一道力扣上的题&#xff0c;通过不同思路的不同时间复杂度来分析&#xff0c;让我们看看有什么不同。 面试题 17…

云动态摘要 2024-05-26

给您带来云厂商的最新动态&#xff0c;最新产品资讯和最新优惠更新。 最新优惠与活动 [免费试用]大模型知识引擎体验招募 腾讯云 2024-05-21 大模型知识引擎产品全新上线&#xff0c;为回馈新老客户&#xff0c;50万token免费送&#xff0c;开通服务即领取&#xff01; 云服…

1.6 什么是程序-编译与调试

目录 1 程序的作用 2 新建项目及编译运行 2.1 新建项目 2.2 HelloWorld 程序说明 2.3 printf 打印输出 2.4 注释 3 程序的编译过程及项目位置 4 断点及调试窗口设置 5 学习C语言后的境界 1 程序的作用 如下图所示&#xff0c;我们编写了一个可以做加法的程序&#xf…

行业分析---造车新势力之蔚来汽车

1 前言 在之前的博客中&#xff0c;笔者分析了苹果《行业分析---我眼中的Apple Inc.》&#xff0c;苹果已经成为世界级的公司。随后也分析了电动汽车公司特斯拉《行业分析---马斯克的Tesla》&#xff0c;特斯拉也在不断成长。目前能分析的新能源汽车公司不多&#xff0c;小米汽…

C++笔记:Hash Function 散列函数

1. Hash Function 散列函数 简单的Hash实现&#xff1a; class CustomerHash { public:size_t operator()(const Customer& c) const {return hash<std::string>()(c.fname) // first namehash<std::string>()(c.lname) // last namehash<long>()(…

Topk问题以及二叉树的三种层序遍历和基本操作

一、Topk问题 1、问题描述 TOP-K问题&#xff1a;即求数据结合中前K个最大的元素或者最小的元素&#xff0c;一般情况下数据量都比较大。 比如&#xff1a;专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。 2、思路 对于Top-K问题&#xff0c;能想到的最简单直接的…

C++数据结构——哈希桶HashBucket

目录 一、前言 1.1 闭散列 1.2 开散列 1.3 string 与 非 string 二、哈希桶的构成 2.1 哈希桶的节点 2.2 哈希桶类 三、 Insert 函数 3.1 无需扩容时 3.2 扩容 复用 Insert&#xff1a; 逐个插入&#xff1a; 优缺点比对&#xff1a; 第一种写法优点 第一种写法…

0成本的副业兼职,虚拟资源项目,1单利润49,操作简单变现快

最新刷某音时&#xff0c;我意外地发现了一位同行&#xff0c;他正在出售一份某音运营和直播的资料。然而&#xff0c;他销售这份资料的方式非常独特。他将这些所谓的某音运营资料全部打印出来。 周周近财&#xff1a;让网络小白少花冤枉钱&#xff0c;赚取第一桶金 每个视频的…

GESP等级大纲

CCF编程能力等级认证概述 CCF编程能力等级认证&#xff08;GESP&#xff09;为青少年计算机和编程学习者提供学业能力验证的规则和平台。GESP覆盖中小学阶段&#xff0c;符合年龄条件的青少年均可参加认证。C & Python编程测试划分为一至八级&#xff0c;通过设定不同等级…