C#开发的3D图表控件,适用于winform项目,

使用了opentk绘制3D图形。图表颜色,文字颜色,均可以替换。欢迎来白嫖。

资源地址:

C#开发的3D图表控件,适用于winform项目,使用了opentk绘制3D图形。图表颜色,文字颜色,均可以替换-C#文档类资源-CSDN下载

核心绘图代码如下:

public class QChart : GLControl
    {

private bool _loaded;
        private int _x;
        private float _rotationx,_rotationy;

private float zIndex = 12;//俯视角度,好看

private bool locked = false;//是否锁定

private readonly Stopwatch _sw = new Stopwatch();

private List<Point3D> points;

public float FontSize { get; set; }

private Dictionary<String, Txture> fts = new Dictionary<string, Txture>();//材质集合

/// <summary>
        /// 坐标线条颜色
        /// </summary>
        public Color LineColor { get; set; }
        /// <summary>
        /// 点颜色
        /// </summary>
        public Color DotColor { get; set; }
        /// <summary>
        /// 标题颜色
        /// </summary>
        public Color TitleColor { get; set; }
        /// <summary>
        /// X轴标题
        /// </summary>
        public String XTitle { get; set; }
        /// <summary>
        /// Y轴标题
        /// </summary>
        public String YTitle { get; set; }
        /// <summary>
        /// Z轴标题
        /// </summary>
        public String ZTitle { get; set; }

public int XRange { get; set; }
        public int YRange { get; set; }
        public int ZRange { get; set; }

public QChart()
        {
            BackColor = Color.White;
            LineColor = Color.Gray;
            DotColor = Color.Green;
            TitleColor = Color.Black;
            XTitle = "X";
            YTitle = "Y";
            ZTitle = "Z";
            XRange = 5;
            YRange = 3;
            ZRange = 3;
            _rotationy = 1;
            FontSize = 12;//文字大小

}

private double maxx, minx, maxy, miny, maxz, minz;

/// <summary>
        /// 传入坐标集合
        /// </summary>
        /// <param name="points"></param>
        public void ShowPoints(List<Point3D> points) {
            this.points = points;
            if (points==null||  points.Count == 0) return;

maxx = points[0].X;
            minx = points[0].X;
            maxy = points[0].Y;
            miny = points[0].Y;
            maxz = points[0].Z;
            minz = points[0].Z;

foreach (Point3D p in points) {
                if (p.X > maxx) maxx = p.X;
                if (p.X < minx) minx = p.X;
                if (p.Y > maxy) maxy =p.Y;
                if (p.Y < miny) miny = p.Y;
                if (p.Z > maxz) maxz = p.Z;
                if (p.Z < minz) minz = p.Z;

}
            //防止直接到边界
            maxx += 0.2;
            minx -= 0.2;
            maxy += 0.2;
            miny -= 0.2;
            maxz += 0.2;
            minz -= 0.2;

}

/// <summary>
        /// 窗体加载
        /// </summary>
        /// <param name="e"></param>
        protected override void OnLoad(EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            base.OnLoad(e);
            this._loaded = true;
            //GL.ClearColor(Color.Black);
            this.SetupViewport();
            Application.Idle += this.Application_Idle;
            this._sw.Start();

this.MouseDown += on_MouseDown;
            this.MouseLeave += on_MouseLeave;
            this.MouseMove += on_MouseMove;
            this.MouseUp += on_MouseUp;
            this.MouseWheel += on_MouseWheel;

}

/// <summary>
        /// 系统空闲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Application_Idle(object sender, EventArgs e)
        {
            while (this.IsIdle)
            {

this.Render();
            }
        }

//时间更新方法
        private double ComputeTimeSlice()
        {
            this._sw.Stop();
            double timeSlice = this._sw.Elapsed.TotalMilliseconds;
            this._sw.Reset();
            this._sw.Start();
            return timeSlice;
        }
        //初始化可视区域
        private void SetupViewport()
        {

var w = this.Width;
            var h = this.Height;

GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();

GL.Viewport(0, 0, w, h); // Use all of the glControl painting area

if (h == 0) h = 1;
            Glu.Perspective(60.0f, w / h, 0.01, 100);
            Glu.LookAt(0, 0, zIndex, 0, 0, 0, 0, 1, 0);

}
        //大小改变
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (!this._loaded)
            {
                return;
            }
            this.SetupViewport();
            this.Invalidate();
        }
        //窗体的绘图事件
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            if (!this._loaded)
            {
                return;
            }
            this.Render();
        }
        //绘图主事件
        private void Render()
        {

GL.ClearColor(BackColor);//背景色
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit| ClearBufferMask.StencilBufferBit);

GL.MatrixMode(MatrixMode.Modelview);

GL.LoadIdentity();

GL.Rotate(_rotationx, 1, 0, 0);//X轴旋转

GL.Rotate(_rotationy, 0, 1, 0);//Y轴旋转
            GL.Enable(EnableCap.DepthTest);//必须开启深度测试
            GL.Enable(EnableCap.AlphaTest);
            GL.AlphaFunc(AlphaFunction.Equal, 1.0f);
            drawText(0, 0, 0, "hello");

//绘制坐标

GL.Color3(LineColor);//线颜色
            //水平线,X面
            for(int i = -XRange; i <= XRange; i++) {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(i, -YRange, -ZRange);
                GL.Vertex3(i, -YRange, ZRange);
                GL.End();
               
             }
            for (int i = -ZRange; i <= ZRange; i++)
            {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(-XRange, -YRange, i);
                GL.Vertex3(XRange, -YRange,i);
                GL.End();
                
            }

//竖直线,Y面
            for (int i = -YRange; i <= YRange; i++)
            {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(-XRange, i, -ZRange);
                GL.Vertex3(-XRange, i, ZRange);
                GL.End();
            }
            
            for (int i = -ZRange; i <= ZRange; i++)
            {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(-XRange, -YRange, i);
                GL.Vertex3(-XRange, YRange, i);
                GL.End();
            }
            //Z面
            for (int i = -YRange; i <= YRange; i++)
            {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(-XRange,i, -ZRange);
                GL.Vertex3(XRange, i, -ZRange);
                GL.End();
            }

for (int i = -XRange; i <= XRange; i++)
            {
                GL.Begin(BeginMode.Lines);
                GL.Vertex3(i,-YRange, -ZRange);
                GL.Vertex3(i, YRange, -ZRange);
                GL.End();
            }

//输出三个坐标标题
           // GL.text

//如果有点,才绘制点

if (points != null && points.Count > 0) {
                GL.Color3(DotColor);
                GL.PointSize(3);
                GL.Begin(BeginMode.Points);
                foreach (Point3D p in points) {
                    double x = XRange*( 2 * (p.X - minx) / (maxx - minx)-1);
                    double y = YRange * (2 * (p.Y - miny) / (maxy - miny) - 1);
                    double z = ZRange * (2 * (p.Z- minz) / (maxz - minz) - 1);
                    GL.Vertex3(x, y, z);
                }
                GL.End();

// GL.DrawPixels

}

this.SwapBuffers();
        }

//按键事件
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.KeyCode == Keys.Space)
            {
                this._x++;
                SetupViewport();
                this.Invalidate();
            }
        }

private bool msDown = false;//是否鼠标按下
        private int oldX = 0;//原始X坐标
        private int oldY = 0;
        private void on_MouseWheel(object sender, MouseEventArgs e)
        {

// MessageBox.Show(e.Delta+"");
            if (e.Delta > 0)
            {
                zIndex += 1;
                if (zIndex > 20) zIndex = 20;
            }
            else if (e.Delta < 0)
            {

zIndex -= 1;
                if (zIndex < 8) zIndex = 8;
            }

SetupViewport();
            this.Invalidate();
        }
        private void on_MouseDown(object sender, MouseEventArgs e)
        {
            msDown = true;
            oldX = e.X;//记录
            oldY = e.Y;
            Cursor = Cursors.Hand;
            ;
        }

private void on_MouseMove(object sender, MouseEventArgs e)
        {
            if (!msDown) return;
            int dx = e.X - oldX;
            int dy = e.Y - oldY;

if (dy > 0) _rotationx += 0.5f;
            else if (dy < 0) _rotationx -= 0.5f;
            if (dx > 0) _rotationy += 0.5f;
            else if (dx < 0) _rotationy -= 0.5f;
            SetupViewport();
            this.Invalidate();

}

private void on_MouseUp(object sender, MouseEventArgs e)
        {
            msDown = false;
            Cursor = Cursors.Default;
        }

private void on_MouseLeave(object sender, EventArgs e)
        {
            msDown = false;
        }

double pixrate = 0.05;//像素比
        /// <summary>
        /// GL绘制文字
        /// </summary>
        /// <param name="x">显示文字的x坐标</param>
        /// <param name="y">显示文字的y坐标</param>
        /// <param name="z">显示文字的z坐标</param>
        /// <param name="s">文字</param>
        private void drawText(double x, double y, double z, String s) {

Txture t = getTexture(s);
          //  GL.Enable(EnableCap.DepthTest);//必须开启深度测试
            //GL.Enable(EnableCap.AlphaTest);
          //  GL.AlphaFunc(AlphaFunction.Greater, 0.0f);
            GL.BindTexture(TextureTarget.Texture2D, t.txtureid);//绑定材质

float width = (float)(t.bmp.Width * pixrate);
            float height = (float)(t.bmp.Height * pixrate);

GL.Begin(BeginMode.Polygon);
            GL.TexCoord2(0.0f, 0.0f);
            GL.Vertex3(x, y, z);//左上
            GL.TexCoord2(1.0f, 0.0f);
            GL.Vertex3(x+width, y, z);//右上
            GL.TexCoord2(1.0f, 1.0f);
            GL.Vertex3(x+width,y-height, z);//右下
            GL.TexCoord2(0.0f, 1.0f);
            GL.Vertex3(x, y-height,z);//左下
            GL.End();

// GL.DrawPixels(t.bmp.Width, t.bmp.Height, GlPixelFormat.Bgra, PixelType.UnsignedByte,t.pix);

}

/// <summary>
        /// 获取文字材质
        /// </summary>
        /// <param name="s">文字</param>
        /// <returns>材质对象</returns>
        private Txture getTxture(String s) {
            if (fts.ContainsKey(s)) return fts[s];

Txture t = new Txture(s,FontSize,TitleColor);
            fts.Add(s, t);

return t;

}

/// <summary>
        /// 创建文字材质,如果有,用现成的,没有就重新绘制
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        private Txture getTexture(String s) {

if (fts.ContainsKey(s)) return fts[s];
            Txture t = new Txture(s, FontSize, TitleColor);
            t.txtureid = LoadTexture(t.bmp);
            fts.Add(s, t);   
            return t;

}
        /// <summary>
        /// 把bmp加载到gl材质
        /// </summary>
        /// <param name="bmp"></param>
        /// <returns></returns>
        int LoadTexture(Bitmap bmp)
        {

//new ShowPic().doShow(bmp);

int texture;
            GL.Enable(EnableCap.Texture2D);
            GL.GenTextures(1, out texture);
            GL.BindTexture(TextureTarget.Texture2D, texture);
            // GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);

BitmapData bitmapData1 = bmp.LockBits(
              new Rectangle(0, 0, bmp.Width, bmp.Height),
              ImageLockMode.ReadOnly,
              SysPixelFormat.Format32bppArgb
          );

GL.TexImage2D(
                TextureTarget.Texture2D,
                0,
                PixelInternalFormat.Rgba,
                bitmapData1.Width,
                bitmapData1.Height,
                0,
                GlPixelFormat.Bgra,
                PixelType.UnsignedByte,
                bitmapData1.Scan0
            );

bmp.UnlockBits(bitmapData1);

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

// GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
            // GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);

return texture;
        }

}

C#开发的3D图表控件,适用于winform项目相关推荐

  1. 用于金融科技应用开发的高性能图表控件

    金钱使世界运转,因此,跟踪和控制金融交易和信息是当今互联世界中任何企业.金融机构或个人最重要的活动之一.为此,你需要金融技术应用. 根据不同的目的,金融技术应用可能有不同的功能,使其符合用户需要.例如 ...

  2. (转)基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts

    http://www.cnblogs.com/wuhuacong/p/3736564.html 在我们做各种应用的时候,我们可能都会使用到图表统计,以前接触过一些不同的图表控件,在无意中发现了图表控件 ...

  3. C# winform使用scottplot图表控件快速入门设置XY轴缩放

    Hello大家好我是开箱测评小汪,在C#项目开发中使用图表控件,有时候我们希望放大或缩小图表控件来看数据细节和整体数据情况.所有本期课程将带介绍Scottplot图表控件如何来实现这个功能. 本期课程 ...

  4. PAZU 是4Fang 为配合“四方在线”软件于2004年开发的WEB打印控件,适用于各种WEB软件项目的打印。...

    PAZU 是4Fang 为配合"四方在线"软件于2004年开发的WEB打印控件,适用于各种WEB软件项目的打印. PAZU是客户端软件,使用于IE作为客户端的所有应用,与服务器端开 ...

  5. android图表控件 坐标,android-charts 基于Java和Android开发的图形图表控件 | 李大仁博客...

    王晓龙 April 8th, 2014 at 09:44 | #1 我再github上看到了你写的控件,给了我很大启发,我现在在做K线图一类的图表,正好用到了您开发的这款控件,但是有些地方使用的不太舒 ...

  6. 提供多种2D和3D图表类型以及组合图、仪表的图表控件CHARTING

    .netCHARTING是一款功能强大的图表控件,利用.NET framework和GDI+为工作于ASP.NET和Winform的C#和VB.NET软件开发人 员提供可托管的图表解决方案,提供了多种 ...

  7. android开发原点表框架,Android图表控件MPAndroidChart——LineChart实现 XY轴、原点线的直尺刻度样式...

    接上文: Android图表控件MPAndroidChart--曲线图LineChart的使用(多条曲线) 其他相关文章: Android图表控件MPAndroidChart的简单介绍(MPAndro ...

  8. 三款ActiveX图表控件对比评测 TeeChart VS ProEssentials…

    概述:本文分别对几款优秀的ActiveX图表控件:TeeChart Pro ActiveX.ProEssentials.ChartDirector作了优势分析,对比评测,希望对用户的图表选型有所帮助. ...

  9. Arction图表控件LightningChart振动分析可以检测什么?

    LightningChart是优化了GPU加速,硬件性能的制图组件,用于实时呈现超过10亿个数据点的海量数据.同时LightningChart是为了处理实时数据采集和处理而开发的,可有效利用CPU和内 ...

  10. 高性能图表控件LightningChart有关闪电图问题解答

    LightningChart.NET完全由GPU加速,并且性能经过优化,可用于实时显示海量数据-超过10亿个数据点.LightningChart包括广泛的2D,高级3D,Polar,Smith,3D饼 ...

最新文章

  1. 创建Swap交换空间
  2. 所有计算机都可以安装win7,几种安装win7系统的方法介绍
  3. boost::container实现双端队列选项的测试程序
  4. Android 图片选择器、图片剪切,文件选择器
  5. java日志级别的作用_Java系统日志级别对性能的影响性
  6. 计算机基础知识ip地址,计算机基础知识练习题
  7. python字典程序题_急!一道关于python字典的编程题!求思路!
  8. 用火车头采集小游戏网站教程[转载]
  9. koa源码分析-generator和yield分析
  10. SynchronousQueueE简介
  11. PAT 乙级 1048. 数字加密(20) Java版
  12. 萨维奇(Savitch)定理证明
  13. 《Java核心技术 卷1》
  14. Linux中vim的安装和使用
  15. android带投屏播放器,投屏播放器app下载
  16. 图片放大像素模糊怎么变清晰?
  17. 二元二次方程 c语言,C语言求二元二次方程组的解 我要代码 谢谢大家了
  18. STM32CubeIDE 复制工程
  19. 浅谈Java类加载:ClassLoader
  20. 软件测试行情前景,你可以做测试多久?到底能干到多少岁?

热门文章

  1. Python爬虫简单入门
  2. java集成Cplex:Cplex下载、IDEA环境搭建、docker部署
  3. String类型转换成json对象
  4. Android UUID.randomUUID()生成唯一数,1到100随机数
  5. E-Prime1.1安装教程及软件下载
  6. servlet+jsp项目改成springboot+jsp+maven
  7. ASCII码对照表 (0-255)
  8. PHP聚合直播盒子网站源码聚合全网直播
  9. 51单片机c语言100例百度云,51单片机C语言编程100例.docx
  10. Vulkan Nvidia 驱动 VK_ERROR_LAYER_NOT_PRESENT