ThingJS 开发使用感悟
ThingJS 开发使用感悟
前言
- 近日,笔者所在公司购买了一个付费 JS 三维可视化框架开发平台——thingjs, 打算基于 thingjs 制作一个数字乡村可视化平台,笔者大概花了 3 个月的时间了解学习 thingjs 并初步制作了一版符合 UI 设计稿及交互的前端项目。初步完成后感触良多,这里写下一些个人感悟点用于有相关业务的开发人员避坑。
什么是 ThingJS
ThingJS 隶属于北京优锘科技有限公司,是优锘科技旗下物联网三维可视化开发平台。ThingJS采用JavaScript开发语言,主要面向前端程序员和实施人员。ThingJS平台让传统企业无需组建3D可视化开发团队,也能开发3D可视化应用。
- 以上解释来自百度百科,我相信应该是由其官方人员编写的。简单的说,ThingJS 是由国人开发的(北京优锘),需要付费使用的,基于
ThreeJS
封装的一个 3d 可视化开发平台。
为何要使用一个付费产品, 不采用开源解决方案?
- 因为传统上,如果我们需要开发图表类的应用,比如说常见的大屏应用,我们可以使用百度的
echarts
, 阿里的AntV
,开源大热的D3JS
,但是这些框架本质上说都是 2d 的图表展示效果,当然,它们也提供了一些三维图表,但是总体上说,echarts
等平台提供的三维图表不满足很多复杂的带有一些特定交互场景的业务,所以在 web 开发方面,尤其是当下智慧城市
方向特别火热时,我们有必要寻求一款可以在 web 端进行较复杂 3d 可视化场景开发的平台。那么在这一方向,目前的技术/框架有:WebGL, ThreeJS. 那它们的关系如何呢:
WebGL可以处理3D图像,听起来是非常高兴的一件事,但是WebGL实在是太底层了,WebGl解决是如何再画布上画图的问题,怎么画点,线,面,怎么上色,怎么贴图,怎么处理光线,视角转动之后怎么换算绘制等等。这些对于一个做3D应用的开发者来说要学的东西太多了。
Threejs库的出现解决了底层的渲染细节和复杂的数据结构,终于将复杂的底层细节抽象出来,使得大家开发3d应用更容易了一些。和很多开发者交流threejs都是他们首次接触的WebGL 3D库,并能很容易的就能开始做一些实验。
但是使用Threejs开发应用还是门槛很高,单就一个加载模型,调光,选择模型弹框的功能,就能干出Threejs上百行代码。同时还有很多复杂的3D概念需要理解。这时就需要ThingJS了。
- 来自来自 ThingJS 团队的文章。
简单的说,WebGL 是需要从零开发 3d 场景的基础知识,而 ThreeJS 封装了 WebGL 的很多底层细节,用 ThreeJS 来做 3d 开发更简便,而 ThingJS 在 ThreeJS 的基础上又做了一层封装,进一步简化非专业人员开发 3d 场景的门槛。
如何使用 ThingJS
笔者以公司目前需要开发的一个业务场景为例:笔者所在公司需要开发一个 3d 可视化的智慧乡村场景,在这个 3d 场景上加上一些 echarts 大屏的图表,同时还会有一些交互。大致场景如下:
该项目的地图背景是一个倾斜摄影模型,当然倾斜摄影模型只是一部分,在其外围是一个普通的,由 ThingJS 官方提供的一个三维底图。我们需要在这个模型基础上加入一些图表的展示,同时在此模型上加入大量的地图点位,每个地图点位都是一个摄像头,可以通过点击地图点位播放实时监控视频。
开发流程
- 首先便是购买 ThingJS 付费服务
来自 thingjs 官网,可以说是价格不菲了,入手需谨慎。
其次,导入倾斜摄影模型,倾斜摄影模型的源数据来自无人机航拍。这里也是 ThingJS 提供的付费服务,我们只需付钱,将源数据交给官方人员,平台帮我们生成倾斜摄影模型。
到此开始正式开发,我们的思路是将项目分成两部分,即
地图模型端
和图表端
。地图模型端主要负责处理地图模型的一些交互,如切换地图底图;从后端获取地图点位数据并渲染到地图上;点击地图点位显示点位信息,并支持视频播放。最终项目在运行时,地图模型端是以一个 iframe 的形式嵌入到图表端的。这里有一点值得注意的是如果要实现最终的效果,不把项目分成两部分也是可以的,即把 echarts 图表部分也写在地图模型端,这样做的好处时之后不需要考虑 iframe 交互的问题。官方也提供了一个类似的例子。于是第一个坑点出现了,thingjs 是不支持目前主流的 JS 模块化方案的(ESM,UMD, CMD……),引入模块化文件需要靠官方提供的一个 api
- 首先便是购买 ThingJS 付费服务
const loadViedeJs = async () => {return new Promise(resolve => {THING.Utils.dynamicLoad(["https://www.thingjs.com/uploads/wechat/xxxx/static/video-js.min.css","https://www.thingjs.com/uploads/wechat/xxxx/static/video.min.js"],function (result) {resolve(true)},true, // 选填 是否带时间戳true, // 选填 是否按顺序下载false //选填 文件是否包含加密文件)})
}
类似如上的写法,而如果要实现一个较为庞大复杂的业务场景时,就不太方便了,所以项目一开始便是分为地图模型端
和图表端
两部分的。
开发流程
在开发流程上笔者先开发了项目的图表端的主要内容,之后再开发地图端部分。因为相比之下图表端的部分以 echarts
和传统 html 网页为主,开发起来较为简单。先易后难的开发流程较好。
- 图表端
- 静态文件的编写
这里笔者新建了一个本地代码备份调试仓库,将所有静态代码现在本地用最基本的 html 文件实现出来。下面以设计稿中的乡村文明-农村基层党建为例
要开发这个小模块,还需要将其细分为两部分,即 echarts 图表和普通 html 部分。新建一个 html 静态文件编写开发内容:
- 静态文件的编写
<!DOCTYPE html>
<html><head><title>HTML</title>
</head><body><div style="display: inline-block"><div style="padding: 2px 0 4px 29px;background: url(./assets/images/common/title-bg.png) no-repeat;font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;">农村基层党建</div><div style="margin-top: 4px;padding: 35px 20px;padding-top: 0;background: url(./assets/images/common/data-bg.png) no-repeat;background-size: cover;overflow: hidden;"><div style="margin: 21px auto;width: 130px;text-align: center;background: url(./assets/images/common/blue.png) no-repeat;background-size: cover;"><div style="font-family: DINAlternate-Bold;font-size: 32px;color: #409aff;text-shadow: 0 0 20px #19acb5;">500</div><div style="margin-top: 34px;font-family: PingFangSC-Regular;font-size: 18px;color: #a8dedd;letter-spacing: 0;text-shadow: 0 1px 2px rgba(35, 26, 124, 0.61);">基层党支部数量</div></div><div><div style="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><img src="./assets/images/manage/decoration-1.png" style="margin-right: 7px" />党员类型</div><div style="height: 132px"><div style="background: url(./assets/images/common/circle.png) no-repeat;"><span>4,961</span></div><div><div><span>预备党员</span> 2,845 <span>44%</span></div><div><span>预备党员</span> 2,845 <span>44%</span></div></div></div></div><div><div style="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><img src="./assets/images/manage/decoration-1.png" style="margin-right: 7px" />党员年龄分布情况</div><div style="padding: 25px 0;margin-left: 46px;width: 314px;background: url(./assets/images/common/Academic-degree.png)no-repeat;background-size: cover;"><div style="text-align: center;font-family: DINAlternate-Bold;font-size: 32px;color: #ffffff;letter-spacing: 0;text-shadow: 0 0 16px #91ffff;">200</div><div style="text-align: center;font-family: PingFangSC-Regular;font-size: 18px;color: #a8dedd;letter-spacing: 0;text-shadow: 0 1px 2px rgba(35, 26, 124, 0.61);">大专以以上学历</div></div><div style="height: 224px">柱状图预留</div></div><div><div style="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><img src="./assets/images/manage/decoration-1.png" style="margin-right: 7px" />男女占比</div><div style="display: flex;justify-content: center;align-items: center;margin-top: 22px;"><div><div style="font-family: PingFangSC-Medium;font-size: 16px;color: #e0f7ff;">男生</div><div style="font-family: DINAlternate-Bold;font-size: 16px;color: #44dbda;">567</div></div><div style="margin: 0 22px"><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /><img src="./assets/images/man.png" /></div><div><div style="font-family: PingFangSC-Medium;font-size: 16px;color: #e0f7ff;">女生</div><div style="font-family: DINAlternate-Bold;font-size: 16px;color: #44dbda;">567</div></div></div></div></div></div>
</body></html>
注意这里笔者没有把样式代码写在 style
标签中,之前是考虑到最终 html 代码会以模板的形式加入到 JS 代码中去,感觉如果将 CSS 代码写在 style 标签会不好插入到模板中。但是后面笔者发现其实将 CSS 代码写在模板中也未尝不可,但是需要注意的时类名的命名上尽量不要重复,因为一旦类名重复可能会影响到其他组件的样式(推荐使用 BEM 方法进行命名)。
- 将静态文件改写成能在 thingjs 图表端空白文件中运行的 JS 文件
如下:
this.clearDom() //在每次进入创建DOM之前必须清除之前的DOM
let dom = this.getDom() //获取DOM节点
let jq = this.getJquery() //获取Jquery
let data = this.getComponentData() //获取组件数据let topTitle = data.topTitle //标签数据
let title = data.title //标题数据
let content = data.content //内容数据const aa = `<div class="civilization" style="display: inline-block"><divstyle="padding: 2px 0 4px 29px;background: url(/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/common/title-bg.png) no-repeat;font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;">农村基层党建</div><divstyle="margin-top: 4px;padding: 35px 20px;padding-top: 0;background: url(/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/common/data-bg.png) no-repeat;background-size: cover;overflow: hidden;"><divstyle="margin: 21px auto;width: 140px;text-align: center;background: url(/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/common/blue.png) no-repeat;background-size: cover;"><divstyle="font-family: DINAlternate-Bold;text-align: center;font-size: 32px;color: #409aff;text-shadow: 0 0 20px #19acb5;">500</div><divstyle="margin-top: 34px;text-align: center;font-family: PingFangSC-Regular;font-size: 18px;color: #a8dedd;letter-spacing: 0;text-shadow: 0 1px 2px rgba(35, 26, 124, 0.61);">基层党支部数量</div></div><div><divstyle="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><imgsrc="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/manage/decoration-1.png"style="margin-right: 7px"/>党员类型</div><div style="height: 110px"><divstyle="background: url(/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/common/circle.png)no-repeat;"><span>4,961</span></div><div><div><span>预备党员</span> 2,845 <span>44%</span></div><div><span>预备党员</span> 2,845 <span>44%</span></div></div></div></div><div><divstyle="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><imgsrc="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/manage/decoration-1.png"style="margin-right: 7px"/>党员年龄分布情况</div><divstyle="padding: 25px 0;margin-left: 46px;width: 314px;background: url(/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/common/Academic-degree.png)no-repeat;background-size: cover;"><divstyle="text-align: center;font-family: DINAlternate-Bold;font-size: 32px;color: #ffffff;letter-spacing: 0;text-shadow: 0 0 16px #91ffff;">200</div><divstyle="text-align: center;font-family: PingFangSC-Regular;font-size: 18px;color: #a8dedd;letter-spacing: 0;text-shadow: 0 1px 2px rgba(35, 26, 124, 0.61);">大专以以上学历</div></div><div style="height: 190px"></div></div><div><divstyle="font-family: YouSheBiaoTiHei;font-size: 20px;color: rgba(255, 247, 224, 0.9);letter-spacing: 0.4px;"><imgsrc="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/manage/decoration-1.png"style="margin-right: 7px"/>男女占比</div><div style="display: flex;justify-content: center; align-items: center; margin-top: 22px"><div><divstyle="font-family: PingFangSC-Medium;font-size: 16px;color: #e0f7ff;">男生</div><divstyle="font-family: DINAlternate-Bold;font-size: 16px;color: #44dbda;">567</div></div><div style="margin: 0 22px"><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /><img src="/uploads/wechat/oLX7p00hNvyDvp6C44l-mJtTtmAo/file/数字清水/static/images/man.png" /></div><div><divstyle="font-family: PingFangSC-Medium;font-size: 16px;color: #e0f7ff;">女生</div><divstyle="font-family: DINAlternate-Bold;font-size: 16px;color: #44dbda;">567</div></div></div></div></div></div>`jq(dom).append(aa) //创建标签、标题和内容的div
这里需要注意的是类似 this.getJquery() //获取Jquery
这样的代码,通过 this 获取 jquery 函数是由 thingsjs 平台提供的能力,作为使用开发者却又无法在全局自定义挂载一个可使用的全局工具函数。
改写完成后,将上述 JS 代码复制粘贴到 thingjs 图表端对应的空白组件代码编写区中去。
这里需要注意的一点是因为在本地调试完毕之后再复制粘贴到 thingjs 在线平台运行,一般来说是不会报什么问题的,但是因为开发环境的不同及一切其他原因,当我们粘贴代码后点击保存&运行
按钮后仍可能运行不正常,这时候只需要 f12 打开浏览器控制台慢慢排查问题即可,待问题排查解决完毕该部分的 HTML 部分功能算是暂时完成了。之后再来处理 echarts 图表部分。echarts 图表部分的开发
在这部分的开发里,笔者发现其有些效果会触发一些 bug 导致无法实现。比如说设计稿给出的 x轴的坐标名是带有图片背景的,笔者在本地开发可以实现这样的效果,但是将代码复制到在线开发平台就不行。接入接口数据
在将一个个模块开发完毕之后,需要接入服务端接口数据。这里笔者是通过新建一个小的空白组件的方式进行的。
这里是用 jquery 自带的 ajax 请求方法进行的请求。之后将请求到的数据通过数据总线发布订阅的方式分发到各个业务组件中。图表端开发综述
图表端的开发难度比想象中要大不少,这种难度不仅体现在对新工具平台的使用探索上,也体现在利用发布订阅的模式总览全局上。在编码方面,由于平台提供的代码编码端体验不佳,我们不得不先在本地进行开发再将相关代码复制到在线平台,而调试修改代码也是如此繁琐,目前暂未探索出更好的方式。
ThingJS 开发使用感悟相关推荐
- 如何利用ThingJS开发物联网可视化小Demo?
如何利用ThingJS平台制作一个3D可视化应用并且发布出去?怎么去制作一个简单的可视化入门项目?如何判断自己能不能进军3D可视化行业?多说不练假把式,今天我们就来学习ThingJS平台中的官方示例, ...
- 一个android应用开发的感悟
对于客户端的开发,以我个人现在的水准,很难进行一个系统的讲解,只能分享下遇到的几个问题点好了! 1:对于tabhost的使用,这个东西真的是过时了:第一个版本,我是用的tabhost确实是很难用,不过 ...
- 5年测试开发工程师感悟——写给还在迷茫中的朋友
自从走出校园,从事软件测试岗位,一转眼5年过去了.这5年,我从一个软件测试0基础的小白成长为懂测试又熟悉开发的测试开发工程师:回顾这些年发展历程,感概万千!!! 第一次听说软件测试这个词,还是在大学最 ...
- 测开转回开发经历感悟
先说下前提:原本是一名两年多的开发,转了测开,工作半年之久目前决定转回开发了(已经在行动). 我这职业经历自己都觉得折腾,就像拿着年轻的资本去在大的方向上去摸索,早知道就听了之前的一句话:当你无法抉择 ...
- 字节8年测试开发工程师感悟,说说我们自动化测试平台的进阶之路
前言 自2015年10月底加入Pactera Edge以来,我一直服务于客户的Quality Engineering项目.这之间经历了很多的技术变革,包括探索,实施,维护,淘汰等一整个流程.下面就写一 ...
- 入职滴滴和头条后的开发工作感悟,希望对你有所帮助!
来源:www.nowcoder.com/discuss/351805 先简单交代一下背景吧,某不知名 985 的本硕,17 年毕业加入滴滴,当时找工作时候也是在牛客跟大家一起奋战的.今年下半年跳槽到了 ...
- 远景智能后台开发面试感悟
一面: 项目(最好有并发项目)我的项目没有涉及到并发的情况存在很多漏洞,没有深入聊下去 java基础,arrayList和linkedList: 多线程: 线程池的可选参数,都有哪些功能,jdk线程池 ...
- 基于WebGL的三维数据可视化大屏开发流 ThingJS
三维数据大屏可视化系统包含多源数据连接.生成二维/三维视图.构建可视化大屏.大屏功能应用等一体化服务,基于多年可视化项目经验,ThingJS平台得出从数据源上传到可视化大屏应用的完整流程,供参考. 多 ...
- 基于WebGL的虚拟太阳系漫游技术实现 ThingJS 科幻片
#三维可视化##3D开发# 虚拟功能需求 2. 太阳系运行需求 3. 3D模型呈现 4. ThingJS技术分析 5. 系统实现步骤 3D可视化技术逐渐应用到现代多媒体的课堂教学中. 虚拟太阳系是一款 ...
- 铁道中文应用开发现状综述
铁道中文应用开发现状综述 2006年8月 An Interim Report of Ruby on Rails Applications and Development in Chinese Stat ...
最新文章
- AS整理代码快捷键 ctl+alt+L
- ADO.NET入门教程(三) 连接字符串,你小觑了吗?
- Centos7 yum安装Python3.6环境,超简单
- c语言assign用法,object-c语言的nonatomic,assign,copy,retain的区别
- Spring MVC的处理流程详解
- python3 beautifulsoup_Python3中BeautifulSoup的使用方法
- 不会写漂亮代码不是优秀的程序员,没有钢铁侠之躯不是合格的程序员
- 3.React学习笔记(完)----nodejs命令备份+跨域问题处理
- php手册 下载,php手册chm
- hyperscan5.0编译方式整理
- android能用svg格式,关于Android SVG图形:Android SVG图形 – 将当前PNG文件转换为svg格式的缺点...
- HTML5游戏开发实战
- unity中使用手柄控制角色移动
- (写着玩)Python仿网络游戏《炉石传说》,继上次部分代码展示
- 阿里云服务器糟挖矿程序攻击
- gsoap linux 编译,gSOAP嵌入式linux下的移植与程序开发
- 【django】Windows下安装Redis
- 四、指针高级应用总结
- 学习DS1820随记
- 计算机专业英语首字母缩略词,计算机专业英语缩略词计算机专业英语缩略词.doc...