C2DPushGraph: 推送图控件






4.74/5 (35投票s)
一个类似于微软任务管理器中图表控件的推进图表控件。
引言
你们中的一些人可能已经意识到我之前通过CodeProject编写并发布了一个类似的控件。尽管上一个控件是使用C++和MFC编写的,但一些读者可能会想知道我为什么要在不涉足未知领域的情况下重新创建相同的控件。但事实是:我确实在涉足新的领域,这不仅仅是一个简单的重新创建。
我以前从未涉足C#。因此,我没有急于求成,开始一个对我来说完全陌生的雄心勃勃的项目,而是决定坚持我熟悉且感到舒适的事情:将我的C2DPushGraph控件移植到C#。在移植控件并发现C#在思想上与C++并没有太大不同之后,我很快将重心转移到改进控件的功能集和整体设计,同时遵守通用的C#标准和规范。
话虽如此(或者说,打字来说),控件的基础保持不变。因此,我之前在CodeProject文章中写的介绍也适用于这里:
“在过去的编程经验中,我经常希望在图表上显示和监控某个操作的速率或性能。无论是写入操作的速率还是每秒提取的内容结果数量,我总是觉得类似于Windows XP任务管理器(CTRL-Alt-Delete)性能和网络选项卡中的图表会很好地完成这项工作。在Google上快速搜索图表控件克隆,但没有找到相关结果后,我决定自己克隆它会是一个有趣且有益的经验。随着时间的推移,克隆控件被证明很容易,我决定添加更多功能,并使其在几乎所有方面都完全可定制。最后,当尘埃落定,我面对的是这篇文章围绕的控件。它的外观和行为都非常出色,尽管开发得很仓促。但是谁会在乎它的过去呢,让我们继续看看它实现起来有多容易……”
Using the Code
将控件添加到您的Windows窗体中
将C2PushGraph
控件添加到Windows窗体最简单的方法是,首先将其添加到Visual Studio的控件工具箱中。要实现此目的,您可以在Visual Studio 2005中按照以下步骤操作:
- 下载控件源代码
- 将控件的DLL解压到您的项目目录
- 打开您的项目
- 打开Visual Studio的“工具”菜单项
- 点击“选择工具箱项”
- 点击浏览按钮
- 找到C2PushGraph DLL,然后点击“打开”
执行这些步骤后,您就可以像拖放其他标准控件一样,从工具箱(在通用控件下)将C2DPushGraph
控件拖放到您的窗体中。要继续使用此方法学习本教程,请将控件拖放到您的窗体中;然后,将其命名为m_PushGraph
。
将控件添加到窗体的另一种方法涉及手动编码控件实例化及其在窗体中的创建。虽然很少使用,但如果您想“即时”添加控件,此方法会证明其有用。
第一步建议是在您的 _cs_文件范围内包含`CustomUIControls.Graphing`命名空间。这当然是通过在文件开头包含“`using CustomUIControls.Graphing`”来完成的。
接下来,您需要在您的窗体类中添加一个新的C2DPushGraph
变量(为了本教程的目的,我们将其命名为m_PushGraph
)。现在,在您希望创建控件的方法中,使用以下代码块之一作为指导,创建并将控件添加到您的窗体中:
// This example creates the control and automatically
// adds it to the form ('this') with the positioning
// referenced in the passed Rectangle:
m_PushGraph = new C2DPushGraph( this,
new Rectangle( Xpos, Ypos, GraphWidth, GraphHeight ));
// This example simple creates the control
// and automatically add it to the form ('this'):
m_PushGraph = new C2DPushGraph( this );
// This example uses the standard manual
// method for adding a control:
m_PushGraph = new C2DPushGraph();
this.Controls.Add( m_PushGraph );
设置图表范围
实例化C2DPushGraph
变量后,您需要设置图表的范围。范围由您打算推送到线的最高和最低幅度组成。一个例子是将CPU使用率图表的范围设置为0到100。
您通过将“`MinPeekMagnitude`”设置为您可能推送到图表中某条线的最小数值幅度来设置范围。反之,“`MaxPeekMagnitude`”指定最大潜在幅度。
注意:如果`AutoAdjustPeek`设置为`true`(默认情况下不是),建议您只提供一个“大致范围”。当此模式启用时,范围将自动调整以包含任何幅度。
添加新线
现在我们的基本图表已经准备就绪,我们希望向其添加一条或多条新线。但在我们深入了解此方法的约定之前,了解线是如何识别的非常重要。
线可以通过数值ID(性能稍好)或名称(更方便)进行唯一标识。这种标识方式使我们能够随时获取线的引用,而无需跟踪线句柄。重要的是要注意,选择使用ID或在创建线后获取并存储线句柄是个人偏好问题(您甚至可以两者结合使用)。
要添加新行,我们调用控件方便命名的“`AddLine`”方法,该方法又创建并将行添加到我们的图表中,然后返回行句柄。“`AddLine`”需要两个参数:将来引用的所需数值ID或名称,以及行的初始颜色。如果行成功添加到图表,则返回行的“`C2DPushGraph.LineHandle`”引用。如果传入的数值ID或名称不唯一,则返回空值。
// This example uses a numerical ID for our line:
const int EXAMPLE_LINE = 47;
MyLineHandle = m_PushGraph.AddLine( EXAMPLE_LINE, Colors.Blue );
if (MyLineHandle == null)
{
// ... Line already exists.
}
// This example uses a name for our line:
MyLineHandle = m_PushGraph.AddLine( "My Example Line", Colors.Blue );
if (MyLineHandle == null)
{
// ... Line already exists.
}
将新幅度点推送到您的线上
将新点推送到我们新创建的线上绝非小事。首先要做的是调用控件的“`Push`”方法,并传入线的ID或名称,以及您想要绘制的幅度。如果您的图表包含多条线,您应该在继续之前对图表上显示的所有其他线执行相同的过程。此过程的示例如下:
const int EXAMPLE_LINE = 47; // Used in our last example
// Push a magnitude of 20 to our numerically identified line:
m_PushGraph.Push( EXAMPLE_LINE, 20 );
// Push a magnitude of 76 to our named line:
m_PushGraph.Push( "My Example Line", 76 );
// Update the graph (explained in next section):
m_PushGraph.UpdateGraph();
更新图表
在我们的图表基本建立,并且我们的第一组幅度愉快地等待着它们的视觉首次亮相之后,我们最后需要的步骤是更新并重绘我们的C2DPushGraph
控件。如果您回顾前面的代码示例,您可能会(并希望)注意到它引入了一个新的未解释的方法:“`UpdateGraph`”。
幸运的是,由于其简单性,`UpdateGraph`的书面解释可以很简短。它正如其名称所暗示的那样;它更新我们的图表控件,以便在渲染控件时(它也这样做)考虑任何新推送的幅度或线。理想情况下,您应该只在向图表中包含的每条线推送相等数量的幅度后才调用“`UpdateGraph`”;但这种方法不是必需的(请参阅“附加说明”)。
自定义图表的外观和行为
尽管我们的图表现在已集成到我们的应用程序中并且完全可用(假设您一直将本教程作为实现控件的一般指南),我们仍然有大量功能需要探索。所有这些功能都涉及调整美学和行为的属性。虽然更改它们纯属可选,但它们会为您的应用程序提供更大的深度和视觉效果。
为了让您对图表的一般组件有一个心理表征,请参考以下图片:

附加属性
AutoAdjustPeek
类型: `boolean`
获取或设置一个布尔值,指示图表是否自动调整其范围以包含推送到其线条的任何幅度(自动缩放)。
BackColor
类型: `Color`
获取或设置图表的背景颜色。
BackgroundImage
类型: `Image`
获取或设置用于图表的背景图像(会覆盖背景颜色)。
GridColor
类型: `Color`
获取或设置图表的网格颜色。
GridSize
类型: `ushort`
获取或设置图表网格中每个正方形的宽度/高度(以像素为单位)。
HighQuality
类型: `boolean`
获取或设置一个布尔值,指示图表是否以“高质量”模式(带抗锯齿)渲染。如果您打算使用条形图样式、粗细大于2的线条显示,或者最大性能至关重要,则建议将此属性设置为`false`。
LineInterval
类型: `ushort`
获取或设置每个显示幅度之间的像素数。
MaxLabel
类型: `String`
获取或设置要显示为图表“最大标签”的字符串。
MinLabel
类型: `String`
获取或设置要显示为图表“最小标签”的字符串。
ShowGrid
类型: `boolean`
获取或设置一个布尔值,指示是否显示图表的网格。
ShowLabels
类型: `boolean`
获取或设置一个布尔值,指示是否显示最小值和最大值标签。
TextColor
类型: `Color`
获取或设置图表中显示的标签的颜色。
自定义线条外观
可以通过使用线的句柄更改属性来修改单个线的外观。如果您没有保留每条线的句柄,可以通过调用“`GetLineHandle`”并传入每条后续线的数字ID或名称作为唯一参数来检索它们。一旦您有了线句柄,您就可以访问句柄的以下公共属性:
属性
Color
类型: `Color`
设置或获取线的当前颜色。
ShowAsBar
类型: `boolean`
获取或设置一个布尔值,指示该线的幅度是否以条形图样式显示。
Thickness
类型: `uint`
设置或获取线的像素厚度。注意:如果使用大于两像素的厚度,建议将控件的`HighQuality`属性设置为`false`,因为抗锯齿会产生瑕疵。
Visible
类型: `boolean`
获取或设置一个布尔值,指示线条是否可见。
其他说明
- 此图表控件不会以固定间隔自动更新;开发人员需要通过计时器或其他技术实现此功能。
- 要删除一条线,调用控件的“`RemoveLine`”方法,将线的数字ID或名称作为唯一参数。如果线成功删除,返回值为“`true`”。
- 要检查线条是否存在,请调用控件的“`LineExists`”方法,并将线条的数字ID或名称作为唯一参数。如果线条存在,返回值为“`true`”。
- 您可以通过调用线句柄的“`Clear`”方法来清除线的幅度。
- 建议如果使用一条或多条线,并且厚度大于两个像素,则禁用“高质量”模式,因为抗锯齿会导致瑕疵。
- 尽管不建议,但在更新图表之前,有可能不均匀地将幅度推送到线上(即:两条推到一条线,一条推到另一条线)。图表会自动补偿并无中断地显示线条。
- 这个类之所以命名为`C2DPushGraph`(使用匈牙利派生词)而不是`2DPushGraph`,是因为无法使用前导数字命名类。
联系作者
如果您对本控件有任何问题或意见,请随时发送电子邮件至skonen@gmail.com联系Stuart Konen。
也可以通过AOL的即时通讯工具联系Stuart Konen:屏幕名称“Griblik3”。
历史
- 2006年11月28日 - 开始着手
C2DPushGraph
。 - 2006年12月2日 - 将
C2DPushGraph
提交到The Code Project。 - 2008年1月14日 - 添加了针对锁定工作站可能出现的卡顿的修复。