当前位置: 首页 > news >正文

数据可视化看板:基于 Echarts + Python Flask 动态实时大屏

目录

  • 可视化管理看板作用
  • 一. 确定需求方案
    • 1 、屏幕分辨率
    • 2、 部署方式
  • 二. 整体架构设计
  • 三.编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码)
    • 1、前端html代码
    • 2、拖放之ondragover
    • 3、拖放之ondragstart
    • 4、拖放之ondrop
    • 5、前端JS - 数据定时更新控制
    • 6.后端 flask 服务器
  • 四. 启动命令
  • 五. 运行效果
  • 六. 源码下载

可视化管理看板作用

  • 1、形象直观,有利于提高效率
    岗位看板可视化使得部门之间、员工之间不必语言沟通,通过观察就可以了解运行流程和状况。而且由于看板可视化管理直观而简单,信息的传递速度大大加快,从而提高了生产效率。

  • 2、透明度高,便于配合和监督
    岗位看板可视化要求生产管理的公开化。在各个生产环节上,什么人干、干什么、怎么干、干多长时间等问题都被明确。这样一来,各个岗位的员工首先可以做好本职工作,其次可以默契配合、相互监督,促进生产效率的提高。

  • 3、传递现场的生产信息,统一思想
    生产现场人员众多,而且由于分工的不同导致信息传递不及时的现象时有发生。而实施看板管理后,任何人都可从看板中及时了解现场的生产信息,并从中掌握自己的作业任务,避免了信息传递中的遗漏。

  • 4、保证生产现场作业秩序,提升公司形象
    现场看板既可提示作业人员根据看板信息进行作业,对现场物料、产品进行科学、合理的处理,也可使生产现场作业有条不紊的进行,给参观公司现场的客户留下良好的印象,提升公司的形象。

一. 确定需求方案

1 、屏幕分辨率

这个案例的分辨率是16:9,最常用的的宽屏比。

根据电脑分辨率屏幕自适应显示,F11全屏查看;

2、 部署方式

B/S方式: 支持Windows、Linux、Mac等各种主流操作系统;支持主流浏览器Chrome,Microsoft Edge,360等;服务器采用python语言编写,配置好python环境即可。效果展示

在这里插入图片描述

二. 整体架构设计

  1. 前端Echarts开源库: 使用 WebStorm 编辑器;
  2. 后端 http服务器:基于 Python 实现,使用 Pycharm 或 VSCode 编辑器;
  3. 数据传输格式:JSON;
  4. 数据源类型:JSON文件。实际开发需求中,支持定制HTTP API接口方式或其它各种类型数据库,如PostgreSQL、MySQL、Oracle、Microsoft SQL Server、SQLite、Excel表格等。
  5. 数据更新方式: 采用http get 轮询方式 。在实际应用中,也可以视情况选择j监测后端数据实时更新,实时推送到前端的方式;

三.编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码)

1、前端html代码

使用bootstrap container-fluid, row, col等实现。

<div id="vue_app" class="container-fluid">
          <!-- 外框 在row这里设置样式-->
          <div class="row" style="height: 100%;">
               <!-- 左侧 -->
               <div class="col-3">
                    <!-- 左侧第1行 -->
                    <div class="row" id="layout_l1" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_l1" draggable="true" ondragstart="drag(event)">
                              <div class="col-6" id="container_l1_1"></div>
                              <div class="col-6" id="container_l1_2"></div>
                         </div>
                    </div>
                    <!-- 左侧第2行 -->
                    <div class="row" id="layout_l2" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_l2" draggable="true" ondragstart="drag(event)">
                         </div>
                    </div>
                    <!-- 左侧第3行 -->
                    <div class="row" id="layout_l3" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_l3" draggable="true" ondragstart="drag(event)">
                         </div>
                    </div>
               </div>
               <!-- 中间 -->
               <div class="col-6">
                    <div style="background-color:rgb(21,62,119);">
                         <!-- 中间第一行 -->
                         <div class="row" id="layout_m1" ondrop="drop(event)" ondragover="allowDrop(event)">
                              <div class="row" id="container_m1" draggable="true" ondragstart="drag(event)">
                              </div>
                         </div>
                         <!-- 中间第二行 -->
                         <div class="row" id="layout_m2" ondrop="drop(event)" ondragover="allowDrop(event)">
                              <div class="row" id="container_m2" draggable="true" ondragstart="drag(event)">
                                   <div class="col-3" id="container_m2_1"></div>
                                   <div class="col-3" id="container_m2_2"></div>
                                   <div class="col-3" id="container_m2_3"></div>
                                   <div class="col-3" id="container_m2_4"></div>
                              </div>
                         </div>
                         <!-- 中间第三行 -->
                         <div class="row" id="layout_m3" ondrop="drop(event)" ondragover="allowDrop(event)">
                              <div class="row" id="container_m3" draggable="true" ondragstart="drag(event)">
                                   <div class="col-4" id="container_m3_1"></div>
                                   <div class="col-4" id="container_m3_2"></div>
                                   <div class="col-4" id="container_m3_3"></div>
                              </div>
                         </div>
                    </div>
               </div>

               <!-- 右侧 -->
               <div class="col-3">
                    <!-- 右侧第一行 -->
                    <div class="row" id="layout_r1" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_r1" draggable="true" ondragstart="drag(event)">
                              <dv-scroll-board id="container_r1_1" :config="config" />
                         </div>
                    </div>
                    <!-- 右侧第二行 -->
                    <div class="row" id="layout_r2" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_r2" draggable="true" ondragstart="drag(event)">
                         </div>
                    </div>
                    <!-- 右侧第三行 -->
                    <div class="row" id="layout_r3" ondrop="drop(event)" ondragover="allowDrop(event)">
                         <div class="row" id="container_r3" draggable="true" ondragstart="drag(event)">
                         </div>
                    </div>
               </div>
          </div>
     </div>

2、拖放之ondragover

// 释放目标时触发的事件:
// ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
function allowDrop(ev) {
  // 判断目标元素是否允许放入被拖动元素
  if (ev.target.ondrop) {
    ev.preventDefault();
  }
}

3、拖放之ondragstart

// 在拖动目标上触发事件(源元素);
// ondragstart 用户开始拖动元素时触发;
function drag(ev) {
  ev.dataTransfer.setData("Text", ev.target.id);
}

4、拖放之ondrop

// 释放目标时触发的事件:
// ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
function drop(ev) {
  ev.preventDefault();

  var target = ev.target;
  var target_child = target.firstChild;

  var data = ev.dataTransfer.getData("Text");
  var node = document.getElementById(data);
  var src_parent = node.parentNode;

  // 交换子节点
  target.appendChild(node);
  src_parent.appendChild(target_child);
  echart_resize(target_child.id);
  echart_resize(node.id);

  save_layout(gen_layout());
}

5、前端JS - 数据定时更新控制

支持在每个echarts图表中独立控制定时更新的间隔。

 // 定时1s执行数据更新函数
  setInterval(function () {
    async_echart_bar_horizontal(
      container,
      path_bar_horizontal + "bar_horizontal.json"
    );
  }, 1000);

6.后端 flask 服务器

from flask import Flask
app = Flask(__name__, static_folder="static", template_folder="template")


# 主程序在这里
if __name__ == "__main__":

    # 开启线程,触发动态数据
    a = threading.Thread(target=asyncJson.loop)
    a.start()

    # 开启 flask 服务
    app.run(host='0.0.0.0', port=88, debug=True)

四. 启动命令

<!-- 启动server命令 -->
python main.py 

<!-- 浏览器中输入网址查看大屏(端口为 main.py 中的 port 参数定义) -->
http://localhost:88/static/index.html

<!-- 更多资料参考我的博客主页  -->
https://yydatav.blog.csdn.net/

<!-- 更多案例参考 -->
https://blog.csdn.net/lildkdkdkjf/article/details/120705616

五. 运行效果

六. 源码下载

技术交流、核心代码都搞定。目前群友已超过3000人,技术交流,添加时最好的备注方式为:来源+目的(加群或者代码)

方式①、添加微信号:dkl88191,备注:来自CSDN+大屏
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:大屏

相关文章:

  • 5道真题训练|学会了二叉树的前世今生
  • python专区--时间模块
  • 36、Java 中的 String、StringBuilder、StringBuffer、字符串常量池和 intern 方法
  • 基于正交设计的折射反向学习樽海鞘群算法
  • 国庆假期浏览了几十篇YOLO改进英文期刊,总结改进创新的一些相同点(期刊创新点持续更新)
  • 《计算机视觉基础知识蓝皮书》第5篇 目标检测基础
  • 提升能力和认知边界,最有效的方法是赚钱
  • Window下使用RegisterWindowMessage来实现消息通讯
  • Java 数组、排序和查找(1)
  • 你还没用过Mybatis-Plus?丝般顺滑,快速上手!
  • css3d动画:平移、旋转、缩放
  • 【英语:基础进阶_正式场景表达】F1.五步法搞定英文面试
  • SplitFS(SOSP‘19)
  • 【数据结构与算法】第十一篇:优先级队列
  • 【LeetCode】替换空格消失的数字分割链表除自身以外数组的乘积
  • 【译】React性能工程(下) -- 深入研究React性能调试
  • 345-反转字符串中的元音字母
  • Android系统模拟器绘制实现概述
  • Computed property XXX was assigned to but it has no setter
  • ECS应用管理最佳实践
  • STAR法则
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 近期前端发展计划
  • 理解IaaS, PaaS, SaaS等云模型 (Cloud Models)
  • 每天一个设计模式之命令模式
  • 前端性能优化--懒加载和预加载
  • 区块链技术特点之去中心化特性
  • 软件开发学习的5大技巧,你知道吗?
  • 通过npm或yarn自动生成vue组件
  • 运行时添加log4j2的appender
  • 在Docker Swarm上部署Apache Storm:第1部分
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • ​渐进式Web应用PWA的未来
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $(selector).each()和$.each()的区别
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (Git) gitignore基础使用
  • (Matalb回归预测)PSO-BP粒子群算法优化BP神经网络的多维回归预测
  • (python)数据结构---字典
  • (二)PySpark3:SparkSQL编程
  • (原創) 如何優化ThinkPad X61開機速度? (NB) (ThinkPad) (X61) (OS) (Windows)
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)socket Aio demo
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .net core 依赖注入的基本用发
  • .Net FrameWork总结
  • .Net 应用中使用dot trace进行性能诊断
  • .NET/C# 推荐一个我设计的缓存类型(适合缓存反射等耗性能的操作,附用法)
  • .net6解除文件上传限制。Multipart body length limit 16384 exceeded
  • .NET面试题(二)
  • .set 数据导入matlab,设置变量导入选项 - MATLAB setvaropts - MathWorks 中国
  • []sim300 GPRS数据收发程序