1.引言

  1. 由于工作原因,需要对数据进行图表展示,.NET默认的控件库或者DotNetBar的控件库又不能满足需求。去网上找到了这个开源的ZedGraph绘制2D图表的程序集,之所以选择这个ZedGraph程序集,一来它能够满足业务需求,二来它网上相关资料很多,三来它是开源代码。本篇中主要是给大家介绍几个我在开发过程中遇到的一些稍微棘手的问题,或者说是在网上资源较少的问题。在面对这些问题时,对于刚刚接触这个*.dll的我来说还是花了一些时间的,故而总结成篇。

2.相关资料

1.C# WinForm开发系列 - ZedGraph 
2.ZedGraph使用经验 
3.ZedGraph属性\方法介绍

  1. 相信认真参研上面的几篇博文,尤其是第一个之后,你对ZedGraph的入门使用会了解许多。如果你想更多的了解ZedGraph,可以Down下源码,仔细研究。ZedGraph的相对来说还是比较简单的,虽然说界面不甚美观,但其功能还算完善,我是做GIS二次开发的,它的几个基本功能:图表漫游、放大、缩小、上一视图等与GIS软件不谋而合。

3.ZedGraph节点Symbol问题

  1. ZedGraph中有个枚举列举了节点的所有常见Symbol(如下),但是有些时候特殊问题特殊处理,我们需要用不同的symbol来表示节点,怎么办?
  1. public enum SymbolType
  2. {
  3. Square,
  4. Diamond,
  5. Triangle,
  6. Circle,
  7. XCross,
  8. Plus,
  9. Star,
  10. TriangleDown,
  11. HDash,
  12. VDash,
  13. UserDefined,//用户自定义
  14. Default,
  15. None
  16. }

参考如下Demo:ZedGraph自定义图标

4.ZedGraph上下文菜单问题

  1. 在开发过程中,如果需要实现图表的上下文菜单,需要将ZedGraphControlIsShowContextMenu属性设置为true才可显示,当然你也可以实现自己的自定义上下文菜单。这里需要注意的是,有些你下载的dll可能上下菜单是中文,而有些却是英文并且有可能"缺损"了那么几项,造成这个问题的主要是由于ZedGraph开源,网友很有可能是改完源码之后上传的,这就造成你Down下来的dll不尽相同。现在的问题是:怎么修改ZedGraph的上下文菜单,英文<->中文?隐藏某一选项?代码如下:
  1. private void zGCDateChart_ContextMenuBuilder(ZedGraphControl sender, ContextMenuStrip menuStrip, Point mousePt, ZedGraphControl.ContextMenuObjectState objState)
  2. {
  3. try
  4. {
  5. //每次循环只能遍历一个键
  6. foreach (ToolStripMenuItem item in menuStrip.Items)
  7. {
  8. if ((string)item.Tag == "copy")
  9. {
  10. item.Text = "复制";
  11. item.Visible = true;
  12. break;
  13. }
  14. }
  15. foreach (ToolStripMenuItem item in menuStrip.Items)
  16. {
  17. if ((string)item.Tag == "save_as")
  18. {
  19. item.Text = "另存图表";
  20. item.Visible = true;
  21. break;
  22. }
  23. }
  24.  
  25. foreach (ToolStripMenuItem item in menuStrip.Items)
  26. {
  27. if ((string)item.Tag == "show_val")
  28. {
  29. item.Text = "显示XY值";
  30. item.Visible = true;
  31. break;
  32. }
  33. }
  34. foreach (ToolStripMenuItem item in menuStrip.Items)
  35. {
  36. if ((string)item.Tag == "unzoom")
  37. {
  38. item.Text = "上一视图";
  39. item.Visible = true;
  40. break;
  41. }
  42. }
  43. foreach (ToolStripMenuItem item in menuStrip.Items)
  44. {
  45. if ((string)item.Tag == "undo_all")
  46. {
  47. item.Text = "还原缩放/移动";
  48. item.Visible = true;
  49. break;
  50. }
  51. }
  52. foreach (ToolStripMenuItem item in menuStrip.Items)
  53. {
  54. if ((string)item.Tag == "print")
  55. {
  56. menuStrip.Items.Remove(item);
  57. item.Visible = false; //不显示
  58. break;
  59. }
  60. }
  61. foreach (ToolStripMenuItem item in menuStrip.Items)
  62. {
  63. if ((string)item.Tag == "page_setup")
  64. {
  65. menuStrip.Items.Remove(item);//移除菜单项
  66. item.Visible = false; //不显示
  67. break;
  68. }
  69. }
  70. foreach (ToolStripMenuItem item in menuStrip.Items)
  71. {
  72. if ((string)item.Tag == "set_default")
  73. {
  74. menuStrip.Items.Remove(item);//移除菜单项
  75. item.Visible = false; //不显示
  76. break;
  77. }
  78. }
  79.  
  80. }
  81. catch (System.Exception ex)
  82. {
  83. MessageBox.Show("初始化右键菜单错误" + ex.ToString());
  84. }
  85. }

  1. 这里需要注意几点:
  2. 1.事件为ContextMenuBuilder
  3. 2.每次foreach循环只能遍历一个键,因为你改变了枚举项。

5.添加文本问题

  1. 有些时候需要你在图表是添加一些文本,比如说:

  1. TextObj text_obs = new TextObj("缩放:鼠标滚轮\n移动:鼠标中键\n菜单:鼠标右键", 0.899f, 0.001f, CoordType.ChartFraction, AlignH.Center, AlignV.Bottom);
  2. text_obs.FontSpec.StringAlignment = StringAlignment.Center;
  3. text_obs.FontSpec.Fill = new Fill(Color.LightBlue);
  4. text_obs.FontSpec.FontColor = Color.Black;
  5. myPane_obs.GraphObjList.Add(text_obs);

  1. double xVal = Math.Round(list[i].X, 2);
  2. double yVal = Math.Round(list[i].Y, 2);
  3. string lab = string.Format("高潮位\r\n时间:{0}\r\n潮位:{1}", GetStrTime(xVal), yVal);
  4. TextObj text = new TextObj(lab, (float)xVal, (float)yVal * 1.01);//设置一个偏移量
  5. text.FontSpec.StringAlignment = StringAlignment.Near;
  6. text.Location.CoordinateFrame = CoordType.AxisXYScale;//很重要,设置参考系,或者说参考坐标
  7. text.FontSpec.Size = 10;
  8. text.FontSpec.FontColor = Color.Blue;
  9. text.Location.AlignH = AlignH.Center;
  10. text.Location.AlignV = AlignV.Bottom;
  11. text.FontSpec.Border.IsVisible = false;
  12. text.FontSpec.Angle = 0;
  13. text.FontSpec.Fill.IsVisible = false; myPane.GraphObjList.Add(text);

6.节点显示悬停提示和悬停提示闪烁问题

  1. 当你需要鼠标悬停在图表节点上提示节点的位置值,或者其他的一些内容时,你需要首先将ZedGraphControlIsShowPointValues属性设置为true,然后关联事件PointValueEvent
  1. private string zGCDateChart_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt)
  2. {
  3. PointPair pt = curve[iPt];
  4. return "时间:" + pt.X.ToString() + " \n潮位:" + pt.Y.ToString();
  5. }
  1. 如果这样就把问题解决了,那固然好,可我在做的过程中发现的一个问题,或者说是不尽如人意的地方:当鼠标悬停在节点上时,内容是显示出来了,没有问题,但是悬停提示框就是一直在闪烁,这个问题困扰了我很久,解决方法如下:
  2.  
  3. 找来ZedGraph的源码,在ZedGraphControl.Event.cs中找到了下面这块代码:
  1. private Point HandlePointValues( Point mousePt )
  2. {
  3. int iPt;
  4. GraphPane pane; object nearestObj;
  5. using ( Graphics g = this.CreateGraphics() )
  6. {
  7. if ( _masterPane.FindNearestPaneObject( mousePt,g, out pane, out nearestObj, out iPt ) )
  8. {
  9. if ( nearestObj is CurveItem && iPt >= 0 )
  10. {
  11. //................ //code to show the tooltip
  12. }
  13. else
  14. this.pointToolTip.Active = false;
  15. }
  16. else
  17. this.pointToolTip.Active = false;
  18. }
  19. return mousePt;
  20. }
  1. 分析后发现,原来这段代码不论鼠标移动的范围大小,甚至乎不论鼠标是否移动,都要刷新一次Tooltip,所以才会导致CPU爆满。
  2.  
  3. 解决方案并不复杂,包括三个步骤:
  4. 1、创建私有变量lastObj用以保存上次为之显示Tooltip的对象;
  5. 2、显示Tooltip前判断对象是否就是lastObj
  6. 3、将新获得的对象保存到lastObj中。
  7. 修改后的代码结构如下:
  1. private object lastObj;
  2. private Point HandlePointValues( Point mousePt )
  3. {
  4. int iPt;
  5. GraphPane pane; object nearestObj;
  6. using ( Graphics g = this.CreateGraphics() )
  7. {
  8. if ( _masterPane.FindNearestPaneObject( mousePtg, out pane, out nearestObj, out iPt ) )
  9. {
  10. if (nearestObj is CurveItem && iPt >= 0 && !object.Equals(nearestObj, lastObj))
  11. {
  12. //................ //code to show the tooltip
  13. }
  14. //else
  15. // this.pointToolTip.Active = false;
  16. }
  17. else
  18. this.pointToolTip.Active = false;
  19. }
  20. lastObj = nearestObj;
  21. return mousePt;
  22. }

7.X轴刻度重写(X轴刻度循环问题)

  1. 简单的XY轴刻度刻度形式可以通过设置以下属性来实现:
  1. myPane_obs.XAxis.Scale.Format = "";
  2. myPane_obs.YAxis.Scale.Format = "";

本次开发中碰到的是关于X轴循环问题,X轴是一根绝对的数轴,但是现实的数值代表时间,并且时间从0—23时不断重复循环,也就是说不会出现负数和大于23的整数,具体解决方案如下:

  1. myPane_obs.XAxis.Scale.Min = 0;
  2. myPane_obs.XAxis.Scale.Max = 24;
  3. myPane_obs.XAxis.Scale.MajorStep = 4;
  4. myPane_obs.XAxis.Scale.MinorStep = 1;
  1. /// <summary>
  2. /// X轴刻度重定义
  3. /// </summary>
  4. /// <param name="pane"></param>
  5. /// <param name="axis"></param>
  6. /// <param name="val"></param>
  7. /// <param name="index"></param>
  8. /// <returns></returns>
  9. string XAxis_ScaleFormatEvent(GraphPane pane, Axis axis, double val, int index)
  10. {
  11. if (val >= 0 && val < 24)
  12. return val.ToString();
  13. else if (val >= 24)
  14. return (val % 24).ToString();
  15. else
  16. return (24-Math.Abs(val % 24)).ToString();
  17. }

关于ZedGraph几个难点的更多相关文章

  1. C#图表控件ZedGraph使用

    最近从java转到C#下开发PC端的桌面程序,之前也尝试用java GUI写桌面程序,发现java写桌面程序还是诸多不便变,虽然最后也写出来了,但是决心还是另起平台,有了一定的java基础,来学习C# ...

  2. 【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇二:基于OneNote难点突破和批量识别

    篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html 篇二:基于OneNote难点突破和批量识别:http://www.cnblog ...

  3. Android开发重点难点1:RelativeLayout(相对布局)详解

    前言 啦啦啦~博主又推出了一个新的系列啦~ 之前的Android开发系列主要以完成实验的过程为主,经常会综合许多知识来写,所以难免会有知识点的交杂,给人一种混乱的感觉. 所以博主推出“重点难点”系列, ...

  4. Unity 难点目录

    1.mesh的任意切割.(难点) 2.扇形区域识别玩家.(解决) 3.NGUI横滑同时竖滑,或滑动同时点击冲突处理.(解决)

  5. 新浪微博SDK开发(2):上传图片的技术难点

    在微博模块中,有一个API是可以发表带一张图片的微博的,当然提交方式是POST.在封装的时候,可能会遇到一个难点——如何上传图片? 要POST微博的同时带有图片,POST的内容必须为MultiPart ...

  6. C# ZedGraph 控件各属性以及示例

    ZedGraph属性\方法介绍 Copy(Boolean) ->> 将图像复制到剪贴板.DoPageSetup()() ->> 打开打印设置对话框. DoPrint()() - ...

  7. .NET_RSA加密全接触(重、难点解析)

    .NET_RSA加密全接触(重.难点解析) .NET Framework提供了两个类供我们使用RSA算法,分别是:用于加密数据的RSACryptoServiceProvider和用于数字签名的DSAC ...

  8. js 函数闭包内部返回函数体调用方法难点解答

    今天在网上,看到一篇关于js函数难点的文章,js函数的一些难点.在那上面提了一下,关于js函数返回另一个函数的问题,并附上了一道面试题: var add = function(x){ var sum ...

  9. C# WinForm开发系列 - ZedGraph

    ZedGraph是用于创建任意数据的二维线型.条型.饼型图表的一个类库,也可以作为Windows窗体用户控件和Asp.Net网页控件.这个类库具有高度的适应性,几乎所有式样的图表都能够被创建.这个类库 ...

随机推荐

  1. LPC43xx State Configurable Timer : SCT

  2. High accuracy voltage regulator

    High accuracy voltage regulator Good morning everybody, I want to make a accurate voltage regulator ...

  3. Timer-triggered memory-to-memory DMA transfer demonstrator

    http://www.efton.sk/STM32/bt.c // Timer-triggered memory-to-memory DMA transfer demonstrator for STM ...

  4. ARM Memory Copy

    MODULE ARM_MEMORY PUBLIC ARM_MEMCPY PUBLIC ARM_MEMSET PUBLIC ARM_MEMSET8 PUBLIC ARM_MEMSET16 PUBLIC ...

  5. epoll的LT和ET使用EPOLLONESHOT

    epoll有两种触发的方式即LT(水平触发)和ET(边缘触发)两种,在前者,只要存在着事件就会不断的触发,直到处理完成,而后者只触发一次相同事件或者说只在从非触发到触发两个状态转换的时候儿才触发. 这 ...

  6. Java---16---多线程---死锁

    死锁: 概念: 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用.它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的 ...

  7. centos下从源码安装openssl 1.0.1g

    cd /usr/srcwget https://www.openssl.org/source/openssl-1.0.1g.tar.gz -O openssl-1.0.1g.tar.gz tar -z ...

  8. 理解 block

    开始:Block 简介 Block 是 iOS 4.0 和 Mac OSX 10.6 引入的一个新特性. Block 可以极大的简化代码. 他们可以帮助你减少代码, 减少对代理的依赖, 并且写出更加简 ...

  9. 【CentOS】centos如何修改你的主机名

    转载地址:https://www.linuxidc.com/Linux/2014-11/109238.htm ============================================= ...

  10. WordPress主题开发:评论框

    方法一:调出内置评论框: 文章开启评论: 页面开启评论:(注意:如果使用的是插件,点快速编辑是没有“允许评论”可勾选的) 在对应的地方,插入 <?php comments_template(); ...