You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
11 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}
}