티스토리 뷰

C#/C# 강좌 Winform

Doridori C# 강의 2) 51.차트 (Chart)

꼬꼬마도리도리 2021. 1. 10. 19:38

======================================================

안녕하세요 Doridori 입니다.


새해들어서 힘내려고 하는데 회사고 업무고 힘빠지는 일이 너무 많아 기운 빠지는 하루를 보내고 있습니다. 


이번 프로젝트 들어서 차트 관련 해서 해야 하는것들이 많아 보다가 C# 쪽 차트도 간략하게 나마 정리해 보면 좋을 듯 하여


지난강의에 이어서 차트 부분을 정리해 보았습니다. 


2015년 쯤 잠도 못자고 일했던 적이 있는데 그때 참 힘들다 싶었는데 이번에는 참 몸이 아니고 마음이 힘듦을 격고 있네요.


뭔가 다시 마음을 다잡을 계기를 만들어 봐야 겠습니다.!! 


한번씩 남겨주시는 댓글들로 많은 기운을 얻고 있습니다. 


감사합니다.!!

======================================================




51.차트 (Chart)

 

 

Source UI) (지난 강의와 이어짐으로 지난 강의 내용 참고)

Soruce) Study_51_차트 (Chart).zip

교재) 51. 차트 (Chart).pdf








지난번 강의는 차트강의를 위한 뼈대를 만드는 부분이다.!!


라는 느낌으로 진행했던 강의로 이어서 차트 부분을 가지고 왔습니다. 


DataGridView을 처음 봤을 때, TreeView를 처음 봤을 때 . . .


이런 느낌으로 Chart의 경우도 사용하려고 하면 알아야하는 내용들이 있습니다. 


생소해서 그렇지 어려운 내용들은 아니니 보고 익숙해 지면 좋을듯 합니다. 




UI) 


지난 강의에 이어지는 부분으로 차트 부분보다는 프로그램 전반적으로 데이터의 이동을 보시면 더 좋을 것 같습니다.






강의)


화면도 많고 클래스도 나눠 놓았기 때문에 프로그램을 짜면서도 왔다 갔다 하면서 개발하게 됩니다. 


영상에서도 왔다 갔다 하는데 클래스들을 보면서 어디 부분들 진행 중인지 잘 따라가시면 좋을 듯합니다. 


데이터의 이동와 변수들을 왜 저런 부분에 선언해 놓았는지 이런것들을 보면서 천천히 보시면 전체 코드가 길지 않기 때문에 


천천히 따라가보면 좋을 것 같습니다. 





Source)


이거 이제 각자 코드를 다 올려야 하는지 고민이 되는 시기이기는 하네요.


일단 이번 까지는 다 올려 보도록 하겠습니다.!!! 






(Main)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace FrameModeling
{
    public partial class Form1 : Form
    {
        #region 전역 변수
        ucPanel.ucScreen1 ucSc1; // 화면1 
        ucPanel.ucScreen2 ucSc2; // 화면2
        ucPanel.ucScreen3 ucSc3; // 화면3
 
        ChartData cData = new ChartData();  // Chart에 필요한 Data를 가지고 있을 구조체 Class
        #endregion
 
        
        public Form1()
        {
            InitializeComponent();
        }
 
 
        #region Form Event
        private void Form1_Load(object sender, EventArgs e)
        {
            ucSc1 = new ucPanel.ucScreen1();
            ucSc2 = new ucPanel.ucScreen2();
            ucSc3 = new ucPanel.ucScreen3();
 
            ucSc1.eLogSender += UcSc_eLogSender;   // 화면 1 Delegate Event
            ucSc2.eLogSender += UcSc_eLogSender;   // 화면 1 Delegate Event
            ucSc3.eLogSender += UcSc_eLogSender;   // 화면 1 Delegate Event
 
            ucSc1.eDataTableSender += UcSc1_eDataTableSender;  // DataTable을 가져옴
            ucSc3.eChartTypeSender += UcSc3_eChartTypeSender;  // ChartType을 가져옴
 
            pMain.Controls.Add(ucSc1);
        }
 
        
 
        // Main 화면 Button Click Event (동일 Event로 받고 코드 상에서 분기 처리)
        private void button_Click(object sender, EventArgs e)
        {
            Button btn = sender as Button;
 
            switch (btn.Name)
            {
                case "BtnSc1":
                    pMain.Controls.Clear();
                    pMain.Controls.Add(ucSc1);
                    break;
                case "BtnSc2":
                    pMain.Controls.Clear();
                    pMain.Controls.Add(ucSc2);
                    ucSc2.setCData(cData);  // 2번 화면 전환 Button을 누를 때 가지고 있던 Chart Data를 2번 화면으로 전달 해 줌
                    break;
                case "BtnSc3":
                    pMain.Controls.Clear();
                    pMain.Controls.Add(ucSc3);
                    break;
                case "BtnExit":
                    Application.Exit();
                    break;
                default:
                    break;
            }
 
            Log(enLogLevel.Info, $"{btn.Text} 버튼 Click");
        }
        #endregion
 
 
        #region del Event
        /// <summary>
        /// Log Sender
        /// </summary>
        /// <param name="oSender"></param>
        /// <param name="eLevel"></param>
        /// <param name="strLog"></param>
        private void UcSc_eLogSender(object oSender, enLogLevel eLevel, string strLog)
        {
            Log(eLevel, $"[{oSender.ToString()}] {strLog}");
        }
 
        /// <summary>
        /// Data Table Sender
        /// </summary>
        /// <param name="oSender"></param>
        /// <param name="dt"></param>
        private void UcSc1_eDataTableSender(object oSender, DataTable dt)
        {
            cData.ChartMain = dt;
        }
 
        /// <summary>
        /// Chart Type Sender
        /// </summary>
        /// <param name="oSender"></param>
        /// <param name="ct"></param>
        private void UcSc3_eChartTypeSender(object oSender, System.Windows.Forms.DataVisualization.Charting.SeriesChartType ct)
        {
            cData.ChartType = ct;
        }
        #endregion
 
 
        #region Log OverLoading
        private void Log(enLogLevel eLevel, string LogDesc)
        {
            DateTime dTime = DateTime.Now;
            string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
            lboxLog.Items.Insert(0, LogInfo);
        }
        private void Log(DateTime dTime, enLogLevel eLevel, string LogDesc)
        {
            string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
            lboxLog.Items.Insert(0, LogInfo);
        }
        #endregion
 
 
    }
}
 
cs




(Global - 전역)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;
 
namespace FrameModeling
{
    public class cGlobal
    {
        //public static DataTable dt;   // Chart Data 값을 전역으로 사용 (사용하지 않음)
    }
    
    // Log Level을 지정 할 Enum
    public enum enLogLevel
    {
        Info,
        Warning,
        Error,
    }
 
    // UserControl에서 Main으로 Log를 전달 하기 위한 Delegate 정의
    public delegate void delLogSender(object oSender, enLogLevel eLevel, string strLog);
 
    // UserControl에서 Main으로 DataTable 값을 전달 하기 위한 Delegate 정의
    public delegate void delDataTableSender(object oSender, DataTable dt);
 
    // UserControl에서 Main으로 ChartType 값을 전달 하기 위한 Delegate 정의
    public delegate void delChartTypeSender(object oSender, SeriesChartType ct);
 
 
    // Enum 요일 (영문)
    public enum enWeek
    {
        Mon,
        Tue,
        Wen,
        Thu,
        Fri,
        Sat,
        Sun
    }
 
    // Enum 요일 (한글)
    public enum enWeek_Han
    {
        월,
        화,
        수,
        목,
        금,
        토,
        일
    }
 
 
    // ChartData를 구조체 처럼 가지고 있을 Class
    public class ChartData
    {
        DataTable _ChartMain;
        SeriesChartType _ChartType = SeriesChartType.Area;
 
        public DataTable ChartMain { get => _ChartMain; set => _ChartMain = value; }
        public SeriesChartType ChartType { get => _ChartType; set => _ChartType = value; }
    }
 
 
}
 
cs



(ucScreen1 - Data 생성)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace FrameModeling.ucPanel
{
    /// <summary>
    /// Chart에서 사용 할 DataTable을 생성 하는 부분
    /// </summary>
    public partial class ucScreen1 : UserControl
    {
        public event delLogSender eLogSender;
        public event delDataTableSender eDataTableSender;
 
        DataTable dtMain = new DataTable();
 
 
        public ucScreen1()
        {
            InitializeComponent();
            //dgView.Rows.Add();
            //dgView.Rows.Add();
            
        }
 
 
        #region Form Event
        private void btnSc1_Click(object sender, EventArgs e)
        {
            eLogSender("Screen1 Button", enLogLevel.Info, "Random Set Button Click : 임의의 Chart Data를 생성 합니다.");
 
            Dataclear();
            DataSet();
 
            //cGlobal.dt = dgView.DataSource as DataTable;  // Data를 Memory에 올려놓음 (사용하지 않음)
 
            DataTable dt = dgView.DataSource as DataTable;
            eDataTableSender(this, dt);
        }
        #endregion
 
 
        #region Function
        /// <summary>
        /// Chart Data 생성
        /// </summary>
        private void DataSet()
        {
            dtMain = new DataTable();
 
            //DataColumn 생성
            DataColumn colProduction = new DataColumn("제품"typeof(string));
            DataColumn colMon = new DataColumn("월"typeof(int));
            DataColumn colTue = new DataColumn("화"typeof(int));
            DataColumn colWen = new DataColumn("수"typeof(int));
            DataColumn colThu = new DataColumn("목"typeof(int));
            DataColumn colFri = new DataColumn("금"typeof(int));
            DataColumn colSat = new DataColumn("토"typeof(int));
            DataColumn colSun = new DataColumn("일"typeof(int));
 
 
            //생성된 Column을 DataTable에 Add
            dtMain.Columns.Add(colProduction);
            dtMain.Columns.Add(colMon);
            dtMain.Columns.Add(colTue);
            dtMain.Columns.Add(colWen);
            dtMain.Columns.Add(colThu);
            dtMain.Columns.Add(colFri);
            dtMain.Columns.Add(colSat);
            dtMain.Columns.Add(colSun);
 
            Random rd = new Random();
 
            dtMain.Rows.Add(RowAdd(dtMain, "컵라면", rd));
            dtMain.Rows.Add(RowAdd(dtMain, "맥주", rd));
            dtMain.Rows.Add(RowAdd(dtMain, "과자", rd));
 
            dgView.DataSource = dtMain;
        }
 
        /// <summary>
        /// DataRow 생성
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="strProduction"></param>
        /// <param name="rd"></param>
        /// <returns></returns>
        private DataRow RowAdd(DataTable dt, string strProduction, Random rd)
        {
            DataRow row = dt.NewRow();
 
            row["제품"= strProduction;
 
            foreach (enWeek_Han oDay in Enum.GetValues(typeof(enWeek_Han)))
            {
                row[oDay.ToString()] = rd.Next(30200);
            }
 
            return row;
        }
 
        private void Dataclear()
        {
            dtMain.Clear();
            dgView.DataSource = null;
        }
        #endregion
        
    }
}
 
cs



(ucScreen2 - Chart 그리기)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
 
namespace FrameModeling.ucPanel
{
    /// <summary>
    /// Data들을 가져와서 Chart를 생성 하는 부분
    /// </summary>
    public partial class ucScreen2 : UserControl
    {
        public event delLogSender eLogSender; 
        ChartData _cData = new ChartData();
 
        public ucScreen2()
        {
            InitializeComponent();
 
            cSales.Titles.Add("판매량");  // Screen 생성 시 Chart의 Title 생성
        }
 
 
        #region Form Event
        private void btnSc2_Click(object sender, EventArgs e)
        {
            eLogSender("Screen2 Button", enLogLevel.Info, "Chart Load Click : Chart에 Data를 Load 합니다.");
 
            ChartDataLoad(_cData);
 
        }
        #endregion
 
 
        #region Function
        /// <summary>
        /// Chart에 Data를 Load 합니다. 
        /// </summary>
        /// <param name="cData"></param>
        private void ChartDataLoad(ChartData cData)
        {
            cSales.Series.Clear();  // 기존 시리즈 내용 삭제
            
            DataTable dt = cData.ChartMain;
 
            if (dt != null && dt.Rows.Count > 0)
            {
                foreach (DataRow oRow in dt.Rows)
                {
                    Series series = cSales.Series.Add(oRow["제품"].ToString());
                    series.ChartType = cData.ChartType;  // 차트 종류
                    series.Points.AddXY(enWeek.Mon.ToString(), oRow[enWeek_Han.월.ToString()]);
                    series.Points.AddXY(enWeek.Tue.ToString(), oRow[enWeek_Han.화.ToString()]);
                    series.Points.AddXY(enWeek.Wen.ToString(), oRow[enWeek_Han.수.ToString()]);
                    series.Points.AddXY(enWeek.Thu.ToString(), oRow[enWeek_Han.목.ToString()]);
                    series.Points.AddXY(enWeek.Fri.ToString(), oRow[enWeek_Han.금.ToString()]);
                    series.Points.AddXY(enWeek.Sat.ToString(), oRow[enWeek_Han.토.ToString()]);
                    series.Points.AddXY(enWeek.Sun.ToString(), oRow[enWeek_Han.일.ToString()]);
 
                }
            }
 
            /*  Chart Loading 하는 부분 Sample
            Series series = cSales.Series.Add("일별 판매량");
            series.ChartType = _cData.ChartType;  // 차트 종류
            // DT For문
            series.Points.AddXY("MON", 100);
            series.Points.AddXY("TUS", 80);
            series.Points.AddXY("WEN", 120);
            series.Points.AddXY("THU", 110);
            series.Points.AddXY("FRI", 90);
            series.Points.AddXY("SAT", 70);
            series.Points.AddXY("SUN", 60);
            Series series2 = cSales.Series.Add("일별 재고");
            series2.ChartType = _cData.ChartType;  // 차트 종류
            series2.Points.AddXY("MON", 90);
            series2.Points.AddXY("TUS", 40);
            series2.Points.AddXY("WEN", 20);
            series2.Points.AddXY("THU", 10);
            series2.Points.AddXY("FRI", 70);
            series2.Points.AddXY("SAT", 20);
            series2.Points.AddXY("SUN", 70);
            */
        }
        
        /// <summary>
        /// 외부에서 2번 화면으로 Chart Data를 전달
        /// </summary>
        /// <param name="cData"></param>
        public void setCData(ChartData cData)
        {
            _cData = cData;
        }
        #endregion
 
    }
}
 
cs



(ucScreen3 - Config Setting)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
 
namespace FrameModeling.ucPanel
{
    /// <summary>
    /// Chart에서 사용 할 설정 값들을 설정 하는 부분
    /// </summary>
    public partial class ucScreen3 : UserControl
    {
        public event delLogSender eLogSender;
        public event delChartTypeSender eChartTypeSender;
 
        public ucScreen3()
        {
            InitializeComponent();
            
        }
 
        #region Form Event
        /// <summary>
        /// Combo 값이 변경 될 때 호출
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cboxType_SelectedIndexChanged(object sender, EventArgs e)
        {
            eLogSender("Screen3 ComboChange", enLogLevel.Info, "Chart Type Changed : " + cboxType.SelectedItem.ToString());
 
            SeriesChartType cType = (SeriesChartType)Enum.Parse(typeof(SeriesChartType), cboxType.SelectedItem.ToString());
            eChartTypeSender(this, cType);
        }
 
        /// <summary>
        /// Loading 시 Chart Type를 Combo에 넣어줌
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ucScreen3_Load(object sender, EventArgs e)
        {
            foreach (SeriesChartType oType in Enum.GetValues(typeof(SeriesChartType)))
            {
                cboxType.Items.Add(oType.ToString());
            }
 
            cboxType.SelectedIndex = 0;
        }
        #endregion
 
    }
}
 
cs


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함