123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545 |
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.Linq;
- using System.Text;
- namespace FurnaceUI.Controls
- {
- /// <summary>
- /// 整个组件的代码辅助工具,提供了一个基础的类库方法
- /// </summary>
- public class Helper
- {
- /// <summary>
- /// 从一个矩形的图形中获取菱形的坐标数组
- /// </summary>
- /// <param name="rect">矩形</param>
- /// <returns>数组结果</returns>
- public static Point[] GetRhombusFromRectangle(Rectangle rect)
- {
- return new Point[]
- {
- new Point(rect.X, rect.Y + rect.Height / 2),
- new Point(rect.X + rect.Width / 2, rect.Y + rect.Height - 1),
- new Point(rect.X + rect.Width - 1, rect.Y + rect.Height / 2),
- new Point(rect.X + rect.Width / 2, rect.Y),
- new Point(rect.X, rect.Y + rect.Height / 2),
- };
- }
- /// <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)
- {
- if ((max - min) == 0f)
- {
- return height;
- }
- else
- {
- 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, float height, float value)
- {
- if ((max - min) == 0f)
- {
- return height;
- }
- else
- {
- 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.Leftward)
- {
- 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="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, PointF point, int size, GraphDirection direction)
- {
- PointF[] points = new PointF[4];
- if (direction == GraphDirection.Leftward)
- {
- points[0] = new PointF(point.X, point.Y - size);
- points[1] = new PointF(point.X, point.Y + size);
- points[2] = new PointF(point.X - 2 * size, point.Y);
- }
- else if (direction == GraphDirection.Rightward)
- {
- points[0] = new PointF(point.X, point.Y - size);
- points[1] = new PointF(point.X, point.Y + size);
- points[2] = new PointF(point.X + 2 * size, point.Y);
- }
- else if (direction == GraphDirection.Upward)
- {
- points[0] = new PointF(point.X - size, point.Y);
- points[1] = new PointF(point.X + size, point.Y);
- points[2] = new PointF(point.X, point.Y - 2 * size);
- }
- else
- {
- points[0] = new PointF(point.X - size, point.Y);
- points[1] = new PointF(point.X + size, point.Y);
- points[2] = new PointF(point.X, point.Y + 2 * size);
- }
- points[3] = points[0];
- g.FillPolygon(brush, points);
- }
- /// <summary>
- /// 一个通用的数组新增个数方法,会自动判断越界情况,越界的情况下,会自动的截断或是填充 ->
- /// A common array of new methods, will automatically determine the cross-border situation, in the case of cross-border, will be automatically truncated or filled
- /// </summary>
- /// <typeparam name="T">数据类型</typeparam>
- /// <param name="array">原数据</param>
- /// <param name="data">等待新增的数据</param>
- /// <param name="max">原数据的最大值</param>
- public static void AddArrayData<T>(ref T[] array, T[] data, int max)
- {
- if (data == null) return; // 数据为空
- if (data.Length == 0) return; // 数据长度为空
- if (array.Length == max)
- {
- Array.Copy(array, data.Length, array, 0, array.Length - data.Length);
- Array.Copy(data, 0, array, array.Length - data.Length, data.Length);
- }
- else
- {
- if ((array.Length + data.Length) > max)
- {
- T[] tmp = new T[max];
- for (int i = 0; i < (max - data.Length); i++)
- {
- tmp[i] = array[i + (array.Length - max + data.Length)];
- }
- for (int i = 0; i < data.Length; i++)
- {
- tmp[tmp.Length - data.Length + i] = data[i];
- }
- // 更新数据
- array = tmp;
- }
- else
- {
- T[] tmp = new T[array.Length + data.Length];
- for (int i = 0; i < array.Length; i++)
- {
- tmp[i] = array[i];
- }
- for (int i = 0; i < data.Length; i++)
- {
- tmp[tmp.Length - data.Length + i] = data[i];
- }
- array = tmp;
- }
- }
- }
- /// <summary>
- /// 尺寸转换,计算旋转后的尺寸。
- /// </summary>
- /// <param name="size"></param>
- /// <param name="angle"></param>
- /// <returns></returns>
- public static SizeF ConvertSize(SizeF size, float angle)
- {
- Matrix matrix = new Matrix();
- matrix.Rotate(angle);
- // 旋转矩形四个顶点
- PointF[] pts = new PointF[4];
- pts[0].X = -size.Width / 2f;
- pts[0].Y = -size.Height / 2f;
- pts[1].X = -size.Width / 2f;
- pts[1].Y = size.Height / 2f;
- pts[2].X = size.Width / 2f;
- pts[2].Y = size.Height / 2f;
- pts[3].X = size.Width / 2f;
- pts[3].Y = -size.Height / 2f;
- matrix.TransformPoints(pts);
- // 求取四个顶点的包围盒
- float left = float.MaxValue;
- float right = float.MinValue;
- float top = float.MaxValue;
- float bottom = float.MinValue;
- foreach (PointF pt in pts)
- {
- // 求取并集
- if (pt.X < left)
- left = pt.X;
- if (pt.X > right)
- right = pt.X;
- if (pt.Y < top)
- top = pt.Y;
- if (pt.Y > bottom)
- bottom = pt.Y;
- }
- SizeF result = new SizeF(right - left, bottom - top);
- return result;
- }
- /// <summary>
- /// 绘制旋转文本
- /// </summary>
- /// <param name="g"></param>
- /// <param name="s"></param>
- /// <param name="font"></param>
- /// <param name="brush"></param>
- /// <param name="point"></param>
- /// <param name="format"></param>
- /// <param name="angle"></param>
- public static void DrawString(Graphics g, string s, Font font, Brush brush, PointF point, StringFormat format, float angle)
- {
- // Save the matrix
- Matrix mtxSave = g.Transform;
- Matrix mtxRotate = g.Transform;
- mtxRotate.RotateAt(angle, point);
- g.Transform = mtxRotate;
- g.DrawString(s, font, brush, point, format);
- // Reset the matrix
- g.Transform = mtxSave;
- }
- private static int GetPow(int digit)
- {
- int result = 1;
- for (int i = 0; i < digit; i++)
- {
- result *= 10;
- }
- return result;
- }
- /// <summary>
- /// 获得数据的上限值,这个上限值是自动计算的。
- /// </summary>
- /// <param name="values">数据值</param>
- /// <returns>数据值</returns>
- public static int CalculateMaxSectionFrom(int[] values)
- {
- int max = values.Max();
- if (max <= 5) return 5;
- if (max <= 10) return 10;
- int digit = max.ToString().Length - 2;
- int head = int.Parse(max.ToString().Substring(0, 2));
- if (head < 12) return 12 * GetPow(digit);
- if (head < 14) return 14 * GetPow(digit);
- if (head < 16) return 16 * GetPow(digit);
- if (head < 18) return 18 * GetPow(digit);
- if (head < 20) return 20 * GetPow(digit);
- if (head < 22) return 22 * GetPow(digit);
- if (head < 24) return 24 * GetPow(digit);
- if (head < 26) return 26 * GetPow(digit);
- if (head < 28) return 28 * GetPow(digit);
- if (head < 30) return 30 * GetPow(digit);
- if (head < 40) return 40 * GetPow(digit);
- if (head < 50) return 50 * GetPow(digit);
- if (head < 60) return 60 * GetPow(digit);
- if (head < 80) return 80 * GetPow(digit);
- return 100 * GetPow(digit);
- }
- /// <summary>
- /// 获取当前颜色更淡的颜色信息
- /// </summary>
- /// <param name="color">颜色信息</param>
- /// <returns>颜色</returns>
- public static Color GetColorLight(Color color)
- {
- return Color.FromArgb(color.R + (255 - color.R) * 40 / 100, color.G + (255 - color.G) * 40 / 100, color.B + (255 - color.B) * 40 / 100);
- }
- /// <summary>
- /// 获取当前颜色更淡的颜色信息
- /// </summary>
- /// <param name="color">颜色信息</param>
- /// <returns>颜色</returns>
- public static Color GetColorLightFive(Color color)
- {
- return Color.FromArgb(color.R + (255 - color.R) * 50 / 100, color.G + (255 - color.G) * 50 / 100, color.B + (255 - color.B) * 50 / 100);
- }
- #if NET45
- /// <summary>
- /// 获取当前颜色更淡的颜色信息
- /// </summary>
- /// <param name="color">颜色信息</param>
- /// <returns>颜色</returns>
- public static System.Windows.Media.Color GetColorLight( System.Windows.Media.Color color )
- {
- return System.Windows.Media.Color.FromRgb( (byte)(color.R + (255 - color.R) * 40 / 100), (byte)(color.G + (255 - color.G) * 40 / 100), (byte)(color.B + (255 - color.B) * 40 / 100) );
- }
- /// <summary>
- /// 获取当前颜色更淡的颜色信息
- /// </summary>
- /// <param name="color">颜色信息</param>
- /// <returns>颜色</returns>
- public static System.Windows.Media.Color GetColorLightFive( System.Windows.Media.Color color )
- {
- return System.Windows.Media.Color.FromRgb( (byte)(color.R + (255 - color.R) * 50 / 100), (byte)(color.G + (255 - color.G) * 50 / 100), (byte)(color.B + (255 - color.B) * 50 / 100) );
- }
- #endif
- /// <summary>
- /// 从字符串表示的点位信息里解析出真正的点位信息
- /// </summary>
- /// <param name="points">字符串的点位</param>
- /// <param name="soureWidth">原来的长度信息</param>
- /// <param name="sourceHeight">原来的高度信息</param>
- /// <param name="width">实际的宽度信息</param>
- /// <param name="height">实际的高度信息</param>
- /// <param name="dx">x偏移量信息</param>
- /// <param name="dy">y偏移量信息</param>
- /// <returns></returns>
- public static PointF[] GetPointsFrom(string points, float soureWidth, float sourceHeight, float width, float height, float dx = 0, float dy = 0)
- {
- string[] itemPoint = points.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
- PointF[] ret = new PointF[itemPoint.Length];
- for (int i = 0; i < itemPoint.Length; i++)
- {
- int index = itemPoint[i].IndexOf(',');
- float x = Convert.ToSingle(itemPoint[i].Substring(0, index));
- float y = Convert.ToSingle(itemPoint[i].Substring(index + 1));
- ret[i] = new PointF(width * (x + dx) / soureWidth, height * (y + dy) / sourceHeight);
- }
- return ret;
- }
- }
- /// <summary>
- /// 图形的方向
- /// </summary>
- public enum GraphDirection
- {
- /// <summary>
- /// 向上
- /// </summary>
- Upward = 1,
- /// <summary>
- /// 向下
- /// </summary>
- Downward = 2,
- /// <summary>
- /// 向左
- /// </summary>
- Leftward = 3,
- /// <summary>
- /// 向右
- /// </summary>
- Rightward = 4,
- }
- /// <summary>
- /// 指示控件的样子
- /// </summary>
- public enum HslDirectionStyle
- {
- /// <summary>
- /// 控件是横向摆放的
- /// </summary>
- Horizontal = 1,
- /// <summary>
- /// 控件是纵向摆放的
- /// </summary>
- Vertical = 2
- }
- /// <summary>
- /// 系统的主题样式,将会改变一些控件的外观
- /// </summary>
- public enum HslThemeStyle
- {
- /// <summary>
- /// 浅色的主题
- /// </summary>
- Light = 1,
- /// <summary>
- /// 深色的主题
- /// </summary>
- Dark = 2,
- }
- /// <summary>
- /// 某些特殊图形的表现形式
- /// </summary>
- public enum HslRenderStyle
- {
- /// <summary>
- /// 椭圆
- /// </summary>
- Ellipse = 1,
- /// <summary>
- /// 矩形
- /// </summary>
- Rectangle = 2,
- /// <summary>
- /// 菱形
- /// </summary>
- Rhombus = 3
- }
- /// <summary>
- /// 包含整型和字符串描述的数据类型
- /// </summary>
- public struct Paintdata
- {
- /// <summary>
- /// 数量
- /// </summary>
- public int Count { get; set; }
- /// <summary>
- /// 描述
- /// </summary>
- public string Description { get; set; }
- }
- /// <summary>
- /// 计算的基础数据
- /// </summary>
- public class CenterPoint
- {
- /// <summary>
- /// 中心点的位置
- /// </summary>
- public Point Point { get; set; }
- /// <summary>
- /// 半径
- /// </summary>
- public int Radius { get; set; }
- /// <summary>
- /// 角度
- /// </summary>
- public double Angle { get; set; }
- }
- }
|