0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

讲解一下通用可视化搭建平台整体的设计思路

OSC开源社区 来源:vivo互联网技术 作者:Wang Lei 2022-10-20 09:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

一、前言

一直以来,许多产品平台都在尝试通过可视化搭建的手段来降低 GUI 应用的研发门槛,提高生产效率。随着我们业务的发展,数据建设的完善,用户对于数据可视化的诉求也日益增多,而数据大屏是数据可视化的其中一种展示方式,它作为大数据展示媒介的一种,被广泛运用于各种会展、公司展厅、发布会等。

相比于传统手工定制的图表与数据仪表盘,通用大屏搭建平台的出现,可以解决定制开发, 数据分散带来的应用开发、数据维护成本高等问题,通过数据采集、清洗、分析到直观实时的数据可视化展现,能够多方位、多角度、全景展现各项指标,实时监控,动态一目了然。

本文将通过敏捷BI平台的通用大屏搭建能力的实现方案,来讲解一下通用可视化搭建平台整体的设计思路。

二、快速了解可视化大屏

2.1 什么是数据可视化

技术层面上来讲,最直观的就是前端可视化框架:Echart、Antv、Chart.js、D3.js、Vega 等,这些库都能帮我们快速把数据转换成各种形式的可视化图表。

12b9a87e-4fc4-11ed-a3b6-dac502259ad0.png


业务层面来讲, 其最主要的意义就在于通过数据 -> 图表组合 -> 可视化页面这一业务流程,来帮助用户更加直观整体的分析不同行业和场景的趋势和规律。

132cab44-4fc4-11ed-a3b6-dac502259ad0.png


所以在数据领域里,对于复杂难懂且体量庞大的数据而言,图表的信息量要大得多,这也是数据可视化最根本的目的。

2.2 可视化大屏都有哪些部分

主要由可视化组件+ 事件交互 + 坐标关系组成,效果如下图所示:

13451cb0-4fc4-11ed-a3b6-dac502259ad0.jpg

2.3 可视化大屏和常见的BI报表看板的区别

经常会有同学会问到,可视化大屏和BI报表看板的区别是什么?

这里简单的做一下介绍:

大屏和报表看板都只是BI的其中一种展现方式,大屏更多是通过不同尺寸的显示器硬件上进行投屏,而报表看板更多是在电脑端进行展示使用。

大屏更加注重数据动态变化 ,会有极强的视觉体验和冲击力,提供丰富的轮播动画、表格滚动等动画特效。而报表看板更注重交互式数据探索分析,例如上卷下钻、排序、过滤、图表切换、条件预警等。

三、设计思路

3.1 技术选型

前端框架:React全家桶(个人习惯)

可视化框架:EchartsDataV-React(封装度高,json结构的配置项易拓展)D3.js(可视化元素粒度小、定制能力强)

拖拽插件:dnd-kit(满足树状结构视图的跨组件拖拽)

布局插件:React-Grid-Layout(网格自由布局,修改源码,支持多个方向的拖拽,自由布局、锁定缩放比等)

3.2 架构设计

下图是我们搭建平台的整体架构设计:

139fb7b0-4fc4-11ed-a3b6-dac502259ad0.png

整个大屏搭建平台包含四个非常重要的子系统和模块:

可视化物料中心是整个平台最基础的模块,我们在开源的图表库和自主开发的可视化组件上面定义了一层标准的 DSL 协议,这个协议和接入 画布编辑器 的协议是对应的,目前已经有 40+ 相关组件,组件数量还在不断增长。

画布编辑器:是搭建平台的核心与难点,支持页面布局配置、页面交互配置和组件数据配置等功能,另外还支持代码片段的配置,也可以称得上是一个低代码平台。

数据中心:是提供专门用于连接不同数据源的服务,例如直连 MySQL、ClickHouse、Elasticsearch、Presto 等,提供了大屏搭建所需要的原始数据。

管理中心:是大屏的后台运营管理模块,包含了大屏模版管理、大屏发布下线、访问权限等管理功能。

3.3搭建流程

通过上面提到的大屏组成元素,我们可以分析总结出大屏搭建主流程如下图所示:

13f7234c-4fc4-11ed-a3b6-dac502259ad0.png

四、核心功能实现

接下来我们会逐一对平台几个核心功能实现进行解析:

1、大屏自适应布局

背景:解决页面错乱问题,实现多种分辨率的大屏适配:

思考:首先我们想到的是移动端适配主流的 vh、vw、rem组合的方式以及 font.js+rem 等两种方案。第一种方案主要是通过媒体查询来定义父级大小,然后对组件的height、margin、padding等多种css属性采用rem作为单位,继承父级设置等单位(1vw),实现自适应适配,第二种方案是引用第三方脚本,通过在main.js中写代码计算,使用rem进行继承,实现适配。

①vh、vw、rem组合

//vw vh单位 w3c的官方解释 vw:1% of viewport’s width vh:1% of viewport’s height
//例如,设计稿的宽度为1920px,则1vw=19.2px,为了方便计算,我们将html元素的font-size大小设置为100px,也就是5.208vw=100px。
body,html {
     font-size:5.208vw
}

②font.js + rem

//监听窗口的oversize事件,来动态计算根节点字体大小,再配合rem做适配
(function(doc, win) {
    const docEl = doc.documentElement
    const resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'
    const recalc = function() {
      let clientWidth = docEl.clientWidth
      if (!clientWidth) return
      docEl.style.fontSize = 100 * (clientWidth / 1920) + 'px'
    }
    if (!doc.addEventListener) return
    win.addEventListener(resizeEvt, recalc, false)
    doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window)

缺陷:当我们大屏里面使用到的第三方插件,它的样式使用的是px为单位时,例如 line-height 的设置为20px,此时就不能适应行高,就会出现重叠等错乱问题。或者我们利用 postcss-px2rem 插件进行全局替换,但是在使用过程中,需要注意对已经处理过适配的插件,例如 Ant Design,否则引入的antd 控件使用会出现样式错乱的问题

解决思路:采用了css3 的缩放 transform: scale(X,Y) 属性,主要是通过监听浏览器窗口的 onresize 事件,当窗口大小发生变化时,我们只需要根据大屏容器的实际宽高,去计算对应的放大缩小的比例,就可以实现布局的自适应了,我们也提供了不同的布局适应效果,例如等高缩放、等宽缩放、全屏铺满等,不同的缩放方式,决定了我们在计算宽高比例的优先级。因此我们后面在做画布的缩小功能,也可以直接使用这种方案来实现。

// 基于设置的设计稿尺寸 换算对应的宽高比
useEffect(() => {
    const wR = boxSize.width / viewWidth;
    const hR = boxSize.height / viewHeight;
 
    setBgScaleRatio(wR);
    setBgHeightScaleRatio(hR);
}, [boxSize, viewWidth, viewHeight]);
 
//根据等宽、等高、全屏等不同的缩放比例 计算scale值
const getScale = (proportion, x, y) => {
    if (proportion === 'radioWidth') {
        return `scaleX(${x})`
    }
    if (proportion === 'radioHeight') {
        return `scaleY(${y})`
    }
    return `scale(${x}, ${y})`
}

2、大屏组件通用开发流程设计

背景:随着可视化组件的增多、新增组件流程繁琐冗长,为了避免重复的造轮子以及后续引入第三方组件,需要制定一套通用的组件开发流程:

设计思路:组件 =component 组件主体 +schema 组件配置协议层 + 组件定义层(类型、从属关系、初始化宽高等)

① component 组件主体:

可视化框架选型:行业主流可视化库有 Echart、Antv、Chart.js、D3.js、Vega、DataV-React 基于可视化的通用性和定制性的需求,我们选择了 Echart、DataV-React 作为基础组件的开发框架,面对定制性要求更高的自定义组件,我们选择了可视化粒度更小的 D3.js。

封装通用 Echarts 组件(初始化、事件注册、实例注销等):

// initialization echarts
const renderNewEcharts = () => {
    // 1. new echarts instance
    const echartObj = updateEChartsOption();
    // 2. bind events
    bindEvents(echartObj, onEvents || {});
    // 3. on chart ready
    if (typeof onChartReady === 'function') onChartReady(echartObj);
    // 4. on resize
    echartObj.resize();
};
 
// bind the events
const bindEvents = (instance, events) => {
    const _bindEvent = (eventName, func) => {
       instance.on(eventName, (param) => {
           func(param, instance);
       });
    };
 
    // loop and bind
    for (const eventName in events) {
        if (Object.prototype.hasOwnProperty.call(events, eventName)) {
            _bindEvent(eventName, events[eventName]);
        }
    }
};
 
// dispose echarts and clear size-sensor
const dispose = () => {
    if ($chartEl.current) {
       clear($chartEl.current);
       // dispose echarts instance
       (echartsLib || echarts).dispose($chartEl.current);
    }
};

封装通用 DataV 组件(DataV-React、自定义等组件入口,统一负责配置、数据收集、监听resize)

const DataV: React.FC = (props) => {
    const { config } = props;
    const [renderCounter, setRenderCounter] = useState(0);
    const $dataVWarpEl = useRef(null);
    const $componentEl = useRef(null);
 
    useEffect(() => {
        // 绑定容器size监听
        const resizefunc = debounce(() => {
            $componentEl.resize();
        }, 500)
       // fixme
       addResizeListener($dataVWarpEl.current, resizefunc);
       return () => {
           // 清除订阅
           removeResizeListener($dataVWarpEl.current, resizefunc);
       };
    }, []);
 
    return (
        
            
        
    );
};

② schema 组件配置协议层 + 组件定义层(类型、从属关系、初始化宽高等)

我们自定义了一套 schema 组件的DSL,结构协议层。通过DSL约定了组件的配置协议,包括组件的可编辑属性、编辑类型、初始值等,之所以定义一致的协议层,主要是方便后期的组件扩展,配置后移。

140c22c4-4fc4-11ed-a3b6-dac502259ad0.png

JSON Schema设计:

{
    headerGroupName: '公共配置',                         //配置所属类型
    headerGroupKey: 'widget',                           //配置所属类型key值 相同的key值都归属一类
    name: '标题名称',                                    //属性名称
    valueType: ['string'],                              //属性值类型
    optionLabels: [],                                   //服务下拉列表、多选框等控件的标签名
    optionValues: [],                                   //服务下拉列表、多选框等控件的标签值
    tip: false,                                         //配置项的 Tooltip 注解
    ui: ['input'],                                      //使用的控件类型
    class: false,                                       //控件类名,定制控件样式
    css: { width: '50%'},                               //修改控件样式
    dependencies: ['widget,title.show,true'],           //属性之间的联动,规则['配置所属类型, 属性key, 属性值']
    depContext: DepCommonShowState,                     //属性之间的校验回调方法
    compShow: ['line'],                                 //哪些组件可配置
    dataV: { key: 'title.text', value: '' },            //配置的key值和默认value值
},

表单DSL设计:

143e6e78-4fc4-11ed-a3b6-dac502259ad0.png

收益:以上是我们定制的DSL结构协议层,用户只需要填写Excel表格,就可以实现动态表单的创建,实现组件配置项分类、配置复用、配置项之间联动、属性注释等功能。目前属性配置器已经支持了常用的15种的配置UI控件,通过定制的DSL结构协议层,可以快速完成组件的配置界面初始化,为后续规划的组件物料中心做准备。

3、拖拽器实现

背景:React-Grid-Layout 拖拽插件不支持自由布局和组件不同纬度拖拽:

解决方案:通过分析源码,对不同纬度的拖拽事件以及拖拽目标碰撞事件进行了重写,并且也拓展了锁定宽高比、旋转透明度等功能。

源码分析:

1475a596-4fc4-11ed-a3b6-dac502259ad0.png


resize伸缩特性增强(优化),拖拽的同时,除了修改容器宽高外,也动态调整了组件的坐标位置

// CSS Transforms support (default)
if (useCSSTransforms) {
    if (activeResize) {
        const { width, height, handle } = activeResize;
        const clonePos = { ...pos };
        if (["w", "nw", "sw"].includes(handle)) {
            clonePos.left -= clonePos.width - width;
        }
        if (["n", "nw", "ne"].includes(handle)) {
            clonePos.top -= clonePos.height - height;
        }
        style = setTransform(clonePos, this.props.angle);
    } else {
        style = setTransform(pos, this.props.angle);
    }
}

堆叠显示,自由布局(优化),通过控制布局是否压缩,动态调整拖拽目标的层级zIndex来实现多图层组件操作交互和自由定位。

// 每次拖拽时zIndex要在当前最大zIndex基础上 + 1,并返回给组件使用
const getAfterMaxZIndex = useCallback(i => {
    if (i === curDragItemI) {
        return;
    }
    setCurDragItemI(i);
    setMaxZIndex(maxZIndex => maxZIndex + 1);
    return maxZIndex;
}, []);

改造后效果展示

1494ae5a-4fc4-11ed-a3b6-dac502259ad0.jpg

4、大屏状态推送

背景:大屏的后期维护需要有版本发布自更新以及大屏下线等需求,这个时候就需要有一套消息通知机制,通过命令来控制大屏的运行状态。

解决方案:基于websocket通信机制,建立长链接,实现了心跳及重连机制,实时对上线发布后的大屏进行更新或下线管理。

14d84e6c-4fc4-11ed-a3b6-dac502259ad0.png

五、效果预览

14e86dce-4fc4-11ed-a3b6-dac502259ad0.gif

六、总结

本文通过可视化页面搭建、no/low code 平台、Schema 动态表单等技术思想来分析讲解了如何去设计开发一个通用的数据大屏搭建平台。

当前的设计方案基本满足了数据大屏的核心能力搭建需求。如果想实现更富有展现力,满足更多场景的大屏搭建平台,我们还需要进一步提高平台的扩展性和完善整体的物料生态,具体规划如下:

丰富和拓展大屏组件&配置能力,覆盖不同行业的可视化场景。

可视化物料平台的搭建,沉淀优秀的可视化组件、大屏模版素材。

3D以及动效渲染引擎开发实现。





审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • DSL
    DSL
    +关注

    关注

    2

    文章

    61

    浏览量

    39205
  • 数据转换
    +关注

    关注

    0

    文章

    105

    浏览量

    18586
  • MySQL
    +关注

    关注

    1

    文章

    939

    浏览量

    29855

原文标题:从0到1设计通用数据大屏搭建平台

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    基于 HT 的新能源电力可视化管控平台技术实现方案

    本文依托 HT for Web 纯前端可视化插件搭建新能源电力可视化管控平台,底层采用 WebGL+Canvas 实现高性能图形渲染,通过 WebSocket、HTTP 协议对接后端实
    的头像 发表于 05-14 11:20 283次阅读
    基于 HT 的新能源电力<b class='flag-5'>可视化</b>管控<b class='flag-5'>平台</b>技术实现方案

    实验室数据可视化监控管理平台方案

    报管理系统中,存在工作量大、效率低等问题,难以满足实验室精细化管理的需求。 对此,数之能提供工业数据可视化管理平台,能够接入各类PLC实现数据采集与存储,通过可视化数据大屏展示各个设备状态与工艺参数,并提供数据告警
    的头像 发表于 04-27 16:40 163次阅读
    实验室数据<b class='flag-5'>可视化</b>监控管理<b class='flag-5'>平台</b>方案

    3D系统可视化

    本身的深入描述和F-Theta透镜的应用示例。 光学系统的3D-可视化 VirtualLab Fusion提供的工具可以实现光学系统的3D可视化,因此可以用于检查元件的位置,以及快速了解系统内部的光
    发表于 03-30 09:25

    森林消防智慧预警技术实现:火灾监测 Web GIS 可视化平台搭建

    本文基于图扑软件(Hightopo)自研的 HT 前端插件,从技术实现与功能落地角度,解析森林消防火灾监测 Web GIS 可视化平台搭建逻辑、核心技术应用及功能模块实现流程,该平台
    的头像 发表于 03-19 11:31 273次阅读
    森林消防智慧预警技术实现:火灾监测 Web GIS <b class='flag-5'>可视化</b><b class='flag-5'>平台</b><b class='flag-5'>搭建</b>

    KubePi:开源Kubernetes可视化管理面板,让集群管理如此简单

    KubePi:开源Kubernetes可视化管理面板,让集群管理如此简单 在云原生时代,Kubernetes已成为容器编排的事实标准,但其复杂性却让许多开发者望而却步。KubePi作为款现代
    发表于 02-11 12:53

    物联网平台赋能可视化数据与决策,打造工厂“智慧大脑”

    ,无法形成全局视图,更难以支撑快速、精准的管理决策。 打造个集中、直观、智能的数据可视化平台,让关键信息目了然,让管理决策有数可依,成为企业运营管理的迫切需求。数之能物联网
    的头像 发表于 02-04 14:52 287次阅读

    高瓦纸生产数据可视化平台解决方案

    生产企业存在设备数据分散、生产过程不透明、故障响应不及时等问题,导致生产管理效率低下。为解决这些问题,提出以工业组态平台为核心,构建高瓦纸生产数据可视化平台,实现生产数据的集中监控、分析与可视
    的头像 发表于 12-12 15:42 337次阅读

    工业物联网可视化平台是什么?有什么功能?

    工业物联网可视化平台是基于物联网、大数据、人工智能等技术,将工业生产中的设备、系统、流程等数据以图形方式呈现,实现实时监控、智能分析与交互式管理的数字化工具。 其核心功能涵盖数据集成、可视化
    的头像 发表于 11-17 17:49 1556次阅读

    基于 HT 技术的园区元宇宙可视化管理平台

    设计、核心功能实现及技术亮点,展现如何通过HT技术实现园区“安环能”一体化管控。 HT 技术作为平台开发的核心支撑,其基于 HTML5 标准的特性,为园区可视化管理提供了轻量、高效、跨终端的解决方案。
    的头像 发表于 11-07 14:54 690次阅读
    基于 HT 技术的园区元宇宙<b class='flag-5'>可视化</b>管理<b class='flag-5'>平台</b>

    工业可视化平台是什么

    工业可视化平台种基于信息技术和可视化技术,将工业生产过程中的数据、信息、流程等以直观、动态的图形方式呈现,并实现交互式管理与分析的数字
    的头像 发表于 10-24 18:00 1324次阅读

    光伏电站可视化的实现

    实现光伏电站可视化,核心是在于通过直观的视觉界面,解决传统运维中低效巡检、数据孤岛、被动响应等痛点,从而提升运营效率并提供决策支持。这是种有效的技术手段,通过数字孪生、三维建模、数据融合等技术
    的头像 发表于 10-21 17:29 1438次阅读
    光伏电站<b class='flag-5'>可视化</b>的实现

    数字孪生可视化系统构建行业数字智能管理生态!

    数字孪生可视化系统具备丰富的模型组件,包括二维平面组件及3D模型组件,可根据用户需求进行定制。数字孪生可视化系统在行业数字升级、数字管理中有着重要的意义,充分利用大数据技术和信息技
    的头像 发表于 09-19 11:45 966次阅读
    数字孪生<b class='flag-5'>可视化</b>系统构建行业数字<b class='flag-5'>化</b>智能管理生态!

    基于 HT 搭建的农林牧数据可视化监控平台

    图扑 HT 的农林牧数据可视化监控平台,以自主研发的 2D&3D 图形渲染引擎、HT for Web GIS 产品及数据孪生应用开发平台为核心技术支撑,全程未依赖任何第三方插件,实现了从技术底层到
    的头像 发表于 08-29 14:51 776次阅读
    基于 HT <b class='flag-5'>搭建</b>的农林牧数据<b class='flag-5'>可视化</b>监控<b class='flag-5'>平台</b>

    如何使用协议分析仪进行数据分析与可视化

    使用协议分析仪进行数据分析与可视化,需结合数据捕获、协议解码、统计分析及可视化工具,将原始数据转化为可解读的图表和报告。以下是详细步骤及关键方法,涵盖从数据采集到可视化的全流程:、数
    发表于 07-16 14:16

    工业设备可视化管理系统是什么

    工业设备可视化管理系统是种基于物联网(IoT)、大数据、云计算、数字孪生等技术,对工业设备的运行状态、性能参数、维护信息等进行实时监测、数据整合与可视化呈现的智能管理平台。它通过将复
    的头像 发表于 05-27 14:56 1405次阅读
    工业设备<b class='flag-5'>可视化</b>管理系统是什么