HT for Web(http://www.hightopo.com/guide/readme.html)提供了涵盖通用组件、2D拓扑图形组件以及3D引擎的一站式解决方案,正如Hightopo官网所表达的我们希望提供:Everything you need to create cutting-edge 2D and 3D visualization. 这个愿景从功能上是个相当长的战线,从设计架构上也是极具挑战性的,其实HT团队是非常保守的,我们从不贪多图大,只做我们感觉自己能得更好,能给用户综合体验更佳的功能,在这样理念驱动下我们慢慢形成了这样的愿景,慢慢实现了几个有意义的里程碑,慢慢积累下了不少图形组件设计上的创新和经验,我不知道这个系列会写多少篇,也许永远也不会结束,也没有系统的提纲规划,想到什么就写什么,只希望文章能启发有兴趣的同学对图形组件设计更深的思考就足够了。
讨论前先设定话题的边界,HT是基于HTML5的图形组件库,因此文章的案例更多会涉及HTML和JavaScript语言,但并不局限于Web前端,设计思想上同样适用于任何GUI语言平台。完整的前端设计是需要考虑到后台加载并发等因素,但本系列更侧重于纯客户端图形组件,不涉及网络通讯部分的思考,例如最近阿里无线前端招聘让谈谈:讲讲输入完网址按下回车,到看到网页这个过程中发生了什么。这是个能讨论出很多方方面面,让你了解面试者的好话题,但这里讨论的话题会与以下关键字更为相关:企业应用、Single Page Application、重客户端交互、监控、MV*等。
如Linus大神所言:Talk is cheap, show me the code. 因此我选择在话题展开之前,先用HT来扩展定制几个应用案例,以便大家了解HT组件及其扩展设计思路。
http://www.hightopo.com/guide/guide/core/propertyview/examples/example_custom.html
熟悉Flex的程序员应该都了解Tour de Flex这个包罗万象的大杂烩,其中的网络监控拓扑Network Monitor特别其动画切换效果一直给我很深印象,这里不可能有篇幅实现完整例子,我们仅尝试实现其展示CPU和MEM的界面部分。
实现的最终效果如上图所示,模型数据就两个数值,一个代表CPU占用率,一个代表内存占用率,左侧通过HT的图形组件GraphView自定义了矢量图形展示,右上角自定义了属性页PropertyView的两单元格的Renderer,右下角两个Slider可拖动改变CPU和MEN值。
此例子麻雀虽小五脏俱全,三个部分分别采用三种方式实现了自定义组件,同时不同组件共享同一数据源,在呈现的基础上还支持桌面和移动端的Mouse和Touch的交互,还有不同终端屏幕的组件布局功能。
业务上需要在占用率小于40%时呈现律师,40%-70%时显示黄色,超过70%时呈现红色,因此定义了如下getColor的工具函数:
1
2
3
4
5
6
7
|
getColor = function (value) {
if (value < 40)
return '#00A406' ;
if (value < 70)
return '#FFCC00' ;
return '#A60000' ;
}; |
PropertyView上采用的最基础和原始的方式,通过Canvas画笔进行单元格的自定义绘制,在注册PropertyView时重载drawPropertyValue函数即可实现单元格自定义Renderer的绘制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
drawFunc = function (g, value, x, y, w, h){
g.fillStyle = '#A1A1A3' ;
g.beginPath();
g.rect(x, y, w, h);
g.fill();
g.fillStyle = getColor(value);
g.beginPath();
g.rect(x, y, w * value / 100, h);
g.fill();
ht.Default.drawText(g, value + '%' , '12px Arial' , 'white' , x, y, w, h, 'center' );
}; propertyView.addProperties([ {
displayName: 'CPU' ,
drawPropertyValue: function (g, property, value, rowIndex, x, y, w, h, data, view) {
drawFunc(g, data.a( 'cpu' ), x, y, w, h);
}
},
{
displayName: 'MEM' ,
drawPropertyValue: function (g, property, value, rowIndex, x, y, w, h, data, view) {
drawFunc(g, data.a( 'mem' ), x, y, w, h);
}
}
]); |
Slider拉条部分直接在HT封装的组件之上应用,因而无需接触到最底层的Canvas画笔绘制,仅需要在onValueChanged时更新leftBackgroud拉条左侧颜色即可,其实也可以通过重载Slider的getLeftBackground函数实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
formPane.addRow([ 'CPU' , {
slider: {
step: 1,
onValueChanged: function (){
var value = this .getValue();
node.a( 'cpu' , value);
this .setLeftBackground(getColor(value));
},
value: node.a( 'cpu' )
}
}], [50, 0.1]); formPane.addRow([ 'MEM' , {
slider: {
step: 1,
onValueChanged: function (){
var value = this .getValue();
node.a( 'mem' , value);
this .setLeftBackground(getColor(value));
},
value: node.a( 'mem' )
}
}], [50, 0.1]); |
GraphView部分采用了《HT全矢量化的图形组件设计》文章介绍的HT自定义的矢量方式来实现图形效果,这种方式介于以上两种扩展方式之间,需要自定义绘制效果,但通过HT提供的矢量格式,用户可采用较为直观易读的JSON格式来描述图形,并通过数据绑定的方式实现模型数据与界面呈现的关联,避免如第一种自定义renderer的方式,即需要接触到底层绘制函数,同时业务逻辑代码与绘制代码混杂一起不易维护的问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
ht.Default.setImage( 'server_image' , {
width: 300,
height: 200,
comps: [
{
type: "roundRect" ,
rect: [3, 5, 291, 189],
background: "#E3E3E3" ,
gradient: "linear.northeast" ,
shadow: true
},
{
type: "text" ,
text: "CPU" ,
font: "16px Arial" ,
rect: [20, 45, 59, 41]
},
{
type: "text" ,
text: "MEM" ,
font: "16px Arial" ,
rect: [20, 108, 59, 41]
},
{
type: "rect" ,
rect: [82, 55, 145, 22],
background: "#A1A1A3"
},
{
type: "rect" ,
rect: {
func: function (data) {
return [82, 55, 145 * data.a( 'cpu' ) / 100, 22];
}
},
background: {
func: function (data) {
return getColor(data.a( 'cpu' ));
}
}
},
{
type: "rect" ,
rect: [82, 117, 145, 22],
background: "#A1A1A3"
},
{
type: "rect" ,
rect: {
func: function (data) {
return [82, 117, 145 * data.a( 'mem' ) / 100, 22];
}
},
background: {
func: function (data) {
return getColor(data.a( 'mem' ));
}
}
},
{
type: "text" ,
font: "16px Arial" ,
rect: [240, 49, 53, 31],
text: {
func: function (data) {
return data.a( 'cpu' ) + '%' ;
}
},
color: {
func: function (data) {
return getColor(data.a( 'cpu' ));
}
}
},
{
type: "text" ,
font: "16px Arial" ,
rect: [240, 108, 47, 39],
text: {
func: function (data) {
return data.a( 'mem' ) + '%' ;
}
},
color: {
func: function (data) {
return getColor(data.a( 'mem' ));
}
}
}
]
}); |
以上代码注册了名为server-image的图片,绑定了attr上的mem和cpu的两个属性,因此做完这些手脚架的基础工作后,应用人员只需要构建ht.Node对象,通过node.setImage('server-image')即可实现该图元在GraphView上呈现'server-image'描述的矢量效果,并且PropertyView、Slider和GraphView三个组件都通过node的attr上的cpu和mem来显示界面,这样当后台获取到采集的实时数据后,只需要更新到node的attr上的cpu和mem属性,则界面上的所有组件就会自定更新显示:
1
2
3
4
5
6
7
8
|
node = new ht.Node();
node.setName( 'SERVER' );
node.setImage( 'server_image' );
node.a({ cpu: 30,
mem: 70
}); dataModel.add(node); |
当然实际应用中并不需要拉条改变CPU和MEN值,这些值一般通过后台采集实时自动更新仅作为呈现,但有了前端这些组件的一站式支持,我们不需要连接后台也可以很方便在客户端进行模拟测试,有了这样的机制我们就可以分离模块一步步测试,例如我们现在不需要连接服务器也可以测试矢量描述定义的是否正确,数值改变后绿黄红的业务颜色更新是否正确,各个组件的数据同步是否正常,Mouse和Touch交互是否能正常操作,界面在不同设备屏幕上显示是否正常等等,这些纯客户端组件的封装工作都做到位后,你就可以安心连接后台数据进行测试了。
见过太多客户出问题时只会说:界面显示不对。这样的问题描述完全无法定位根源,到底时后台数据库问题,网络通讯问题,解析数据问题,设置模型问题还是组件封装问题?这也是MVC/MVP/MVVM存在的另外一个层面的意义,MV*除了事件派发数据绑定外,能更好的进行呈现、模型和业务逻辑的分工切割进行独立测试的重要意义,就行TCP/IP七层协议的分类,每个协议层都应该确保正确实现自己的协定约定,并且每一层可进行独立的测试,这才是可维护可扩展的系统,因此对于HT客户遇到问题时,我们一般也是一层层的帮忙梳理找根源,如果矢量描述没问题呈现出错,那是HT组件库的问题,如果模拟到Node上的attr数据显示正确,那就去找找实际运行后台通信解析后的数据是否正确的设置到模型上,这样一步步的分析很容易就能定位到问题的根源。
以上三种扩展方式各有利弊,我将在下篇中继续展开分析,本篇结尾上一段该例子在移动终端的运行操作视频
相关推荐
6. **自定义扩展**:jTopo的API设计灵活,允许开发者自定义节点和链路的样式,以及添加新的图形组件,满足个性化需求。 **jTopo的应用场景** jTopo因其强大的功能和易用性,被广泛应用在网络管理、监控系统、...
此外,HT 提供了一系列预定义的图形组件和交互模式,如节点、连接线、拖放、缩放和平移等,开发者无需从零开始编写图形代码,只需配置相应的属性和事件即可。这极大地提高了开发效率,降低了学习曲线。 在电信领域...
好强大的HTML5拓扑图编辑器,不敢私有,0资源分分享给大家,我是做电力SCADA要编辑电力配网图的,但申请看描述该图形组件也能应用到电信、工控等其他需要图形可视化的领域,以前一直用C++做客户端,今天玩了下...
2. **控件自定义**:在Java中,开发者可以通过自定义图形组件来满足特定的拓扑图需求。这包括改变控件的外观、添加交互功能,以及根据数据动态调整组件大小和位置。例如,可以创建一个自定义节点组件,用以表示网络...
总之,HTML5 Canvas结合开源工具包jtopo,为Web开发者提供了一种高效、灵活的方式来构建关系和拓扑图形化界面,促进了交互式应用的发展。通过学习和掌握这些技术,开发者可以创造出更加生动、直观的网络可视化应用。
HTML5 是一种强大的 web 开发技术,它在网页制作领域带来了许多创新,其中之一就是 Canvas 元素。Canvas 提供了一种在浏览器上进行动态图形绘制的能力,使得开发者无需依赖插件就能创建丰富的交互式图形应用。在电力...
这款开发工具包是专门针对关系和拓扑图形界面设计的,它充分利用了HTML5的Canvas技术,提供了一种高效且灵活的方式来创建和展示复杂的数据结构和网络布局。HTML5 Canvas作为一个强大的绘图API,允许开发者在网页上...
Qunee是一个强大的JavaScript库,它提供了丰富的UI组件和图形工具,包括绘制网络拓扑图的功能。使用Qunee,开发者可以方便地创建、编辑和布局网络拓扑图,同时支持交互操作,例如节点拖放、连接线增删等。 在实现...
这个Repository提供的网络拓扑, 是一套完整可用的面向电信级/企业级用户的HTML5网络拓扑图方案. 图形是基于SVG绘制的, 同时配备了一系列UI套件, 使您更直观的了解Topology是如何工作的 指南 因为文件较多, 所以建议...
TWaver HTML5(以下简称TWaver)使用HTML5技术和javascript语言,可在支持HTML5的浏览器上进行绘图。 使用TWaver前,需熟悉几个基本概念:图元...Network是最终用户看到的图形组件,负责图形画面的具体绘制和交互;
HTML5网络拓扑图是一种利用现代网页技术展示网络设备、服务器、线路等元素相互连接的图形化表示方式。在这个项目中,开发人员使用了HTML5的Canvas或SVG元素,结合JavaScript库来创建交互式的网络拓扑图表。下面将...
在本篇【快速开发基于 HTML5 网络拓扑图应用--入门篇(三)】中,我们将进一步深入探讨如何在HTML5环境下构建网络拓扑图应用,并着重讲解如何添加属性组件。这个过程旨在帮助初学者理解网络拓扑图的创建原理,以及...
在开发基于HTML5的网络拓扑图应用时,DataBinding(数据绑定)是核心功能之一,它连接着用户界面和应用程序的数据模型,使得两者之间的数据更新可以自动化进行,极大地简化了开发过程。在这个"快速开发基于HTML5网络...
5. 图形算法:对于拓扑图,需要了解force-directed布局和其他可能的网络图布局算法。 在实现过程中,首先,你需要准备数据,通常是JSON格式,包含节点和边的信息。然后,在HTML文档中引入D3JS库,并创建一个SVG元素...
JTOPO是一款强大的前端拓扑图绘制库,它专为构建网络、系统和业务流程的可视化解决方案而设计。这个DEMO是完全基于前端实现的,不依赖任何后端服务,而是使用模拟数据来展示其功能。这使得开发者可以快速地将它集成...
**jtopo** 是一个基于HTML5 Canvas技术的开源项目,专门用于绘制和交互式的拓扑图工具。这个工具提供了一种高效的方式来展示网络、系统或任何层次结构的图形表示,广泛应用于网络设备布局、数据中心可视化、软件架构...
1. **拓扑图**:拓扑图是一种图形化的方式,用于表示网络设备、服务器、交换机、路由器等之间的连接关系。jTopo通过节点(Nodes)和链路(Links)的概念,帮助用户构建和展示这些网络组件。 2. **节点(Nodes)**:...
可以使用Spark或MX图形组件,如Line或Shape,来绘制连接线,并通过监听鼠标事件来实现拖放和动态调整连线。 4. **数据绑定**:在Flex中,数据绑定允许视图组件自动更新当其绑定的数据源发生变化。这对于实时显示...
总的来说,这个项目融合了SVG图形渲染、JavaScript交互逻辑、HTML页面构建以及可能的GIS和游戏开发技术,构建了一个功能丰富的前端网络拓扑可视化工具,为网络管理和监控提供了直观且互动的手段。