优劣势
ZedGraph 相较同类工具的优势:
- 功能完备,bug 少
- 用户基数大,Bing 搜问题方便
劣势:
- 从 2012 后基本停止维护
- 官网没了,对新上手的小伙伴不友好
- 该问题可以通过浏览 ZedDemo.7z 中的示例项目得到解决
PS:虽然已停止维护快 10 年了,但还能被评为 14 个最好的 .NET 免费控件,希望能有更好的绘图库来替代 ZedGraph 的使命吧。
简介
ZedGraph 是一个强大的 .NET 图形绘制库。
The charting library for .NET
相关资源:
支持平台:
- .NET Framework
基本使用
从 作者写的介绍 中摘抄得来。
第一步:从控件库中拖一个 ZedGraphControl 到 Form 上。
第二步:通过代码初始化并绘制图形。
private void Form1_Load( object sender, EventArgs e )
{
// Setup the graph
CreateGraph( zedGraphControl1 );
}
// Build the Chart
private void CreateGraph( ZedGraphControl zgc )
{
// get a reference to the GraphPane
GraphPane myPane = zgc.GraphPane;
// Set the Titles
myPane.Title.Text = "My Test Graph\n(For CodeProject Sample)";
myPane.XAxis.Title.Text = "My X Axis";
myPane.YAxis.Title.Text = "My Y Axis";
// Make up some data arrays based on the Sine function
double x, y1, y2;
PointPairList list1 = new PointPairList();
PointPairList list2 = new PointPairList();
for ( int i = 0; i < 36; i++ )
{
x = (double)i + 5;
y1 = 1.5 + Math.Sin( (double)i * 0.2 );
y2 = 3.0 * ( 1.5 + Math.Sin( (double)i * 0.2 ) );
list1.Add( x, y1 );
list2.Add( x, y2 );
}
// Generate a red curve with diamond
// symbols, and "Porsche" in the legend
LineItem myCurve = myPane.AddCurve( "Porsche",
list1, Color.Red, SymbolType.Diamond );
// Generate a blue curve with circle
// symbols, and "Piper" in the legend
LineItem myCurve2 = myPane.AddCurve( "Piper",
list2, Color.Blue, SymbolType.Circle );
// Tell ZedGraph to refigure the
// axes since the data have changed
zgc.AxisChange();
}
使用技巧
给柱状图加数值标识
方法一,使用自带的 CreateBarLabels:
BarItem.CreateBarLabels(myPane, false, "f0", "Arial", 28, Color.CadetBlue, false, false, false);
注:如果要清理这些 label,需要使用 zgc.GraphPane.GraphObjList.Clear();
。
方法二,手动绘制:
var myPane = zgc.GraphPane;
var fontSpec = myPane.Legend.FontSpec.Clone();
fontSpec.Family = "Microsoft YaHei";
fontSpec.Size = 22;
fontSpec.Border.IsVisible = false;
fontSpec.Fill.IsVisible = false;
var text = new TextObj("2.33", 0.55, 2.33)
{
Location = { CoordinateFrame = CoordType.AxisXYScale, AlignH = AlignH.Left, AlignV = AlignV.Center },
FontSpec = fontSpec
};
myPane.GraphObjList.Add(text);
修改右键菜单
移除或禁用现有菜单项:
private void MyContextMenuBuilder(
ZedGraphControl control, ContextMenuStrip menuStrip,
Point mousePt,ZedGraphControl.ContextMenuObjectState objState)
{
foreach( ToolStripMenuItem item in menuStrip.Items )
{
if ( (string) item.Tag == "set_default" )
{
// remove the menu item
menuStrip.Items.Remove( item );
// or, just disable the item with this
//item.Enabled = false;
break;
}
}
}
StringID | Menu Item |
---|---|
copy | Copy |
page_setup | Page Setup… |
Print… | |
save_as | Save Image As… |
set_default | Set Scale to Default |
show_val | Show Point Values |
undo_all | Undo All Zoom/Pan |
unzoom | Un-Zoom, Un-Pan, Undo Scroll |
添加新的右键菜单项:
private void MyContextMenuBuilder(
ZedGraphControl control, ContextMenuStrip menuStrip,
Point mousePt,ZedGraphControl.ContextMenuObjectState objState )
{
// create a new menu item
ToolStripMenuItem item = new ToolStripMenuItem();
// This is the user-defined Tag so you can find this menu item later if necessary
item.Name = "my_special_tag";
item.Tag = "my_special_tag";
// This is the text that will show up in the menu
item.Text = "Do Something Special";
// Add a handler that will respond when that menu item is selected
item.Click += new System.EventHandler( DoSomethingSpecial );
// Add the menu item to the menu
menuStrip.Items.Add( item );
}
protected void DoSomethingSpecial( object sender, System.EventArgs e )
{
// do something here. For example, remove all curves from the graph
zedGraphControl1.GraphPane.CurveList.Clear();
zedGraphControl1.Refresh();
}
示例 - 右键菜单中增加导出为 CSV 功能
参考:ZedGraph C# Graph Data Export to CSV Using a Custom Context Menu
private void InitializeZedGraph(ZedGraphControl zgc)
{
...
zgc.ContextMenuBuilder += Zgc_ContextMenuBuilder;
}
private void Zgc_ContextMenuBuilder(ZedGraphControl sender, ContextMenuStrip menuStrip, Point mousePt, ZedGraphControl.ContextMenuObjectState objState)
{
var item = new ToolStripMenuItem
{
Name = "Export Data as CSV",
Tag = "export_data_csv",
Text = "导出波形数据为 CSV"
};
item.Click += ShowSaveAsForExportCSV;
menuStrip.Items.Insert(2, item);
}
private StreamWriter _csvWriter;
private void ShowSaveAsForExportCSV(object sender, EventArgs e)
{
try
{
var dialogExportCSV = new SaveFileDialog
{
Filter = @"CSV Files|*.csv",
Title = @"Export Profile",
FileName = ZgcMain.GraphPane.Title.Text
};
if (dialogExportCSV.ShowDialog() != DialogResult.OK) return;
_csvWriter = new StreamWriter(dialogExportCSV.FileName);
WriteCSVToStream();
_csvWriter.Close();
MessageBox.Show("CSV 波形文件已保存", "波形导出", MessageBoxButtons.OK);
}
catch (Exception ex)
{
_csvWriter.Close();
MessageBox.Show(ex.ToString());
}
}
private void WriteCSVToStream()
{
var xAxisHeader = ZgcMain.GraphPane.XAxis.Title.Text;
var yAxisHeader = ZgcMain.GraphPane.YAxis.Title.Text;
_csvWriter.Write(xAxisHeader + "," + yAxisHeader + "\n");
for (var i = 0; i < _currentPointList.Count; i++)
{
_csvWriter.Write(_currentPointList[i].X + "," + _currentPointList[i].Y + "\n");
}
}
获取当前点击的 Pane
当一个 Zed 上面有多个 Pane 时,可以用FinNearestPaneObject方法获取点击的 Pane。
当然该方法也可以用作获取其它 Object。
using (var g = zed.CreateGraphics())
{
int iPt;
GraphPane pane; object nearestObj;
zed.MasterPane.FindNearestPaneObject(e.Location, g, out pane,out nearestObj,out iPt);
pane.Border=new Border(Color.FromArgb(0,122,204),2);
}
在一行并排显式两个 Pane
首先你要有两个 Pane,再通过SetLayout设置显式模式为SingleRow即可。
切换显式模式还可以得到 211、112、Square 等效果。
var zed = ZedGraphMain;
var master = zed.MasterPane;
var leftPane = master.PaneList[0];
var rightPane = leftPane.Clone();
rightPane.CurveList.Clear();
master.Add(rightPane);
// Tell ZedGraph to auto layout all the panes
using (var g = zed.CreateGraphics())
{
master.SetLayout(g, PaneLayout.SingleRow);
master.AxisChange(g);
}
zed.AxisChange();
zed.Refresh();