在前面的六篇文章之中,我们详细的讲解了甘特图使用的数据结构以及提供的接口,我们可以知道,对于SFData接口的调用方来讲,最主要的就是实体+属性的模式,可是,对于甘特图组件来讲,怎样将这些实体的属性显示在界面上并提供必要的操作,是必须解决的问题。
    针对这个问题,向日葵甘特组件的SFGantt模块使用了"数据列"的概念,"数据列"很多时候和"属性"和"节点"混淆了,我们在这里来使用简单的图说明一下这三者的关系:    
从上面的图可以看出,XML节点是数据的存储来源,而实体属性是数据在SFData运行过程之中的数据形式,而数据列则是属性在界面上的表现形式,通常为了程序逻辑易于处理,也为了用户方便记忆,这三者的名称都是相同的(这也就是为什么容易混淆的原因),例如任务的开始时间,在我们定义的XML格式之中,对应的XML节点名称为Start,而在数据初始化之后,对这项进行读写的属性名称也为Start,而为这个属性定义的数据列名称同样也是Start。
    简单的说,数据列就是显示在甘特图列表左侧的一列一列的数据,左侧列表之中每一列都是一个数据列,但是数据列并不只是在左侧的列表之中使用,实际上,甘特图之中的大部分数据显示都采用数据列的机制,一旦采用此机制,意味着可以完全配置该区域数据的显示内容,例如,在甘特图一下位置同样也使用了数据列:
    1.当用户拖动右侧滚动条的时候,显示在右上角(实时显示当前滚动到何处)的一个或者多个字段名称
    2.甘特图最左侧显示的灰色用来作为标识的列(Logo下方的列)
    3.鼠标放在任务、链接等内容的上的时候弹出的浮动提示上显示的内容
    4.甘特图图表右侧显示的任务名称
    实际上,除了涉及到复杂的绘制逻辑之外(例如甘特图的图形和箭头的形状等),甘特图上的数据显示都应该尽量使用数据列的定义来完成,这样可以保证完全的可灵活的配置显示的内容。下面我们来说明一下数据列的功能和实现。

    每一个数据列必须完成以下功能的定义:
    1.如何显示数据列的表头;
    2.如何显示数据内容;
    3.如果该列需要编辑,如何显示编辑界面;
    同时,数据列还提供了一些方法来提供给用户自定义显示的前景色、背景色、对齐方式等样式。
    当前甘特图之中,提供了SFGanttField类来自定义和管理系统之中的所有数据列的定义,所有的列都应该是SFGanttField的实例,当前,SFGanttField,构造的时候,可以指定以下参数:
参数名称 参数默认值 参数说明
headText '' 默认该列的列表头文本
bodyData 必须指定 数据显示需要的属性名称,如果有多个用逗号分隔,当其中一个属性发生变化的时候,将自动引发该数据列的重绘
inputData 可以编辑的时候必须指定 编辑模式写入的属性名称,只能是一个
width 100 默认该列的显示宽度
ReadOnly false 当设置为
headStyle {textAlign:'center'} 默认列表头的显示y
bodyStyle {textAlign:'left'} 默认内容显示和编辑时的的样式
inputStyle {} 默认内容编辑时的附加样式

    例如,我们需要定义一个用来显示UID的列的时候,可以这样使用:
    SFGanttField.setTaskField("UID", new SFGanttField({width:36,bodyData:'UID',headText:"UID",ReadOnly:true,bodyStyle:{textAlign:'center'}}));
    这样,这个数据列被命名为"UID",这个列宽度为36,显示UID属性的内容,在列表头之中显示"UID",同时这个字段只读(UID是不允许变化的),默认数据居中显示,在定义之后,可以通过SFGanttField.getTaskField("UID")来返回这个数据列;
    一个数据列定义完成之后,还可以使用如下的方法来对数据列进行设置(注意,这些设置不能影响已经绘制完成的内容):
方法名称 方法介绍
setWidth(width) 设置列的显示宽度
setHeadText(text) 设置列表头文本
setHeadAlign(align) 设置列表头对齐方式
setHeadColor(color) 设置列表头颜色
setHeadBgColor(color) 设置列表头背景色
setBodyAlign(align) 设置列内容对齐方式
setBodyColor(color) 设置列内容颜色
setBodyBgColor(color) 设置列内容背景颜色
setReadOnly(ReadOnly) 设置列是否只读

    以上通过new SFGanttField来生成的列通常是采用默认的模式来进行列表头、数据内容、输入模式的绘制,实际上很多情况下,存在需要自定义绘制模式的数据列,因此,系统提供了几个其他的类,这些类继承了SFGanttField,而包含自己的数据显示逻辑,下面逐一的介绍这些类:

    1.SFGanttFieldBool,这个类用来进行Bool类型属性的显示和编辑,如果该数据列不是ReadOnly,则无论是输入模式还是显示模式,都是显示为一个复选框,点击复选框就更改了该属性,如果是ReadOnly模式,直接显示文字"是"或"否",该类使用方法如下:
        SFGanttField.setTaskField("Critical", new SFGanttFieldBool({width:30,bodyData:'Critical',headText:'关键'}));
    2.SFGanttFieldPercent,这个类用来进行百分比数值的显示和编辑,该数据列会在显界面上显示一个进度条,进度条上显示着进度的数值,如果该数据列并不是ReadOnly,则可以拖动进度条右侧的竖线更改进度的值,该类的使用方法如下:
        SFGanttField.setTaskField("PercentComplete", new SFGanttFieldPercent({width:100,bodyData:'PercentComplete',headText:'完成百分比'}));
    3.SFGanttFieldSelected,这个是一个特殊的列定义,这个列用来代表某一列在甘特图上的选中状态,任何方式造成某一列被选中的时候,这一列的复选框将会被勾上,而点击该复选框,也会修改该列的选中状态,当然,如果这一列被设置为只读,和SFGanttFieldBool一样,也只会显示一个文字"是"或"否",该类的用法如下:
        SFGanttField.setTaskField("Selected", new SFGanttFieldSelected({width:30,headText:'选中'}));//因为甘特图对选中的支持属性是一定的,因此,不需要指定字段
    4.SFGanttFieldLongText,这个类是用来支持多行文本的编辑的类,该字段在进入编辑状态的时候,将会显示一个多行的输入框,该类的使用方法如下:
        SFGanttField.setTaskField("Notes", new SFGanttFieldLongText({width:100,bodyData:'Notes',headText:'备注'}));
    5.SFGanttFieldDateTime,这个类用来支持对日期时间字段的显示和编辑,需要说明的是,向日葵甘特图开发过程之中主要转准于向日葵的核心逻辑,因此并没有集成任何辅助输入日期时间的控件,当然,向日葵甘特图可以轻松的和这些控件结合来编辑日期,这一点在后面会专门提到,而这里的日期编辑,依然是需要用户手工输入日期格式的,该类使用方法如下:
        SFGanttField.setTaskField("Start", new SFGanttFieldDateTime({width:100,bodyData:'Start',headText:'开始时间',disableSummaryEdit:true}));
        可以看出,这个类多了一个disableSummaryEdit参数,这个参数可以指定是否允许对大纲任务的日期进行编辑;
    6.SFGanttFieldDuration,这个类用来实现工期的计算,也就是计算两个日期时间字段期间的工期,需要说明的是,这里的工期计算是非常简单的去除周末的计算方法,并没有考虑节假日,也没有通过甘特图之中的工作日历进行计算,该类的使用方法如下:
        SFGanttField.setTaskField("Duration", new SFGanttFieldDuration({width:60,bodyData:'Start,Finish',headText:'工期'}));
    7.SFGanttFieldSelecter,这个类用来实现一个字典类的显示和选择,例如任务的限制类型字段,该字段在XML节点之中之中通常是一个数字,而在显示界面上应该显示成清晰易懂的格式,而这个类就是用来做这个处理的,例如们要实现一个限制类型的数据列,应该采用这个方式:
        var list={0:'越早越好','越晚越好',1:'必须开始于',2:'必须完成于',3:'不得早于...开始',4:'不得晚于...开始',5:'不得早于...完成',6:'不得晚于...完成'};
        SFGanttField.setTaskField("ConstraintType", new SFGanttFieldSelecter({width:120,bodyData:'ConstraintType',headText:names.ConstraintType,options:list}));
        首先按照key-value的模式建立一个object对象,每个key是该任务的属性值,可以为数字也可以为字符串,而每个value是显示的内容,然后将这个对象作为该字段的options参数即可,这个列在进入编辑状态的时候,会显示一个下拉选单供用户编辑。
    8.SFGanttFieldTreeName,这个就是对树形结构的数据实现显示可折叠的+/-树的字段类型,该类型比较固定,能够配置的参数比较少,该字段在进入编辑状态的时候,所编辑的字段是该实体的名称,该类的使用方法如下:
        SFGanttField.setTaskField("Name", new SFGanttFieldTreeName({width:120,'名称'}));
    9.SFGanttFieldIcon,这个类是实现任务的状态图标列的功能,当前支持了如下图标的显示:
        a.当任务已经完成的时候(PercentComplete为100),显示一个已完成的对钩图标,鼠标放在图标上,显示何时完成了该任务
        b.当任务存在1以上的约束类型(ConstraintType,ConstraintDate)的时候,会显示约束图标,鼠标放在图标上,会显示约束详细信息
        c.当任务存在备注信息的时候,显示一个备注图标,鼠标放在图标上,显示备注详细信息
        d.当任务指定了超级链接的时候(HyperlinkAddress,Hyperlink)显示超级链接图标,鼠标放在图标上,显示链接信息,点击图标将会在新窗口之中打开此链接
       虽然从理论上讲可以为这个类添加更多的图标支持,但是因为比较复杂,不在这里做详细的介绍,仅仅提供一个这个类的使用范例(演示任务已完成的实现方法):

        var field=new SFGanttFieldIcon({width:32,headText:'状态'});//这一列默认就是只读的,并且根据支持的图标个数来确定bodyData的值
        field.addIcon(function(element,gantt)//从这里添加一个图标支持函数
        {
                if(element.PercentComplete!=100){return;}//如果任务没有完成,则返回空,不显示任何图标
                var img=this.createImage();//创建一个图标
                img.src="http://……"//在这里指定图标文件的地址
                SFTooltip.setTooltip(img,function()//这里指定鼠标放在图标上之后如何生成浮动提示信息
                {
                        var tooltip=gantt.getTooltip();//获得甘特图的默认工具条提示类
                        var str="该任务在某年月日完成"//这里是提示信息的内容
                        tooltip.setContent(document.createTextNode(str));//设置显示该提示内容
                        return tooltip;
                });
                return img;
        },"PercentComplete");//最后一个参数定义了当任务的PercentComplete属性变化的时候,该图标需要重绘,如果有多个,用逗号分隔

    以上介绍了现在甘特图之中的所有支持的数据列类型,为了使用上的方便,实际上我们也已经定义好了一些数据列可以供直接使用,在下面的列表之中,我们列出了系统集成的数据列类型和相关信息,作为参考:

实体类型 数据列名称 实现类 bodyData inputData 是否只读 说明
任务 Empty SFGanttField

true 一个完全空的列,用来实现什么都不显示
任务 UID SFGanttField UID
true 显示UID
任务 ID SFGanttField ID
true 显示ID
任务 name SFGanttField Name Name
显示一个简单的名称,并允许更改
任务 Name SFGanttField Name,Summary,Collapse Name
显示并更改名称,并按照大纲级别留空,并给大纲提供可折叠的图标
任务 OutlineNumber SFGanttField OutlineNumber
true 显示大纲级别
任务 StatusIcon SFGanttFieldIcon 动态实现
true 显示任务的状态图标
任务 Duration SFGanttFieldDuration Start,Finish
true 显示工期
任务 Start SFGanttFieldDateTime Start Start
显示并更改任务开始时间
任务 Finish SFGanttFieldDateTime Finish Finish
显示并更改任务结束时间
任务 Notes SFGanttFieldLongText Notes Notes
显示并更改任务的备注信息
任务 ClassName SFGanttFieldSelecter ClassName ClassName
显示并更改任务的显示样式
任务 ConstraintType SFGanttFieldSelecter ConstraintType ConstraintType
显示并更改任务的约束类型
任务 ConstraintDate SFGanttFieldDateTime ConstraintDate ConstraintDate
显示并更改任务的约束时间
任务 Critical SFGanttFieldBool Critical Critical
显示并切换该任务是否是关键任务
任务 Selected SFGanttFieldSelected 内部实现
true 显示并切换任务的选中状态
任务 Resource SFGanttField 内部实现
true 显示给任务分配的资源
任务 PercentComplete SFGanttFieldPercent PercentComplete PercentComplete
显示并调整任务的完成百分比
任务 ActualStart SFGanttFieldDateTime ActualStart ActualStart
显示并更改任务实际开始时间
任务 ActualFinish SFGanttFieldDateTime ActualFinish ActualFinish
显示并更改任务实际完成时间
任务 ActualDuration SFGanttFieldDuration ActualStart,ActualFinish
true 显示任务的实际工期
任务 BaselineStart SFGanttFieldDateTime BaselineStart BaselineStart
显示并更改任务的基准开始时间
任务 BaselineFinish SFGanttFieldDateTime BaselineFinish BaselineFinish
显示并更改任务的基准结束时间
链接 Type SFGanttFieldSelecter Type Type
显示并更改链接的类型
链接 FromTask SFGanttFieldElement 内部实现
true 显示链接的起始任务
链接 ToTask SFGanttFieldElement 内部实现
true 显示链接的结束任务

    这里就介绍完成了所有目前向日葵甘特图支持的数据列的信息,每一个数据列都可以对属性进行重新设置或重写,从而实现自己需要的复杂的功能逻辑,假如需要自定义数据列类型,需要自定义一个继承 SFGanttField的类,而这个过程相对比较复杂,因此,不在这里做详细的介绍。
posted on 2009-05-25 22:46  运筹帷幄  阅读(1463)  评论(0编辑  收藏  举报