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