차트 컨트롤 데이타 바인딩
차트 컨트롤에서 X,Y 값을 하나씩 추가하는 방법 이외에 일반적으로 메모리상의 컬렉션 데이타 혹은 외부 데이타 소스에서 데이타를 가져와 차트 컨트롤에 바인딩하는 방식을 흔히 사용한다.
차트 컨트롤은 배열(Array), 리스트(List<T> 동적 배열), 혹은 IEnumerable을 지원하는 컬렉션을 데이타바인딩할 수 있으며, 또한 DataSet, DataView, 그리고 외부 데이타 소스에 대한 DataReader 등을 데이타바인딩할 수 있다.
차트 컨트롤에서 데이타를 바인딩하는 방법은 다음과 같이 크게 5가지가 인데, 각 방법마다 장담점(MSDN 참조)이 존재한다.
(1) Series.Points.DataBindY() / DataBindXY()
(2) Series.Points.DataBind()
(3) Chart.DataBindTable()
(4) Chart.DataSource / Chart.DataBind()
(5) Chart.DataBindCrossTable()
차트 컨트롤은 배열(Array), 리스트(List<T> 동적 배열), 혹은 IEnumerable을 지원하는 컬렉션을 데이타바인딩할 수 있으며, 또한 DataSet, DataView, 그리고 외부 데이타 소스에 대한 DataReader 등을 데이타바인딩할 수 있다.
차트 컨트롤에서 데이타를 바인딩하는 방법은 다음과 같이 크게 5가지가 인데, 각 방법마다 장담점(MSDN 참조)이 존재한다.
(1) Series.Points.DataBindY() / DataBindXY()
(2) Series.Points.DataBind()
(3) Chart.DataBindTable()
(4) Chart.DataSource / Chart.DataBind()
(5) Chart.DataBindCrossTable()
배열/컬렉션에 대한 바인딩
차트 컨트롤은 배열이나 컬렉션 같은 데이타를 차트에 바인딩할 수 있는데, Y값들만 존재하는 경우 (아래 1번과 같이) Points.DataBindY()를 사용하고, X,Y값이 두 개의 배열/컬렉션으로 존재하는 경우 (아래 2번과 같이) Points.DataBindXY()를 사용할 수 있다. 만약 클래스 객체 컬렉션인 경우 (아래 3번과 같이) Points.DataBind(컬렉션, X축속성, Y축속성, 추가옵션) 메서드를 사용할 수 있다.
예제
private void btnData_Click(object sender, EventArgs e)
{
// (1) Y값 배열 데이타바인딩
double[] scores = new double[] { 80, 90, 85, 70, 95 };
chart1.Series[0].Points.DataBindY(scores);
// (2) X, Y값 List<T> 데이타바인딩
List<string> x = new List<string> { "철수", "영희", "길동", "재동", "민희"};
List<double> y = new List<double> { 80, 90, 85, 70, 95 };
chart2.Series[0].Points.DataBindXY(x, y);
// (3) 객체 컬렉션에 대한 데이타바인딩
List<Student> students = new List<Student>();
students.Add(new Student("철수", 80));
students.Add(new Student("영희", 90));
students.Add(new Student("길동", 85));
// X축: Name, Y축: Score
chart3.Series[0].Points.DataBind(students, "Name", "Score", null);
// (참고) DataBindTable() 사용시. (X축: Name, Y축: 자동검색)
// chart3.DataBindTable(students, "Name");
}
class Student
{
public string Name { get; set; }
public double Score { get; set; }
public Student(string name, double score)
{
this.Name = name;
this.Score = score;
}
}
{
// (1) Y값 배열 데이타바인딩
double[] scores = new double[] { 80, 90, 85, 70, 95 };
chart1.Series[0].Points.DataBindY(scores);
// (2) X, Y값 List<T> 데이타바인딩
List<string> x = new List<string> { "철수", "영희", "길동", "재동", "민희"};
List<double> y = new List<double> { 80, 90, 85, 70, 95 };
chart2.Series[0].Points.DataBindXY(x, y);
// (3) 객체 컬렉션에 대한 데이타바인딩
List<Student> students = new List<Student>();
students.Add(new Student("철수", 80));
students.Add(new Student("영희", 90));
students.Add(new Student("길동", 85));
// X축: Name, Y축: Score
chart3.Series[0].Points.DataBind(students, "Name", "Score", null);
// (참고) DataBindTable() 사용시. (X축: Name, Y축: 자동검색)
// chart3.DataBindTable(students, "Name");
}
class Student
{
public string Name { get; set; }
public double Score { get; set; }
public Student(string name, double score)
{
this.Name = name;
this.Score = score;
}
}
테이블 데이타에 대한 바인딩
차트 컨트롤에서 테이블 데이타를 사용하는 경우, Chart.DataBindTable(), Chart.DataSource / Chart.DataBind() 혹은 Series.Points.DataBind() 등을 사용하면 편리하다. 이들 메서드들은 행과 열을 갖는 테이블 데이타들 즉 DataReader, DataTable, DataSet 등과 같은 데이타 타입들을 바인딩할 때 유용한다. 아래 예제는 이들 메서드들을 사용하여 테이블 데이타를 바인딩하는 방법을 예시한 것이다.
예제
// (1) DataBindTable() 사용
string strConn = "Data Source=.;Initial Catalog=pubs;Integrated Security=SSPI;";
string sql = "SELECT stor_name as store, SUM(qty) AS sales " +
"FROM stores st INNER JOIN sales sa ON st.stor_id = sa.stor_id " +
"GROUP BY stor_name";
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dataReader = cmd.ExecuteReader();
// IDataReader 객체와 X축 필드를 지정한다
chart5.DataBindTable(dataReader, "store");
}
// (2) DataSource와 DataBind() 사용
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
DataSet ds = new DataSet();
SqlDataAdapter sa = new SqlDataAdapter(cmd);
sa.Fill(ds);
// DataTable 객체를 DataSource에 지정하고,
// X,Y축 컬럼을 XValueMember와 YValueMembers에 지정
chart6.DataSource = ds.Tables[0];
chart6.Series[0].XValueMember = "store";
chart6.Series[0].YValueMembers = "sales";
chart6.DataBind();
}
// (3) Points.DataBind() 사용
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dataReader = cmd.ExecuteReader();
// IDataReader 객체와 X, Y축 컬럼 지정.
// 4번째 Param: 툴팁과 같은 다른 필드 지정가능. 여기선 sales 컬럼값을 툴팁에 표시
chart7.Series[0].Points.DataBind(dataReader, "store", "sales", "Tooltip=sales");
}
string strConn = "Data Source=.;Initial Catalog=pubs;Integrated Security=SSPI;";
string sql = "SELECT stor_name as store, SUM(qty) AS sales " +
"FROM stores st INNER JOIN sales sa ON st.stor_id = sa.stor_id " +
"GROUP BY stor_name";
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dataReader = cmd.ExecuteReader();
// IDataReader 객체와 X축 필드를 지정한다
chart5.DataBindTable(dataReader, "store");
}
// (2) DataSource와 DataBind() 사용
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
DataSet ds = new DataSet();
SqlDataAdapter sa = new SqlDataAdapter(cmd);
sa.Fill(ds);
// DataTable 객체를 DataSource에 지정하고,
// X,Y축 컬럼을 XValueMember와 YValueMembers에 지정
chart6.DataSource = ds.Tables[0];
chart6.Series[0].XValueMember = "store";
chart6.Series[0].YValueMembers = "sales";
chart6.DataBind();
}
// (3) Points.DataBind() 사용
using (SqlConnection conn = new SqlConnection(strConn))
{
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
SqlDataReader dataReader = cmd.ExecuteReader();
// IDataReader 객체와 X, Y축 컬럼 지정.
// 4번째 Param: 툴팁과 같은 다른 필드 지정가능. 여기선 sales 컬럼값을 툴팁에 표시
chart7.Series[0].Points.DataBind(dataReader, "store", "sales", "Tooltip=sales");
}
DataBindCrossTable() 바인딩
Chart.DataBindCrossTable()은 약간 특별한 용도로 사용하는데, 이 메서드는 테이블 데이타를 사용하면서 X, Y축 이외에 데이타를 그룹으로 묶는 컬럼을 지정한다. 예를 들어, 아래 예제에서 DataBindCrossTable()의 3번째 파라미터인 customer는 X축 컬럼이고, 4번째 파라미터인 orders는 Y축 컬럼을 의미한다. 그리고 2번째 파라미터인 product는 데이타를 그룹으로 나누기 위해 사용하는데, 이 컬럼에 따라서 나뉜 그룹마다 하나씩의 Series 데이타를 자동으로 생성한다. 즉, 아래 예제의 경우, USB, HDD, Monitor 등 3개의 그룹에 각각 하나의 Series가 생성되므로 총 3개의 Series가 추가되며, 각 customer 당 3개의 product에 대한 그래프가 그려진다.
예제
// DataBindCrossTable() 사용
DataTable dt = new DataTable("Order");
dt.Columns.Add("customer");
dt.Columns.Add("product");
dt.Columns.Add("orders");
dt.Rows.Add("Tom", "USB", 10);
dt.Rows.Add("Tom", "HDD", 2);
dt.Rows.Add("Tom", "Monitor", 1);
dt.Rows.Add("Jane", "USB", 3);
dt.Rows.Add("Jane", "HDD", 1);
dt.Rows.Add("Jane", "Monitor", 2);
// Product별로 Series를 하나씩 자동으로 생성
// X축은 customer 컬럼, Y축은 orders 컬럼
// 각 그래프 상단에 product명으로 Label을 붙임
chart9.DataBindCrossTable(dt.AsEnumerable(), "product", "customer", "orders", "Label=product");
DataTable dt = new DataTable("Order");
dt.Columns.Add("customer");
dt.Columns.Add("product");
dt.Columns.Add("orders");
dt.Rows.Add("Tom", "USB", 10);
dt.Rows.Add("Tom", "HDD", 2);
dt.Rows.Add("Tom", "Monitor", 1);
dt.Rows.Add("Jane", "USB", 3);
dt.Rows.Add("Jane", "HDD", 1);
dt.Rows.Add("Jane", "Monitor", 2);
// Product별로 Series를 하나씩 자동으로 생성
// X축은 customer 컬럼, Y축은 orders 컬럼
// 각 그래프 상단에 product명으로 Label을 붙임
chart9.DataBindCrossTable(dt.AsEnumerable(), "product", "customer", "orders", "Label=product");