첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

■ GanttControl 클래스 : 간트 차트 만들기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


Task.cs

 

 

using System;

using System.Collections.Generic;

 

namespace TestProject

{

    /// <summary>

    /// 태스크

    /// </summary>

    public class Task

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region ID - ID

 

        /// <summary>

        /// ID

        /// </summary>

        public int ID { get; set; }

 

        #endregion

        #region 부모 ID - ParentID

 

        /// <summary>

        /// 부모 ID

        /// </summary>

        public int ParentID { get; set; }

 

        #endregion

        #region 작업명 - Name

 

        /// <summary>

        /// 작업명

        /// </summary>

        public string Name { get; set; }

 

        #endregion

        #region 시작일 - StartDate

 

        /// <summary>

        /// 시작일

        /// </summary>

        public DateTime StartDate { get; set; }

 

        #endregion

        #region 종료일 - EndDate

 

        /// <summary>

        /// 종료일

        /// </summary>

        public DateTime EndDate { get; set; }

 

        #endregion

        #region 진행률 - Progress

 

        /// <summary>

        /// 진행률

        /// </summary>

        public double? Progress { get; set; }

 

        #endregion

        #region 담당자 - Charger

 

        /// <summary>

        /// 담당자

        /// </summary>

        public string Charger { get; set; }

 

        #endregion

        #region 이전 ID 리스트 - PreviousIDList

 

        /// <summary>

        /// 이전 ID 리스트

        /// </summary>

        public List<int> PreviousIDList { get; set; }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Static

        //////////////////////////////////////////////////////////////////////////////// Public

 

        #region 리스트 구하기 - GetList()

 

        /// <summary>

        /// 리스트 구하기

        /// </summary>

        /// <returns>리스트</returns>

        public static List<Task> GetList()

        {

            List<Task> list = new List<Task>();

 

            list.Add(GetTask(1, 0, "작업 1"  , new DateTime(2020, 2, 1 ), new DateTime(2020, 2, 29), null, null               ));

            list.Add(GetTask(2, 1, "작업 1-1", new DateTime(2020, 2, 1 ), new DateTime(2020, 2, 10), 10  , null               ));

            list.Add(GetTask(3, 1, "작업 1-2", new DateTime(2020, 2, 10), new DateTime(2020, 2, 20), 20  , new List<int> { 2 }));

            list.Add(GetTask(4, 1, "작업 1-3", new DateTime(2020, 2, 20), new DateTime(2020, 2, 29), 30  , new List<int> { 3 }));

            list.Add(GetTask(5, 1, "완료 1"  , new DateTime(2020, 2, 29), new DateTime(2020, 2, 29), null, new List<int> { 4 }));

            list.Add(GetTask(6, 0, "작업 2"  , new DateTime(2020, 3, 1 ), new DateTime(2020, 3, 31), null, null               ));

            list.Add(GetTask(7, 6, "작업 2-1", new DateTime(2020, 3, 1 ), new DateTime(2020, 3, 10), null, new List<int> { 5 }));

            list.Add(GetTask(8, 6, "작업 2-2", new DateTime(2020, 3, 10), new DateTime(2020, 3, 20), null, new List<int> { 7 }));

 

            return list;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Private

 

        #region 태스크 구하기 - GetTask(id, parentID, name, startDate, endDate, progress, previoudIDList)

 

        /// <summary>

        /// 태스크 구하기

        /// </summary>

        /// <param name="id">ID</param>

        /// <param name="parentID">부모 ID</param>

        /// <param name="name">작업명</param>

        /// <param name="startDate">시작일</param>

        /// <param name="endDate">종료일</param>

        /// <param name="progress">진행률</param>

        /// <param name="previoudIDList">이전 ID List</param>

        /// <returns></returns>

        private static Task GetTask

        (

            int       id,

            int       parentID,

            string    name,

            DateTime  startDate,

            DateTime  endDate,

            double?   progress,

            List<int> previoudIDList

        )

        {

            Task task = new Task();

 

            task.ID             = id;

            task.ParentID       = parentID;

            task.Name           = name;

            task.StartDate      = startDate;

            task.EndDate        = endDate;

            task.Progress       = progress;

            task.PreviousIDList = previoudIDList;

 

            return task;

        }

 

        #endregion

    }

}

 

 

MainForm.cs

 

 

using System;

using System.Drawing;

using System.Collections.Generic;

 

using DevExpress.XtraEditors;

using DevExpress.XtraTreeList.Columns;

using DevExpress.XtraGantt;

using DevExpress.XtraGantt.Exceptions;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : XtraForm

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

        ////////////////////////////////////////////////////////////////////////////////////////// Private

 

        #region Field

 

        /// <summary>

        /// 폰트

        /// </summary>

        private Font font = new Font("나눔고딕코딩", 10f);

 

        /// <summary>

        /// ID 해시 세트

        /// </summary>

        HashSet<int> idHashSet = new HashSet<int> { 2, 3, 4 };

 

        /// <summary>

        /// 스트립 라인 시작일

        /// </summary>

        private DateTime stripLineStartDate = DateTime.Now.Date.AddDays(-10);

 

        /// <summary>

        /// 스트립 라인 종료일

        /// </summary>

        private DateTime stripLineEndDate = DateTime.Now.Date.AddDays(-5);

 

        /// <summary>

        /// 스트립 라인 색상

        /// </summary>

        private Color striplineColor = Color.FromArgb(64, 255, 224, 166);

 

        /// <summary>

        /// 데드 라인 날짜

        /// </summary>

        private DateTime deadLineDate = new DateTime(2020, 2, 29);

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            SetControl(this.ganttControl, false, 550, new DateTime(2020, 2, 1), new DateTime(2020, 4, 30), this.font, this.font, this.font);

 

            AddColumn(this.ganttControl, "Name"     , "Name"     , "작업명", 150, true);

            AddColumn(this.ganttControl, "StartDate", "StartDate", "시작일", 100, true);

            AddColumn(this.ganttControl, "EndDate"  , "EndDate"  , "종료일", 100, true);

            AddColumn(this.ganttControl, "Progress" , "Progress" , "진행률", 100, true);

            AddColumn(this.ganttControl, "Charger"  , "Charger"  , "담당자", 100, true);

 

            AddException(this.ganttControl, 2020, 3, 6);

 

            SetMapping(this.ganttControl, "ID", "ParentID", "Name", "StartDate", "EndDate", "Progress", "PrevioudIDList");

 

            this.ganttControl.CustomDrawTask            += ganttControl_CustomDrawTask;

            this.ganttControl.CustomDrawTaskDependency  += ganttControl_CustomDrawTaskDependency;

            this.ganttControl.CustomTaskDisplayText     += ganttControl_CustomTaskDisplayText;

            this.ganttControl.CustomDrawTimescaleColumn += ganttControl_CustomDrawTimescaleColumn;

 

            this.ganttControl.DataSource = Task.GetList();

 

            this.ganttControl.ExpandAll();

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        //////////////////////////////////////////////////////////////////////////////// Event

 

        #region 간트 컨트롤 태스크 커스텀 그리기 - ganttControl_CustomDrawTask(sender, e)

 

        /// <summary>

        /// 간트 컨트롤 태스크 커스텀 그리기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void ganttControl_CustomDrawTask(object sender, CustomDrawTaskEventArgs e)

        {

            int id = Convert.ToInt32(e.Node.GetValue("ID"));

 

            if(this.idHashSet.Contains(id))

            {

                e.Appearance.BackColor     = Color.Black;

                e.Appearance.ProgressColor = Color.Red;

            }

 

            if(e.Node.Id == 3)

            {

                TimeSpan startOffset = TimeSpan.FromDays(2);

                TimeSpan endOffset   = TimeSpan.FromDays(2);

 

                e.DrawShape(e.Info.StartDate + startOffset, e.Info.FinishDate - endOffset);

 

                e.DrawRightText();

 

                e.Handled = true;

            }

        }

 

        #endregion

        #region 간트 컨트롤 태스크 텍스트 커스텀 표시하기 - ganttControl_CustomTaskDisplayText(sender, e)

 

        /// <summary>

        /// 간트 컨트롤 태스크 텍스트 커스텀 표시하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void ganttControl_CustomTaskDisplayText(object sender, CustomTaskDisplayTextEventArgs e)

        {

            int id = Convert.ToInt32(e.Node.GetValue("ID"));

 

            if(idHashSet.Contains(id))

            {

                e.RightText = "High priority";

            }

            else

            {

                e.RightText = string.Empty;

                e.LeftText  = "Normal priority";

            }

        }

 

        #endregion

        #region 간트 컨트롤 태스크 의존도 커스텀 그리기 - ganttControl_CustomDrawTaskDependency(sender, e)

 

        /// <summary>

        /// 간트 컨트롤 태스크 의존도 커스텀 그리기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void ganttControl_CustomDrawTaskDependency(object sender, CustomDrawTaskDependencyEventArgs e)

        {

            int previousID = Convert.ToInt32(e.PredecessorNode.GetValue("ID"));

            int id         = Convert.ToInt32(e.SuccessorNode.GetValue("ID"));

 

            if(idHashSet.Contains(previousID) && idHashSet.Contains(id))

            {

                e.Appearance.BackColor = Color.Blue;

            }

        }

 

        #endregion

        #region 간트 컨트롤 타임 스케일 컬럼 커스텀 그리기 - ganttControl_CustomDrawTimescaleColumn(sender, e)

 

        /// <summary>

        /// 간트 컨트롤 타임 스케일 컬럼 커스텀 그리기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void ganttControl_CustomDrawTimescaleColumn(object sender, CustomDrawTimescaleColumnEventArgs e)

        {

            GanttTimescaleColumn column = e.Column;

 

            if(column.StartDate <= this.deadLineDate && column.FinishDate >= this.deadLineDate)

            {

                DrawDeadLine(e);

            }

 

            DrawStripLine(e);

 

            e.Handled = true;

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 컨트롤 설정하기 - SetControl(control, autoWidth, splitterPosition, startDate, endDate, milestoneFont,

            summaryTaskFont, taskFont)

 

        /// <summary>

        /// 컨트롤 설정하기

        /// </summary>

        /// <param name="control">간트 컨트롤</param>

        /// <param name="autoWidth">너비 자동 설정 여부</param>

        /// <param name="splitterPosition">스플리터 위치</param>

        /// <param name="startDate">시작일</param>

        /// <param name="endDate">종료일</param>

        /// <param name="milestoneFont">마일스톤 폰트</param>

        /// <param name="summaryTaskFont">요약 태스크 폰트</param>

        /// <param name="taskFont">태스크 폰트</param>

        private void SetControl

        (

            GanttControl control,

            bool         autoWidth,

            int          splitterPosition,

            DateTime     startDate,

            DateTime     endDate,

            Font         milestoneFont,

            Font         summaryTaskFont,

            Font         taskFont

        )

        {

            control.OptionsView.ShowCaption    = true;

            control.OptionsView.AutoWidth      = autoWidth;

            control.OptionsView.ShowHorzLines  = false;

            control.OptionsView.ShowIndicator  = false;

            control.OptionsView.ShowFirstLines = false;

 

            control.SplitterPosition = splitterPosition;

 

            control.ChartStartDate  = startDate;

            control.ChartFinishDate = endDate;

 

            control.Appearance.Milestone.Font   = milestoneFont;

            control.Appearance.SummaryTask.Font = summaryTaskFont;

            control.Appearance.Task.Font        = taskFont;

        }

 

        #endregion

        #region 매핑 설정하기 - SetMapping(control, keyField, parentField, textField, startDateField, endDateField,

            progressField, predecessorField)

 

        /// <summary>

        /// 매핑 설정하기

        /// </summary>

        /// <param name="control">컨트롤</param>

        /// <param name="keyField">키 필드</param>

        /// <param name="parentField">부모 필드</param>

        /// <param name="textField">텍스트 필드</param>

        /// <param name="startDateField">시작일 필드</param>

        /// <param name="endDateField">종료일 필드</param>

        /// <param name="progressField">진행률 필드</param>

        /// <param name="predecessorField">이전 태스크 필드</param>

        private void SetMapping

        (

            GanttControl control,

            string       keyField,

            string       parentField,

            string       textField,

            string       startDateField,

            string       endDateField,

            string       progressField,

            string       predecessorField

        )

        {

            control.TreeListMappings.KeyFieldName       = keyField;

            control.TreeListMappings.ParentFieldName    = parentField;

            control.ChartMappings.TextFieldName         = textField;

 

            control.ChartMappings.StartDateFieldName    = startDateField;

            control.ChartMappings.FinishDateFieldName   = endDateField;

            control.ChartMappings.ProgressFieldName     = progressField;

            control.ChartMappings.PredecessorsFieldName = predecessorField;

        }

 

        #endregion

        #region 컬럼 추가하기 - AddColumn(control, name, fieldName, caption, width, visible)

 

        /// <summary>

        /// 컬럼 추가하기

        /// </summary>

        /// <param name="control">간트 컨트롤</param>

        /// <param name="name">명칭</param>

        /// <param name="fieldName">필드명</param>

        /// <param name="caption">제목</param>

        /// <param name="width">너비</param>

        /// <param name="visible">표시 여부</param>

        /// <returns>인덱스</returns>

        private int AddColumn(GanttControl control, string name, string fieldName, string caption, int width, bool visible)

        {

            TreeListColumn column = new TreeListColumn();

 

            column.Name      = name;

            column.FieldName = fieldName;

            column.Caption   = caption;

            column.Width     = width;

            column.Visible   = visible;

 

            int index = control.Columns.Add(column);

 

            return index;

        }

 

        #endregion

        #region 예외 추가하기 - AddException(control, year, month, day)

 

        /// <summary>

        /// 예외 추가하기

        /// </summary>

        /// <param name="control">컨트롤</param>

        /// <param name="year">연도</param>

        /// <param name="month"></param>

        /// <param name="day"></param>

        /// <returns>처리 결과</returns>

        private bool AddException(GanttControl control, int year, int month, int day)

        {

            YearlyExceptionRule rule = new YearlyExceptionRule();

 

            rule.DayOfMonth  = day;

            rule.Month       = (DevExpress.XtraGantt.Scheduling.Month)month;

            rule.StartDate   = new DateTime(year, month, day);

            rule.Occurrences = 1;

 

            bool result = ganttControl.Exceptions.Add(rule);

 

            return result;

        }

 

        #endregion

 

        #region 데드 라인 그리기 - DrawDeadLine(e)

 

        /// <summary>

        /// 데드 라인 그리기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        private void DrawDeadLine(CustomDrawTimescaleColumnEventArgs e)

        {

            e.DrawBackground();

 

            float x = (float)e.GetPosition(this.deadLineDate);

 

            float width = 4;

 

            RectangleF rectangle = new RectangleF(x, e.Column.Bounds.Y, width, e.Column.Bounds.Height);

 

            e.Cache.FillRectangle(Color.Red, rectangle);

 

            e.DrawHeader();

        }

 

        #endregion

        #region 스트립 라인 그리기 - DrawStripLine(e)

 

        /// <summary>

        /// 스트립 라인 그리기

        /// </summary>

        /// <param name="e">이벤트 인자</param>

        private void DrawStripLine(CustomDrawTimescaleColumnEventArgs e)

        {

            float startPoint = (float)Math.Max(e.GetPosition(this.stripLineStartDate), e.Column.Bounds.Left );

            float endPoint   = (float)Math.Min(e.GetPosition(this.stripLineEndDate  ), e.Column.Bounds.Right);

 

            e.DrawBackground();

 

            RectangleF rectangle = new RectangleF

            (

                startPoint,

                e.Column.Bounds.Y,

                endPoint - startPoint,

                e.Column.Bounds.Height

            );

 

            if(rectangle.Width > 0)

            {

                e.Cache.FillRectangle(striplineColor, rectangle);

            }

 

            e.DrawHeader();

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

Posted by 사용자 icodebroker
TAG

댓글을 달아 주세요