网格中合并(Merge)功能的多种技术方案
2006-12-26 23:46
411 查看
写这篇文章,主要是因为我们的“下午茶时间”(项目内部的一种交流方式)激烈地讨论了此类功能的多种实现,我感觉非常有意思。大家可以参考一下。
我先简单地描述一下功能要求,要求设计一种数据结构,支持网格控件(图形化)实现矩形区域的合并效果(Merged)。非矩形区域的合并不在支持范围之内。
大家可能都在使用各种各样的网格控件,最出名的可能是FlexGrid。不过大家可以也思考思考,如果是你的话,你会如何设计呢?
有一个最基本的方法,每一个网格CELL中预置一个变量:MergeID。我们姑且将这种方法称之为"MergeID法"。此方法规则比较简单:没有合并的CELL的MergeID都是0,相邻矩形区域的合并CELLs的MergeID相同,且不为0。将0特殊处理,是为了加快处理速度,毕竟,大多数都是没有合并的CELL。
如上面的网格,则左上角六个CELL合并,右下角四个CELL合并。
这种方法的最大问题在于,空间占有比较浪费,特别是对那些从没有合并的CELL。另外,对于合并格的描述不清晰,整个网格中有多少合并格也不能简单获取,必须经过遍历才知道。
针对上面的分析,提出第二种方案,我们称之为"MergeRange List",这种方法的最大优势在于将所有合并的矩形区域统一管理起来,形成一个列表。网格控件在访问Merge属性的时候,再到Range列表中查找,如果找到,则属于合并格,否则为非合并格。
这个方式在FlexGrid就被使用。显然这种方法比较成熟。不过这种方式在管理对象的时候,不容易对应。需要经过映射。这在需要大量访问网格CELL对象的时候,会产生一些效率浪费。
熟悉HTML的人,大概还知道HTML的表示方式,在网格上通过rowspan和colspan来定义。在有合并的CELL的左上角上,定义其向右和向下的合并范围。通过这个范围定义,我们也可以确定合并区域。这种方式的定义简单。不过实现起来,其实有一些问题。
我们上面讨论几种方案的时候,忽略了一个问题,那就是我们一般的网格结构,很可能是一个CELL对应一个对象。那样的话,我们可以有一个新的方案,这个方案和第一个MergeID方案联系在一起,但是我们不需要额外的MergeID属性,而是直接使用Object的对象指针。只需要判断CELL周围的对象是否相等,就可以知道其合并范围。合并区域的所有CELL的对象相同。这样,在取数据的时候,不需要进行额外映射。而在网格控件绘制的时候,才需要合并区域查找。效率应该可以满足。我们就将这种方法叫"Ojbect/MergeID"吧。
总结列举一下四种方法:
MergeID
MergeRange List
Span
Object/MergeID
这四种方法各有利弊。其实在我们设计过程中,应该抓住一个基本点,要的是空间还是效率,还是两者都要。不同的要求,使用不同的设计。
我先简单地描述一下功能要求,要求设计一种数据结构,支持网格控件(图形化)实现矩形区域的合并效果(Merged)。非矩形区域的合并不在支持范围之内。
大家可能都在使用各种各样的网格控件,最出名的可能是FlexGrid。不过大家可以也思考思考,如果是你的话,你会如何设计呢?
有一个最基本的方法,每一个网格CELL中预置一个变量:MergeID。我们姑且将这种方法称之为"MergeID法"。此方法规则比较简单:没有合并的CELL的MergeID都是0,相邻矩形区域的合并CELLs的MergeID相同,且不为0。将0特殊处理,是为了加快处理速度,毕竟,大多数都是没有合并的CELL。
1 | 1 | 1 | 0 | 0 |
1 | 1 | 1 | 0 | 0 |
0 | 0 | 0 | 1 | 1 |
0 | 0 | 0 | 1 | 1 |
如上面的网格,则左上角六个CELL合并,右下角四个CELL合并。
这种方法的最大问题在于,空间占有比较浪费,特别是对那些从没有合并的CELL。另外,对于合并格的描述不清晰,整个网格中有多少合并格也不能简单获取,必须经过遍历才知道。
针对上面的分析,提出第二种方案,我们称之为"MergeRange List",这种方法的最大优势在于将所有合并的矩形区域统一管理起来,形成一个列表。网格控件在访问Merge属性的时候,再到Range列表中查找,如果找到,则属于合并格,否则为非合并格。
这个方式在FlexGrid就被使用。显然这种方法比较成熟。不过这种方式在管理对象的时候,不容易对应。需要经过映射。这在需要大量访问网格CELL对象的时候,会产生一些效率浪费。
熟悉HTML的人,大概还知道HTML的表示方式,在网格上通过rowspan和colspan来定义。在有合并的CELL的左上角上,定义其向右和向下的合并范围。通过这个范围定义,我们也可以确定合并区域。这种方式的定义简单。不过实现起来,其实有一些问题。
我们上面讨论几种方案的时候,忽略了一个问题,那就是我们一般的网格结构,很可能是一个CELL对应一个对象。那样的话,我们可以有一个新的方案,这个方案和第一个MergeID方案联系在一起,但是我们不需要额外的MergeID属性,而是直接使用Object的对象指针。只需要判断CELL周围的对象是否相等,就可以知道其合并范围。合并区域的所有CELL的对象相同。这样,在取数据的时候,不需要进行额外映射。而在网格控件绘制的时候,才需要合并区域查找。效率应该可以满足。我们就将这种方法叫"Ojbect/MergeID"吧。
总结列举一下四种方法:
MergeID
MergeRange List
Span
Object/MergeID
这四种方法各有利弊。其实在我们设计过程中,应该抓住一个基本点,要的是空间还是效率,还是两者都要。不同的要求,使用不同的设计。
相关文章推荐
- 网格中合并(Merge)功能的多种技术方案
- 网格中合并(Merge)功能的多种技术方案
- 网格中合并(Merge)功能的多种技术方案
- 网格中合并(Merge)功能的多种技术方案
- Docker 如何支持多种日志方案?- 每天5分钟玩转 Docker 容器技术(88)
- 【技术/方案摘要】——权限功能的实现(SSH)
- my35.net:仿兰亭集势产品标签功能方案及技术实现
- 013_HDFS文件合并上传putmarge功能(类似于hadoop fs -getmerge)
- 【线上直播】测试环境自动部署系统技术的整体方案、技术架构及功能介绍
- C# 实现多种Word邮件合并功能
- PHP开发中多种方案实现高并发下的抢购、秒杀功能
- 网格计算环境下安全认证技术方案分析
- Docker 如何支持多种日志方案?- 每天5分钟玩转 Docker 容器技术(88)
- Docker 如何支持多种日志方案?- 每天5分钟玩转 Docker 容器技术(88)
- Docker 如何支持多种日志方案?- 每天5分钟玩转 Docker 容器技术(88)
- 【数据存储全方案,详解 持久化技术】实现记住密码功能
- PHP开发中多种方案实现高并发下的抢购、秒杀功能
- Unity MeshBaker 合并网格和材质
- IE8等不支持placeholder,通过javascript实现此功能,能够兼容多种浏览器
- Android APK加壳技术方案