65.9K
CodeProject 正在变化。 阅读更多。
Home

图形库

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.84/5 (41投票s)

2008年2月26日

CPOL

3分钟阅读

viewsIcon

143947

downloadIcon

7030

本文介绍了使用 C# 构建一个简单的图形库。

pic1.jpg
Pic2.jpg
Pic3.jpgPic4.JPG

引言

.NET Framework 中的图形是一个强大的功能,可以适用于广泛的用途。 在这里,我开发了一个类来演示使用图形创建如下所示的图表:

  • 条形图
  • 饼图
  • 折线图

Using the Code

附加的项目包含一个名为DrawGraph.cs的文件,它是一个用于生成图表的通用库。 此库中的方法生成诸如单维度条形图、3D 条形图、单维度饼图、3D 饼图和折线图之类的图表。 所有图表都以位图格式生成。 下面的代码演示了如何在 Windows 应用程序中使用此库。

// Values used to create graph 


string [] keyValue=new string[ui_lbx_DataKey.Items.Count];
float[] values = new float[ui_lbx_DataKey.Items.Count];

 for (int i = 0; i < ui_lbx_DataKey.Items.Count; i++)
 {
    keyValue[i] = ui_lbx_DataKey.Items[i].ToString();
    values[i] = float.Parse(ui_lbx_DataValue.Items[i].ToString());
 }


//Include namespace System.Anoop.Graph and initiaze the
//bargraph object with values,label on x & y axis, font format and alpha
 

 DrawGraph bargraph = new DrawGraph(keyValue, values, 
                      ui_txt_xlabel.Text, ui_txt_ylabel.Text,
                      "Courier", 255);


//Generating graph and assigning it to respective picture box 


 p1.Image = bargraph.DrawBarGraph();
 p2.Image = bargraph.Draw3dBarGraph();
 p3.Image = bargraph.DrawPieGraph();
 p4.Image = bargraph.Draw3DPieGraph();


//Generating Line graph
 

 DrawGraph bargraph1 = new DrawGraph(keyValue, values, 
                      ui_txt_xlabel.Text, ui_txt_ylabel.Text,
                      "Courier", 255);
 p5.Image = bargraph1.DrawLineGraph();

下面的代码演示了如何在 ASP.NET 应用程序中使用此库。

 DrawGraph bargraph = new DrawGraph(keyValue, values,
                      "Financial Year","Profit", "Courier", 255);
 

//Generating graph and assigning it to respective imagebox 


 System.Drawing.Bitmap b = new System.Drawing.Bitmap(400, 400);
 b = bargraph.DrawLineGraph(); 
 b.Save(Server.MapPath("Graph")+"\\LineGraph.bmp");
 Image1.ImageUrl =".\\Graph\\LineGraph.bmp"; 

 System.Drawing.Bitmap b1 = new System.Drawing.Bitmap(400, 400);
 b1 = bargraph.DrawPieGraph();
 b1.Save(Server.MapPath("Graph") + "\\PieGraph.bmp");
 Image2.ImageUrl = ".\\Graph\\PieGraph.bmp"; 

 System.Drawing.Bitmap b2 = new System.Drawing.Bitmap(400, 400);
 b2 = bargraph.Draw3DPieGraph();
 b2.Save(Server.MapPath("Graph") + "\\3DPieGraph.bmp"); 
 Image3.ImageUrl = ".\\Graph\\3DPieGraph.bmp"; 

 System.Drawing.Bitmap b3 = new System.Drawing.Bitmap(400, 400);
 b3 = bargraph.Draw3dBarGraph();
 b3.Save(Server.MapPath("Graph") + "\\3dBarGraph.bmp");
 Image4.ImageUrl = ".\\Graph\\3dBarGraph.bmp";

代码

在类的开始处有一些导入。 这些导入是为了处理图像文件而包含的。

 using System;
 using System.Collections.Generic;
 using System.Text;
 using System.Drawing.Imaging;
 using System.Drawing.Drawing2D;
 using System.Drawing;

现在是全局变量。

string[] valueLabels; float[] values;
string xLabel; 
//Label displayed on x axis


string yLabel; 
//Label displayed on y axis


string fontFormat; 
//format for labels


int alpha; 
//alpha for graph 


List <color> colorList; 
//Dark colors only

这些全局变量正在使用构造函数进行初始化。

public DrawGraph(string[] valueLabels,float[] values,string xLabel,string
                               yLabel,string fontFormat,int alpha)
{
  this.valueLabels = valueLabels;
  this.values = values;
  this.xLabel = xLabel;
  this.yLabel = yLabel;
  this.alpha = alpha;
  this.fontFormat=fontFormat;
  InitColorList();
}

这里InitColorList()是一个用深色初始化colorList的方法。

//Initiatialize color list with dark color's 

 
private void InitColorList() 
{
 colorList = new List();
 foreach (string colorName in Enum.GetNames(typeof(System.Drawing.KnownColor)))
 {
  
//Check if color is dark 


  if (colorName.StartsWith("D") == true)
  {
   colorList.Add(System.Drawing.Color.FromName(colorName));
  }
 }
}

//Embed axis for bar graphs

在这个类中,我们还有一些私有方法,如EmbedAxis()EmbedXPanel()EmbedXLinePanel()。 这些用于创建轴,创建 x 轴值与颜色的映射,并分别创建 x 轴值与线条颜色的映射。

Bitmap EmbedAxis(Bitmap graph,bool showAxis) 
{
  Bitmap backgroundCanvas = new Bitmap(400, 300);
  Bitmap yLabelImage = new Bitmap(15,200);
  Graphics graphicsBackImage = Graphics.FromImage(backgroundCanvas);
  Graphics objGraphic2 = Graphics.FromImage(graph);
  Graphics objGraphicY = Graphics.FromImage(yLabelImage);

  Pen blackPen = new Pen(Color.Black, 2); 
//Paint the graph canvas white SolidBrush


  whiteBrush = new SolidBrush(Color.White);
  graphicsBackImage.FillRectangle(whiteBrush,0, 0, 400, 300);
  if (showAxis == true)
  {
   
//draw lable for y axis


   StringFormat sf = new StringFormat(StringFormatFlags.DirectionVertical);
   Font f = new Font(fontFormat,8);
   SizeF sizef = objGraphicY.MeasureString("<- " + yLabel, f, Int32.MaxValue,sf); 
   RectangleF rf = new RectangleF(0, 0, sizef.Width, sizef.Height);
   objGraphicY.DrawRectangle(Pens.Transparent,rf.Left, rf.Top, rf.Width, rf.Height);
   objGraphicY.DrawString((yLabel.Length>0?"<-":"") + yLabel, 
                   f, Brushes.Black, rf, sf);
   graphicsBackImage.DrawString(xLabel +(xLabel.Length>0?" ->":""), 
                  f, Brushes.Black, 30, 235);
   graphicsBackImage.DrawLine(blackPen,new Point(0, 230), new Point(230, 230));
   graphicsBackImage.DrawLine(blackPen, new Point(20, 20), new Point(20, 250));
  }

 graphicsBackImage.DrawImage(graph, 25, 25);
 if (showAxis == true)
 {
 graphicsBackImage.DrawImage(yLabelImage, 0, 90); 
 }
 return (backgroundCanvas);
 }


//Embed x Panel 


Bitmap EmbedXPanel(Bitmap graph)
{
 Bitmap xPanel = new Bitmap(100, 200); 
 Graphics objGraphicPanel = Graphics.FromImage(xPanel);
 Graphics graphicGraph = Graphics.FromImage(graph);
 for (int i = 0, x = 10; i <values.Length; i++)
 {
 
//Draw the bar


 SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
 objGraphicPanel.FillRectangle(brush, 10, 190 - x, 10, 10); 
 string drawString = valueLabels[i] + " = " + values[i].ToString();
 Font drawFont = new Font(fontFormat, 8);
 SolidBrush drawBrush = new SolidBrush(Color.Black); 
 objGraphicPanel.DrawString(drawString,drawFont, drawBrush, 20, 190 - x);
 
//x axis spacing by 20


 x += 20;
 }
 graphicGraph.DrawImage(xPanel,300, 25); return (graph);
 }

 
//Embed x Panel[Line graph style] 


Bitmap EmbedXLinePanel(Bitmap graph)
 {
 Bitmap xPanel = new Bitmap(100, 200);
 Graphics objGraphicPanel = Graphics.FromImage(xPanel);
 Graphics graphicGraph = Graphics.FromImage(graph);
 for (int i = 1, x = 10; i < values.Length; i++)
 {
  
//Draw the bar


 SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
 Pen colorPen = new Pen(brush,2);
 objGraphicPanel.DrawLine(colorPen,10, 190 - x, 20, 190 - x);
 string drawString = valueLabels[i - 1].ToString() + " - " + valueLabels[i].ToString();
 Font drawFont = new Font(fontFormat, 8);
 SolidBrush drawBrush = new SolidBrush(Color.Black);
 objGraphicPanel.DrawString(drawString, drawFont, drawBrush, 20, 190 - x);
 
//x axis spacing by 20 


 x += 20;
 }
 graphicGraph.DrawImage(xPanel,300, 25);
 return (graph);
 }

让我们来看看创建条形图的方法。这里,该方法遵循一个简单的算法。

  1. 首先准备一个尺寸为 200 X 200 的白色画布。
  2. 计算最高值 [x 轴值]。
  3. 对于 x 轴上的每个值...
    • 使用公式计算条形高度:条形高度=(x 值 / 最高值)* 190。
    • 绘制条形。
  4. 使用EmbedAxis()绘制轴并将条形图放置在放大的画布上。
  5. 使用EmbedXPanel()将 x 值映射到颜色。
 //Generate Bar graph


 public Bitmap DrawBarGraph()
 {
 Bitmap objgraph = new Bitmap(200, 200); 
// Canvas for graph


 Graphics graphicGraph = Graphics.FromImage(objgraph); 
//Paint the graph canvas white

 
 SolidBrush whiteBrush = new SolidBrush(Color.White);
 graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);

 float highestValue; 
//Highest value in the values array 




//Get the highest value 


 float[] tempValue = new float[values.Length];
 for (int j = 0; j < values.Length; j++)
 {
 tempValue[j] = values[j]; } Array.Sort<float>(tempValue);
 highestValue = tempValue[values.Length - 1]; 
//Generate bar for each value


 for (int i = 0, x = 10; i < values.Length; i++)
 {
 float barHeight; 
//hight of the bar


 barHeight = (values[i] / highestValue) * 190; 
//Draw the bar 


 SolidBrush brush = new SolidBrush(Color.FromArgb(alpha, colorList[i]));
 graphicGraph.FillRectangle(brush,x, 194 - barHeight, 10, barHeight);
 
//x axis spacing by 20

 
 x += 20;
 }

 
//

Increase the size of the canvas and draw axis 
 objgraph = EmbedAxis(objgraph, true); 
//Draw the key-value pair with repective color code 


 objgraph = EmbedXPanel(objgraph);
 return (objgraph);
 }

绘制 3D 条形图与上述条形图的代码类似,除了我们需要执行一些额外的任务,例如:

  1. 绘制阴影。
  2. 在图表的底部绘制一条白线以隐藏阴影。
 public Bitmap Draw3dBarGraph()
 {
 Bitmap objgraph = new Bitmap(200, 200); 
//Canvas for graph 


 Bitmap objXValuePanel = new Bitmap(100,200); 
//Canvas to display x-axis values

  
 Graphics graphicGraph = Graphics.FromImage(objgraph);
 Graphics graphicXValuePanel = Graphics.FromImage(objXValuePanel); 
//Paint the graph canvas white

 
 SolidBrush whiteBrush = new SolidBrush(Color.White);
 graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);
 float highestValue; 
//Highest value in the values array


 
//Get the highest value


 float[] tempValue = new float[values.Length];
 for (int j = 0; j < values.Length; j++)
 {
 tempValue[j] = values[j];
 }
 Array.Sort<float>(tempValue);
 highestValue = tempValue[values.Length - 1]; 
//Generate bar for each value

 
 for (int i = 0, x = 10; i < values.Length; i++)
 {
 SolidBrush brush = new SolidBrush(Color.FromArgb(alpha,colorList[i]));
 float barHeight; 
//hight of the bar


 barHeight = (values[i] / highestValue)* 190; 
//Draw continuous shade for 3D effect


 float shadex = x + 10; float shadey = 194 - ((int)barHeight) + 10;
 for (int iLoop2 = 0; iLoop2 < 10; iLoop2++) 
 {
 graphicGraph.FillRectangle(brush, shadex - iLoop2, shadey - iLoop2, 10, barHeight);
 }

 
//Draw bar


 graphicGraph.FillRectangle(new HatchBrush(HatchStyle.Percent50, brush.Color),
            x, 194 - barHeight, 10, barHeight); 

//Increment the x position 
 x += 20;


 }

 
//Mask bottom with a white line


 Pen whitePen = new Pen(Color.White, 10);
 graphicGraph.DrawLine(whitePen,new Point(10, 200), new Point(230, 200)); 

 
//Increase the size of the canvas and draw axis


 objgraph = EmbedAxis(objgraph, true); 
//Draw the key-value pair with repective color code

 
 objgraph = EmbedXPanel(objgraph);
 return (objgraph);
 }

要绘制饼图,请遵循以下算法:

  1. 首先准备一个尺寸为 200 X 200 的白色画布。
  2. 计算所有 x 值的总和 [x 轴值]。
  3. 将饼图的起始角度初始化为 0 度。
  4. 对于每个值...
    • 使用公式计算sweepAngle:扫描角度 = (x 值 * 360) / 所有 x 值的总和。
    • 绘制饼图。
    • 用扫描角度增加起始角度。
  5. 使用 EmbedAxis() 将饼图放置在放大的画布上,并将 showAxis 标志设置为 false
  6. 使用EmbedXPanel()将 x 值映射到颜色。
public Bitmap DrawPieGraph()
{
 Bitmap objgraph = new Bitmap(200, 200);
 Graphics graphicGraph = Graphics.FromImage(objgraph); 
//Create location and size of ellipse.


 int x = 0;
 int y = 0;
 int width = 200;
 int height = 100; 
//Create start and sweep


 angles. float sweepAngle = 0;
 float startAngle = 0;
 float total = 0;
 for (int i = 0; i < values.Length; i++)
 {
 total += values[i];
 }
 for (int i = 0; i < values.Length; i++)
 {
 SolidBrush objBrush = new SolidBrush(colorList[i]);
 sweepAngle = (values[i] * 360) / total;
 graphicGraph.SmoothingMode = SmoothingMode.AntiAlias;
 graphicGraph.FillPie(objBrush, x, y, width, height, startAngle, sweepAngle);
 startAngle += sweepAngle; } 
//Increase the size of the canvas in which the graph resides

 
 objgraph = EmbedAxis(objgraph, false); 
//Draw the key-value pair with repective color code


 objgraph = EmbedXPanel(objgraph); return (objgraph); 
}

绘制 3D 饼图与绘制饼图类似,但需要添加一个额外的任务:绘制阴影。

 Bitmap Draw3DPieGraph()
 {
 Bitmap objgraph = new Bitmap(200, 200);
 Graphics graphicGraph = Graphics.FromImage(objgraph); 
//Create location and size of ellipse.


 int x =0;
 int y = 0;
 int width = 200;
 int height = 100;

 
//Find the sum of all values float


 total = 0; for (int i = 0; i < values.Length; i++)
 {
 total += values[i];
 }
 
//When loop=0: Draw shadow


 
//loop=1: Draw graph

 
 for (int loop = 0; loop < 2; loop++)
 {
 
//Create start and sweep angles

 
 float sweepAngle = 0;
 float startAngle = 0;

 
//Draw pie for each value


 for (int i = 0; i < values.Length; i++)
 {
 SolidBrush objBrush = new SolidBrush(colorList[i]);
 sweepAngle = (values[i] * 360) / total;
 graphicGraph.SmoothingMode = SmoothingMode.AntiAlias;
 if (loop == 0)
 {
 for (int iLoop2 = 0; iLoop2 < 10; iLoop2++) 
 graphicGraph.FillPie(new HatchBrush(HatchStyle.Percent50,objBrush.Color), 
               x, y + iLoop2, width, height, startAngle, sweepAngle);
 }
 else 
 {
 graphicGraph.FillPie(objBrush, x, y, width, height, startAngle, sweepAngle);
 }
 startAngle += sweepAngle;
 }
 }
 
//Increase the size of the canvas in which the graph resides


 objgraph = EmbedAxis(objgraph, false); 
//Draw the key-value pair with repective


 color code objgraph = EmbedXPanel(objgraph);
 return (objgraph);
 }

要绘制折线图,我们使用与条形图相同的公式来计算高度。 一旦标记了点,只需使用不同颜色的线条连接它们即可。 必须使用 EmbedXLinePanel() 绘制 x-Panel。

 //Generate Line graph


 public Bitmap DrawLineGraph()
 {
 Bitmap objgraph = new Bitmap(200, 200); 
//Canvas for graph

 
 Graphics graphicGraph = Graphics.FromImage(objgraph); 
 
//Paint the graph canvas white 


 SolidBrush whiteBrush = new SolidBrush(Color.White);
 graphicGraph.FillRectangle(whiteBrush,0, 0, 200, 200);
 int highestValue; 
//Highest value in the values array


 
//Get the highest value


 int[] tempValue = new int[values.Length];
 for (int j = 0; j < values.Length;j++)
 {
 tempValue[j] = (int)values[j];
 }
 Array.Sort<int>(tempValue);
 highestValue = tempValue[values.Length - 1];
 int[,] points = new int[values.Length, 2];

 
//Generate bar for each value


 for (int i = 0, x = 10; i < values.Length; i++) 
 {
  decimal barHeight; 
//height of the bar


  barHeight = (decimal)(values[i] / highestValue * 190);
  points[i, 0] = x; barHeight = 194 - barHeight;
  points[i, 1] = (int)Decimal.Round(barHeight,0);
  Font f = new Font(fontFormat, 8);
  graphicGraph.FillEllipse(Brushes.Black, points[i,0]-2, points[i, 1]-2, 5, 5);
  graphicGraph.DrawString(values[i].ToString(), f, 
              Brushes.Black,new Point(points[i, 0]-14, points[i, 1]-5));
  x += 20;
 }

 for (int i = 1; i < values.Length; i++)
 {
 Point startPoint = new Point(points[i - 1, 0], points[i - 1, 1]);
 Point endPoint = new Point(points[i, 0], points[i, 1]);
 SolidBrush brush = new SolidBrush(colorList[i]); Pen colorPen = new Pen(brush, 2);
 graphicGraph.DrawLine(colorPen, startPoint, endPoint);
 }

 objgraph = EmbedAxis(objgraph,true);
 objgraph = EmbedXLinePanel(objgraph);
 return (objgraph);
 }

历史

  • 2008 年 2 月 27 日 - 发布原始版本
  • 2008 年 3 月 27 日 - 引入条形折线图
© . All rights reserved.