控件之美_甘特图

记得曾经做过一个项目管理软件,前些天看到有些人问起甘特图,想起自己曾经做过一个控件(使用ASP.NET+VB.NET),翻箱倒柜就找了出来,许久以前的东西了,现在看着有点不堪入目了,但想当初也是很费了一番功夫的,为了便于阅读,就把一些枝节的东西去掉了,留下主体的部分,也算个总结吧。

这个控件提供了几个公开的属性,分别是BeginDate(开始日期),EndDate(结束日期)ShowStyle(显示类型,提供三种方式,分别是日视图,周视图,月视图,这个地方用个枚举GttShowStyle传入),Data(传入的数据,是个DataSet,甘特图就是根据里面的数据显示当前的进度),提供了一个公开的方法ReFresh,属性设置完毕后,使用这个方法,就可以显示出甘特图。首先建一个用户控件,空间上拖入个table控件,看html部分应该能够看到<asp:table id="gtttb" runat="server" GridLines="Both"></asp:table>

后台代码部分:

Imports System.Text

Imports System.Math

Imports System.Web.UI.HtmlControls

Imports System.Drawing

Public MustInherit Class gtt

    Inherits System.Web.UI.UserControl

    '显示类型图,开始日期,结束日期(每个基本格为一天)

    Private m_ShowStyle As GttShowStyle

    Private m_BeginDate As Date

    Private m_EndDate As Date

    Private m_data As DataSet

Private tbcell As TableCell     单元格

    Private m_PreDays As Integer '在日视图中使用,为了从周一开始,可以把起始日期前置,此为前置的天数

    Protected WithEvents gtttb As System.Web.UI.WebControls.Table

     Public Sub ReFresh()

        If m_data.Tables(0).Rows.Count > 0 Then

            BindFace()

        End If

    End Sub

 

 

    '根据显示类型

   Private Sub BindFace()

        gtttb.CellPadding = 0

        gtttb.CellSpacing = 0

        gtttb.BorderColor = Color.FromArgb(153, 153, 153)

        gtttb.BackColor = Color.FromArgb(240, 240, 232)

        Select Case m_ShowStyle

            Case GttShowStyle.ShowDayView    ‘日视图

                ShowDayView()

            Case GttShowStyle.ShowMonthView   ‘月视图

                ShowMonthView()

            Case GttShowStyle.ShowWeekView    ‘周视图

                ShowWeekView()

        End Select

        ShowDetail()

    End Sub

 

 

    '显示各种视图的通用部分(包括任务名称,年、月名称)

    Private Sub ShowComName()

        Dim tbrowY As TableRow = New TableRow()

        tbrowY.BackColor = Color.FromArgb(216, 200, 168)

        '设置任务名称

        Dim tbcell As TableCell = New TableCell()

        tbcell.RowSpan = "2"

        tbcell.Wrap = False

        tbcell.Text = " "

        tbcell.Font.Size = FontUnit.Parse(10)

        tbrowY.Cells.Add(tbcell)

 

 

        Dim Width As Integer                            '宽度

        Dim tmpdate As Date = m_BeginDate               '临时数据

        m_PreDays = ReturnDayOfWeek(tmpdate) - 1        '返回是本周的第几天

        '设置日期头(yyyy-mm'包括三种格式

        Select Case m_ShowStyle

            Case GttShowStyle.ShowDayView

                '日视图,标头显示,年月日,不过只显示每周开头的日期,下面表示为星期,所以用7作为步进 ok

                tmpdate = m_BeginDate.AddDays(-m_PreDays)           '从每周一开始

                '获得最后一周

                Dim tmpenddayofweek As Integer = ReturnDayOfWeek(m_EndDate)

                If tmpenddayofweek <> 6 Then

                    m_EndDate = m_EndDate.AddDays(7 - tmpenddayofweek + 1)

                End If

                While tmpdate.CompareTo(m_EndDate) < 0

                    tbcell = New TableCell()

                    Width = 7

                    tbcell.Text = tmpdate.Year & "-" & tmpdate.Month & "-" & tmpdate.Day

                    tbcell.HorizontalAlign = HorizontalAlign.Center

                    tbcell.ColumnSpan = Width

                    tbcell.Wrap = False

                    tbcell.Font.Size = FontUnit.Parse("9")

                    tbrowY.Cells.Add(tbcell)

                    tmpdate = tmpdate.AddDays(7)

                End While

                gtttb.Rows.Add(tbrowY)

            Case GttShowStyle.ShowMonthView

                '月视图(标头以年为单位) ok

                Dim DaysOfYear As Integer

                While (tmpdate.Year <= m_EndDate.Year)

                    tbcell = New TableCell()

                    If tmpdate.IsLeapYear(tmpdate.Year) Then

                        DaysOfYear = 366

                    Else

                        DaysOfYear = 365

                    End If

                    Select Case tmpdate

                        Case m_BeginDate

                            '第一个年

                            Width = DaysOfYear - tmpdate.DayOfYear + 1

                        Case Else

                            If tmpdate.Year = m_EndDate.Year Then

                                '最后一个年

                                Width = m_EndDate.DayOfYear

                            Else

                                '其他的年份

                                Width = DaysOfYear

                            End If

                    End Select

                    '起始日期与结束日期是同一年的情况

                    If m_BeginDate.Year = m_EndDate.Year Then

                        Width = m_EndDate.Subtract(m_BeginDate).Days + 1

                    End If

                    tbcell.Text = tmpdate.Year.ToString

                    tbcell.HorizontalAlign = HorizontalAlign.Center

                    tbcell.ColumnSpan = Width

                    tbcell.Wrap = False

                    tbcell.Font.Size = FontUnit.Parse("9")

                    tbrowY.Cells.Add(tbcell)

                    tmpdate = tmpdate.AddYears(1)

                End While

                gtttb.Rows.Add(tbrowY)

            Case GttShowStyle.ShowWeekView

                '周视图(标头以月为单位)

                Dim DaysOfMonth As Integer

                While (tmpdate.CompareTo(m_EndDate) < 0) Or (tmpdate.CompareTo(m_EndDate) > 0 And tmpdate.Subtract(m_EndDate).Days < 7)

                    tbcell = New TableCell()

                    DaysOfMonth = tmpdate.DaysInMonth(tmpdate.Year, tmpdate.Month)

                    If tmpdate.Year = m_BeginDate.Year And tmpdate.Month = m_BeginDate.Month Then

                        '如果是第一个月

                        Width = DaysOfMonth - tmpdate.Day + 1

                    End If

                    If (tmpdate.Year < m_EndDate.Year) Or (tmpdate.Year = m_EndDate.Year And tmpdate.Month < m_EndDate.Month) Then

                        '如果是当中的月份

                        Width = DaysOfMonth

                    End If

                    If tmpdate.Year = m_EndDate.Year And tmpdate.Month = m_EndDate.Month Then

                        '如果是最后的月份

                        Width = m_EndDate.Day

                    End If

                    If m_BeginDate.Year = m_EndDate.Year And m_BeginDate.Month = m_EndDate.Month Then

                        Width = m_EndDate.Subtract(m_BeginDate).Days + 1

                    End If

                    tbcell.Text = tmpdate.Year & "-" & tmpdate.Month

                    tbcell.HorizontalAlign = HorizontalAlign.Center

                    tbcell.ColumnSpan = Width

                    tbcell.Wrap = False

                    tbcell.Font.Size = FontUnit.Parse("9")

                    tbrowY.Cells.Add(tbcell)

                    tmpdate = tmpdate.AddMonths(1)

                End While

                gtttb.Rows.Add(tbrowY)

        End Select

    End Sub

 

 

    '显示日视图

    Private Sub ShowDayView()

        ShowComName()

        '设置天

        Dim tmpdate As Date = m_BeginDate.AddDays(-m_PreDays)

        Dim tbrowB As TableRow

        tbrowB = New TableRow()

        tbrowB.BackColor = Color.FromArgb(216, 200, 168)

        While tmpdate.CompareTo(m_EndDate) < 0

            tbcell = New TableCell()

            tbcell.Text = ReturnWeek(tmpdate.DayOfWeek)

            tbrowB.Cells.Add(tbcell)

            tbcell.Font.Size = FontUnit.Parse("9")

            tmpdate = tmpdate.AddDays(1)

        End While

        gtttb.Rows.Add(tbrowB)

    End Sub

 

 

    Private Function ReturnWeek(ByVal dayofweek As DayOfWeek) As String

        Select Case dayofweek

            Case dayofweek.Monday

                Return ""

            Case dayofweek.Tuesday

                Return ""

            Case dayofweek.Wednesday

                Return ""

            Case dayofweek.Thursday

                Return ""

            Case dayofweek.Friday

                Return ""

            Case dayofweek.Saturday

                Return ""

            Case dayofweek.Sunday

                Return ""

        End Select

    End Function

 

 

    '返回当前日是周几

    Private Function ReturnDayOfWeek(ByVal datetmp As Date) As Integer

        Select Case datetmp.DayOfWeek

            Case DayOfWeek.Monday

                Return 1

            Case DayOfWeek.Tuesday

                Return 2

            Case DayOfWeek.Wednesday

                Return 3

            Case DayOfWeek.Thursday

                Return 4

            Case DayOfWeek.Friday

                Return 5

            Case DayOfWeek.Saturday

                Return 6

            Case DayOfWeek.Sunday

                Return 7

        End Select

    End Function

 

 

    '显示周视图(还是由天为单位)

    Private Sub ShowWeekView()

        ShowComName()

        '设置周

        Dim width As Integer

        Dim tmpdate As Date = m_BeginDate

        Dim tbrowB As TableRow = New TableRow()

        tbrowB.BackColor = Color.FromArgb(216, 200, 168)

        Dim WeekCount As Integer = 1

        While (tmpdate.CompareTo(m_EndDate) < 0) Or (tmpdate.CompareTo(m_EndDate) > 0 And tmpdate.Subtract(m_EndDate).Days < 7)

            tbcell = New TableCell()

            tbcell.Text = "" & WeekCount & ""

            tbcell.ColumnSpan = 7

            If (tmpdate.CompareTo(m_EndDate) > 0 And tmpdate.Subtract(m_EndDate).Days < 7) Then

                tbcell.ColumnSpan = tmpdate.Subtract(m_EndDate).Days

            End If

            tbcell.Wrap = False

            tbcell.Font.Size = FontUnit.Parse("9")

            tbrowB.Cells.Add(tbcell)

            tmpdate = tmpdate.AddDays(7)

            WeekCount += 1

        End While

        gtttb.Rows.Add(tbrowB)

    End Sub

 

 

    '显示月视图 ok

    Private Sub ShowMonthView()

        ShowComName()

        '设置月

        Dim tmpdate As Date = m_BeginDate

        Dim tbrowB As TableRow = New TableRow()

        tbrowB.BackColor = Color.FromArgb(216, 200, 168)

        Dim DaysOfMonth As Integer

        Dim MonthCount As Integer

        While (tmpdate.Year < m_EndDate.Year) Or (tmpdate.Year = m_EndDate.Year And tmpdate.Month <= m_EndDate.Month)

            '设置宽度

            DaysOfMonth = Date.DaysInMonth(tmpdate.Year, tmpdate.Month)

            Dim width As Integer

            Select Case tmpdate

                Case m_BeginDate

                    '第一个月

                    width = DaysOfMonth - tmpdate.Day + 1

                Case Else

                    If tmpdate.Year = m_EndDate.Year And tmpdate.Month = m_EndDate.Month Then

                        '最后一个月

                        width = m_EndDate.Day

                    Else

                        '其他的月份

                        width = tmpdate.DaysInMonth(tmpdate.Year, tmpdate.Month)

                    End If

            End Select

            tbcell = New TableCell()

            tbcell.Text = tmpdate.Month

            tbcell.ColumnSpan = width

            '用最小宽度

            tbcell.Wrap = False

            tbcell.Font.Size = FontUnit.Parse("9")

            tbrowB.Cells.Add(tbcell)

            tmpdate = tmpdate.AddMonths(1)

            MonthCount += 1

        End While

        gtttb.Rows.Add(tbrowB)

    End Sub

 

 

    '显示下面的图形

    '每个图形部分必须包含三个单元格,中间的单元格背景色作为任务,前面显示的是任务的进度

    Private Sub ShowDetail()

        Dim drow As DataRow

        ' = "<img src='../../img/button/depnull.gif' border=0 height=5 width=" & layer * 20 & ">"

        For Each drow In m_data.Tables(0).Rows

            Dim tbrow As TableRow = New TableRow()

            Dim tbname As TableCell = New TableCell()

            Dim tbcell1 As TableCell = New TableCell()

            Dim tbcell2 As TableCell = New TableCell() '此处显示图形

            Dim tbcell3 As TableCell = New TableCell()

            Dim firstwidth As Integer

            Dim midwidth As Integer

            Dim endwidth As Integer

            If ShowStyle = GttShowStyle.ShowDayView Then

                firstwidth = CType(drow("bdate"), Date).Subtract(CType(m_BeginDate, Date).AddDays(-m_PreDays)).Days

                midwidth = CType(drow("edate"), Date).Subtract(CType(drow("bdate"), Date)).Days + 1

                endwidth = CType(m_EndDate, Date).Subtract(CType(drow("edate"), Date)).Days + 1

            Else

                firstwidth = CType(drow("bdate"), Date).Subtract(CType(m_BeginDate, Date)).Days + 1

                midwidth = CType(drow("edate"), Date).Subtract(CType(drow("bdate"), Date)).Days + 1

                endwidth = CType(m_EndDate, Date).Subtract(CType(drow("edate"), Date)).Days + 1

            End If

            If drow("layer") < 3 Then

                tbname.Text = "<img src='../../img/button/depnull.gif' border=0 height=3 width=" & (drow("layer") + 1) * 20 & ">" & "<img src='../../img/number" & drow("layer") + 2 & ".gif' border=0 height=12  >" & drow("name")

            Else

                tbname.Text = "<img src='../../img/button/depnull.gif' border=0 height=3 width=" & (drow("layer") + 1) * 20 & ">" & drow("name")

            End If

            tbname.Wrap = False

            tbname.Font.Size = FontUnit.Parse("9")

            tbcell1.ColumnSpan = firstwidth

            tbcell2.ColumnSpan = midwidth

            '显示图形

            tbcell2.VerticalAlign = VerticalAlign.Middle

            tbcell2.BackColor = Color.SteelBlue

 

 

            Dim btn As New Button()

            Dim width As String = (drow("taskpercent") * 100).ToString & "%"

            btn.Width = Unit.Parse(width)

            '根据任务的执行情况,设定背景色

            Select Case drow("state")

                Case True    '已完成

                    btn.BackColor = Color.Green

                Case False   '进行中

                    btn.BackColor = Color.GreenYellow

            End Select

            btn.Height = Unit.Parse(6)

            btn.Enabled = False

            '根据是否超时,超支,确定边框的颜色

            If drow("cost") > drow("plancost") Or (CType(drow("edate"), Date).CompareTo(Date.Now) < 0 And Not drow("state")) Then

                tbcell2.BorderWidth = Unit.Parse(2)

                tbcell2.BorderColor = Color.Red

            End If

            tbcell2.Controls.Add(btn)

            tbcell3.ColumnSpan = endwidth

            tbrow.Cells.Add(tbname)

            tbrow.Cells.Add(tbcell1)

            tbrow.Cells.Add(tbcell2)

            tbrow.Cells.Add(tbcell3)

            gtttb.Rows.Add(tbrow)

        Next

    End Sub

 

 

    '设置此控件的属性

    '开始日期

    Public Property BeginDate() As Date

        Get

            Return m_BeginDate

        End Get

        Set(ByVal Value As Date)

            m_BeginDate = Value

        End Set

    End Property

 

 

    '结束日期

    Public Property EndDate() As Date

        Get

            Return m_EndDate

        End Get

        Set(ByVal Value As Date)

            m_EndDate = Value

        End Set

    End Property

 

 

    '显示哪种视图

    Public Property ShowStyle() As GttShowStyle

        Get

            Return m_ShowStyle

        End Get

        Set(ByVal Value As GttShowStyle)

            m_ShowStyle = Value

        End Set

    End Property

 

 

 

 

    '在此图中欲显示的数据(此处应固定格式,也许应该从某个地方继承)

    Public Property Data() As DataSet

        Get

            Return m_data

        End Get

        Set(ByVal Value As DataSet)

            m_data = Value

        End Set

    End Property

 

 

    '确定显示的类型(包括日视图,周视图,月视图)

    Public Enum GttShowStyle

        ShowDayView = -1

        ShowWeekView = 0

        ShowMonthView = 1

    End Enum

End Class

 

 

以上代码构成了甘特图的主体部分,现在重新检查代码,感觉问题还是不少的,不过作为前进中的纪念,还是基本按照原样记录下来。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值