티스토리 뷰
======================================================
안녕하세요 Doridori 입니다.
새해들어서 힘내려고 하는데 회사고 업무고 힘빠지는 일이 너무 많아 기운 빠지는 하루를 보내고 있습니다.
이번 프로젝트 들어서 차트 관련 해서 해야 하는것들이 많아 보다가 C# 쪽 차트도 간략하게 나마 정리해 보면 좋을 듯 하여
지난강의에 이어서 차트 부분을 정리해 보았습니다.
2015년 쯤 잠도 못자고 일했던 적이 있는데 그때 참 힘들다 싶었는데 이번에는 참 몸이 아니고 마음이 힘듦을 격고 있네요.
뭔가 다시 마음을 다잡을 계기를 만들어 봐야 겠습니다.!!
한번씩 남겨주시는 댓글들로 많은 기운을 얻고 있습니다.
감사합니다.!!
======================================================
51.차트 (Chart)
Source UI) (지난 강의와 이어짐으로 지난 강의 내용 참고)
Soruce) Study_51_차트 (Chart).zip
지난번 강의는 차트강의를 위한 뼈대를 만드는 부분이다.!!
라는 느낌으로 진행했던 강의로 이어서 차트 부분을 가지고 왔습니다.
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(30, 200); } 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 |
'C# > C# 강좌 Winform' 카테고리의 다른 글
Doridori C# 강의 2) 53.Loading 화면 만들기 (Program.cs) (4) | 2021.03.13 |
---|---|
Doridori C# 강의 2) 52.추상클래스(abstract), 봉인클래스(sealed) (1) | 2021.02.20 |
Doridori C# 강의 2) 50.화면 전환 (Frame Modeling) (10) | 2020.12.19 |
Doridori C# 강의 2) 49.크롤링 (crawling) (6) | 2020.09.13 |
Doridori C# 강의 2) 48.비동기 제어 (async, await) (32) | 2020.08.02 |
- Total
- Today
- Yesterday
- 칵테일
- 아이랑
- 프로그램 강의
- 주말
- 하이볼
- 게임
- 보드카
- 증류주
- C# 강좌
- WinForm
- C# 강의
- Visual Studio
- 위스키
- 가볼만한 곳
- 도리도리
- 와인
- 전통주
- 도리도리 C#
- 서울
- 광저우
- 맛집
- 맥주
- 나들이
- 술
- 소주
- C# 기초 강의
- 막걸리
- C#
- 가볼만한곳
- 모바일
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |