雪連,李家
(遼寧師范大學 城市與環境學院, 遼寧 大連 116029)
摘要:針對B/S模式下甘特圖交互操作性差、傳統的單線條甘特圖不便于對比分析項目的計劃和實施情況等問題,提出了利用列模板技術實現雙線條甘特圖的解決方案。甘特圖中包含上下兩根線條,分別代表項目的進度計劃和實施情況。用戶通過簡單地點擊甘特圖可以對計劃進行微調,對實施進行記錄。使用結果表明,這種雙線條甘特圖擴展了甘特圖的使用方式,可以直觀地對比檢查計劃和實施情況;交互操作性好,易于掌握和使用;基于通用的列模板技術,易于開發。
關鍵詞:項目進度管理;甘特圖;列模板;DevExpress ASPxGridView
0引言
項目進度控制是項目計劃控制的中心任務和重要內容,它直接關系到項目能否按期完成,并最終影響項目的成功[1]。甘特圖是進行工期計劃和控制的有效工具,它以橫坐標表示時間,縱坐標表示項目分解的各項工作任務, 清楚地表達了活動的開始時間、結束時間和持續時間[2]。目前已經可以基于B/S模式繪制甘特圖[25]。
以往所見的甘特圖是一條線條圖,表示在整個期間上計劃或實施情況。這種方式不能直觀表達計劃方案與實際完成情況的對比,不便于檢查和大數據挖掘。另外,受計算機軟件技術發展所限,有些以Web方式實現的甘特圖只能將數據顯示為圖形,不能與圖形進行直觀的互操作,反作用于數據;有些甘特圖軟件的開發方法過于復雜,不易實現。
由于在使用甘特圖進行項目管理系統開發時遇到了上述問題,因此在工作中以提高甘特圖的互操作性和直觀對比計劃和實施情況為研究目的,基于B/S模式以常用的列模板技術實現了甘特圖。系統中采用上下兩根線條表示一項任務的計劃和實施情況,如圖1所示。上面的計劃條如為灰色表示該時段有這項任務的計劃,下面的實施條如為黑色表示該時段的任務已實施。在計劃階段,用戶可以通過選擇起止日期對整個區間設定計劃,可以點擊某個時間段的任務塊進行微調,取消或設定該時間段的計劃。在實施階段,用戶可以在完成某個時間段的任務后點擊該時間段的任務塊,使該任務塊中下面的實施條從灰變紅,表示實施了該時段的任務。系統擴展了甘特圖的使用方式,提供了較好的交互操作功能和用戶體驗,同時因采用了常用的模板技術開發而易于實現。
1系統設計與實現
系統的實現方法如下:
(1)確定計劃和實施值在數據庫中存儲方式。因時間段很多,不能為每個時間段建立一個字段,各時間段的計劃和實施值在數據庫要分別合并存儲為一個字符串;
(2)將數據庫中的表取到程序中后,自動增加各時間段的字段,以便用戶可以對每一個時間段中的任務塊進行交互處理;
(3)將數據表每條記錄中的計劃和實施值轉換為各時間段字段的值;
(4)將步驟(2)~(3)改造后的數據表綁定到ASPxGridView后,將各時間字段的值表現為任務塊圖片;
(5)為每個任務塊圖片的鼠標點擊事件給出客戶端響應函數,改變圖片的顏色。
1.1計劃、實施數據在數據庫中的存儲
系統中需將每項任務的起止日期、計劃、實施情況記錄到數據庫中。本系統中以半天作為最小時間段,為節省存儲空間,沒有為每個時間段建立一個字段,而是將所有時間段的計劃值和實施值分別記錄在一個字符串字段中,用“1”或“0”表示該時間段是否有值,每個字符在串中的位置隱含了其代表的時間段。例如,圖2中,第一條記錄中,計劃字段中的第一個字符“1”表示9月6日上午有方案制定任務,實施字段中的第三個字符“1”表示9月7日上午實施了方案制定任務。
程序中制定計劃并存儲的主要代碼為:
string plan = "", real = "";
for (DateTime date1 = (DateTime)newValues["起始日期"]; date1 <= (DateTime)newValues["截止日期"]; date1 = date1.AddDays(1))
{
plan += "11";
real += "00";
}
row["計劃"] = plan;
row["實施"] = real;
代碼中newValues["起始日期"]和newValues["截止日期"]為用戶在為某項任務制定計劃界面上輸入的起止日期,row為在數據表中為該任務新增的一條記錄,制定計劃時每天的計劃值為“11”,實施值為“00”,將其累加后賦給row中對應的字段值,更新到數據庫中。
1.2增加時間段字段
圖2中的數據的前兩行在系統中的顯示結果如圖1所示。圖1中各時間段字段不是數據庫中已有字段,而是將數據取到程序中后,根據起止日期為數據表中增加的字段。主要代碼如下:
TimeSpan ts = date2 - date1;
string[] fields = new string[(ts.Days + 1) * 2];
for (int i = 0; i < fields.Length; date1 = date1.AddHours(12), i++)
{
string s = date1.Year.ToString().Substring(2) + "-" + date1.Month + "-" + date1.Day;
if (date1.Hour < 12)
s += "上午";
else
s += "下午";
fields[i] = s;
table.Columns.Add(s);
}
代碼中date1、date2為要顯示的時間段的起止日期,fields為根據起止日期建立的時間字段名數組,循環中根據起止日期生成每個時間段字段的名稱,最后增加到數據表table的列中。
1.3確定記錄中時間段字段的值
時間段字段中的值是在程序中根據計劃、實施字段值生成的,代碼為:
row[s1] = "" + row["計劃"].ToString()[k] + row["實施"].ToString()[k];
代碼中row為某一條任務記錄,s1為某一個時間段的字段名,row["計劃"].ToString()[k]為計劃字段中從起始日期開始第k個半天的值,row["實施"].ToString()[k]為實施字段中第k個半天的值,row[s1]為計算后得到的s1字段的值,它可能的值為:“00”、“01”、“10”、“11”。以其中兩例說明:“10”值采用列模板技術顯示在界面中時對應的任務塊圖片名稱為 “10.png”,該圖片的計劃條為灰色,實施條為淺灰色;“11”對應的任務塊圖片名稱為 “11.png”,該圖片的計劃條灰色,實施條為黑色。
1.4利用列模板將時間字段值表現為任務塊圖片
ASP.NET為了更精確地控制列的內容和布局,在DataGrid中支持綁定列和模板列的定義,該模板列可創建HTML文本和服務器控件的組合,以便為列設計自定義布局[6]。這種列模板技術易于掌握,為表現復雜的頁面提供了方便的工具。本系統利用DevExpress 的ASP.NET 控件庫ASPxGridView中的列模板表現甘特圖。
程序中取到數據表增加時間段字段并為每條記錄的時間段字段賦值后,綁定到ASPxGridView中,利用ASPxGridView的列模板將表中每行中每個時間段字段列顯示為與該列字段值對應的任務塊圖片。代碼為:
(ASPxGridView1.Columns[i]as GridViewDataColumn). DataItemTemplate = new scheduleItemTemplateG( ASPxGridView1.Columns[i].FieldName);
代碼中Columns[i]為某一時間段列,DataItemTemplate為該列的數據模板屬性,scheduleItemTemplateG為自定義的模板類,在該類中為每行每列的值顯示相應的圖片。主要代碼如下:
public class scheduleItemTemplateG : System.Web.UI.Page, ITemplate
{
string field;
public scheduleItemTemplateG(string field)
{
this.field = field;
}
public void InstantiateIn(Control container)
{
…
GridViewDataItemTemplateContainer gridContainer = (GridViewDataItem TemplateContainer)container;
ASPxHyperLink link = new ASPxHyperLink();
link.ImageUrl = imgPath + gridContainer.Text + ".png";
…//為超鏈增加客戶端點擊事件處理函數
gridContainer.Controls.Add(link);
}
}
代碼中在該類的構造函數中傳入了該列時間字段的名稱,記錄在field成員中。InstantiateIn函數在該行該列顯示時自動調用,傳來了該行該列中的控件容器。函數中imgPath為圖片所在路徑,gridContainer.Text為控件中顯示的字符串,其值為該列的計劃字符+實施字符,imgPath + gridContainer.Text + ".png"為包含路徑在內的圖片名稱,將其賦給新建超鏈link的ImageUrl屬性,以便在超鏈中顯示該圖片。最后將超鏈加入到該控件容器中,顯示為圖片。
1.5處理任務塊圖片的鼠標點擊事件
在計劃制定時可以進行微調,如圖3所示,用戶點擊“微調”按鈕,然后點擊某個時段的任務塊,就能取消或設定該時段的計劃。類似地,點擊“執行任務”按鈕可以在實施時標識某個時段的任務已執行,如圖4所示。這需要對每個任務塊超鏈的客戶端點擊事件給出響應函數,以便在客戶端改動任務塊圖片的計劃條或實施條的顏色,同時改動該任務塊對應于計劃字段或實施字段字符串中的那個字符的值。
為此,在上述代碼“為超鏈增加客戶端點擊事件處理函數”注釋處增加以下代碼:
DateTime startDate = (DateTime)gridContainer.Grid.GetRowValues(gridContainer. VisibleIndex, "起始日期");
DateTime date = Convert.ToDateTime("20" + field.Replace("上午?", "").Replace("下午", ""));
int indexInValueArray = (date - startDate).Days*2 + (field.IndexOf("上午") > 0 ? 0 : 1);
link.ClientSideEvents.Click = "function(s,e){onLinkClick(e," + gridContainer. VisibleIndex + "," + indexInValueArray + ")}";
代碼中startDate為表中該行任務的起始日期,date為該列字段名(某天的上午或下午)代表的日期,indexInValueArray為該時間字段列在時間字段數組中的序數,也就是該列在計劃和實施字段中對應字符的下標。onLinkClick為超鏈的客戶端Click事件的響應函數,響應函數中傳入了該列所在的行數和該列在計劃和實施字段中對應字符的下標。JavaScript中onLinkClick函數的主要代碼如下:
function onLinkClick(e, rowIndex, indexInValueArray)
{
if (document.getElementById("rowIndex_button").value.indexOf("微調") > 0)
var w = -2;
else
var w = -1;
var n = e.htmlElement.innerHTML.indexOf(".png");
var s = e.htmlElement.innerHTML.substring(0, n + w) + s1 + e.htmlElement.innerHTML. substring(n + w + 1);
e.htmlElement.innerHTML = s;
…
var value = document.getElementById("valueArray").value;
document.getElementById("valueArray").value = value.substring(0, indexInValueArray) + s1 + value.substring(indexInValueArray + 1);
}
代碼中e.htmlElement為事件中鼠標所點超鏈,n為擴展名“.png”在該超鏈的innerHTML中的位置。如果在計劃階段點擊“微調”按鈕修改計劃(見圖3),則w=-2,s1對應圖片名中的第一個字符即計劃字符;如果點擊“執行任務”或“結束任務”按鈕(見圖4),則w=-1,s1對應圖片名的第二個字符即實施字符。s1 的值為跟頭鍵值,原來為“0”則變為“1”,原來為“1”則變為“0”。改動了e.htmlElement.innerHTML中圖片名后,相應的任務塊中的計劃條或實施條也就改變了顏色。
document.getElementById("valueArray").value為鼠標所在行中計劃列或實施列的字符串值,當用戶點擊“微調”、“執行任務”或“結束任務”按鈕時取得,保存在客戶端hidden標簽valueArray中。在鼠標點擊事件中,該值中鼠標所點時間段對應的字符也要相應地改為s1的值,臨時記錄在客戶端,點擊“更新”按鈕時再一起更新到數據庫中。
2結論
本系統基于DevExpress ASPxGridView控件的列模板技術實現,已用于房地產評估項目管理系統中。使用結果表明,這種雙線條甘特圖可以直觀地對比檢查計劃和實施情況,打破了傳統的單線條甘特圖的使用方式,表現力更豐富;通過簡單點擊就可以對每個任務塊進行交互操作,克服了以往B/S模式下的甘特圖只能看不能交互操作的弊病;根據本文給出的實現方法,可以很容易地采用ASP.NET 中的Gridview中的模板技術實現,或利用其他開發平臺中的相關技術實現。
參考文獻
[1] 肖偉,趙嵩正. 基于OLE技術的項目甘特圖設計與實現[J]. 微型電腦應用, 2003,19(10):20-22.
[2] 梁海燕,趙嵩正. 基于JSP技術工程項目甘特圖的設計與實現[J]. 計算機應用與軟件, 2006,23(8):43-44,59.
[3] 夏臻,陳建勛. 基于SVG技術的甘特圖繪制組件設計與實現[J]. 計算機工程與設計, 2010,31(10):2354-2357.
[4] 王俊,楊濤. 基于JSP技術的項目甘特圖設計與實現[J]. 現代制造工程,2008(2):80-83.
[5] 安思,張菹,葉鑫. 基于AMT算法的時間序列數據在甘特圖中的應用[J]. 計算機與數字工程, 2011,39(6):146-149.
[6] 李林靜. 基于DataGrid模板列的分析及應用[J].計算機系統應用,2009,18(3):57-61.