logo资料库

可视化数据平台的前端实现.pdf

第1页 / 共4页
第2页 / 共4页
第3页 / 共4页
第4页 / 共4页
资料共4页,全文预览结束
可视化数据平台的前端实现 可视化数据平台的前端实现 前言前言 随着公司的发展和进步,数据大屏的业务日益增长,公司目前的做法大致可以分为两种 人肉 or 第三方工具平台 . 人肉人肉:很简单,一个前端配备,熟练的 html + css + js 技能就完事了 ; 优点:开发灵活多变 不足:效率低,页面复用度不高(几乎为0复用度),大量重复性工作,占用前端开发时间 等 当然,也有人会说,目前比较主流的前端框架,像 Vue ,React 都是组件化,模块儿化的工程,组件复用性很高,也对,这点毋庸置疑,但也改变不了大量重复性的工作和消耗前端资 源的劣势 ;甚至还有人会说,当组件封装的够多,质量够好,工程架构的得体,就可以解决上述的缺点,很对 !这就是我要分享给大家的《可视化数据平台》稍安勿躁 emmm ~ ~ 第三方工具 :如:阿里云的dataV , 百度的 Sugar 都是很优秀的工具平台 ; 第三方工具 优点:组件丰富,功能强大,基本满足大中小型企业对数据大屏的需求 不足:有没有不足请大家去体验一下 , 这里我就不做过多的评价 OKey,综上所述,随着公司业务的增多 ,市场未来对数据可视化的需求,为了降低开发成本,提高开发效率,降低开发难度,我们的 NTDVP《数据可视化平台》就这样诞生了,在 这里,我作为主要开发人员来给大家分享一下平台的具体实现 。 NTDVP – 简单认识一下吧 简单认识一下吧 NTDVP – 技术栈技术栈 Vue 2.6 + Webpack 3.6 + Node + eCharts + D3
这里简单讲一下 Node 在项目里的应用情况 1,通过 node 启动 dev-server.js 文件,然后运行如下代码(dev-server.js); webpack-dev-server 主要是启动了一个基于 express 的 Http 服务器 ;这个Http服务器和 client (客户机)使用了websocket通讯协议,原始文件作出改动后,webpack-dev-server会实时的 编译,实时编译后的文件都保存到了内存当中 ;所以我们可以看到实时更新 。重点:基于启动的http服务实时编译工程 2,就比较明了了,主要写一些接口,来实现平台目录和文件的保存,读取,复制,删除,修改等功能,后期有导入导出…目的是可以满足本地部署和云部署 // dev-server.js 文件 var webpack = require('webpack') var webpackDevServer = require('webpack-dev-server') var webpackDevconfig = require("./webpack.dev.conf.js"); var opn = require('opn') var port = process.env.PORT || config.dev.port // api var apiServer = { setup: (app) => { // 具体接口就不做展示了 } } webpackDevconfig.then(res => { var compiler = webpack(res); var server = new webpackDevServer(compiler, Object.assign(res.devServer, apiServer)); server.listen(port, "0.0.0.0", function (error) { console.log(error); }); opn("http://127.0.0.1:" + port) // 打开本地页面 }) NTDVP – 设计思路 设计思路 整个工程结构在这里不做分享,涉及到公司的产品代码,我简单说一下产品实现的思路和原理 ; 其实,以拖拉拽的方式做可视化页面的产品有很多,原理也大同小异,无非就是拥有一个舞台,一定数量的组件,然后组件通过配置二次加工后放进舞台的过程,最后集成的舞台就 是我们想要的成品 ; 首先分析一下舞台和组件的实现方式 舞台舞台 舞台很简单,就是一个容器 , 用来盛放拖拽出来的组件 , 当然这个舞台可能有 宽,高,背景等配置属性,适用于已知宽高的大屏 ;这其中也会有未知宽高的大屏,终端设备等,所以 采用了自适应模式 ;那么舞台如何渲染组件的呢 ? 这里使用到了 Vue.extends() 构造器 + document.createDocumentFragment() 1,对组件配置文件的信息读取通过 Vue.extends() 构造器来渲染组件 2,使用原生Api Document.createDocumentFragment 文档片段模拟虚拟dom做性能优化 # Vue-extends() 查看 //使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。 //data 选项是特例,需要注意 - 在 Vue.extend() 中它必须是函数 // 创建构造器 var Profile = Vue.extend({ template: ' {{firstName}} {{lastName}} aka {{alias}} ', data: function () { return { firstName: 'Walter', lastName: 'White', alias: 'Heisenberg' } } }) // 创建 Profile 实例,并挂载到一个元素上。 new Profile().$mount('#mount-point') //结果如下: Walter White aka Heisenberg # Document.createDocumentFragment() 查看 let fragment = document.createDocumentFragment(); //fragment 是一个指向空DocumentFragment对象的引用。 有兴趣的可以在控制台实践一下 DocumentFragments 是DOM节点。它们不是主DOM树的一部分。通常的用例是创建文档片段,将元素附加到文档片段,然后将文档片段附加到DOM树。在DOM树中,文档片段被 其所有的子元素所代替。 因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。 组件组件 组件就相对比较复杂一点,由于我们的工程使用的 Vue 技术栈, 所以这里使用的是字符串模板来动态的创建组件,如何创建呢 ? 每一个组件分别有三个文件(暂不考虑公共提取部 分) 1,组件配置文件 – 相当于组件的父文件,通过对配置属性的修改来渲染对应组件 2,组件文件 – 图表及组件,根据父文件的属性配置生成对应的组件 3,属性配置文件 – 属性样式配置文件,也就是编辑页面图的右侧属性栏 看到这里也许有的童鞋已经联想到如何让它们联合工作了,其实就是采用简单的发布订阅模式,不管是组件的拖动位置,大小变化还是右侧栏的属性值变化,都会触发当前选中组件 的更新,让我们进一步剖析一下 ; 组件配置文件 - 样例代码 => 返回一个模板和最新属性键值对 var handle = function (attr, info) { let attributes = { name: "BarAlien", infoId: info.id, zIndex: 1, top: 1, left: 10, width: 300, height: 200, title: "柱状图", remark: '', //图表简介
chartCustomStyle: false, //开启图表自定义背景和边框 chartBackgroundColor: '', //图表背景颜色 chartBorderRadius: false, //图表圆角 borderWidth: 10, //图表边框宽度 borderColor: '', //图表边框颜色 shadowWidth: 0, //图表阴影宽度 ...... // 更多省略 } // 合并属性 Object.assign(attributes, attr) // 获取 attr 属性并传入组件,组件通过props获取 let stringAttr = getStringTypeAttr(attributes); //字符串模板操作 let template = `` return { template, attributes } } export default handle; 组件 – 就简单了, 通过父文件传过来的参数, props 接收,渲染 属性配置文件 - 样例文件 这里的右侧属性栏,相对来讲比较麻烦,采用的是 Vue 的双向绑定原理 ; 样式则是通过配置的数组对象遍历生成对应的属性栏 ; 而属性栏风格很多,输入框,下拉框,单选,多选,开关,颜色,表格,自定义 等等分别是一个独立的组件 ,提供单独的事 件监听与广播 ; [{ label: "开启图表自定义配色", bind: "openCustomColor", tipLink: "/docs/Chart-Common#图表的自定义配色", tipText: "自定义配色说明", type: "switch" }, { type: "color", bind: "textColor", format: "rgb", label: "文字颜色", visiblity: "openCustomColor", placement: "right-top-right-bottom" }, { type: "number", bind: "shadowBlur", visiblity: "openCustomShadow", label: "阴影模糊大小", min: 0 },{ type: 'table', bind: "customColors", visiblity: "openCustomColor", label: "可增加多个配色项,依次对应各项颜色", addTipText: "新增配色项", controls: [{ type: "color", label: "颜色", bind: "color", defaultValue: "#23b7e5", tdStyle: { minWidth: 100 } }] }] NTDVP – 编辑(核心) 编辑(核心) 上图可以看出来,整个编辑页可以拆分为四部分 顶部 – 包含logo + 组件分类列表 + 舞台操作 左栏 – 当前舞台组件管理 ,目前有删除 ,后期考虑提供功能键对组件进行复制,层管理等 右栏 – 核心位置之一,操作选中组件的所有配置项和动态数据(api , sql , ws 等方式 )以及体验交互(联动和下钻), 支持自动刷新 等 舞台 – 中间的展示区,支持编辑布局,拖拽组件,整体拖动,实时刷新,局部刷新,所见即所得 NTDVP – 遇到的问题及解决方案 遇到的问题及解决方案
整个初级阶段,开发遇到的问题其实还是蛮多的,都在日常积累中一一击破,这里捡几个记忆深刻的分享一下吧 ; 1,如何解析字符串 { key:function () {} , key2:function () {} } 实现组件自有函数 解决:acorn.js , 尝试了多种方法,最终迫不得已使用了 acorn.js javascript 解析器 目标:解析如上字符串,获取对应的函数的实体,进行二次编辑,保存回原函数,这里小弟不才,没能想到其它更好的方式,如有哪位大佬知道,评论告知,非常感谢 ; //项目中解析代码 var ast = acorn.parse(res.data).body[0]; var nodeBinds = {}; for (let nb of ast.declarations[0].init.properties) { nodeBinds[nb.key.name] = res.data.substring(nb.value.body.start, nb.value.body.end); } //结果 nodeBinds[key] 就是上述字符串的第一个函数 key 2,舞台跟预览如何减少重排与重绘 , 如何提高渲染速度 , 如何确定页面后处理执行时间 解决: 通过文档片段Document.createDocumentFragment()模拟虚拟Dom来整合当前舞台所有组件渲染 ,整合期间记录通知数量,然后统计通知数量等于当前页面所有组件length,则认为整合完 毕,最后挂载Dom,执行后处理 。 3,发布订阅模式,修改右侧栏属性频率较高,组件渲染负担重 ,如何处理 起初呢,我也考虑过是否做成手动渲染,就是在所有配置参数被设置完后,点击按钮渲染组件,后来发现虽然渲染性能大大提升,但是看不到实时效果,因为大部分同事并不知道配 置项的具体页面效果,造成重复性的修改与点击渲染 ,而且页违背了我们想做一款实时图形化编辑的平台初衷 ;(放弃) 解决: ①,右侧栏的广播事件,发布通知均使用防抖函数,组件响应以最后一次为准,这个时间可配置,不同人体验不同 ②,组件渲染数据方面,采用必要条件同时满足策略,如:普通折线图,调试数据层,字段映射必须满足x轴,y轴,data数据,均有值方可渲染,否则不做渲染动作 ③,这里的组件与右侧栏属性是订阅模式,相互通知更新,渲染 ;并且组件与之对应的属性有唯一infiId,不会影响舞台上其它组件渲染与重绘 。 4,待整理 , NTDVP – 特色特色 近百种丰富组件,拖拽式图形化编辑,所见即所得 自定义组件满足私有定制化服务 响应式,自适应,支持移动端 多数据源支持 MySQL、SQL Server、Oracle 等数据源,本地 Excel 文件 或者 api 接口 ,ws 长连接 灵活部署和发布 支持云部署,私有化部署, 本地部署 当然了,NTDVP 目前处于初级阶段 ,零碎的功能点就不一一列出了,还有许多功能需要完善和添加 , 我们正在全力以赴 ,争取做出来一款市场认可的可视化产品 。 NTDVP – 后续计划 后续计划 丰富组件是必不可少的 添加快速构建模板 添加舞台组件复制,粘贴 权限管理,角色管理,想要做的太多,太多了,就不一一列举了,emmm~~ 总结总结 整个项目截至到现在,收货满满,不论是对技术的提升还是场景的应用,甚至到对一个Web项目的架构理念都有了新的认识和理解。在这里不做实质技术点的踩坑与分享,后续慢慢 记录。 结束语结束语 未来是数字化时代,可视化会越来越重要,相信在未来的场景中,必将占领一席之地 。 志同道合的朋友们,相信你们有更好的构建方案,分享出来的时候,希望我们可以再见面 ,谢谢阅读。 作者:Hi-Sen
分享到:
收藏