在软件开发中,很多应用需要生成图表来展示数据,以便使用者更好的了解数据的趋势和变化。本文将介绍如何使用C#中的Graphics类,生成基于月份的折线图报表。
步骤1:创建项目
首先,需要创建一个C#控制台应用程序。在Visual Studio中选择菜单项 File -> New -> Project,选择Console Application。这将创建一个最简单的控制台应用程序。
步骤2:引入System.Drawing命名空间
在C#中,要使用Graphics类,需要引入System.Drawing命名空间。在代码中使用以下命令即可:
using System.Drawing;
步骤3:绘制坐标轴
绘制坐标轴是生成折线图的第一步。需要使用Graphics类中的方法,绘制坐标轴。请参考以下代码:
Graphics g = this.CreateGraphics();
Pen p = new Pen(Color.Black, 1);
// Y 轴
g.DrawLine(p, new Point(50, 30), new Point(50, 220));
// X 轴
g.DrawLine(p, new Point(50, 220), new Point(350, 220));
p.Dispose();
g.Dispose();
步骤4:绘制折线图
有了坐标轴,就可以开始绘制折线图了。可以通过指定月份和相应的数据来绘制折线图。请参考以下代码:
int[] data = { 12, 15, 18, 16, 22, 24, 25, 27, 16, 19, 22, 25 };
string[] months = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
Point[] points = new Point[12];
for (int i = 0; i < 12; i++)
{
points[i] = new Point(50 + i * 25, 220 - data[i] * 2);
}
g = this.CreateGraphics();
p = new Pen(Color.Blue, 2);
g.DrawLines(p, points);
p.Dispose();
g.Dispose();
步骤5:添加数据标签
为了让折线图更加易于理解,可以添加一些数据标签,用来表示每个月份对应的具体数值。请参考以下代码:
g = this.CreateGraphics();
Font font = new Font("Arial", 8);
for (int i = 0; i < 12; i++)
{
g.DrawString(data[i].ToString(), font, Brushes.Black, new Point(points[i].X - 5, points[i].Y - 15));
g.DrawString(months[i], font, Brushes.Black, new Point(points[i].X - 5, 225));
}
font.Dispose();
g.Dispose();
步骤6:保存图片
最后一步是将生成的图片保存下来。请使用以下代码:
Bitmap bmp = new Bitmap(this.Width, this.Height);
Graphics g2 = Graphics.FromImage(bmp);
g2.CopyFromScreen(this.Location.X, this.Location.Y, 0, 0, bmp.Size);
bmp.Save(@"D:\chart.png", ImageFormat.Png);
g2.Dispose();
bmp.Dispose();
上面是思路,这种思路,做起来还是比较麻烦的,既然是实体,我们可以将数据是集合实体化,然后调用方法搞定
先建一个实体:
public class StatYear
{
/// <summary>
/// 月份
/// </summary>
public string month { get; set; }
/// <summary>
/// 数量
/// </summary>
public int count { get; set; }
}
调用该方法:
public void DrawLine(List<StatYear> list, string title)
{
int height = this.zpic.Height, width = this.zpic.Width;
System.Drawing.Bitmap image = new System.Drawing.Bitmap(width, height);
//创建Graphics类对象
Graphics g = Graphics.FromImage(image);
//清空图片背景色
g.Clear(Color.White);
g.FillRectangle(Brushes.WhiteSmoke, 0, 0, width, height);
Font font1 = new System.Drawing.Font("宋体", 20, FontStyle.Regular);
Brush brush1 = new SolidBrush(Color.Blue);
g.DrawString(title, font1, brush1, new PointF((width - title.ToString().Length * 22) / 2, 20));
//计算数量最大值
int countmax = list.Max(x => x.count);
if (countmax.ToString().Length <= 2) { countmax = countmax + (10 - int.Parse(countmax.ToString().Substring(countmax.ToString().Length - 1, 1))); }
else { countmax = countmax + (int.Parse("1".PadRight(countmax.ToString().Length, '0')) - int.Parse(countmax.ToString().Substring(1, countmax.ToString().Length - 1))); }
Font font = new System.Drawing.Font("Arial", 10, FontStyle.Regular);
System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Blue, Color.Blue, 1.2f, true);
Pen mypen = new Pen(brush, 1);
//坐标距离上下左右距离
int stop = 90, sleft = 60, sbottom = 20, sright = 30;
//画2条主坐标X和Y线条
Pen penxy = new Pen(Color.Blue, 2);
//绘制Y柱主线
g.DrawLine(penxy, sleft, stop, sleft, height - sbottom);
//绘制X柱主线
g.DrawLine(penxy, sleft - 1, height - sbottom, width - sright, height - sbottom);
//Y柱拆分成10条线路,间距为
int yspace = (height - sbottom - stop) / 10;
for (int i = 1; i <= 10; i++)
{
//从底部向上画Y线条
g.DrawLine(mypen, sleft, height - sbottom - yspace * i, width - sright, height - sbottom - yspace * i);
}
//Y柱文字写入
int value = countmax / 10;
for (int i = 0; i <= 10; i++)
{
//从底部向上写文字
g.DrawString((value * i).ToString(), font, Brushes.Red, 25, height - sbottom - yspace * i - 8); //设置文字内容及输出位置
}
//写X坐标线
int xspace = (width - sleft - sright) / list.Count;
for (int i = 1; i < list.Count; i++)
{
g.DrawLine(mypen, sleft + xspace * i, stop, sleft + xspace * i, height - sbottom);
}
}
效果图如下: