2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的节奏。

3D呈现固然比2D方式更直观,但如果摆放图元布局却比2D麻烦,毕竟增加了一个维度,手工布局不如以前2D手工操作方便,因此3D的自动布局功能比2D凸显其重要性。最近玩了玩HT的弹力自动布局插件挺有意思,特别在平板上Touch方式拖拽三维空间图元节点时,对我这种控制欲较强者很有满足感。

弹力布局也不是啥新鲜玩意儿了,传统弹力布局算法都是采用通过CPU迭代运算的方式,对于海量数据特别是在纯客户端运算的方式肯定是不可行的,因此这些年也有很多采用GPU的方式进行并行计算的方式可极大提高性能,等OpenCL更成熟HT for Web提供了WebCL的解决方案我再来张开这个话题。今天的话题采用的还是CPU,只不过我把自动布局的算法拉到了Web Worker来运算,纯属为了好玩实际意义不大,毕竟Worker运算结果还得不断序列化给GUI页面层,不断来回数据传输也挺耗性能,当然如果你让Worker运行一段时间,只把最终结果push回Web层进行呈现还是有点实际意义的,毕竟不用Worker时js单线程运行,对这种计算密集型的算法只会卡死界面无法进行其他业务操作。

以下是页面部分的代码,通过new Worker('workderjs')构建Worker后台运行对象,通过worker.addEventListener('message', ..)监听后台自动布局后派发的图元位置信息进行更新,通过worker.postMessage(info)发送界面拖拽图元位置变化信息。

       function reload() {
var info = {
A: parseInt($("A").value),
B: parseInt($("B").value)
};
reloadModel(dataModel, info);
worker.postMessage(info);
} function init() {
dataModel = new ht.DataModel();
g3d = new ht.graph3d.Graph3dView(dataModel);
toolbar = new ht.widget.Toolbar(items);
borderPane = new ht.widget.BorderPane();
borderPane.setTopView(toolbar);
borderPane.setCenterView(g3d); g3d.mi(function(evt){
if(evt.kind === 'betweenMove'){
moveMap = {};
g3d.sm().each(function(data){
if(data instanceof ht.Node){
moveMap[data._id] = data.p3();
}
});
worker.postMessage({moveMap: moveMap});
}
}); worker = new Worker("worker.js");
worker.addEventListener('message', function(e) {
var info = e.data;
for(var id in info.result){
var data = dataModel.getDataById([id]);
if(data && !g3d.isSelected(data)){
data.p3(info.result[id]);
}
}
}); reload();
}

以下是后台Work.js的代码,通过importScripts("ht.js")引入HT核心包,通过importScripts("ht-forcelayout.js")引入HT的弹力布局插件,通过importScripts("util.js")引入和页面代码共享的一些通用函数,通过self.postMessage({result: result})发送自动布局运算结果推送到页面,通过
self.addEventListener('message', ...)监听页面发过来的位置变化信息,从而实现了前后台的互通。

importScripts("ht.js");
importScripts("ht-forcelayout.js");
importScripts("util.js"); ht = self.ht;
dataModel = new ht.DataModel();
forceLayout = new ht.layout.Force3dLayout(dataModel); forceLayout.onRelaxed = function(){
var result = {};
dataModel.each(function(data){
if(data instanceof ht.Node){
result[data._id] = data.p3();
}
});
self.postMessage({result: result});
};
forceLayout.start(); self.addEventListener('message', function(e) {
var info = e.data;
if(info.moveMap){
dataModel.sm().cs();
for(var id in info.moveMap){
var data = dataModel.getDataById(id);
if(data){
data.p3(info.moveMap[id]);
dataModel.sm().as(data);
}
}
}
else{
reloadModel(dataModel, info);
}
}, false);

以下视频为在Android平板上跑3D拓扑自动布局的效果,这个例子纯粹为了玩玩Web Workers,这样折腾性能并不会提高,甚至因为来回序列化更费性能,Web Worker可以使用的场景并不太多,比较适合纯数学运算的业务逻辑,同时还需要注意跑在Worker的代码是不能操作任何界面对象,例如window和document之类的对象。

下篇《3D拓扑自动布局之Node.js篇》我们再将算法移到Node.js端玩

  

  

3D拓扑自动布局之Web Workers篇的更多相关文章

  1. 3D拓扑自动布局之Node.js篇

    上篇将3D弹力布局的算法运行在Web Workers后台,这篇我们将进一步折腾,将算法运行到真正的后台:Node.js,事先申明Node.js篇和Web Workers篇一样,在这个应用场景下并不能提 ...

  2. 基于HTML5的3D网络拓扑自动布局

    上篇将HT for Web的3D拓扑弹力布局的算法运行在Web Workers后台(http://www.hightopo.com/blog/70.html),这篇我们将进一步折腾,将算法运行到真正的 ...

  3. 基于HT for Web的3D拓扑树的实现

    在HT for Web中2D和3D应用都支持树状结构数据的展示,展现效果各异,2D上的树状结构在展现层级关系明显,但是如果数据量大的话,看起来就没那么直观,找到指定的节点比较困难,而3D上的树状结构在 ...

  4. HT for Web列表和3D拓扑组件的拖拽应用

    很多可视化编辑器都或多或少有一些拖拽功能,比如从一个List列表中拖拽一个节点到拓扑组件上进行建模,并且在拖拽的过程中鼠标位置下会附带一个被拖拽节点的缩略图,那么今天我们就来实现这样的拖拽效果. 首先 ...

  5. Web Workers文档

    Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法.线程可以执行任务而不干扰用户界面.此外,他们可以使用XMLHttpRequest执行 I/O  (尽管responseXML和 ...

  6. JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景

    摘要: 理解Web Workers. 原文:JavaScript是如何工作的:Web Workers的构建块 + 5个使用他们的场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这 ...

  7. [翻译]Review——How JavaScript works:The building blocks of Web Workers

    原文地址:https://blog.sessionstack.com/how-javascript-works-the-building-blocks-of-web-workers-5-cases-w ...

  8. 分享数百个 HT 工业互联网 2D 3D 可视化应用案例之 2019 篇

    继<分享数百个 HT 工业互联网 2D 3D 可视化应用案例>2018 篇,图扑软件定义 2018 为国内工业互联网可视化的元年后,2019 年里我们与各行业客户进行了更深度合作,拓展了H ...

  9. 数百个 HT 工业互联网 2D 3D 可视化应用案例分享 - 2019 篇

    继<分享数百个 HT 工业互联网 2D 3D 可视化应用案例>2018 篇,图扑软件定义 2018 为国内工业互联网可视化的元年后,2019 年里我们与各行业客户进行了更深度合作,拓展了H ...

随机推荐

  1. tbb flow graph node types

  2. Gradle 构建 android 应用常见问题解决指南

    前言 android gradle 插件已经发展到0.5.7,同时gradle 本身也到了1.8,相比两个月前,android gradle 更快,更完善,也更好用了,为了让各位androider 早 ...

  3. CoreData多线程安全

    CoreData中的NSManagedObjectContext在多线程中不安全,如果想要多线程访问CoreData的话,最好的方法是一个线程一个NSManagedObjectContext, ,每个 ...

  4. 昨日尝试使用百度死链提交,使用lCGI规则提交

    本来打算去掉北盟网校的死链,但就算配了规则,提交百度,但是好像还是没有删除到 认真阅读了百度的死链工具 好像需要将死链返回404错误提示 检查北盟的代码,发现北盟做了404从定向 在程序里面404从定 ...

  5. 文件系统管理 之 Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍

    一.df 命令:df 是来自于coreutils 软件包,系统安装时,就自带的:我们通过这个命令可以查看磁盘的使用情况以及文件系统被挂载的位置: 举例: [root@localhost beinan] ...

  6. HL AsySocket 服务开发框架 - 一般性测试1

    一 概述 Socket服务器性能要好就要经过无数次的测试,来保证,以下是记录一次的测试经过. 机器配置:Inter(R) Core(TM) i3-2310m CPU 2.10GHz RAM 6.00G ...

  7. 解决cxf+spring发布的webservice,types,portType和message以import方式导入

    用cxf+spring发布了webservice,发现生成的wsdl的types,message和portType都以import的方式导入的.. 原因:命名空间问题 我想要生成的wsdl在同个文件中 ...

  8. Hadoop2.x源码-编译剖析

    1.概述 最近,有小伙伴涉及到源码编译.然而,在编译期间也是遇到各种坑,在求助于搜索引擎,技术博客,也是难以解决自身所遇到的问题.笔者在被询问多次的情况下,今天打算为大家来写一篇文章来剖析下编译的细节 ...

  9. PS 如何改变一个icon的颜色

    好吧,码农被逼到一定程度也会自己出手的. PS:如何改变图标颜色 新建一个图层,设置前景色为你想要的前景色,按Alt+Delete键用前景色填充该图层,将该图层拖到这个图片所在图层的上方,按Ctrl+ ...

  10. C# 使用 SAP NCO3.0 调用SAP RFC函数接口

    最近使用C#调用SAP RFC函数,SAP提供了NCO3.0组件. 下载组件安装,之后引用“sapnco.dll”和“sapnco_utils.dll”两个文件. 在程序中 using SAP.Mid ...