C#使用GDI画直角坐标系之画两个纵坐标

初学C#,想要在上位机上显示坐标轴,而且需要两条坐标轴,由于chart控件在数据量大了之后会卡顿、更新变慢,于是学习了一下GDI绘图,参考了网络上的一些实现方式,并加了一些自己的改动,最终实现了目标,效果如图:

主要思路是在Panel控件里面,利用类graphics来进行绘图,绘图的位置标是通过Panel控件的一些属性来确定的,比如panel的长度和宽度:panel.Width、panel.Height

需要引用的头文件如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

主要代码如下:


        #region   画出X轴与Y轴
        /// <summary>
        /// 在任意的panel里画一个坐标,坐标所在的四边形距离panel边缘50像素
        /// </summary>
        /// <param name="pan"></param>
        public static void DrawXY(Panel pan)
        {
            Graphics g = pan.CreateGraphics();
            //整体内缩move像素
            float move = 50f;
            float newX = pan.Width - move;  
            float newY = pan.Height - move;


            //绘制X轴,
            PointF px1 = new PointF(move, newY);
            PointF px2 = new PointF(newX, newY);
            g.DrawLine(new Pen(Brushes.Black, 2), px1, px2);
            //绘制Y轴
            PointF py1 = new PointF(move, move);
            PointF py2 = new PointF(move, newY);
            PointF py3 = new PointF(newX, move);
            g.DrawLine(new Pen(Brushes.Black, 2), py1, py2);  //左边的Y轴
            g.DrawLine(new Pen(Brushes.Black, 2), px2, py3);  //右边的Y轴
        }
        #endregion

        /// <summary>
        /// 画出Y轴上的分值线,从零开始
        /// </summary>
        /// <param name="pan"></param>
        /// <param name="maxY"></param>
        /// <param name="len"></param>
        #region   画出Y轴上的分值线,从零开始
        public static void DrawYLine(Panel pan, float maxY, int len)
        {
            float move = 50f;
            float LenX = pan.Width - 2 * move;
            float LenY = pan.Height - 2 * move;
            Graphics g = pan.CreateGraphics();
            for (int i = 0; i <= len; i++)    //len等份Y轴
            {
                PointF px1 = new PointF(move, LenY * i / len + move);
                PointF px2 = new PointF(move + 4, LenY * i / len + move);
                string sx = (maxY - maxY * i / len).ToString();
                g.DrawLine(new Pen(Brushes.Black, 2), px1, px2);
                StringFormat drawFormat = new StringFormat();
                drawFormat.Alignment = StringAlignment.Far;
                drawFormat.LineAlignment = StringAlignment.Center;
                g.DrawString(sx, new Font("宋体", 8f), Brushes.Black, new PointF(move / 1.2f, LenY * i / len + move * 1.1f), drawFormat);
            
            }
            Pen pen = new Pen(Color.Black, 1);
            g.DrawString("温度", new Font("宋体 ", 10f), Brushes.Black, new PointF(move / 3, move / 2f));
        }
        #endregion

        /// <summary>
        /// 画出Y轴上的分值线,从任意值开始
        /// </summary>
        /// <param name="pan"></param>
        /// <param name="minY"></param>
        /// <param name="maxY"></param>
        /// <param name="len"></param>
        #region   画出Y轴上的分值线,从任意值开始
        public static void DrawYLine(Panel pan, float minY, float maxY, int len)
        {
            float move = 50f;
            float newX = pan.Width - move;
            float newY = pan.Height - move;
            float LenX = pan.Width - 2 * move;
            float LenY = pan.Height - 2 * move;
            Graphics g = pan.CreateGraphics();
            for (int i = 0; i <= len; i++)    //len等份Y轴
            {
                PointF px1 = new PointF(move, LenY * i / len + move);
                PointF px2 = new PointF(move + 4, LenY * i / len + move);
                PointF px3 = new PointF(newX-4, LenY * i / len + move);
                PointF px4 = new PointF(newX, LenY * i / len + move);
                string sx = (maxY - (maxY - minY) * i / len).ToString();   // 分刻度值(0、10、20、30....100)
                g.DrawLine(new Pen(Brushes.Black, 2), px1, px2);  //画刻度线
                g.DrawLine(new Pen(Brushes.Black, 2), px3, px4);  //画刻度线
                StringFormat drawFormat = new StringFormat();
                drawFormat.Alignment = StringAlignment.Far;
                drawFormat.LineAlignment = StringAlignment.Center;
                g.DrawString(sx, new Font("宋体", 8f), Brushes.Black, new PointF((newX + move)/ 1.1f, LenY * i / len + move * 1.1f), drawFormat);//写出分度值
                g.DrawString(sx, new Font("宋体", 8f), Brushes.Black, new PointF(move / 1.2f, LenY * i / len + move * 1.1f), drawFormat);
            }
            Pen pen = new Pen(Color.Black, 1);
            g.DrawString("温度/℃", new Font("宋体 ", 10f), Brushes.Black, new PointF(move / 3, move / 2f));
            g.DrawString("功率/W", new Font("宋体 ", 10f), Brushes.Black, new PointF(pan.Width - move / 0.8f, move / 2f));
        }

        #endregion
        /// <summary>
        /// 画出X轴上的分值线,从零开始
        /// </summary>
        /// <param name="pan"></param>
        /// <param name="maxX"></param>
        /// <param name="len"></param>
        #region   画出X轴上的分值线,从零开始
        public static void DrawXLine(Panel pan, float maxX, int len)
        {
            float move = 50f;
            float LenX = pan.Width - 2 * move;
            float LenY = pan.Height - 2 * move;
            Graphics g = pan.CreateGraphics();
            for (int i = 1; i <= len; i++)
            {
                PointF py1 = new PointF(LenX * i / len + move, pan.Height - move - 4);
                PointF py2 = new PointF(LenX * i / len + move, pan.Height - move);
                string sy = (maxX * i / len).ToString();
                g.DrawLine(new Pen(Brushes.Black, 2), py1, py2);
                g.DrawString(sy, new Font("宋体", 8f), Brushes.Black, new PointF(LenX * i / len + move, pan.Height - move / 1.1f));
            }
            Pen pen = new Pen(Color.Black, 1);
            g.DrawString("时间/s", new Font("宋体 ", 10f), Brushes.Black, new PointF((pan.Width - move / 1.5f)/2, pan.Height - move / 2f));
        }
        #endregion

        #region   画出X轴上的分值线,从任意值开始
        /// <summary>
        /// 画出X轴上的分值线,从任意值开始
        /// </summary>
        /// <param name="pan"></param>
        /// <param name="minX"></param>
        /// <param name="maxX"></param>
        /// <param name="len"></param>
        public static void DrawXLine(Panel pan, float minX, float maxX, int len)
        {
            float move = 50f;
            float LenX = pan.Width - 2 * move;
            float LenY = pan.Height - 2 * move;
            Graphics g = pan.CreateGraphics();
            for (int i = 0; i <= len; i++)
            {
                PointF py1 = new PointF(LenX * i / len + move, pan.Height - move - 4);
                PointF py2 = new PointF(LenX * i / len + move, pan.Height - move);
                string sy = ((maxX - minX) * i / len + minX).ToString();
                g.DrawLine(new Pen(Brushes.Black, 2), py1, py2);
                g.DrawString(sy, new Font("宋体", 8f), Brushes.Black, new PointF(LenX * i / len + move, pan.Height - move / 1.1f));
            }
            Pen pen = new Pen(Color.Black, 1);
            g.DrawString("时间", new Font("宋体 ", 10f), Brushes.Black, new PointF(pan.Width - move / 1.5f, pan.Height - move / 1.5f));
        }
        #endregion

以上就是画X轴、Y轴以及对应的刻度的函数,接下来只需要在设计器里拖动一个panel控件添加到窗体里,然后编写该控件的Paint事件并添加该事件就可以了。

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            {
                DrawXY(panel1);
                DrawYLine(panel1, 0, 100, 10); // 坐标轴显示0~100,每隔10分一小格
                DrawXLine(panel1, 100, 10);
            }

        }

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值