Â÷Æ® ¿ä¼Ò

¾Ö³ëÅ×À̼Ç

¾Ö³ëÅ×À̼ÇÀº ¼³¸íÀ̳ª °­Á¶¸¦ À§ÇØ Â÷Æ®¿¡ ¹èÄ¡ÇÏ´Â ÀÏÁ¾ÀÇ µµÇüÀÌ´Ù. Annotation Ŭ·¡½º·ÎºÎÅÍ 13°³ÀÇ Å¬·¡½º°¡ ÆÄ»ýµÇ¸ç °¢ÀÚ ¸ð¾çÀ̳ª ¿ëµµ°¡ ´Ù¸£´Ù.

 

ÀÌ Áß 2°³ÀÇ ¾Ö³ëÅ×À̼ÇÀ» »ý¼ºÇÏ¿© Â÷Æ®¿¡ ¹èÄ¡ÇØ º¸ÀÚ. ÃàÀ» ±âÁØÀ¸·Î »ó´ë ÁÂÇ¥¿¡ ³õÀ» ¼öµµ ÀÖ°í Æ¯Á¤ µ¥ÀÌÅÍ Æ÷ÀÎÆ®¿¡ ºÎÂøÇÒ ¼öµµ ÀÖ´Ù. ¿øÇÏ´Â °´Ã¼¸¦ »ý¼ºÇÏ°í ¼Ó¼ºÀ» Á¶Á¤ÇÑ ÈÄ Â÷Æ®ÀÇ Annotations Ä÷º¼Ç¿¡ Ãß°¡Çϸé È­¸é¿¡ ³ªÅ¸³­´Ù.

 

private void Form1_Load(object sender, EventArgs e)

{

       Random R = new Random(100);

       for (int i = 0; i < 5; i++)

       {

                  chart1.Series[0].Points.AddY(R.Next(10, 100));

       }

 

       Border3DAnnotation b3d = new Border3DAnnotation();

       b3d.BackColor = Color.Lime;

       b3d.Text = "ÃÖÀú";

       b3d.Width = 13;

       b3d.Height = 12;

       b3d.AnchorDataPoint = chart1.Series[0].Points[1];

       chart1.Annotations.Add(b3d);

 

       ArrowAnnotation aa = new ArrowAnnotation();

       aa.ArrowStyle = ArrowStyle.Simple;

       aa.Height = -10;

       aa.Width = 0;

       aa.ArrowSize = 7;

       aa.LineColor = Color.Red;

       aa.LineWidth = 2;

       aa.BackColor = Color.Yellow;

       aa.AnchorDataPoint = chart1.Series[0].Points[2];

       aa.AnchorOffsetY = -2;

       aa.AllowMoving = true;

       chart1.Annotations.Add(aa);

}

µÎ ¹øÂ°, ¼¼ ¹øÂ° µ¥ÀÌÅÍ Æ÷ÀÎÆ® À§¿¡ ¾Ö³ëÅ×À̼ÇÀ» ºÙ¿´´Ù. Äڵ忡¼­ º¸´Ù½ÃÇÇ Å©±â, »ö»ó, ±½±â, ¸ð¾ç, °Å¸®, À̵¿ ¿©ºÎ µîÀ» ¼¼¼¼ÇÏ°Ô Á¶Á¤ÇÒ ¼ö ÀÖ´Ù. È­»ìÇ¥ ¾Ö³ëÅ×À̼ÇÀº ¸¶¿ì½º·Î µå·¡±×ÇÏ¿© À̵¿ÇÒ ¼öµµ ÀÖ´Ù.

ÇÊ¿äÇÑ ¼Ó¼ºÀº °ÅÀÇ ´Ù ÀÖÁö¸¸ ŸÀÔº°·Î ¼Ó¼ºÀÌ ´Ù¸£°í »ç¿ë ¹æ¹ýµµ »óÀÌÇØ Çѹø¿¡ ´Ù ¾Ë±â´Â ¾î·Æ´Ù. ÀÌ·² ¶§´Â ÄÚµå·Î ¼Ó¼ºÀ» ¹Ù²ã º¸´Â °Íº¸´Ù µðÀÚÀ̳ʿ¡¼­ ¼Ó¼ºÀ» ¹Ù²ã °¡¸ç ½Ç½Ã°£À¸·Î È¿°ú¸¦ È®ÀÎÇØ º¸´Â °ÍÀÌ ÁÁ´Ù.

¾çÀÌ ³Ê¹« ¸¹À¸´Ï ¿©±â¼­´Â ¾Ö³ëÅ×À̼ÇÀÇ ¿ëµµ Á¤µµ¸¸ ¼Ò°³Çϰí ÇÊ¿äÇÒ ¶§ ·¹ÆÛ·±½º¸¦ Âü°íÇÏ¿© »ç¿ëÇØ º¸ÀÚ. Ŭ·¡½º°¡ ³Ê¹« ¸¹¾Æ ¿©±â¼­ ÀÏÀÏÀÌ ¼³¸íÇÒ ¼ö°¡ ¾ø´Ù. ¼ÖÁ÷È÷ ´Ù ½á º¸Áöµµ ¾Ê¾Ò´Ù.

Ä¿½ºÅÒ ±×¸®±â

Â÷Æ®´Â ¿©·¯ °¡Áö °´Ã¼·Î ±×·¡ÇÁ´Â ¹°·ÐÀÌ°í ¼³¸í, ²Ù¹Ì±â µîÀÇ ´Ù¾çÇÑ Ãâ·ÂÀ» Áö¿øÇÏÁö¸¸ ±×·³¿¡µµ ºÒ±¸Çϰí Ãß°¡ Á¤º¸¸¦ Â÷Æ® À§¿¡ ´õ ±×¸± Çʿ䰡 ÀÖ´Ù. ÃÖÁ¾ÀûÀ¸·Î ¿øÇÏ´Â ¸ð¾çÀ» ¸¶À½´ë·Î ±×¸®·Á¸é À̺¥Æ®¸¦ ó¸®ÇØ¾ß ÇÑ´Ù.

Â÷Æ®´Â ±×¸®±â Àü¿¡ PrePaint À̺¥Æ®¸¦ È£ÃâÇÏ°í ±×¸° ÈÄ¿¡ PostPaint À̺¥Æ®¸¦ È£ÃâÇÑ´Ù. ÀÌ À̺¥Æ®¿¡ ´ëÇÑ Çڵ鷯¸¦ ¼³Ä¡Çϸé Â÷Æ® À§¿¡ ¹«¾ùÀ̵çÁö ±×¸± ¼ö ÀÖ´Ù.

 

private void Form1_Load(object sender, EventArgs e)

{

       Random R = new Random(100);

       double value = 30;

       for (int i = 0; i < 30; i++)

       {

                  value += R.Next(-9, 9);

                  chart1.Series[0].Points.AddXY(i, value);

       }

       chart1.Series[0].ChartType = SeriesChartType.Line;

       chart1.Series[0].Color = Color.Blue;

       chart1.Series[0].BorderWidth = 2;

 

       chart1.PostPaint += PostPaintHandler;

}

 

void PostPaintHandler(object sender, ChartPaintEventArgs e)

{

       Debug.WriteLine(e.ChartElement + " => " + e.Position);

       e.ChartGraphics.Graphics.DrawEllipse(Pens.Red, 60, 90, 200, 100);

}

 

¶óÀÎ ±×·¡ÇÁ¸¦ Çϳª ¹èÄ¡Çϰí PostPaint À̺¥Æ®¿¡ ´ëÇÑ Çڵ鷯¸¦ µî·ÏÇϸé Â÷Æ®¸¦ ´Ù ±×¸° ÈÄ ÀÌ À̺¥Æ®¸¦ È£ÃâÇÑ´Ù. Àμö·Î ChartPaintEventArgs °´Ã¼¸¦ Àü´ÞÇÏ¿© ±×¸®±â¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ ¾Ë·Á ÁØ´Ù.

 

¼Ó¼º

¼³¸í

Chart

±×¸®±â ´ë»ó Â÷Æ®ÀÌ´Ù.

ChartElement

Â÷Æ®ÀÇ ¾î¶² ºÎºÐÀ» ±×¸®°í ÀÖ´ÂÁö ¾Ë·Á ÁØ´Ù.

ChartGraphics

±×¸®±â¿¡ ÇÊ¿äÇÑ Á¤º¸¸¦ °¡Áö´Â °´Ã¼ÀÌ´Ù. ÀÌ °´Ã¼ ¾ÈÀÇ Graphics ¼Ó¼ºÀÌ GDI+ÀÇ ±×¸®±â °´Ã¼ÀÌ¸ç ±× ¿Ü¿¡ ÁÂÇ¥ º¯È¯À» ó¸®ÇÏ´Â ¸Þ¼­µå°¡ Æ÷ÇԵǾî ÀÖ´Ù.

Position

±×¸®´Â ¿ä¼ÒÀÇ À§Ä¡ Á¤º¸°¡ ÀúÀåµÇ¾î ÀÖ´Ù.

 

Äڵ忡¼­´Â À̺¥Æ® ÀμöÀÇ ÁÖ¿ä Á¤º¸¸¦ µð¹ö±ë â¿¡ Ãâ·ÂÇÏ°í ±×·¡ÇÈ °´Ã¼¸¦ »ç¿ëÇÏ¿© Àû´çÇÑ Å©±âÀÇ Å¸¿øÀ» ±×·È´Ù. Ãâ·ÂµÈ µð¹ö±ë Á¤º¸´Â ´ÙÀ½°ú °°´Ù.

 

Series-Series1=>10.35352, 6.15, 64.91257, 81.1875

ChartArea-ChartArea1=>10.35352, 6.15, 64.91257, 81.1875

LegendCell-LegendCell1=>80.5383, 4.516129, 5.175983, 4.516129

LegendCell-LegendCell2=>85.71429, 4.516129, 9.730849, 4.516129

Legend-Legend1=>Auto

System.Windows.Forms.DataVisualization.Charting.Chart=>0, 0, 100, 100

 

½Ã¸®Áî, ¿¡¸®¾î, ¹ü·Ê, Â÷Æ®¸¦ ±×¸± ¶§¸¶´Ù ÀÌ À̺¥Æ®°¡ È£ÃâµÇ¸ç °¢ ¿ä¼Ò°¡ ¾îµðÂë¿¡ ÀÖ´ÂÁö ¾Ë·Á ÁØ´Ù. Â÷Æ®¸¦ ´Ù ±×¸° ÈÄ ±× À§¿¡ Ÿ¿øÀ» ±×·È´Ù.

°ú¿¬ Ÿ¿øÀÌ Àß ±×·ÁÁö±â´Â Çß´Ù. ±×·¯³ª ÀÌ Å¸¿øÀÇ ÁÂÇ¥´Â Çȼ¿ ´ÜÀ§¿©¼­ Â÷Æ®ÀÇ Å©±â¿Í´Â »ó°ü¾øÀÌ Ç×»ó ÀÏÁ¤ÇÏ´Ù. ÆûÀ» ÀÛ°Ô Ãà¼ÒÇØµµ Ÿ¿øÀº Â÷Æ®¿Í´Â ¿ÏÀüÈ÷ µû·Î ³í´Ù.

Â÷Æ®´Â Å©±â¿Í »ó°ü¾øÀÌ ÀÏÁ¤ÇÑ ¸ð¾çÀ» À¯ÁöÇϱâ À§ÇØ »ó´ë ÁÂÇ¥°è¸¦ »ç¿ëÇÑ´Ù. Á»ó´ÜÀÌ (0,0)ÀÌ°í ¿ìÇÏ´ÜÀº (100, 100)À̸ç Áß°£ÀÇ ÁÂÇ¥´Â »ó´ëÀûÀÎ ºñÀ²¿¡ µû¶ó °áÁ¤µÈ´Ù. Â÷Æ® Á¤Áß¾ÓÀº (50, 50)ÀÌ´Ù.

µð¹ö±ë â¿¡ Ãâ·ÂÇÑ Â÷Æ® ¿ä¼ÒÀÇ À§Ä¡¸¦ º¸¸é ´Ù 0 ~ 100 »çÀÌÀÇ ÁÂÇ¥ÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. Â÷Æ®ÀÇ ¸ðµç ¿ä¼Ò´Â ¿ìÇÏ´ÜÀ» 100%·Î ÇÑ ¹éºÐÀ² ÁÂÇ¥ÀÌ´Ù. µû¶ó¼­ Á÷Á¢ ±×¸± ¶§´Â ¿øÇÏ´Â »ó´ë ÁÂÇ¥¸¦ Çȼ¿ ÁÂÇ¥·Î ¹Ù²Ù¾î »ç¿ëÇØ¾ß ÇÑ´Ù.

ÁÂÇ¥°£ÀÇ º¯È¯Àº ChartGraphics °´Ã¼°¡ Á¦°øÇϸç PointF, SizeF, RectangleF¸¦ »óÈ£ º¯È¯ÇÑ´Ù. ¹éºÐÀ² ÁÂÇ¥ÀÌ´Ù º¸´Ï ¸ðµç ÁÂÇ¥´Â ½Ç¼öÀÌ´Ù. Á¦ÀÏ °£´ÜÇÑ ÁÂÇ¥ º¯È¯ ¸Þ¼­µåºÎÅÍ º¸ÀÚ.

 

PointF GetAbsolutePoint(PointF)

PointF GetRelativePoint(PointF)

 

¾ÆÁÖ Á÷°üÀûÀÌ´Ù. »ó´ë ÁÂÇ¥¸¦ ÁÖ¸é Àý´ë ÁÂÇ¥·Î ¹Ù²ã ÁÖ°í Àý´ë ÁÂÇ¥¸¦ ÁÖ¸é »ó´ë ÁÂÇ¥·Î ¹Ù²ã ÁØ´Ù. SizeF³ª RectangleF·Î ¸¶Âù°¡ÁöÀÌ´Ù.

 

SizeF GetAbsoluteSize (SizeF size);

SizeF GetRelativeSize (SizeF size);

RectangleF GetAbsoluteRectangle (RectangleF rectangle);

RectangleF GetRelativeRectangle (RectangleF rectangle);

 

Ÿ¿øÀº »ç°¢ ¿µ¿ªÀ̹ǷΠGetAbsoluteRectangle ¸Þ¼­µå·Î Çȼ¿ ÁÂÇ¥¸¦ ±¸ÇÏ¸é µÈ´Ù.

 

void PostPaintHandler(object sender, ChartPaintEventArgs e)

{

       RectangleF relRect = new RectangleF(30, 30, 40, 40);

       RectangleF absRect = e.ChartGraphics.GetAbsoluteRectangle(relRect);

       e.ChartGraphics.Graphics.DrawEllipse(Pens.Red, absRect);

}

 

(30, 30) »ó´ë ÁÂÇ¥¿¡¼­ Æø°ú ³ôÀ̰¡ °¢°¢ 40 Å©±âÀÎ »ç°¢ÇüÀ» Á¤ÀÇÇß´Ù. ÆøÀ̳ª ³ôÀ̳ª 30% ~ 70%±îÁö¿¡ °ÉÄ¡´Â Áß¾Ó¿¡ À§Ä¡ÇÑ Å¸¿ø ÁÂÇ¥ÀÌ´Ù. ÀÌ »ó´ë ÁÂÇ¥¸¦ GetAbsoluteRectangle ¸Þ¼­µå·Î Çȼ¿ ÁÂÇ¥¸¦ ±¸Çϰí ÀÌ ÁÂÇ¥¿¡ Ÿ¿øÀ» ±×·È´Ù.

Â÷Æ®ÀÇ Áß¾Ó(¿¡¸®¾îÀÇ Áß¾ÓÀÌ ¾Æ´Ï°í)¿¡ Ÿ¿øÀÌ ±×·ÁÁö¸ç Â÷Æ®ÀÇ Å©±â°¡ ¹Ù²î¾îµµ Ç×»ó Áß¾Ó¿¡ ±×·ÁÁø´Ù.

 

ÀÌ º¯È¯ ¸Þ¼­µå¸¦ »ç¿ëÇÏ¸é »ó´ë ÁÂÇ¥¿Í Àý´ë ÁÂÇ¥¸¦ ÀÚÀ¯·Ó°Ô º¯È¯ÇÏ¿© Â÷Æ®ÀÇ ¿øÇÏ´Â °÷¿¡ ¿øÇÏ´Â µµÇüÀ» ÀÚÀ¯·Ó°Ô ±×¸± ¼ö ÀÖ´Ù. ´ÙÀ½ ¿¹Á¦´Â Â÷Æ®ÀÇ ÀÓÀÇ ¿µ¿ª¿¡ ¸¶¿ì½º¸¦ °®´Ù ´ë¸é ÇöÀç À§Ä¡¿Í °ªÀ» º¸¿©ÁØ´Ù.

 

void PostPaintHandler(object sender, ChartPaintEventArgs e)

{

       if (e.ChartElement != chart1.ChartAreas[0]) return;

       ChartArea area = chart1.ChartAreas[0];

       Graphics g = e.ChartGraphics.Graphics;

 

       // XÃàÀÇ ¹üÀ§¸¦ ±¸ÇÔ

       double xstart = area.AxisX.ValueToPixelPosition(area.AxisX.Minimum);

       double xend = area.AxisX.ValueToPixelPosition(area.AxisX.Maximum);

 

       // ¹üÀ§ ¹Ù±ùÀÌ¸é ¸®ÅÏ

       Point pt = PointToClient(MousePosition);

       if (pt.X < xstart || pt.X > xend) return;

 

       // ¼öÁ÷¼± ±×¸²

       Pen vertPen = new Pen(Color.Gray, 2);

       vertPen.DashStyle = DashStyle.Dash;

       RectangleF rtArea = e.ChartGraphics.GetAbsoluteRectangle(e.Position.ToRectangleF());

       g.DrawLine(vertPen, pt.X, rtArea.Y, pt.X, rtArea.Bottom);

 

       // »ç°¢Çü ±×¸²

       Rectangle rt = new Rectangle(pt.X + 10, pt.Y, 100, 80);

       if (rt.Right > xend) rt.X = pt.X - 110;

       if (rt.Bottom > rtArea.Bottom) rt.Y = pt.Y - 80;

       g.FillRectangle(new SolidBrush(Color.FromArgb(128, 255, 255, 0)), rt);

       g.DrawRectangle(Pens.Gray, rt);

 

       // Ä¿¼­ À§Ä¡ÀÇ X, Y°ªÀ» ã´Â´Ù.

       double x = Math.Round(area.AxisX.PixelPositionToValue(pt.X), 2);

       double y = 0;

       foreach (DataPoint p in chart1.Series[0].Points)

       {

                  if (p.XValue > x)

                  {

                            y = p.YValues[0];

                            break;

                  }

       }

       String content = String.Format("pt.X = {0}\nX={1}\nY={2}", pt.X, x, y);

       g.DrawString(content, Font, Brushes.Black, rt.X + 10, rt.Y + 10);

}

 

private void chart1_MouseMove(object sender, MouseEventArgs e)

{

       chart1.Invalidate();

}

 

 ¸¶¿ì½º°¡ ¿òÁ÷ÀÏ ¶§¸¶´Ù Â÷Æ®¸¦ ´Ù½Ã ±×·Á¾ß ÇϹǷΠMouseMove À̺¥Æ® Çڵ鷯¿¡¼­ Invalidate¸¦ È£ÃâÇÑ´Ù. Â÷Æ®¸¦ ¿ÏÀüÈ÷ ´Ù½Ã ±×¸®°í PostPaint ¸Þ¼­µåµµ È£ÃâµÈ´Ù.

±×¸®±â À̺¥Æ®°¡ µé¾î¿À¸é ¸ÕÀú ±×¸®±â ´ë»óÀÌ ¿¡¸®¾îÀÎÁö Á¡°ËÇÑ´Ù. ¾Õ¿¡¼­ À̺¥Æ® Àμö¸¦ ´ýÇÁÇØ ºÃ´Âµ¥ PostPoint´Â ¿¡¸®¾î»Ó¸¸ ¾Æ´Ï¶ó ½Ã¸®Áî, ¹ü·Ê µî¿¡ ´ëÇØ¼­µµ ¹ß»ýÇÑ´Ù. À̶§´Â ±»ÀÌ ¹Ýº¹ÀûÀÎ ±×¸®±â¸¦ ÇÒ Çʿ䰡 ¾ø´Ù.

´ÙÀ½Àº ¸¶¿ì½º°¡ Â÷Æ® ¾È¿¡ ÀÖ´ÂÁö Á¡°ËÇÑ´Ù. ¹ü·Ê³ª Â÷Æ® ¿ÞÂÊ¿¡ ÀÖÀ¸¸é ±»ÀÌ ±×¸± Çʿ䰡 ¾ø´Ù. ¹üÀ§ Á¡°ËÀ» À§ÇØ XÃàÀÇ ÁÂÇ¥¸¦ ±¸ÇÑ´Ù. À̶§´Â ´ÙÀ½ ¸Þ¼­µå¸¦ »ç¿ëÇÑ´Ù.

 

double ValueToPosition (double axisValue);

double ValueToPixelPosition (double axisValue);

 

XÃàÀÇ °ªÀ» ÁÖ¸é °¢ °ªÀÌ Â÷Æ®ÀÇ ¾îµðÂë¿¡ ÀÖ´ÂÁö ÁÂÇ¥¸¦ ¸®ÅÏÇ쵂 °¢°¢ »ó´ë ÁÂÇ¥¿Í Çȼ¿ ÁÂÇ¥ÀÌ´Ù. AxisXÀÇ Minimum°ú Maximum¿¡ ´ëÇØ »ó´ë ÁÂÇ¥¸¦ Á¶»çÇÏ¸é ´ë·« 10 ~ 75 ¹üÀ§°¡ µÈ´Ù. Â÷Æ®ÆøÀÇ 10%¿¡¼­ XÃàÀÌ ½ÃÀÛÇØ¼­ 75%±îÁö Â÷ÁöÇϴµ¥ ¹ü·Ê¸¦ »©¸é ¿À¸¥ÂÊ ¹üÀ§°¡ ´õ ´Ã¾î³­´Ù.

¸¶¿ì½º Ä¿¼­¿Í ºñ±³ÇÏ·Á¸é ¾Æ¿¹ Çȼ¿ ÁÂÇ¥·Î ±¸ÇÏ´Â °ÍÀÌ Æí¸®ÇÏ´Ù. »ó´ë ÁÂÇ¥·ÎºÎÅÍ Çȼ¿ ÁÂÇ¥¸¦ ±¸ÇÏ´Â °Íµµ »ç½Ç ±×¸® ¾î·ÆÁö´Â ¾Ê´Ù. ¾îÂ÷ÇÇ »ó´ëÁÂÇ¥¶ó´Â °ÍÀÌ Æø¿¡ ´ëÇÑ ¹éºÐÀ²ÀÏ »ÓÀ̹ǷΠÂ÷Æ® Æø¿¡ ´ëÇØ »ó´ë ÁÂÇ¥¸¦ °öÇÑ ÈÄ 100À¸·Î ³ª´©¸é µÈ´Ù.

 

double xstart = chart1.Width * area.AxisX.ValueToPosition(area.AxisX.Minimum) / 100;

double xend = chart1.Width * area.AxisX.ValueToPosition(area.AxisX.Maximum) / 100;

 

XÃàÀÇ ¹üÀ§¸¦ ±¸ÇÑ ÈÄ ¸¶¿ì½º Ä¿¼­ ÁÂÇ¥°¡ ÀÌ ¹üÀ§¾È¿¡ ÀÖ´ÂÁö Á¶»çÇÑ´Ù. Ä¿¼­ ÁÂÇ¥´Â ÆûÀÇ MousePositionÀ¸·Î ±¸Ç쵂 ÀÌ °ªÀº È­¸é ÁÂÇ¥¿©¼­ PointToClient·Î ÀÛ¾÷ ¿µ¿ª ÁÂÇ¥·Î ¹Ù²Ù¾î¾ß ÇÑ´Ù.

Ä¿¼­ÀÇ ¼öÆò ÁÂÇ¥°¡ XÃà ¹üÀ§ ³»¿¡ ÀÖÀ¸¸é ±×¸®±â¸¦ Ç쵂 ±×·¸Áö ¾ÊÀ¸¸é ¸®ÅÏÇØ ¹ö¸°´Ù. Â÷Æ® ¹Ù±ù¿¡ ÀÖÀ» ¶§´Â ±»ÀÌ ±×¸± Çʿ䰡 ¾ø°í ¶Ç Ãà°ªÀ» Á¶»çÇÒ ¶§ ¹üÀ§ ¹Ù±ùÀº ¿¹¿Ü°¡ ¹ß»ýÇÏ´Â ¹®Á¦µµ ÀÖ´Ù. YÃàÀÇ ¹üÀ§µµ Á¡°ËÇÒ ¼ö ÀÖÁö¸¸ ¾Æ·¡À§·Î ¹þ¾î³ª´Â °ÍÀº Çã¿ëÇϱâ·Î Çß´Ù.

XÃà ´ë½Å ¿¡¸®¾îÀÇ InnerPlotPosition ¼Ó¼ºÀ¸·Î ÇÃ·Ô ¿µ¿ªÀ» ´ë½Å »ç¿ëÇØµµ µÉ °Í °°Áö¸¸ Ç÷ÔÀº ¹ü·Ê±îÁö Æ÷ÇÔÇϱ⠶§¹®¿¡ ¾ÈµÈ´Ù. ¹üÀ§ ¾È¿¡ µé¾î ¿ÔÀ¸¸é Ä¿¼­ À§Ä¡¿¡ ¼öÁ÷¼±À» ±×¸°´Ù. ¿¡¸®¾îÀÇ Çȼ¿ ¹üÀ§¸¦ rtArea¿¡ ±¸Çϰí ÀÌ ¿µ¿ªÀÇ ¼öÁ÷ ¿µ¿ª¿¡ ´ëÇØ ¼±À» ±ß´Â´Ù.

´ÙÀ½Àº ¼öÁ÷¼± ¿·¿¡ ¹ÝÅõ¸íÇÑ »öÀ¸·Î »ç°¢ÇüÀ» ±×¸°´Ù. Ä¿¼­¿Í ³Ê¹« ¹ÐÂøÇÏ¸é ´ä´äÇØ º¸À̹ǷΠ10Çȼ¿¸¸Å­ °Å¸®¸¦ ¶ç¿ì°í »ç°¢ÇüÀÌ ¿À¸¥ÂÊÀ̳ª ¾Æ·¡·Î ¹þ¾î³ª¸é Â÷Æ® ¿µ¿ª ¾ÈÀ¸·Î ÁÂÇ¥¸¦ Á¶Á¤Çß´Ù. ´ÙÀ½ ¸Þ¼­µå´Â °¢°¢ »ó´ë ÁÂÇ¥¿Í Çȼ¿ ÁÂÇ¥ÀÇ ÇöÀç XÃà°ªÀ» Á¶»çÇÑ´Ù.

 

double PositionToValue (double position);

double PixelPositionToValue (double position);

 

¸¶¿ì½º À§Ä¡ÀÇ XÃà Çȼ¿ ÁÂÇ¥¸¦ x¿¡ ±¸Çϰí ÀÌ À§Ä¡ÀÇ y°ªÀº ½Ã¸®Áî¿¡¼­ ¼øÂ÷ °Ë»öÇÏ¿© ã´Â´Ù. µ¥ÀÌÅÍ Æ÷ÀÎÆ® Àüü¸¦ ¼øÈ¸Çϸç x°ªº¸´Ù ÃÖÃÊ·Î ´õ Å« XValue¸¦ ã°í ±× ÁöÁ¡ÀÇ y°ªÀ» ±¸ÇÏ¸é µÈ´Ù. ÀÌÇØÇϱâ´Â ½¬¿î ÄÚµåÀÌ´Ù.

±×·¯³ª µ¥ÀÌÅͰ¡ ÀÛÀ» ¶§´Â ÀÌ·± °£´ÜÇÑ ¹æ¹ýµµ ¾µ¸¸ÇÏÁö¸¸ XÃà °ªÀÌ ¼öõ°³ Á¤µµ µÈ´Ù¸é ¼øÂ÷ °Ë»öÀº ³Ê¹« ´À¸®´Ù. X°ªÀÌ Á¤·ÄµÇ¾î ÀÖÀ¸´Ï ÀÌ·² ¶§´Â ´ç¿¬È÷ À̺Р°Ë»öÀ» »ç¿ëÇØ¾ß ÇÑ´Ù. Á÷Á¢ À̺Р°Ë»öÀ» ÇÒ ÇÊ¿ä´Â ¾ø°í Æ÷ÀÎÆ® Ä÷º¼ÇÀÇ FindByValue ¸Þ¼­µå¸¦ »ç¿ëÇÏ¸é µÈ´Ù.

 

DataPoint dp = chart1.Series[0].Points.FindByValue(Math.Round(x), "X");

if (dp != null) y = dp.YValues[0];

 

ÀÌ ¸Þ¼­µå´Â ÁÖ·Î Y°ªÀ» °Ë»öÇÒ ¶§ ¾²Áö¸¸ µÎ ¹øÂ° Àμö·Î "X"³ª "Y2" µîÀ» ÁöÁ¤ÇÏ¸é ´Ù¸¥ °ªµµ ãÀ» ¼ö ÀÖ´Ù. ³»ºÎÀûÀ¸·Î °¡Àå È¿À²ÀûÀÎ °Ë»ö ¹æ¹ýÀ» ÃëÇÒ °ÍÀÌ´Ù. Á¤È®ÇÑ X°ª¸¸ °Ë»öÇϱ⠶§¹®¿¡ ½Ã¸®Áî¿¡ ÀúÀåÇÑ °ª°ú °°Àº Æ÷¸ËÀ¸·Î ¸ÂÃç ÁÖ¾î¾ß ÇÑ´Ù.

PixelPositionToValue´Â ¼Ò¼öÁ¡ ÀÌÇÏ ÀÚ¸®±îÁö °è»êÇØ ÁÖÁö¸¸ ½Ã¸®Áî¿¡ X´Â Á¤¼ö·Î µé¾î°¡ ÀÖÀ¸´Ï ¹ö¸²ÇÑ ÈÄ °Ë»öÇØ¾ß Á¤È®ÇÏ´Ù. ¶ÇÇÑ X°¡ Â÷Æ® ¹üÀ§¸¦ ¹þ¾î³ª¸é nullÀÌ ¸®Å쵃 ¼öµµ ÀÖÀ¸¹Ç·Î ¿¡·¯ 󸮵µ ²À ÇÊ¿äÇÏ´Ù.

»ç½Ç ÀÌ ÄÚµå´Â ³ªµµ ¾ÆÁÖ ³ªÁß¿¡ ¾Ë°Ô µÇ¾ú´Âµ¥ ´öºÐ¿¡ Â÷Æ®ÀÇ ¼Óµµ°¡ ±²ÀåÈ÷ »¡¶óÁ³´Ù. ÀÌ·¡¼­ Ç×»ó °ü½ÉÀ» °¡Áö°í ·¹ÆÛ·±½º¸¦ Æ´Æ´ÀÌ µÚÁ® ºÁ¾ß ÇÑ´Ù. ¹«½ÄÇÑ ÄÚµå ¸¸µéÁö ¸»°í Àß ¸¸µé¾î ³õÀº Äڵ带 Àû±Ø Ȱ¿ëÇÏÀÚ. ÀÌ·¸°Ô ±¸ÇÑ ¼¼ °ªÀ» »ç°¢ ¿µ¿ª¾È¿¡ Ãâ·ÂÇÑ´Ù.

Ä¿¼­¸¸ °®´Ù ´ë¸é ÀÌ °ªÀÌ XÃàÀÇ ¾îµðÂëÀÎÁö, Y°ªÀº ¾ó¸¶ÀÎÁö ÃàÀ¸·Î ½Ã¼±À» À̵¿ÇÏÁö ¾Ê°íµµ Á¤È®ÇÑ °ªÀ» ¾Ë ¼ö ÀÖ¾î Æí¸®ÇÏ´Ù. Â÷Æ®¸¦ ±×¸± ¶§¸¶´Ù PostPaint À̺¥Æ®°¡ ³¯¶ó¿À°í ¿øÇÏ´Â ¸ðµç Á¤º¸¸¦ ´Ù ±¸ÇÒ ¼ö ÀÖ¾î ¾ó¸¶µçÁö ¿¹»Û ¸ð¾çÀ¸·Î Á¤º¸¸¦ º¸¿©ÁÙ ¼ö ÀÖ´Ù.

3D Â÷Æ®

Â÷Æ®¸¦ 3D·Îµµ Ãâ·ÂÇÒ ¼ö ÀÖ´Ù. ¿¡¸®¾îÀÇ Area3DStyle °´Ã¼°¡ 3D Ãâ·Â °ü·Ã ±â´ÉÀ» Á¦°øÇÏ¸ç ´ÙÀ½°ú °°Àº ¼Ó¼ºÀ» °¡Áø´Ù.

 

¼Ó¼º

¼³¸í

Enable3D

3Â÷¿ø Ãâ·Â ±â´ÉÀ» »ç¿ëÇÑ´Ù. µðÆúÆ® °ªÀÌ false¿©¼­ º°´Ù¸¥ ÁöÁ¤ÀÌ ¾øÀ¸¸é 2D·Î Ãâ·ÂµÈ´Ù. ÀÌ °ªÀ» true·Î ¹Ù²Ù¾î¾ß 3DÂ÷Æ®°¡ ³ªÅ¸³­´Ù.

Inclination

¼öÆòÃà¿¡¼­ÀÇ È¸Àü °¢µµ¸¦ ÁöÁ¤ÇÑ´Ù. µðÆúÆ®´Â À§¿¡¼­ ¾Æ·¡·Î ³»·Áº¸´Â 30µµ·Î µÇ¾î ÀÖ´Ù.

Rotation

¼öÁ÷Ãà¿¡¼­ÀÇ È¸Àü °¢µµÀÌ´Ù. µðÆúÆ®´Â ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ» ¹Ù¶óº¸´Â 30µµ·Î µÇ¾î ÀÖ´Ù. À½¼ö °¢µµÀÌ¸é º®ÀÌ ¿À¸¥ÂÊÀ¸·Î À̵¿ÇÑ´Ù.

Perspective

¿ø±Ù°¨À» ÁöÁ¤ÇÑ´Ù. ±×¸®µå ¼±ÀÌ ÆòÇàÇÏÁö ¾Ê°í ±¸¼®ÀÇ ¼Ò½ÇÁ¡À» ÇâÇÏ´Â Çü½ÄÀÌ µÈ´Ù.

IsRightAngleAxes

isometric projection ±â¹ýÀ» »ç¿ëÇÑ´Ù. ÁøÂ¥ 3D´Â ¾Æ´ÏÁö¸¸ ƯÁ¤ ±íÀÌ¿¡¼­´Â °¡Àå ÀÚ¿¬½º·´´Ù. Perspective¿Í´Â ¹èŸÀûÀÌ´Ù.

WallWidth

º®ÀÇ µÎ²²¸¦ ÁöÁ¤ÇÑ´Ù.

PointDepth

µ¥ÀÌÅÍ Æ÷ÀÎÆ®ÀÇ ±íÀ̸¦ Æø¿¡ ´ëÇÑ ºñÀ²·Î ÁöÁ¤ÇÑ´Ù. 100%ÀÌ¸é ¸·´ë ±×·¡ÇÁ À­¸éÀÌ Á¤»ç°¢ÇüÀÌ¸ç ±×º¸´Ù ´õ ±íÀ¸¸é ¾ÈÂÊÀ¸·Î ±æÂßÇØÁø´Ù.

PointGapDepth

µ¥ÀÌÅÍ Æ÷ÀÎÆ®°£ÀÇ °£°ÝÀ» ÁöÁ¤ÇÑ´Ù. µÎ °³ÀÇ ¸·´ë ±×·¡ÇÁ¸¦ ¾Õ µÚ·Î ¹èÄ¡ÇßÀ» ¶§ ÀÌ ¼Ó¼º¿¡ µû¶ó ¸·´ë°£ÀÇ °Å¸®°¡ ´Þ¶óÁø´Ù.

IsClustered

¹Ù, Ä÷³ Â÷Æ®°¡ Ŭ·¯½ºÅÍ »óÅÂÀÎÁö¸¦ ÁöÁ¤ÇÑ´Ù. ÀÌ °ªÀÌ trueÀÌ¸é ¸·´ë¸¦ ³ª¶õÈ÷ ¹èÄ¡Çϰí falseÀÌ¸é ¾ÕµÚ·Î ¹èÄ¡ÇÑ´Ù.

 

¼Ó¼ºÀÇ Àǹ̸¦ ÀÐ¾î ºÁµµ ÀÌ °ªÀÌ Â÷Æ®ÀÇ ¾î¶² ¸é¿¡ ¿µÇâÀ» ¹ÌÄ¡´ÂÁö Á÷°üÀûÀ¸·Î ÆÄ¾ÇÇÏ±â ¾î·Æ´Ù. °°ÀÌ ÁöÁ¤ÇÒ ¼ö ¾ø´Â ¹èŸÀûÀÎ ¼Ó¼ºµµ ÀÖ°í Â÷Æ® ŸÀÔ¿¡ µû¶ó È¿°ú°¡ ¾à°£¾¿ ´Þ¶óÁö±âµµ ÇÑ´Ù.

ÀÌ·± º¹ÀâÇÑ ¼Ó¼ºÀº ±ÛÀ» Àоî ÀÌÇØÇÏ´Â °Íº¸´Ù´Â ½ÇÁ¦ °ªÀ» ¹Ù²ã °¡¸ç ´«À¸·Î È¿°ú¸¦ È®ÀÎÇØ º¸´Â °ÍÀÌ ÀÌÇØÇϱ⠽±´Ù. ´ÙÀ½ ¿¹Á¦´Â ÀÌ·± ¸ñÀûÀ¸·Î ¸¸µç °ÍÀ̸ç Űº¸µå·Î °¢ ¼Ó¼ºÀ» ½ÇÇàÁß¿¡ Á¶Á¤ÇØ º»´Ù. ¼Ò½º¸¦ º¸¸é °¢ ۰¡ ¾î¶² °ªÀ» Á¶Á¤ÇÏ´ÂÁö, °ªÀÇ ¹üÀ§´Â ¾î¶²Áö, µðÆúÆ®´Â ¹«¾ùÀÎÁö ¾Ë ¼ö ÀÖ´Ù.

 

private void Form1_Load(object sender, EventArgs e)

{

       chart1.Series.Add("");

       chart1.Series.Add("");

       Random R = new Random(100);

       double sale = 50;

       double cost = 30;

       double profit = 10;

       for (int i = 0; i < 10; i++)

       {

                  sale += R.Next(-4, 5);

                  chart1.Series[0].Points.AddY(sale);

                  cost += R.Next(-4, 5);

                  chart1.Series[1].Points.AddY(cost);

                  profit += R.Next(-4, 5);

                  chart1.Series[2].Points.AddY(profit);

       }

       chart1.Series[0].ChartType = SeriesChartType.Line;

       chart1.Series[0].Color = Color.Blue;

       chart1.Series[0].BorderWidth = 2;

       chart1.Series[1].ChartType = SeriesChartType.Column;

       chart1.Series[1].Color = Color.Red;

       chart1.Series[2].ChartType = SeriesChartType.Column;

       chart1.Series[2].Color = Color.Green;

 

       chart1.Focus();

}

 

private void chart1_KeyPress(object sender, KeyPressEventArgs e)

{

       ChartArea3DStyle a = chart1.ChartAreas[0].Area3DStyle;

       switch (e.KeyChar)

       {

                  case 'q':a.Inclination = Math.Min(a.Inclination + 5, 90); break;

                  case 'a':a.Inclination = Math.Max(a.Inclination -5, -90); break;

                  case 'w':a.Rotation = Math.Min(a.Rotation + 5, 180); break;

                  case 's':a.Rotation = Math.Max(a.Rotation - 5, -180);break;

                  case 'e': a.Perspective = Math.Min(a.Perspective + 5, 100); break;

                  case 'd': a.Perspective = Math.Max(a.Perspective - 5, 0); break;

                  case 'r': a.WallWidth = Math.Min(a.WallWidth + 2, 30); break;

                  case 'f': a.WallWidth = Math.Max(a.WallWidth - 2, 0); break;

                  case 't': a.PointDepth = Math.Min(a.PointDepth + 25, 1000); break;

                  case 'g': a.PointDepth = Math.Max(a.PointDepth - 25, 0); break;

                  case 'y': a.PointGapDepth = Math.Min(a.PointGapDepth + 25, 1000); break;

                  case 'h': a.PointGapDepth = Math.Max(a.PointGapDepth - 25, 0); break;

                  case 'z': a.Enable3D = !a.Enable3D;break;

                  case 'x':

                            a.Inclination = 30;

                            a.Rotation = 30;

                            a.Perspective = 0;

                            a.WallWidth = 7;

                            a.PointDepth = 100;

                            a.PointGapDepth = 100;

                            a.IsClustered = false;

                            a.IsRightAngleAxes = true;

                            break;

                  case 'c':a.IsClustered = !a.IsClustered;break;

                  case 'v':a.IsRightAngleAxes = !a.IsRightAngleAxes;break;

       }

 

       Text = String.Format("inc={0},rot={1},per={2},wall={3},dep={4},gap={5}",

                  a.Inclination, a.Rotation,a.Perspective, a.WallWidth,

                  a.PointDepth, a.PointGapDepth);

}

 

µÎ °³ÀÇ Ä÷³ ½Ã¸®Áî¿Í ÇѰ³ÀÇ ¶óÀÎ ½Ã¸®Á Â÷Æ®¿¡ Ç¥½ÃÇß´Ù. Űº¸µå ÀÔ·ÂÀ» ¹ÞÀ¸·Á¸é Â÷Æ®¿¡°Ô Æ÷Ä¿½º¸¦ ÁÖ¾î¾ß Çϸç KeyPress À̺¥Æ®¿¡¼­ ´­·¯Áø Ű¿¡ µû¶ó ¼Ó¼º°ªÀ» Á¶Á¤ÇÑ´Ù. 3D ¿É¼ÇÀ» ÁöÁ¤ÇÏÁö ¾Ê¾Æ óÀ½ ½ÇÇàÇϸé 2D·Î Ãâ·ÂµÈ´Ù.

ÀÌ »óÅ¿¡¼­ ۸¦ ´­·¯ ¼Ó¼ºÀ» Á¶Á¤ÇÏ¸ç °¢ ŰÀÇ ±â´ÉÀº ¼Ò½º¸¦ º¸¸é ¾Ë ¼ö ÀÖ´Ù. z۰¡ 3D ¿É¼ÇÀ» Åä±ÛÇϸç xŰ´Â ¸ðµç ¼Ó¼ºÀ» µðÆúÆ®·Î µÇµ¹¸°´Ù. Z۸¦ ´©¸£¸é 3D Â÷Æ®°¡ ³ªÅ¸³­´Ù.

Çϴÿ¡ ÆÄ¶õ ±¸¸§ÀÌ ¶° ÀÖ°í ¶¥¿¡ ¾ÆÆÄÆ® 2µ¿ÀÌ ÁÙ Áö¾î ¼­ ÀÖ´Ù. ÀÌ »óÅ¿¡¼­ qa, ws۸¦ ´­·¯ ¼öÆò, ¼öÁ÷ °¢µµ¸¦ Ʋ¸é ´Ù¸¥ °¢µµ¿¡¼­ ¹Ù¶óº¼ ¼ö ÀÖ´Ù. x۸¦ ´©¸£¸é ¾ðÁ¦µçÁö µðÆúÆ® ¿É¼ÇÀ¸·Î µ¹¾Æ°£´Ù.

ed, rfŰ´Â ¿ø±Ù°¨°ú º® µÎ²²¸¦ Á¶Á¤ÇÑ´Ù.

tg´Â ¸·´ëÀÇ µÎ²²¸¦ Á¶Á¤Çϰí yh´Â ¸·´ë°£ÀÇ °Å¸®¸¦ º¯°æÇÑ´Ù. °Å¸®¸¦ ÃæºÐÈ÷ ¶ç¿ì¸é µÎ Â÷Æ®°¡ °¢°¢ µû·Î ¹èÄ¡µÈ´Ù.

c۸¦ ´­·¯ Ŭ·¯½ºÅÍ »óÅ·Π¹èÄ¡ÇÏ¸é µÎ ¸·´ë°¡ ¾ÕµÚ°¡ ¾Æ´Ñ Á¿ì·Î ³ª¶õÈ÷ ¹è¿­µÈ´Ù. 2D¿¡¼­´Â ´ç¿¬È÷ ³ª¶õÈ÷ ¹èÄ¡ÇÒ ¼ö¹Û¿¡ ¾øÁö¸¸ 3D¿¡¼­´Â ¾ÕµÚ·Îµµ ¹èÄ¡ÇÒ ¼ö ÀÖ´Ù.

v۸¦ ´­·¯ IsRightAngleAxes ¿É¼ÇÀ» Åä±ÛÇÏ¸é °¢µµ°¡ Â÷Æ®¿¡ ¿µÇâÀ» ¹ÌÄ¡´Â ¹æ½ÄÀÌ ´Þ¶óÁø´Ù. °¢µµ¸¦ ¹Ù²ã °¡¸ç Â÷Æ®¸¦ ȸÀü½Ãų ¶§´Â ÀÌ ¿É¼ÇÀ» ²ô´Â °ÍÀÌ ´õ ÀÚ¿¬½º·´´Ù.

ÀÌ ¿¹Á¦¸¦ ÅëÇØ 3D Â÷Æ®ÀÇ °¢ ¼Ó¼ºÀÌ ¾î¶² ¿µÇâÀ» ¹ÌÄ¡´ÂÁö ¿¬±¸ÇØ º¸°í ¸ñÀû¿¡ µü ¸Â´Â ¿É¼ÇÀ» ã¾Æ Àû¿ëÇÏ¸é µÈ´Ù. ¸»·Î ¼³¸íÇÏ´Â °Íº¸´Ù´Â ÈξÀ ´õ Á÷°üÀûÀ¸·Î ÀÌÇØÇÒ ¼ö ÀÖ°í ¿É¼Ç°£ÀÇ Á¶ÇÕ È¿°ú¸¦ Å×½ºÆ®Çϱ⵵ ½±´Ù.

 

ÀÌ»óÀ¸·Î Â÷Æ® ÄÁÆ®·Ñ¿¡ ´ëÇÑ °­Á¸¦ ¸¶Ä£´Ù. °³¹ßÅø¿¡ ±âº» Æ÷ÇÔµÈ ÄÁÆ®·ÑÀ̶ó±â¿¡´Â ±â´ÉÀÌ ´Ùä·Ó°í ¾ÈÁ¤¼ºÀ̳ª ¼º´Éµµ ÃæºÐÈ÷ ¸¸Á·ÇÒ¸¸ÇÑ ÄÁÆ®·ÑÀÌ´Ù. ¾çÀÌ Á» ¸¹Áö¸¸ ÃæºÐÇÑ ½Ã°£À» ÅõÀÚÇÏ¿© Àß ¿¬±¸ÇØ µÎ¿ö µÎ¸é ½Ç¹«¿¡ À¯¿ëÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖ´Ù.