当前位置: 首页 > news >正文

C#自定义曲线绘图面板

一、实现功能

1、显示面板绘制。

2、拖动面板,X轴、Y轴都可以拖动。

3、显示面板缩放,放大或者缩小。

4、鼠标在面板中对应的XY轴数值。

5、自动生成的数据数组,曲线显示。

6、鼠标是否在曲线上检测。

二、界面

拖动面板

鼠标在曲线上识别

三、部分功能代码实现

1、图形面板

        /// <summary>/// 生成坐标系图片面板/// </summary>/// <returns></returns>public Bitmap DrawImage(){ImageBoardInit();return bitMap;}
        /// <summary>/// 创建绘图面板-显示坐标系/// </summary>private void ImageBoardInit(){//1、绘制X、Y坐标轴if ((int)height != 0 && (int)width != 0)  //做这个判断是因为在最小化的情况下width=0。{bitMap = new Bitmap((int)width, (int)height);  //根据给定的高度和宽度创建一个位图图像}            graphics = Graphics.FromImage(bitMap);    //从指定的 objBitmap 对象创建 objGraphics 对象 (即在objBitmap对象中画图)//根据给定颜色(LightGray)填充图像的矩形区域 (背景)graphics.DrawRectangle(new Pen(boardColor, 1), 0, 0, width - 1, height - 1);    //画边框graphics.FillRectangle(new SolidBrush(backColor), 1, 1, width - 2, height - 2); //填充边框//画X轴,注意图像的原始X轴和Y轴计算是以左上角为原点,向右和向下计算的xAxisPoint1.X = xSpace + xSliceBegin;xAxisPoint1.Y = (height / 2) + ySliceBegin;    //xAxisPoint2.X = width;xAxisPoint2.Y = xAxisPoint1.Y;graphics.DrawLine(new Pen(new SolidBrush(axisColor), 2), xAxisPoint1, xAxisPoint2);//画Y轴yAxisPoint1.X = xSpace + xSliceBegin;yAxisPoint1.Y = height ;yAxisPoint2.X = xSpace + xSliceBegin;yAxisPoint2.Y = 0 ;graphics.DrawLine(new Pen(new SolidBrush(axisColor), 2), yAxisPoint1, yAxisPoint2);//2、面板标题//graphics.DrawString("曲线编辑器", new Font("宋体", fontSize), new SolidBrush(Color.Blue), new PointF(width / 2, ySpace / 2));//3、画X轴上刻度、刻度说明            xSlice = (width - xSpace ) / xSliceCount;ySlice = (height / 2) / (ySliceCount / 2);int tempCountX1 = (int)(- xSliceBegin / xSlice);int tempCountY1 = (int)Math.Abs((ySliceBegin / ySlice));tempCountX = tempCountX1 + xSliceCount;tempCountY = tempCountY1 + ySliceCount/2;//画网格虚线Pen penDashed = new Pen(new SolidBrush(Color.Black));penDashed.DashStyle = DashStyle.Dash;for (int i = 1; i < tempCountX + 1; i++){//X轴刻度虚线graphics.DrawLine(penDashed, new PointF(i * xSlice + xSpace + xSliceBegin, 0 ), new PointF(i * xSlice + xSpace + xSliceBegin, height));//X轴刻度值标识文字string xStr = (i * xSliceValue).ToString();int nStrLength = xStr.Length;graphics.DrawString(xStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(i * xSlice + xSpace - fontSize * nStrLength + xSliceBegin, height / 2 + fontSize + ySliceBegin));}//Y轴虚线、刻度文字-正半轴for (int i = 0; i < tempCountY + 1; i++){graphics.DrawLine(penDashed, new PointF(xSpace + xSliceBegin, height / 2 - i * ySlice + ySliceBegin), new PointF(width, height / 2 - i * ySlice + ySliceBegin));//Y轴刻度值标识文字string yStr = (i * ySliceValue).ToString();int nStrLength = yStr.Length;if(i>0)graphics.DrawString(yStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * nStrLength + xSliceBegin, height / 2 - i * ySlice + ySliceBegin));}//Y轴虚线、刻度文字-负半轴for (int i = 1; i < tempCountY  + 1; i++){graphics.DrawLine(penDashed, new PointF(xSpace + xSliceBegin, height / 2 + i * ySlice + ySliceBegin), new PointF(width, height / 2 + i * ySlice + ySliceBegin));//Y轴刻度值标识文字string yStr = (-i * ySliceValue).ToString();int nStrLength = yStr.Length;graphics.DrawString(yStr, new Font("宋体", fontSize), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * nStrLength + xSliceBegin, height / 2 + i * ySlice + ySliceBegin));}//4、原点刻度说明graphics.DrawString("0", new Font("宋体", fontSize + 2), new SolidBrush(Color.Black), new PointF(xSpace - fontSize * 2 + xSliceBegin, height / 2 + ySliceBegin));}

2、数据点曲线显示

        /// <summary>/// 绘制XY轴曲线/// </summary>/// <param name="xDatas">X轴数据</param>/// <param name="yDatas">Y轴数据</param>/// <param name="splineColor">曲线颜色</param>/// <param name="tension">曲线系数:0.0f-1.0f,默认0.5f,0.0f是直线</param>/// <param name="isPointFill">是否标出点</param>public void DrawXY(float[] xDatas,float[] yDatas,Color splineColor,float tension,bool isPointFill){int xLength = xDatas.Length;int yLength = yDatas.Length;if(xLength!=yLength){graphics.DrawString("X和Y数据长度不相等",new Font("宋体", fontSize + 5), new SolidBrush(Color.Blue), new Point((int)xSpace, (int)(height / 2)));return;}PointF[] splinePoints = new PointF[xDatas.Length];float xSlicePos = 0, ySlicePos = 0; //转换后的点在Image面板上像素点位置Brush brushPoint = new SolidBrush(splineColor);        //数据点画刷for(int i=0;i<xDatas.Length;i++){xSlicePos = xSliceBegin + xSpace + xDatas[i] * xSlice / xSliceValue;ySlicePos = ySliceBegin + height / 2 - yDatas[i] * ySlice / ySliceValue;splinePoints[i] = new PointF(xSlicePos, ySlicePos);if (isPointFill){//graphics.FillEllipse(brushPoint, xSlicePos - 4, ySlicePos - 4, 8, 8); //原点graphics.FillRectangle(brushPoint, xSlicePos - 4, ySlicePos - 4, 8, 8); //矩形}                }graphics.DrawCurve(new Pen(splineColor, 2.0f), splinePoints, tension);//graphics.Dispose();}

3、鼠标当前所在面板位置对应的坐标系统XY值

        int ex = 0, ey = 0;int mouseToValueX = 0;float mouseToValueY = 0;   //鼠标位置当前值float fMouseToValueX = 0;private void pictureBox1_MouseMove(object sender, MouseEventArgs e){ex = e.X;ey = e.Y;//1、显示鼠标在坐标系内X、Y对应的值fMouseToValueX =cureDraw.MousePosToValue_X(ex);mouseToValueX = (int)Math.Round(cureDraw.MousePosToValue_X(ex));//mouseToValueY = (float)Math.Round(cureDraw.MousePosToValue_Y(ey));mouseToValueY = cureDraw.MousePosToValue_Y(ey);if (mouseToValueX<0){mouseToValueX = 0;}if (mouseToValueX >= 0 && ex < pictureBox1.Width - 60){                labMousePos.Text = "X:" + mouseToValueX.ToString() + ";" + "Y:" + mouseToValueY.ToString();labMousePos.Location = new Point(ex + 50, ey + 40);}if (mouseToValueX >= 0 && ex > pictureBox1.Width - 60){                labMousePos.Text = "X:" + mouseToValueX.ToString() + ";" + "Y:" + mouseToValueY.ToString();labMousePos.Location = new Point(ex - 50, ey + 40);}}

4、鼠标是否在曲线上检测

        bool isMouseOn = false;private void timer1_Tick(object sender, EventArgs e){//bool isMouseOn = cureDraw.IsMouseOnPointCheck(xDatas, yDatas, ex, ey);//bool isMouseOn = cureDraw.IsMouseOnPointCheck(xDatasExpand, yDatasExpand, ex, ey);float tempX = 0, tempY = 0;int n = 0;bool b1 = false, b2 = false;foreach (var xData in xDatasExpand){if(Math.Abs(xData-fMouseToValueX)<0.02){tempX = xData;}}for (int i = 0; i < xDatasExpand.Length;i++ ){if(xDatasExpand[i]==tempX){n = i;}}if (Math.Abs(yDatasExpand[n] - mouseToValueY)<2.5){isMouseOn = true;}else{isMouseOn = false;}txtValue1.Text = xDatasExpand[n].ToString();    //YtxtValue2.Text = fMouseToValueX.ToString();txtValue3.Text = yDatasExpand[n].ToString();    //XtxtValue4.Text = mouseToValueY.ToString();txtValue5.Text = n.ToString();if (isMouseOn){labMousePos.ForeColor = Color.Red;                }else{labMousePos.ForeColor = Color.Black;}}

四、、工程下载链接

https://download.csdn.net/download/panjinliang066333/89775386


http://www.mrgr.cn/news/31164.html

相关文章:

  • 【前端面试系列】JavaScript闭包
  • Spring boot + Vue2小项目基本模板
  • 高效实现自动化运维的Python工具开发与集成
  • 从建立TRUST到实现FAIR:可持续海洋经济的数据管理
  • 打假官方咨询(续)
  • 自闭症机构推荐:让孩子找回快乐与自信
  • Xinstall助力App推广,下载自动绑定提升转化率
  • 15.多线程概述一(下篇)
  • 如何限制任何爬虫爬取网站的图片
  • 无人机之4G模块的主要功能和优势
  • 【时时三省】(C语言基础)指针笔试题1
  • 专利管理系统如何确保专利资产持续有效?
  • 技术老总眼中的品宣与促销:挑战与对策
  • 【算法竞赛】栈
  • QT的dropEvent函数进入不了
  • ASPICE认证、咨询和培训的价值是什么?
  • 零基础玩转实在Agent -- 基础篇|实在Agent研究
  • 【北京迅为】《STM32MP157开发板使用手册》- 第四十一章 计数信号量实验
  • 二级C语言2024-3易错题
  • 【ppt2svg svg2png/jpg】ppt转图片解决方案
  • Pandas中df常用方法介绍
  • C++日期类详解 第二级支线任务
  • FB FC里调用全局变量注意事项
  • 用 JS 实现一个发布订阅模式
  • Unity的Text组件中实现输入内容的渐变色效果
  • FedOV