作者 | vivo 互联网大数据团队- Wang Lei
一、前言
不时以来,许多产品平台都在尝试经过可视化搭建的手腕来降落 GUI 运行的研发门槛,提高消费效率。随着咱们业务的开展,数据树立的完善,用户关于数据可视化的诉求也日益增多,而数据大屏是数据可视化的其中一种展现方式,它作为大数据展现媒介的一种,被宽泛运用于各种会展、公司展厅、颁布会等。
相比于传统手工定制的图表与数据仪表盘,通用大屏搭建平台的出现,可以处置定制开发, 数据扩散带来的运行开发、数据保养老本初等疑问,经过数据采集、荡涤、剖析到直观实时的数据可视化展现,能够多方位、多角度、全景展现各名目的,实时监控,灵活了如指掌。
本文将经过矫捷BI平台的通用大屏搭建才干的成功打算,来解说一下通用可视化搭建平台全体的设计思绪。
二、极速了解可视化大屏
2.1 什么是数据可视化
从技术层面过去讲,最直观的就是前端可视化框架:Echart、Antv、Chart.js、D3.js、Vega等,这些库都能帮咱们极速把数据转换成各种方式的可视化图表。
从业务层面来讲, 其最关键的意义就在于经过数据 -> 图表组合 -> 可视化页面这一业务流程,来协助用户愈加直观全体的剖析不同行业和场景的趋向和法令。
所以在数据畛域里,关于复杂难懂且体量宏大的数据而言,图表的信息量要大得多,这也是数据可视化最基本的目的。
2.2 可视化大屏都有哪些局部
关键由可视化组件+ 事情交互 + 坐标相关组成,成果如下图所示:
2.3 可视化大屏和经常出现的BI报表看板的区别
经常会有同窗会问到,可视化大屏和BI报表看板的区别是什么?
这里繁难的做一下引见:
三、设计思绪
3.1 技术选型
3.2 架构设计
下图是咱们搭建平台的全体架构设计:
整个大屏搭建平台蕴含四个十分关键的子系统和模块:
3.3搭建流程
经过下面提到的大屏组成元素,咱们可以剖析总结出大屏搭建干流程如下图所示:
四、**性能成功
接上去咱们会逐个对平台几个**性能成功启动解析:
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.documentElementconst resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize'const recalc = function() {let clientWidth = docEl.clientWidthif (!clientWidth) returndocEl.style.fontSize = 100 * (clientWidth / 1920) + 'px'}if (!doc.addEventListener) returnwin.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 组件主体:
// initialization echartsconst renderNewEcharts = ()// 1. new echarts instanceconst echartObj = updateEChartsOption();// 2. bind eventsbindEvents(echartObj, onEvents || {});// 3. on chart readyif (typeof onChartReady === 'function') onChartReady(echartObj);// 4. on resizeechartObj.resize();};// bind the eventsconst bindEvents = (instance, events) =>const _bindEvent = (eventName, func) =>(param) =>func(param, instance);});};// loop and bindfor (const eventName in events) {if (Object.prototype.hasOwnProperty.call(events, eventName)) {_bindEvent(eventName, events[eventName]);}}};// dispose echarts and clear size-sensorconst dispose = ()if ($chartEl.current) {clear($chartEl.current);// dispose echarts instance(echartsLib || echarts).dispose($chartEl.current);}};
const>② schema 组件性能协定层 + 组件定义层(类型、附属相关、初始化宽初等)咱们自定义了一套 schema 组件的DSL,结构协定层。经过DSL商定了组件的性能协定,包括组件的可编辑属性、编辑类型、初始值等,之所以定义分歧的协定层,关键是繁难前期的组件裁减,性能后移。
{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结构协定层,用户只有要填写Excel表格,就可以成功灵活表单的创立,成功组件性能项分类、性能复用、性能项之间联动、属性注释等性能。目前属性性能器曾经允许了罕用的15种的性能UI控件,经过定制的DSL结构协定层,可以极速成功组件的性能界面初始化,为后续规划的组件物料中心做预备。
3、拖拽器成功
背景:React-Grid-Layout 拖拽插件不允许自在规划和组件不同纬度拖拽:
处置打算:经过火析源码,对不同纬度的拖拽事情以及拖拽目的碰撞事情启动了重写,并且也拓展了锁定宽高比、旋转透明度等性能。
源码剖析:
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(iif (i === curDragItemI) {return;}setCurDragItemI(i);maxZIndex maxZIndex + 1);return maxZIndex;}, []);
变革后成果展现
4、大屏形态推送
背景:大屏的前期保养须要有版本颁布自降级以及大屏下线等需求,这个时刻就须要有一套信息通知机制,经过命令来控制大屏的运转形态。
处置打算:基于websocket通讯机制,树立长链接,成功了心跳及重连机制,实时对上线颁布后的大屏启动降级或下线治理。
五、成果预览
六、总结
本文经过可视化页面搭建、no/low code 平台、Schema 灵活表单等技术思想来剖析解说了如何去设计开发一个通用的数据大屏搭建平台。
的设计打算基本满足了数据大屏的**才干搭建需求。假构想成功更富裕展现力,满足更多场景的大屏搭建平台,咱们还须要进一步提高平台的裁减性和完善全体的物料生态,详细规划如下:
起源:
vivo互联网技术
数据可视化
大屏搭建
BI平台