using System;
using System.IO;//用于文件存取
using System.Data;//用于数据访问
using System.Drawing;//提供画GDI+图形的基本功能
using System.Drawing.Text;//提供画GDI+图形的高级功能
using System.Drawing.Drawing2D;//提供画高级二维,矢量图形功能
using System.Drawing.Imaging;//提供画GDI+图形的高级功能
namespace Drawpicture
{
/// <summary>
/// BarChart 的摘要说明。
/// </summary>
public class BarChart
{
private int Pic_Width = 410;
private int Pic_Height = 320;
public static bool hasNeg = false;
private const string FontWord = "Arial";
private const int FontSize = 9;
public int SIDE_WIDTH = 400;
public int SIDE_HEIGHT = 400;
private const int CHART_TOP = 60;
private int CHART_HEIGHT = 300;
private const int CHART_LEFT = 60;
private const int CHART_WIDTH = 300;
public void Render(string[] word,int[] data, out string fileName)
{
for(int i=0;i<data.Length;i++)
{
if(data[i]<0)
{
Pic_Height *=2;
hasNeg = true;
SIDE_HEIGHT = (int)(SIDE_HEIGHT*1.5);
CHART_HEIGHT =(int)(CHART_HEIGHT*0.3);
break;
}
}
ChartUtil cu = new ChartUtil();
PointF[] zuoBiaoStart;
PointF[] zuoBiaoEnd;
Graphics g;
Bitmap bm;
createCanvas(out bm, out g, out zuoBiaoEnd, out zuoBiaoStart,cu);
//画坐标轴
int chiDu = drawAxes(data, zuoBiaoStart, g, zuoBiaoEnd,cu);
//画条形图
float barWidth = CHART_WIDTH / (2 * 2);
PointF barOrigin = new PointF(CHART_LEFT + (barWidth / 2),0);
float barHeight = 2;
for(int i=0;i<2;i++)
{
barHeight = ((float)data[i]/chiDu) *(CHART_HEIGHT/5) ;
if(barHeight<0)
{
barOrigin.Y = CHART_TOP + CHART_HEIGHT;
}
else
{
barOrigin.Y = CHART_TOP + CHART_HEIGHT - barHeight;
}
g.FillRectangle(new SolidBrush(ChartUtil.GetChartItemColor(i)),barOrigin.X,barOrigin.Y,barWidth,Math.Abs(barHeight));
barOrigin.X = barOrigin.X + (barWidth * 2);
}
//画右上角的说明图形
drawInstruction(CHART_LEFT, CHART_HEIGHT, CHART_TOP, g, word, data);
//输出图形
fileName = cu.PicPath + Guid.NewGuid().ToString() + ".gif";
bm.Save(fileName, ImageFormat.Gif);
//资源回收
bm.Dispose();
g.Dispose();
}
private int drawAxes(int[] data, PointF[] zuoBiaoStart, Graphics g, PointF[] zuoBiaoEnd,ChartUtil cu)
{
int chiDu =1;
int[] t = cu.getZuoBiaoValue(data,out chiDu);
for(int i=0;i<zuoBiaoStart.Length;i++)
{
PointF txtPos = new PointF();
txtPos.X = zuoBiaoStart[i].X -50;
txtPos.Y = zuoBiaoStart[i].Y - 5;
g.DrawString(t[i].ToString(),new Font(FontWord,8),Brushes.Black,txtPos);
g.DrawLine(Pens.Black,zuoBiaoStart[i],zuoBiaoEnd[i]);
}
return chiDu;
}
private void createCanvas(out Bitmap bm, out Graphics g, out PointF[] zuoBiaoEnd, out PointF[] zuoBiaoStart,ChartUtil cu)
{
//建立一个Graphics对象实例
bm = new Bitmap(Pic_Width,Pic_Height);
g = Graphics.FromImage(bm);
//设置条图图形和文字属性
g.ScaleTransform((Convert.ToSingle(Pic_Width))/SIDE_WIDTH,(Convert.ToSingle(Pic_Height))/SIDE_HEIGHT);
g.SmoothingMode = SmoothingMode.Default;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
//设定画布和边
g.Clear(Color.White);
g.DrawRectangle(Pens.Black,0,0,SIDE_WIDTH-1,SIDE_HEIGHT-1);
//设置条形图的边
g.DrawRectangle(new Pen(Color.Black,1),CHART_LEFT,CHART_TOP,CHART_WIDTH, CHART_HEIGHT);
if(hasNeg)
{
g.DrawRectangle(new Pen(Color.Black,1),CHART_LEFT,CHART_TOP+CHART_HEIGHT,CHART_WIDTH, CHART_HEIGHT);
}
zuoBiaoEnd = null;
zuoBiaoStart = cu.getZuoBiaoPoint(new PointF(CHART_TOP,CHART_LEFT),CHART_HEIGHT,CHART_WIDTH,out zuoBiaoEnd,hasNeg);
}
private void drawInstruction(int CHART_LEFT, int CHART_HEIGHT, int CHART_TOP, Graphics g, string[] word, int[] data)
{
PointF colsNamePoint = new PointF(CHART_LEFT + 55,CHART_HEIGHT + CHART_TOP + 2);
if(hasNeg)
{
colsNamePoint = new PointF(CHART_LEFT + 55,CHART_HEIGHT*2 + CHART_TOP + 2);
}
PointF boxOrigin = new PointF(Pic_Width*5/6-30,CHART_TOP*1/3);
PointF textOrigin = new PointF(Pic_Width*4/5+8,CHART_TOP*1/3 -3 );
for(int i=0;i<2;i++)
{
g.FillRectangle(new SolidBrush(ChartUtil.GetChartItemColor(i)),boxOrigin.X,boxOrigin.Y,20,10);
//g.DrawRectangle(Pens.Black,boxOrigin.X,boxOrigin.Y,20,10);
g.DrawString(word[i],new Font(FontWord,FontSize),Brushes.DarkBlue,colsNamePoint);
g.DrawString(data[i].ToString(),new Font(FontWord,FontSize),Brushes.Black,textOrigin);
colsNamePoint.X += 150;
boxOrigin.Y += 15;
textOrigin.Y += 15;
}
}
}
public class ChartUtil
{
public readonly string PicPath = System.AppDomain.CurrentDomain.BaseDirectory + "Temp/";
public PointF[] getZuoBiaoPoint(PointF orign,int height,int width,out PointF[] endPoint,bool hasNeg)
{
int num = 6;
if(hasNeg) num = 11;
PointF[] startPoint = new PointF[num];
endPoint = new PointF[num];
for(int i =0;i<num;i++)
{
PointF pfStart = new PointF();
PointF pfEnd = new PointF();
pfStart.X = orign.X;
pfEnd.X = orign.X + width;
pfStart.Y = orign.Y + i*height/5;
pfEnd.Y = pfStart.Y;
startPoint[i] = pfStart;
endPoint[i] = pfEnd;
}
return startPoint;
}
public int[] getZuoBiaoValue(int[] data,out int chidu)
{
int[] result = new Int32[11];
int Max = data[0];
for(int i=0;i<data.Length;i++)
{
if(Max < data[i])
Max = data[i];
}
string strMax = Max + "";
chidu =(int)((Convert.ToInt32(strMax.Substring(0,1)) +1)* Math.Pow(10,strMax.Length-1))/5;
for(int i=0;i<result.Length;i++)
{
result[i] = chidu* (5-i) ;
}
return result;
}
#region get color
public static Color GetChartItemColor(int itemIndex)
{
Color selectedColor;
switch(itemIndex)
{
case 0:
selectedColor = Color.Blue;
break;
case 1:
selectedColor = Color.Red;
break;
case 2:
selectedColor = Color.Yellow;
break;
case 3:
selectedColor = Color.Purple;
break;
default:
selectedColor = Color.Green;
break;
}
return selectedColor;
}
#endregion
}
}