`
xhload3d
  • 浏览: 206045 次
社区版块
存档分类
最新评论

HT图形组件设计之道(一)

阅读更多

HT for Web简称HT提供了涵盖通用组件、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组件及其扩展设计思路。

1282039088303

熟悉Flex的程序员应该都了解Tour de Flex这个包罗万象的大杂烩,其中的网络监控拓扑Network Monitor特别其动画切换效果一直给我很深印象,这里不可能有篇幅实现完整例子,我们仅尝试实现其展示CPU和MEM的界面部分。

IMG_3641

实现的最终效果如上图所示,模型数据就两个数值,一个代表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数据显示正确,那就去找找实际运行后台通信解析后的数据是否正确的设置到模型上,这样一步步的分析很容易就能定位到问题的根源。

 

以上三种扩展方式各有利弊,我将在下篇中继续展开分析,本篇结尾上一段该例子在移动终端的运行操作视频

1
0
分享到:
评论

相关推荐

    ht6023&ht7038电源板原理图,ht6872电路图,PDF

    至于ht6872,虽然在描述中没有详细信息,但通常情况下,这可能是另一种电源管理IC或者与之相关的特定功能模块。在电路设计中,ht6872可能负责特定的电源转换或保护功能,比如开关电源控制或电池管理。 "att7022 pdf...

    ht_ht2002制图软件_java_

    【ht_ht2002制图软件】是一个专为用户设计的图形绘制工具,它采用Java编程语言开发,使得该软件具有跨平台性,可以在多种操作系统上运行,如Windows、Linux和Mac OS等。Java是一种面向对象的编程语言,以其“一次...

    HT 手册-07311656.pdf

    HT-for-web 的概述、开发类库、开发工具、运行环境、函数简写、模型、设计模式、类包层次、工具类、数据类型、数据容器、选择模型、组件、配置、图片、动画、属性组件、列表组件、树形组件、表格组件、工具条组件、...

    ht-for-web

    【ht-for-web】是一款专为前端开发者设计的框架,主要用于创建和管理拓扑图以及页面布局。这个框架的强大之处在于它的灵活性和可定制性,使得开发者可以轻松地构建出复杂且交互性强的可视化应用。 在拓扑图制作方面...

    HT for Web Demo

    海马云是一家专注于2D/3D图形渲染及数据可视化的技术提供商,其开发的HT for Web库是一个强大的Web组件库,尤其适用于构建复杂的业务流程图、3D场景等。 在给定的资源中,我们可以看到以下几个关键文件: 1. **ht...

    HT1621.rar

    标题中的"HT1621.rar"表明这是一个与HT1621相关的资源文件,通常在电子工程领域,HT1621是一款常见的128x32点阵液晶显示控制器。这种芯片常用于制作小型显示屏,如智能仪器、家用电器的用户界面等。这个RAR压缩包...

    合泰单片机应用能力设计大赛——HT-IDE3000操作步骤(HT66F70A).zip

    它提供了一个用户友好的图形界面,支持C语言和汇编语言编程,内置了编译器、调试器以及仿真器等功能,使得开发过程更为便捷。通过这个IDE,开发者可以快速地将源代码转化为可执行程序,并在硬件或仿真环境中进行测试...

    hightopo HT for Web(hightopo.zip)

    【描述】:HighTopo(简称HT)是一款强大的Web图形库,它专为开发人员提供了构建现代化、跨桌面和移动终端的企业级应用的解决方案。通过使用HT for Web,开发者无需过于关注复杂的跨平台兼容性问题,以及在触屏设备...

    HT for Web 入门手册

    HT for Web是基于HTML5标准的企业应用图形界面一站式解决方案, 其包含通用组件、拓扑组件和3D渲染引擎等丰富的图形界面开发类库,提供了完全基于HTML5的矢量编辑器、拓扑编辑器及 3D场景编辑器等多套可视化设计工具...

    LCD_HT1621模块资料

    1. **HT1621控制器**:HT1621是一款专用的液晶驱动控制器,由台湾辉达科技(Hitech)设计。它能够驱动多达8行×16列的点阵液晶显示器,同时支持128个字符的内部存储器,这使得它能够显示丰富的字符和简单的图形。 2...

    基于HT for Web矢量实现HTML5文件上传进度条

    HT for Web是一款强大的Web可视化工具,它允许开发者通过矢量图形来构建交互式的Web应用程序。在HTML5中,File API提供了处理文件和数据的能力,包括读取本地文件、监控文件上传进度等功能。 这篇博客(博文链接:...

    HT9B92 PDF

    根据所提供的信息,我们可以深入探讨有关HT9B92 LCD驱动IC的技术知识点。 HT9B92是一款专为液晶显示(LCD)设计...无论是开发者还是电子工程师,在设计用于多种应用场景的消费电子产品时,HT9B92都是值得考虑的组件。

    libht.js.zip

    其中,ht.js(又称libht.js)是一款专为数据可视化和图形交互设计的轻量级库,尤其在3D场景建模、科学计算可视化等方面表现出色。本文将详细介绍ht.js的核心功能、使用方法以及在实际项目中的应用场景。 ht.js的...

    ht精华代码

    "vector"通常指的是矢量图,这类图像使用数学公式表示,可以在不同尺寸下保持清晰,常用于图形设计和网页艺术。"master"可能是Git仓库的主分支,表明这是项目的核心部分,包含了完整的源代码和资源文件。 在这个...

    stm8 驱动定制的段式液晶 HT1621

    HT1621是一种段式液晶显示控制器,专为驱动点阵或段式液晶屏设计。这种控制器可以管理多达128个独立的段,使得它适合于创建定制的字符或图形显示。它具有内置的RAM和译码功能,可以简化与微控制器的接口,减少外部...

    基于HT for Web矢量实现HTML5上传文件进度条

    1. 创建一个HTML表单,包含一个`&lt;input type="file"&gt;`元素,以及一个显示进度的 HT for Web 组件。 2. 使用JavaScript监听文件选择事件,当用户选择文件后,开启Web Worker处理文件上传。 3. 在Web Worker中,使用...

    ht.rar_画图

    BCB是Borland公司推出的一种集成开发环境,它集成了C++编译器和VCL(Visual Component Library)组件库,方便开发者快速构建图形用户界面应用程序。 【描述】提到的“用bcb制作的画图程序”意味着这个程序是利用BCB...

    HT66F40 LCD+LED+KEY

    在这个例程中,合泰(Holtek)的HT66F40单片机被用于控制LCD显示屏、LED灯以及按键,这些都是嵌入式系统中常见的硬件组件。 **HT66F40微控制器** HT66F40是一款8位的微控制器,属于Holtek的HT6x系列。它集成了中央...

    ht1621的一个驱动程序

    【ht1621驱动程序】是一个专为51单片机设计的、采用汇编语言编写的控制程序。在嵌入式系统中,驱动程序是操作系统与硬件设备之间的桥梁,它负责管理和控制硬件资源,使得操作系统能有效地利用硬件设备进行工作。51...

Global site tag (gtag.js) - Google Analytics