Tuesday, February 2, 2010

LineChart 그래프를 만들어보자. (ASP.NET using C#)

[GDI+] LineChart 그래프를 만들어보자. (ASP.NET using C#) TIPandTech
2005/02/08 20:17
http://blog.naver.com/syd38/10006705
1. Introduction



닷넷은 GDI+의 지원으로 더욱더 강력한 웹페이지를 만들어 낼수 있다고 생각한다. 이번 아티글은 동적으로 저장된 데이터를 가지고 바로 Line으로 표현하는 LineChart를 만들어 보고자 한다.

2. Code
Line Chart클래스의 클래스이다. 현재 Current페이지의 ContentType 를 Image/jpeg로 설정한후 바로 브라우저에 그래픽을 뿌려지게 된다. 내부의 코드를 따로 설명하지 않아도 주석을 보면 코드를 충분히 이해 할수 있을것이다.
namespace에 using System.Drawing.Imaging;를 선언한다.

class LineChart
{

public Bitmap b;
public string Title="Default Title";
public ArrayList chartValues = new ArrayList();//데이터저장
public float Xorigin=0, Yorigin=0;
public float ScaleX, ScaleY;
public float Xdivs=2, Ydivs=2;

private int Width, Height;
private Graphics g;

//데이터 구조체
struct datapoint
{
public float x;
public float y;
public bool valid;
}

//생성자,초기설정
public LineChart(int myWidth, int myHeight)
{
Width = myWidth; Height = myHeight;
ScaleX = myWidth; ScaleY = myHeight;
b = new Bitmap(myWidth, myHeight);
g = Graphics.FromImage(b);
}

public void AddValue(int x, int y) //데이터를 저장한다.
{
datapoint myPoint;
myPoint.x=x;
myPoint.y=y;
myPoint.valid=true;
chartValues.Add(myPoint);
}

public void Draw() //그리기
{
int i;
float x, y, x0, y0;
string myLabel;
Pen YellowPen = new Pen(Color.Yellow,1);
Brush YellowBrush = new SolidBrush(Color.Yellow);
Font axesFont = new Font("arial",10);

//먼저 이미지 사이즈와 초기화 지역을 잡는다.
HttpContext.Current.Response.ContentType="image/jpeg";
g.FillRectangle(new
SolidBrush(Color.Black),0,0,Width,Height);
int ChartInset = 50;
int ChartWidth = Width-(2*ChartInset);
int ChartHeight = Height-(2*ChartInset);
g.DrawRectangle(new
Pen(Color.Yellow,1),ChartInset,ChartInset,ChartWidth,ChartHeight);

//위에서 설정한 Chart제목을 그린다.
g.DrawString(Title, new Font("arial",14), YellowBrush,Width/3, 10);

//X축 좌표 그리기
for(i=0; i<=Xdivs; i++)
{
x=ChartInset+(i*ChartWidth)/Xdivs;
y=ChartHeight+ChartInset;
myLabel = (Xorigin + (ScaleX*i/Xdivs)).ToString();
g.DrawString(myLabel, axesFont, YellowBrush, x-4,
y+10);
g.DrawLine(YellowPen, x, y+2, x, y-2);
}
//Y축 좌표 그리기
for(i=0; i<=Ydivs; i++)
{
x=ChartInset;
y=ChartHeight+ChartInset-(i*ChartHeight/Ydivs);
myLabel = (Yorigin + (ScaleY*i/Ydivs)).ToString();
g.DrawString(myLabel, axesFont, YellowBrush, 5, y-6);
g.DrawLine(YellowPen, x+2, y, x-2, y);
}

//시작점을 0,0으로 설정한다.
g.RotateTransform(180);
g.TranslateTransform(0,-Height);
g.TranslateTransform(-ChartInset,ChartInset);
g.ScaleTransform(-1, 1);

//데이터를 그래프로 표혀한다.
datapoint prevPoint = new datapoint();
prevPoint.valid=false;
foreach(datapoint myPoint in chartValues)
{
if(prevPoint.valid==true)
{
x0=ChartWidth*(prevPoint.x-Xorigin)/ScaleX;
y0=ChartHeight*(prevPoint.y-Yorigin)/ScaleY;
x=ChartWidth*(myPoint.x-Xorigin)/ScaleX;
y=ChartHeight*(myPoint.y-Yorigin)/ScaleY;
g.DrawLine(YellowPen,x0,y0,x,y);
g.FillEllipse(YellowBrush,x0-2,y0-2,4,4);
g.FillEllipse(YellowBrush,x-2,y-2,4,4);
}
prevPoint = myPoint;
}

//바지막으로 객체를 저장하여 브라우저에 뿌려준다.
b.Save(HttpContext.Current.Response.OutputStream, ImageFormat.Jpeg);
}

//소멸자
~LineChart()
{
g.Dispose();
b.Dispose();
}
}

아래는 클래스를 생성하여 적용하는 예제이다. Title과 x,y의 Scale을 설정한다. 그리고 데이터를 ArrayList배열에 추가하면 간단한 차트 그래프가 완성된다.
private void Page_Load(object sender, System.EventArgs e)
{
//객체 생성하기
LineChart c = new LineChart(640, 480);

//차트의 크기를 설정한다.
c.Title="Hoons Line Chart (ASP.NET GDI+)";
c.Xorigin=0; c.ScaleX=500; c.Xdivs=5;
c.Yorigin=0; c.ScaleY=1000; c.Ydivs=5;

//임의의 데이터를 넣는다.
c.AddValue(50,50);
c.AddValue(100,100);
c.AddValue(200,150);
c.AddValue(450,450);

//메모리에 그려서 브라우저로 전달한다.
c.Draw();
}