1.引言

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

2.相关资料

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

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

3.ZedGraph节点Symbol问题

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

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

4.ZedGraph上下文菜单问题

在开发过程中,如果需要实现图表的上下文菜单,需要将ZedGraphControl的IsShowContextMenu属性设置为true才可显示,当然你也可以实现自己的自定义上下文菜单。这里需要注意的是,有些你下载的dll可能上下菜单是中文,而有些却是英文并且有可能"缺损"了那么几项,造成这个问题的主要是由于ZedGraph开源,网友很有可能是改完源码之后上传的,这就造成你Down下来的dll不尽相同。现在的问题是:怎么修改ZedGraph的上下文菜单,英文<->中文?隐藏某一选项?代码如下:
private void zGCDateChart_ContextMenuBuilder(ZedGraphControl sender, ContextMenuStrip menuStrip, Point mousePt, ZedGraphControl.ContextMenuObjectState objState)
{
try
{
//每次循环只能遍历一个键
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "copy")
{
item.Text = "复制";
item.Visible = true;
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "save_as")
{
item.Text = "另存图表";
item.Visible = true;
break;
}
} foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "show_val")
{
item.Text = "显示XY值";
item.Visible = true;
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "unzoom")
{
item.Text = "上一视图";
item.Visible = true;
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "undo_all")
{
item.Text = "还原缩放/移动";
item.Visible = true;
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "print")
{
menuStrip.Items.Remove(item);
item.Visible = false; //不显示
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "page_setup")
{
menuStrip.Items.Remove(item);//移除菜单项
item.Visible = false; //不显示
break;
}
}
foreach (ToolStripMenuItem item in menuStrip.Items)
{
if ((string)item.Tag == "set_default")
{
menuStrip.Items.Remove(item);//移除菜单项
item.Visible = false; //不显示
break;
}
} }
catch (System.Exception ex)
{
MessageBox.Show("初始化右键菜单错误" + ex.ToString());
}
}

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

5.添加文本问题

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

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

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

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

当你需要鼠标悬停在图表节点上提示节点的位置值,或者其他的一些内容时,你需要首先将ZedGraphControl的IsShowPointValues属性设置为true,然后关联事件PointValueEvent。
private string zGCDateChart_PointValueEvent(ZedGraphControl sender, GraphPane pane, CurveItem curve, int iPt)
{
PointPair pt = curve[iPt];
return "时间:" + pt.X.ToString() + " \n潮位:" + pt.Y.ToString();
}
如果这样就把问题解决了,那固然好,可我在做的过程中发现的一个问题,或者说是不尽如人意的地方:当鼠标悬停在节点上时,内容是显示出来了,没有问题,但是悬停提示框就是一直在闪烁,这个问题困扰了我很久,解决方法如下:

找来ZedGraph的源码,在ZedGraphControl.Event.cs中找到了下面这块代码:
private Point HandlePointValues( Point mousePt )
{
int iPt;
GraphPane pane; object nearestObj;
using ( Graphics g = this.CreateGraphics() )
{
if ( _masterPane.FindNearestPaneObject( mousePt,g, out pane, out nearestObj, out iPt ) )
{
if ( nearestObj is CurveItem && iPt >= 0 )
{
//................ //code to show the tooltip
}
else
this.pointToolTip.Active = false;
}
else
this.pointToolTip.Active = false;
}
return mousePt;
}
分析后发现,原来这段代码不论鼠标移动的范围大小,甚至乎不论鼠标是否移动,都要刷新一次Tooltip,所以才会导致CPU爆满。

解决方案并不复杂,包括三个步骤:
1、创建私有变量lastObj用以保存上次为之显示Tooltip的对象;
2、显示Tooltip前判断对象是否就是lastObj;
3、将新获得的对象保存到lastObj中。
修改后的代码结构如下:
private object lastObj;
private Point HandlePointValues( Point mousePt )
{
int iPt;
GraphPane pane; object nearestObj;
using ( Graphics g = this.CreateGraphics() )
{
if ( _masterPane.FindNearestPaneObject( mousePtg, out pane, out nearestObj, out iPt ) )
{
if (nearestObj is CurveItem && iPt >= 0 && !object.Equals(nearestObj, lastObj))
{
//................ //code to show the tooltip
}
//else
// this.pointToolTip.Active = false;
}
else
this.pointToolTip.Active = false;
}
lastObj = nearestObj;
return mousePt;
}

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

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

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

myPane_obs.XAxis.Scale.Min = 0;
myPane_obs.XAxis.Scale.Max = 24;
myPane_obs.XAxis.Scale.MajorStep = 4;
myPane_obs.XAxis.Scale.MinorStep = 1;
/// <summary>
/// X轴刻度重定义
/// </summary>
/// <param name="pane"></param>
/// <param name="axis"></param>
/// <param name="val"></param>
/// <param name="index"></param>
/// <returns></returns>
string XAxis_ScaleFormatEvent(GraphPane pane, Axis axis, double val, int index)
{
if (val >= 0 && val < 24)
return val.ToString();
else if (val >= 24)
return (val % 24).ToString();
else
return (24-Math.Abs(val % 24)).ToString();
}

关于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. ftp通用类1

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.N ...

  2. In-Place upgrade to Team Foundation Server (TFS) 2015 from TFS 2013Team Foundation Server TFS TFS 2015 TFS upgrade TFS with Sharepoint

    This upgrade document gives detailed step by step procedure for the In-Place upgrade from TFS 2013 t ...

  3. ASP.NET Web API实践系列02,在MVC4下的一个实例, 包含EF Code First,依赖注入, Bootstrap等

    本篇体验在MVC4下,实现一个对Book信息的管理,包括增删查等,用到了EF Code First, 使用Unity进行依赖注入,前端使用Bootstrap美化.先上最终效果: →创建一个MVC4项目 ...

  4. 线程中sleep方法和wait方法有什么区别?(转)

    本文转自https://www.cnblogs.com/linkstar/p/6043846.html 线程中sleep方法和wait方法有什么区别?   如果你没有接触过java的多线程,那么多对于 ...

  5. [DevExpress使用随笔]之预览repx报表(转)

    来自:http://blog.csdn.net/HXC_HUANG/article/details/78181962?locationNum=9&fps=1 在[DevExpress使用随笔] ...

  6. WordPress主题开发:实现分页功能

    注意的是这个受后台这里的文章篇数设置所影响~ 一.使用内置方法 (WordPress 4.1以前无效) the_posts_pagination 输出分页式导航,用法: <?php the_po ...

  7. HTML5学习笔记简明版(8):新增的全局属性

    contenteditable属性 不论什么元素使用contenteditable属性的话,代表该元素是一个可编辑的区域. 用户能够改变元素的内容以及操作标记.比如: <p contentedi ...

  8. nodeJS 相关开源项目

    摘要:NodeJS是一个服务器端JavaScript解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处理数万条同时连接到一个(只有一个)物理机的连接代码 ...

  9. 能添加图标的label

    能添加图标的label 效果 源码 https://github.com/YouXianMing/UI-Component-Collection 中的 IconEdgeInsetsLabel // / ...

  10. win7凭据管理、win7多用户远程登录、主机头设置、nuget.org无法访问

    前言  最近遇到的几个问题,然后处理在此对处理方式进行记录一下. 1.服务器共享文件夹,在本机进行访问登录时,每次登录或者每次开机进入都要进行登录的权限认证,这样很麻烦. 2.服务器难免会有多用户同时 ...