C#记录(十一):串口上位机实例之二

一、C# Graphics绘制

上一篇有介绍:Chart绘图存在的问题:当显示的数据量很大,达到上万数据时,整个winform窗口变得卡顿。固决定用Graphics重新绘制同台曲线图。

1.1  绘制坐标轴


        public Bitmap drawCurve(int[] X_array, float[] Y_array, int X_Localtion, int Y_Localtion, int X_Size, int Y_Size)
        {

            Console.WriteLine("size: {0},{1}, {2}, {3}",X_Localtion,Y_Localtion, X_Size, Y_Size );

            //画图初始化
            Bitmap bmap = new Bitmap(X_Size, Y_Size);                       //画布图片大小
            Graphics gph = Graphics.FromImage(bmap);
            gph.Clear(Color.White);

            //曲线坐标轴设定
            PointF cpt = new PointF(30, Y_Size - 30);                        //坐标原点,坐标轴起始点
            PointF X_EndPoint = new PointF(X_Size - 30, Y_Size - 30);        //X轴终点
            PointF Y_EndPoint = new PointF(30, 30);                          //Y轴终点


            //坐标轴三角形箭头
            PointF[] xpt = new PointF[3] { new PointF(X_EndPoint.X + 15, X_EndPoint.Y), new PointF(X_EndPoint.X, X_EndPoint.Y - 4), new PointF(X_EndPoint.X, X_EndPoint.Y + 4) };//x轴三角形
            PointF[] ypt = new PointF[3] { new PointF(Y_EndPoint.X, Y_EndPoint.Y - 15), new PointF(Y_EndPoint.X - 4, Y_EndPoint.Y), new PointF(Y_EndPoint.X + 4, Y_EndPoint.Y) };//y轴三角形           

            //画图表标题
            //gph.DrawString(chartTitle, new Font("宋体", 14), Brushes.Black, new PointF(Y_EndPoint.X + 60, Y_EndPoint.Y - 30));//图表标题

            //画x轴、三角箭头、标题
            gph.DrawLine(Pens.Black, cpt.X, cpt.Y, X_EndPoint.X, X_EndPoint.Y);
            gph.DrawPolygon(Pens.Black, xpt);
            gph.FillPolygon(new SolidBrush(Color.Black), xpt);
            //gph.DrawString(X_title, new Font("宋体", 12), Brushes.Black, new PointF(X_EndPoint.X + 10, X_EndPoint.Y + 10));


            //画y轴三角箭头、标题
            gph.DrawLine(Pens.Black, cpt.X, cpt.Y, Y_EndPoint.X, Y_EndPoint.Y);
            gph.DrawPolygon(Pens.Black, ypt);
            gph.FillPolygon(new SolidBrush(Color.Black), ypt);
            //gph.DrawString(Y_title, new Font("宋体", 12), Brushes.Black, new PointF(0, Y_EndPoint.Y - 30));

            //Y轴刻度值
            float[] Y_KeduArr = new float[YkeduCount];   
            for (int i = 0; i < YkeduCount; i++)
            {
                Y_KeduArr[i] = (float)0.5*(i+1);
            }

            给刻度值数组赋值
            //setKeduStringArray(X_KeduArr, X_AvgIncrement);
            //setKeduStringArray(Y_KeduArr, Y_AvgIncrement);

            //PointF X_KeduStart = new PointF(0, 590);
            PointF X_KeduEnd = new PointF(340 + 130, X_EndPoint.Y);             //(430,440) x轴最后一根刻度线

            //刻度线位置坐标增量
            Console.WriteLine("X_array.Length: {0}, {1}", X_array.Length, XkeduCount);
            if (X_array.Length > XkeduCount)
            {
                _X_KeduInCrementValue = (float)(X_array.Length - XkeduCount) * (float)1.1;
            }
            else
            { 
                _X_KeduInCrementValue = 25;
            }

            _Y_KeduInCrementValue = 40;

            //X,Y刻度线起始位置,  X_KeduEnd 和 Y_KeduEnd没有使用                        //quanwu.xu  20200415
            PointF X_KeduStart = new PointF(cpt.X + _X_KeduInCrementValue, cpt.Y);              
            PointF X_KeduEnd = new PointF(X_EndPoint.X - 30, X_EndPoint.Y);
            PointF Y_KeduStart = new PointF(cpt.X, cpt.Y - _Y_KeduInCrementValue);                 
            PointF Y_KeduEnd = new PointF(Y_EndPoint.X, Y_EndPoint.Y - 30 + 300);     

            //设置X轴刻度值显示方向
            StringFormat X_StringFormat = new StringFormat();
            if (XdirectionVertical)
            {
                X_StringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
            }
            StringFormat Y_StringFormat = new StringFormat();
            if (YdirectionVertical)
            {
                Y_StringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
            }
            Console.WriteLine("X_Kedu: {0},{1}, {2}, {3}", X_KeduStart.X, X_KeduStart.Y, X_KeduEnd.X, X_KeduEnd.Y);
            Console.WriteLine("Y_Kedu: {0},{1}, {2}, {3}", Y_KeduStart.X, Y_KeduStart.Y, Y_KeduEnd.X, Y_KeduEnd.Y);
            Console.WriteLine("InCrementValue: {0},{1}", _X_KeduInCrementValue, _Y_KeduInCrementValue);


            //画x轴刻度线、刻度值
            for (int i = 1; i <= XkeduCount; i++)
            {
                gph.DrawString(X_array[i - 1].ToString(Xformat), new Font("Times New Roman", 11), Brushes.Black, new PointF(X_KeduStart.X - 5 + (i - 1) * _X_KeduInCrementValue, cpt.Y + 5), X_StringFormat);// new StringFormat(StringFormatFlags.DirectionVertical));//最后一个参数实现文字竖排,默认为横排
                gph.DrawLine(Pens.LightGray, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, cpt.Y, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, Y_EndPoint.Y);
            }

            画y轴刻度线、刻度值
            for (int i = 1; i <= YkeduCount; i++)
            {
                gph.DrawString(Y_KeduArr[i - 1].ToString(Yformat), new Font("Times New Roman", 11), Brushes.Black, new PointF(Y_KeduStart.X - 30 , Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue - 6), Y_StringFormat);
                gph.DrawLine(Pens.LightGray, Y_KeduStart.X, Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue, X_EndPoint.X, Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue);
            }


            return bmap;
            //保存输出图片
        }

效果图如下:

 

1.2  绘制曲线(Graphics里面好像没有特别的曲线绘制方法,暂且用drawline吧),效果如下,当然没有Chart控件好看:

    #region 曲线绘制class
    public class CurvePaint
    {

        public CurvePaint() { }
        //刻度线条数
        private int _X_KeduCount = 15;
        private int _Y_KeduCount = 5;

        //刻度值位置对应刻度线左移像素
        private float _X_KeduInCrementValue = 1f;
        private float _Y_KeduInCrementValue = 1f;

        //格式化刻度值
        private string _X_Format = "#0";
        private string _Y_Format = "#0.0";

        //X轴刻度值文字方向
        private bool _X_DirectionVertical = false;
        private bool _Y_DirectionVertical = false;
        public int XkeduCount
        {
            get { return _X_KeduCount; }
            set { _X_KeduCount = value; }
        }

        public float X_KeduIncrement                              //quanwu.xu 
        {
            get { return _X_KeduInCrementValue; }
            set { _X_KeduInCrementValue = value; }
        }

        public int YkeduCount
        {
            get { return _Y_KeduCount; }
            set { _Y_KeduCount = value; }
        }

        public float Y_KeduIncrement                              //quanwu.xu 
        {
            get { return _Y_KeduInCrementValue; }
            set { _Y_KeduInCrementValue = value; }
        }


        public bool XdirectionVertical
        {
            get { return _X_DirectionVertical; }
            set { _X_DirectionVertical = value; }
        }

        public bool YdirectionVertical
        {
            get { return _Y_DirectionVertical; }
            set { _Y_DirectionVertical = value; }
        }

        public string Xformat
        {
            get { return _X_Format; }
            set { _X_Format = value; }
        }

        public string Yformat
        {
            get { return _Y_Format; }
            set { _Y_Format = value; }
        }

        // Y轴数据规格化
        private float Standard(float Value, float k, float b)
        {
            //return C * (A * x + B) + D;
            return b - Value / k;
        }

        public Bitmap drawCurve(int LinesIndex, List<float>[] Y_array, int X_Localtion, int Y_Localtion, int X_Size, int Y_Size)
        {

            Console.WriteLine("size: {0},{1}, {2}, {3}",X_Localtion,Y_Localtion, X_Size, Y_Size );

            //画笔定义 pen1
            Pen pen1 = new Pen(Color.Black, 2);
            pen1.DashStyle = DashStyle.Custom;

            //画图初始化
            Bitmap bmap = new Bitmap(X_Size, Y_Size);                           //画布图片大小
            Graphics gph = Graphics.FromImage(bmap);
            gph.Clear(Color.White);

            //曲线坐标轴设定
            PointF cpt = new PointF(30, Y_Size - 30);                           //坐标原点,坐标轴起始点
            PointF X_EndPoint = new PointF(X_Size - 30, Y_Size - 30);           //X轴终点
            PointF Y_EndPoint = new PointF(30, 30);                             //Y轴终点

            //坐标轴三角形箭头
            PointF[] xpt = new PointF[3] { new PointF(X_EndPoint.X + 15, X_EndPoint.Y), new PointF(X_EndPoint.X, X_EndPoint.Y - 4), new PointF(X_EndPoint.X, X_EndPoint.Y + 4) };//x轴三角形
            PointF[] ypt = new PointF[3] { new PointF(Y_EndPoint.X, Y_EndPoint.Y - 15), new PointF(Y_EndPoint.X - 4, Y_EndPoint.Y), new PointF(Y_EndPoint.X + 4, Y_EndPoint.Y) };//y轴三角形           

            //画图表标题
            //gph.DrawString(chartTitle, new Font("宋体", 14), Brushes.Black, new PointF(Y_EndPoint.X + 60, Y_EndPoint.Y - 30));//图表标题

            //画x轴、三角箭头、标题
            gph.DrawLine(pen1, cpt.X, cpt.Y, X_EndPoint.X, X_EndPoint.Y);
            gph.DrawPolygon(pen1, xpt);
            gph.FillPolygon(new SolidBrush(Color.Black), xpt);
            //gph.DrawString(X_title, new Font("宋体", 12), Brushes.Black, new PointF(X_EndPoint.X + 10, X_EndPoint.Y + 10));


            //画y轴三角箭头、标题
            gph.DrawLine(pen1, cpt.X, cpt.Y, Y_EndPoint.X, Y_EndPoint.Y);
            gph.DrawPolygon(pen1, ypt);
            gph.FillPolygon(new SolidBrush(Color.Black), ypt);
            //gph.DrawString(Y_title, new Font("宋体", 12), Brushes.Black, new PointF(0, Y_EndPoint.Y - 30));

            //Y轴刻度值
            float[] Y_KeduArr = new float[YkeduCount];   
            for (int i = 0; i < YkeduCount; i++)
            {
                Y_KeduArr[i] = (i + 1)*0.5f;
            }

            给刻度值数组赋值
            //setKeduStringArray(X_KeduArr, X_AvgIncrement);
            //setKeduStringArray(Y_KeduArr, Y_AvgIncrement);

            //PointF X_KeduStart = new PointF(0, 590);
            //PointF X_KeduEnd = new PointF(340 + 130, X_EndPoint.Y);             //(430,440) x轴最后一根刻度线

            //刻度线位置坐标增量
            int GreatestCnt = Y_array[0].Count;
            for (int i = 0; i < Y_array.Length; i++)
            {
                if (GreatestCnt < Y_array[i].Count)
                {
                    GreatestCnt = Y_array[i].Count;
                }
            }

            int Temp = GreatestCnt / 20;
            float _X_KeduInCrementDisplayValue = 25; 
            if (Temp != 0)
            {
                _X_KeduInCrementValue = _X_KeduInCrementDisplayValue / (Temp + 1);
            }
            else
            {
                _X_KeduInCrementValue = _X_KeduInCrementDisplayValue;
            }
            _Y_KeduInCrementValue = 40;

            Console.WriteLine("Greatest.Length: {0}, {1}", GreatestCnt, _X_KeduInCrementValue);

            //X,Y刻度线起始位置,  X_KeduEnd 和 Y_KeduEnd没有使用                        //quanwu.xu  20200415
            PointF X_KeduStart = new PointF(cpt.X + _X_KeduInCrementDisplayValue, cpt.Y);              
            PointF X_KeduEnd = new PointF(X_EndPoint.X - 30, X_EndPoint.Y);
            PointF Y_KeduStart = new PointF(cpt.X, cpt.Y - _Y_KeduInCrementValue);                 
            PointF Y_KeduEnd = new PointF(Y_EndPoint.X, Y_EndPoint.Y - 30 + 300);     

            //设置X轴刻度值显示方向
            StringFormat X_StringFormat = new StringFormat();
            if (XdirectionVertical)
            {
                X_StringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
            }
            StringFormat Y_StringFormat = new StringFormat();
            if (YdirectionVertical)
            {
                Y_StringFormat.FormatFlags = StringFormatFlags.DirectionVertical;
            }

            //Console.WriteLine("X_Kedu: {0},{1}, {2}, {3}", X_KeduStart.X, X_KeduStart.Y, X_KeduEnd.X, X_KeduEnd.Y);
            //Console.WriteLine("Y_Kedu: {0},{1}, {2}, {3}", Y_KeduStart.X, Y_KeduStart.Y, Y_KeduEnd.X, Y_KeduEnd.Y);
            //Console.WriteLine("InCrementValue: {0},{1}", _X_KeduInCrementValue, _Y_KeduInCrementValue);

            //画笔定义 pen1
            Pen pen2 = new Pen(Color.LightGray, 1);
            pen2.DashStyle = DashStyle.Dash;

            //画x轴刻度线、刻度值
            for (int i = 1; i <= XkeduCount; i++)
            {
                gph.DrawString((i*(Temp + 1)).ToString(Xformat), new Font("Times New Roman", 8), Brushes.Black, new PointF(X_KeduStart.X - 5 + (i - 1) * _X_KeduInCrementDisplayValue, cpt.Y + 5), X_StringFormat);// new StringFormat(StringFormatFlags.DirectionVertical));//最后一个参数实现文字竖排,默认为横排
                gph.DrawLine(pen2, X_KeduStart.X + (i - 1) * _X_KeduInCrementDisplayValue, cpt.Y, X_KeduStart.X + (i - 1) * _X_KeduInCrementDisplayValue, Y_EndPoint.Y);
            }

            画y轴刻度线、刻度值
            for (int i = 1; i <= YkeduCount; i++)
            {
                gph.DrawString(Y_KeduArr[i - 1].ToString(Yformat), new Font("Times New Roman", 11), Brushes.Black, new PointF(Y_KeduStart.X - 30 , Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue - 6), Y_StringFormat);
                gph.DrawLine(pen2, Y_KeduStart.X, Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue, X_EndPoint.X, Y_KeduStart.Y - (i - 1) * _Y_KeduInCrementValue);
            }

            //画连接线
            if (LinesIndex != 0)
            {
                float Y_K = 12.5f;
                float Y_B = 500.0f;
                float Y_Value1;
                float Y_Value2;

                Console.WriteLine("Y_Cnt: {0},{1}, {2}, {3}", Y_array[0].Count, Y_array[1].Count, Y_array[2].Count, Y_array[3].Count);

                //画笔定义 pen1
                Pen pen3 = new Pen(Color.Green, 1.5f);
                pen3.DashStyle = DashStyle.Solid;
                if (((LinesIndex & 0x01) == 0x01) && (Y_array[0].Count > 1))                              //Co
                {
                    for (int i = 2; i <= Y_array[0].Count; i++)
                    {
                        Y_Value1 = Standard(Y_array[0][i - 2], Y_K, Y_B);
                        Y_Value2 = Standard(Y_array[0][i - 1], Y_K, Y_B);

                        //画点
                        //gph.DrawEllipse(Pens.Black, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, Y_Value1, 3, 3);

                        //画折线
                        gph.DrawLine(pen3, cpt.X + (i - 2) * _X_KeduInCrementValue, Y_Value1, cpt.X + (i - 1) * _X_KeduInCrementValue, Y_Value2);

                    }
                }

                //画笔定义 pen1
                Pen pen4 = new Pen(Color.Black, 1.5f);
                pen3.DashStyle = DashStyle.Solid;
                if (((LinesIndex & 0x02) == 0x02) && (Y_array[1].Count > 1))                              //Dark
                {
                    for (int i = 2; i <= Y_array[1].Count; i++)
                    {
                        Y_Value1 = Standard(Y_array[1][i - 2], Y_K, Y_B);
                        Y_Value2 = Standard(Y_array[1][i - 1], Y_K, Y_B);

                        //画点
                        //gph.DrawEllipse(Pens.Black, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, Y_Value1, 3, 3);

                        //画折线
                        gph.DrawLine(pen4, cpt.X + (i - 2) * _X_KeduInCrementValue, Y_Value1, cpt.X + (i - 1) * _X_KeduInCrementValue, Y_Value2);

                    }
                }

                //画笔定义 pen1
                Pen pen5 = new Pen(Color.Red, 1.5f);
                pen3.DashStyle = DashStyle.Solid;
                if (((LinesIndex & 0x04) == 0x04) && (Y_array[2].Count > 1))                              //Light
                {
                    for (int i = 2; i <= Y_array[2].Count; i++)
                    {
                        Y_Value1 = Standard(Y_array[2][i - 2], Y_K, Y_B);
                        Y_Value2 = Standard(Y_array[2][i - 1], Y_K, Y_B);

                        //画点
                        //gph.DrawEllipse(Pens.Black, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, Y_Value1, 3, 3);

                        //画折线
                        gph.DrawLine(pen5, cpt.X + (i - 2) * _X_KeduInCrementValue, Y_Value1, cpt.X + (i - 1) * _X_KeduInCrementValue, Y_Value2);

                    }
                }


                //画笔定义 pen1
                Pen pen6 = new Pen(Color.Blue, 1.5f);
                pen3.DashStyle = DashStyle.Solid;
                if (((LinesIndex & 0x08) == 0x08) && (Y_array[3].Count > 1))                              //L_D
                {
                    for (int i = 2; i <= Y_array[3].Count; i++)
                    {
                        Y_Value1 = Standard(Y_array[3][i - 2], Y_K, Y_B);
                        Y_Value2 = Standard(Y_array[3][i - 1], Y_K, Y_B);

                        //画点
                        //gph.DrawEllipse(Pens.Black, X_KeduStart.X + (i - 1) * _X_KeduInCrementValue, Y_Value1, 3, 3);

                        //画折线
                        gph.DrawLine(pen6, cpt.X + (i - 2) * _X_KeduInCrementValue, Y_Value1, cpt.X + (i - 1) * _X_KeduInCrementValue, Y_Value2);

                    }
                }
            }

            return bmap;
            //保存输出图片
        }
    }

    #endregion

三、完整代码

https://download.csdn.net/download/xqw19891201/12334992

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值