|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Drawing;
|
|
|
using System.Linq;
|
|
|
using System.Text;
|
|
|
|
|
|
namespace HslCommunication.BasicFramework
|
|
|
{
|
|
|
/*******************************************************************************
|
|
|
*
|
|
|
* Create Date:2017-05-03 16:56:39
|
|
|
* 应该包含常用的绘图方法,资源,比如绘制直方图,居中的文本等
|
|
|
*
|
|
|
*
|
|
|
********************************************************************************/
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 图形的方向
|
|
|
/// </summary>
|
|
|
public enum GraphDirection
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 向上
|
|
|
/// </summary>
|
|
|
Upward=1,
|
|
|
/// <summary>
|
|
|
/// 向下
|
|
|
/// </summary>
|
|
|
Downward=2,
|
|
|
/// <summary>
|
|
|
/// 向左
|
|
|
/// </summary>
|
|
|
Ledtward=3,
|
|
|
/// <summary>
|
|
|
/// 向右
|
|
|
/// </summary>
|
|
|
Rightward=4,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 包含整型和字符串描述的数据类型
|
|
|
/// </summary>
|
|
|
public struct Paintdata
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 数量
|
|
|
/// </summary>
|
|
|
public int Count { get; set; }
|
|
|
/// <summary>
|
|
|
/// 描述
|
|
|
/// </summary>
|
|
|
public string Description { get; set; }
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 图形的呈现方式
|
|
|
/// </summary>
|
|
|
public enum GraphicRender
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 直方图
|
|
|
/// </summary>
|
|
|
Histogram = 1,
|
|
|
/// <summary>
|
|
|
/// 饼图
|
|
|
/// </summary>
|
|
|
Piechart,
|
|
|
/// <summary>
|
|
|
/// 折线图
|
|
|
/// </summary>
|
|
|
Linegraph,
|
|
|
}
|
|
|
/// <summary>
|
|
|
/// 静态类,包含了几个常用的画图方法,获取字符串,绘制小三角等
|
|
|
/// </summary>
|
|
|
public static class SoftPainting
|
|
|
{
|
|
|
|
|
|
/********************************************************************************************************
|
|
|
*
|
|
|
* 以下都是辅助绘图的静态方法
|
|
|
*
|
|
|
*
|
|
|
*
|
|
|
*
|
|
|
***********************************************************************************************************/
|
|
|
|
|
|
/// <summary>
|
|
|
/// 获取一个直方图
|
|
|
/// </summary>
|
|
|
/// <param name="array">数据数组</param>
|
|
|
/// <param name="width">宽度</param>
|
|
|
/// <param name="height">高度</param>
|
|
|
/// <param name="degree">刻度划分等级</param>
|
|
|
/// <param name="lineColor">线条颜色</param>
|
|
|
/// <returns></returns>
|
|
|
public static Bitmap GetGraphicFromArray(int[] array, int width, int height, int degree, Color lineColor)
|
|
|
{
|
|
|
if (width < 10 && height < 10) throw new ArgumentException("长宽不能小于等于10");
|
|
|
int Max = array.Max();
|
|
|
int Min = 0;
|
|
|
int Count = array.Length;
|
|
|
|
|
|
StringFormat sf = new StringFormat();
|
|
|
sf.Alignment = StringAlignment.Far;
|
|
|
Pen dash = new Pen(Color.LightGray, 1f);
|
|
|
dash.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
|
|
|
dash.DashPattern = new float[] { 5, 5 };
|
|
|
|
|
|
Font font_8 = new Font("宋体", 9f);
|
|
|
Bitmap bitmap = new Bitmap(width, height);
|
|
|
Graphics g = Graphics.FromImage(bitmap);
|
|
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
|
|
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
|
|
|
g.Clear(Color.White);
|
|
|
//计算边框长度及图像边距
|
|
|
int left = 60, right = 8, up = 8, down = 8;
|
|
|
int paint_width = width - left - right;
|
|
|
int paint_heigh = height - up - down;
|
|
|
|
|
|
Rectangle rect = new Rectangle(left - 1, up - 1, paint_width + 1, paint_heigh + 1);
|
|
|
//g.FillRectangle(Brushes.WhiteSmoke, rect);
|
|
|
g.DrawLine(Pens.Gray, left - 1, up, left + paint_width + 1, up);
|
|
|
g.DrawLine(Pens.Gray, left - 1, up + paint_heigh + 1, left + paint_width + 1, up + paint_heigh + 1);
|
|
|
g.DrawLine(Pens.Gray, left - 1, up - 1, left - 1, up + paint_heigh + 1);
|
|
|
|
|
|
//画刻度
|
|
|
//for (int i = 0; i <= degree; i++)
|
|
|
//{
|
|
|
// int value = (Max - Min) * i / degree + Min;
|
|
|
// int location = (int)ComputePaintLocationY(Max, Min, paint_heigh, value) + up + 1;
|
|
|
// g.DrawLine(Pens.DimGray, left - 1, location, left - 4, location);
|
|
|
// if (i != 0 && i < degree)
|
|
|
// {
|
|
|
// g.DrawLine(dash, left, location, width - right, location);
|
|
|
// }
|
|
|
// g.DrawString(value.ToString(), font_8, Brushes.DimGray, new Rectangle(-5, location - 4, left, 10), sf);
|
|
|
//}
|
|
|
|
|
|
PaintCoordinateDivide(g, Pens.DimGray, dash, font_8, Brushes.DimGray, sf, degree, Max, Min, width, height, left, right, up, down);
|
|
|
|
|
|
|
|
|
PointF[] alldata = new PointF[array.Length];
|
|
|
for (int i = 0; i < array.Length; i++)
|
|
|
{
|
|
|
alldata[i].X = paint_width * 1.0f / (array.Length - 1) * i + left;
|
|
|
alldata[i].Y = ComputePaintLocationY(Max, Min, paint_heigh, array[i]) + up + 1;
|
|
|
}
|
|
|
|
|
|
Pen pen = new Pen(lineColor);
|
|
|
g.DrawLines(pen, alldata);
|
|
|
|
|
|
pen.Dispose();
|
|
|
dash.Dispose();
|
|
|
font_8.Dispose();
|
|
|
sf.Dispose();
|
|
|
g.Dispose();
|
|
|
return bitmap;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 计算绘图时的相对偏移值
|
|
|
/// </summary>
|
|
|
/// <param name="max">0-100分的最大值,就是指准备绘制的最大值</param>
|
|
|
/// <param name="min">0-100分的最小值,就是指准备绘制的最小值</param>
|
|
|
/// <param name="height">实际绘图区域的高度</param>
|
|
|
/// <param name="value">需要绘制数据的当前值</param>
|
|
|
/// <returns>相对于0的位置,还需要增加上面的偏值</returns>
|
|
|
public static float ComputePaintLocationY(int max, int min, int height, int value)
|
|
|
{
|
|
|
return height - (value - min) * 1.0f / (max - min) * height;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 计算绘图时的相对偏移值
|
|
|
/// </summary>
|
|
|
/// <param name="max">0-100分的最大值,就是指准备绘制的最大值</param>
|
|
|
/// <param name="min">0-100分的最小值,就是指准备绘制的最小值</param>
|
|
|
/// <param name="height">实际绘图区域的高度</param>
|
|
|
/// <param name="value">需要绘制数据的当前值</param>
|
|
|
/// <returns>相对于0的位置,还需要增加上面的偏值</returns>
|
|
|
public static float ComputePaintLocationY( float max, float min, int height, float value )
|
|
|
{
|
|
|
return height - (value - min) / (max - min) * height;
|
|
|
}
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 绘制坐标系中的刻度线
|
|
|
/// </summary>
|
|
|
/// <param name="g"></param>
|
|
|
/// <param name="penLine"></param>
|
|
|
/// <param name="penDash"></param>
|
|
|
/// <param name="font"></param>
|
|
|
/// <param name="brush"></param>
|
|
|
/// <param name="sf"></param>
|
|
|
/// <param name="degree"></param>
|
|
|
/// <param name="max"></param>
|
|
|
/// <param name="min"></param>
|
|
|
/// <param name="width"></param>
|
|
|
/// <param name="height"></param>
|
|
|
/// <param name="left"></param>
|
|
|
/// <param name="right"></param>
|
|
|
/// <param name="up"></param>
|
|
|
/// <param name="down"></param>
|
|
|
public static void PaintCoordinateDivide(
|
|
|
Graphics g,
|
|
|
Pen penLine,
|
|
|
Pen penDash,
|
|
|
Font font,
|
|
|
Brush brush,
|
|
|
StringFormat sf,
|
|
|
int degree,
|
|
|
int max,
|
|
|
int min,
|
|
|
int width,
|
|
|
int height,
|
|
|
int left = 60,
|
|
|
int right = 8,
|
|
|
int up = 8,
|
|
|
int down = 8
|
|
|
)
|
|
|
{
|
|
|
for (int i = 0; i <= degree; i++)
|
|
|
{
|
|
|
int value = (max - min) * i / degree + min;
|
|
|
int location = (int)ComputePaintLocationY(max, min, (height - up - down), value) + up + 1;
|
|
|
g.DrawLine(penLine, left - 1, location, left - 4, location);
|
|
|
if (i != 0)
|
|
|
{
|
|
|
g.DrawLine(penDash, left, location, width - right, location);
|
|
|
}
|
|
|
g.DrawString(value.ToString(), font, brush, new Rectangle(-5, location - font.Height / 2, left, font.Height), sf);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据指定的方向绘制一个箭头
|
|
|
/// </summary>
|
|
|
/// <param name="g"></param>
|
|
|
/// <param name="brush"></param>
|
|
|
/// <param name="point"></param>
|
|
|
/// <param name="size"></param>
|
|
|
/// <param name="direction"></param>
|
|
|
public static void PaintTriangle(Graphics g, Brush brush, Point point, int size, GraphDirection direction)
|
|
|
{
|
|
|
Point[] points = new Point[4];
|
|
|
if (direction == GraphDirection.Ledtward)
|
|
|
{
|
|
|
points[0] = new Point(point.X, point.Y - size);
|
|
|
points[1] = new Point(point.X, point.Y + size);
|
|
|
points[2] = new Point(point.X - 2 * size, point.Y);
|
|
|
}
|
|
|
else if (direction == GraphDirection.Rightward)
|
|
|
{
|
|
|
points[0] = new Point(point.X, point.Y - size);
|
|
|
points[1] = new Point(point.X, point.Y + size);
|
|
|
points[2] = new Point(point.X + 2 * size, point.Y);
|
|
|
}
|
|
|
else if (direction == GraphDirection.Upward)
|
|
|
{
|
|
|
points[0] = new Point(point.X - size, point.Y);
|
|
|
points[1] = new Point(point.X + size, point.Y);
|
|
|
points[2] = new Point(point.X, point.Y - 2 * size);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
points[0] = new Point(point.X - size, point.Y);
|
|
|
points[1] = new Point(point.X + size, point.Y);
|
|
|
points[2] = new Point(point.X, point.Y + 2 * size);
|
|
|
}
|
|
|
|
|
|
points[3] = points[0];
|
|
|
g.FillPolygon(brush, points);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/********************************************************************************************************
|
|
|
*
|
|
|
* 以下都是生成图形类的静态方法
|
|
|
*
|
|
|
*
|
|
|
*
|
|
|
*
|
|
|
***********************************************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据数据生成一个可视化的图形
|
|
|
/// </summary>
|
|
|
/// <param name="array">数据集合</param>
|
|
|
/// <param name="width">需要绘制图形的宽度</param>
|
|
|
/// <param name="height">需要绘制图形的高度</param>
|
|
|
/// <param name="graphic">指定绘制成什么样子的图形</param>
|
|
|
/// <returns>返回一个bitmap对象</returns>
|
|
|
public static Bitmap GetGraphicFromArray(Paintdata[] array, int width, int height, GraphicRender graphic)
|
|
|
{
|
|
|
if (width < 10 && height < 10) throw new ArgumentException("长宽不能小于等于10");
|
|
|
array.Max(m => m.Count);
|
|
|
Action<Paintdata[], GraphicRender, Graphics> paintAction =
|
|
|
delegate (Paintdata[] array1, GraphicRender graphic1, Graphics g)
|
|
|
{
|
|
|
|
|
|
};
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
|
|
|
}
|
|
|
}
|