HBarChart






4.97/5 (87投票s)
简单的 C# 控件,
目录
引言
HBarChart
是一个简单的 C# 控件。它可以帮助您快速开发自己的图表并轻松打印。
背景
不久前,我创建了一个 MFC 条形图控件并将其发布在 Code Project 上。在那篇文章的讨论中,我承诺会创建一个相同控件的 C# 版本,现在它来了。唯一的问题是,代码可能看起来更像 C++ 而不是 C#。我希望您能原谅我;这是我写过的少数几个 C# 代码之一。
请享受,并请用您认为可以提高此代码质量的宝贵笔记、错误报告、想法等来帮助我。
Using the Code
创建图表
要使用此控件,首先我们需要将其添加到项目中。您可以使用以下两种方法之一来添加它。
向项目添加引用
- 将本文附件中的 CPBarChart 源文件夹中的 BarChart 文件夹及其所有内容复制到您的解决方案文件夹中。
- 右键单击 Visual Studio 的解决方案资源管理器,然后选择:添加现有项目,并选择 BarChart 文件夹。
- 选择您要添加图表的项目,并在解决方案资源管理器中右键单击它。
- 选择添加引用,选择打开的对话框的项目选项卡,然后选择
BarChart
,然后重新编译解决方案。 - 在 Visual Studio 工具箱窗口中,您应该能看到一个名为
[您的项目名称] 组件
的新组,其中可见HBarChart
项。 - 将
HBarChart
组件拖到任何 Windows 窗体控件上。
添加 DLL
- 在 Visual Studio 工具箱中,右键单击某个类别(如常规)的顶部,然后选择选择项。
- 在 .NET Framework 组件选项卡中,找到浏览按钮,然后使用浏览窗口选择 BarChart.dll。
- 现在,将添加到工具箱中的新条形图控件拖到窗体上。
您也可以将 DLL 拖到 Visual Studio 工具箱中。
图表背景
图表的背景可以是线性/径向渐变或纯色。渐变使用两种颜色来绘制图表的背景。
要设置背景模式,请使用 Background.PaintingMode
。它是 enum
类型,可以设置为 SolidColor
、LinearGradient
或 RadialGradient
。
图表背景还需要定义颜色。颜色取决于当前选择的模式。如果选择了渐变,则需要设置两种颜色:GradientColor1
和 GradientColor2
。如果选择纯色作为背景,则应指定 SolidColor
。背景默认模式为径向渐变,默认颜色为:Argb(255, 140, 210, 245)
和 Argb(255, 0, 30, 90)
,可以在 CBackgroundProperty()
构造函数中修改。要在代码中更改模式或颜色,请使用图表的 Background
属性。
barChart.Background.PaintingMode = CBackgroundProperty.PaintingMode.LinearGradient;
barChart.Background.GradientColor1 = Color.Aqua;
图表描述
描述是图表最底部的描述性文本行。在截图中,它是:“Hello C# Chart
”。它的作用是描述图表显示的内容。您可以修改其 Text
、Color
、Font
和 Visibility
。
barChart.Description.Font = fontDialog.Font;
barChart.Description.Text = "Annual coffee usage of c# team.";
barChart.Description.Color = Color.White;
barChart.Description.Visible = true;
标签和值
为了使图表更灵活,我使其能够修改每个条形底部的标签以及每个条形顶部的值文本。请注意,虽然可以修改标签和值,但它们只能作为一个整体进行修改,并且不可能为每个条形单独进行修改。
barChart.Label.Font = fontDialog.Font;
barChart.Label.Color = Color.White;
barChart.Label.Visible = true;
barChart.Values.Font = fontDialog.Font;
barChart.Values.Color = Color.White;
barChart.Values.Visible = true;
除了每个条形的值之外,还可以使用百分比。在我为特定目的创建的 MFC 版本图表中,我需要显示每个值相对于最大值的百分比。它将最大值视为 100%。在此专门为 CodeProject 成员创建的图表中,我采用了更实用、可能更流行的方法,即使用值相对于总值的百分比,这意味着只有一个独立的条形图将显示 100%,通过添加第二个条形图,每个百分比显示条形图占总值的份额。在这种情况下,具有相同值的两个条形图将各占总值的 50%。
barChart.Values.Mode = CValueProperty.ValueMode.Percent;
Border
HBarchart
可以在图表周围显示一个实心边框。其大小和颜色可以自定义。
barChart.Border.Color = colorDialog.Color; barChart.Border.Width = 5;
阴影
图表周围可以显示两种类型的阴影:内部
和外部
。内部阴影从图表边界矩形的内部边缘开始,向图表中心移动;外部阴影从边界矩形的外部边缘开始,向外移动。您可以将图表设置为绘制其中任何一种、两种或不绘制。
// Just Inner shadow, could be: Outer, Both, None
barChart.Shadow.Mode = CShadowProperty.Modes.Inner;
您还可以设置阴影
的大小
barChart.Shadow.WidthInner = 2;
最后是阴影
的颜色
barChart.Shadow.ColorInner = Color.Black;
请注意,阴影
颜色的透明度(alpha)对于获得更强(更深)或更浅的阴影很重要。
大小调整
图表的最后一次自定义是关于大小调整。图表有两种大小调整模式。Normal
模式对任何绘图都没有限制。例如,您可以更改字体,使部分文本超出图表控件,从而使其不可见。Normal
大小调整模式以及字体、颜色、文本、BarSize
和 BarGapSize
(条形之间的空白)使得创建完全自定义的图表成为可能。
另一种可能的模式是 AutoScale
,在这种情况下,控件决定大小。它只是尝试将图表适应其边界矩形。将使用您想要的颜色和字体,但字体和条形的大小是自动计算的。
barChart.SizingMode = HBarChart.BarSizingMode.AutoScale;
将图表自定义到您满意后,是时候通过添加新值、检索或删除它们来使用它了。
添加值(条形)
要向图表添加新值,请使用 Add
方法,如下所示:
barChart.Add(
1600.356, // A value to be shown at the top of the bar
"Jan", // A label under the bar chart
Color.Aqua); // Color of the bar
请注意,控件使用此颜色(Add
的最后一个参数)为条形创建渐变,在我看来,这更精致。渐变的深色比浅色暗 100 个单位,因此要获得最佳效果,请使用 (R, G, B) 都大于 100 的颜色。例如,Color.FromArgb(255, 150, 160, 255)
。
您也可以直接使用 Items
属性。它是一个 IList
集合。
barChart.Items.Add( new HBarItem(
1600.356, // A value to be shown at the top of the bar
"Jan", // A label under the bar chart
Color.Aqua)); // Color of the bar
移除值
您可以使用 RemoveAt
从控件中删除特定基于零索引的条形。
barChart.RemoveAt(0); // Removing first value
或者再次使用 Items
集合。
barChart.Items.RemoveAt(0); // Removing first value
修改值
调用 ModifyAt
来更改条形的值。
barChart.ModifyAt(0, 6250); // Changing value of first bar
或直接更改值。
barChart.Items[0].Value = 6250.1148; // Changing value of first bar
插入条形
调用 InsertAt
或 Items.Insert
以在指定的零基索引处插入条形。
barChart.InsertAt(
3, // Where bar will be inserted
// (zero based index of this new bar)
2650.8265, // Value of the new bar
NewLabel, // Label of the new bar
Color.Red); // Color of the new bar
检索值
要获取每个条形的值或任何其他信息,您可以调用 GetAt
方法。该方法有两个定义:一个返回对应于条形(当给定其基于 0
的索引时)的 double
值;另一个重载函数返回一个 HBarItem
对象。HBarItem
是一个类,它保存了有关条形的所有数据,包括其值、颜色、标签、图表内的边界矩形等等。
HBarItem bar;
if (barChart.GetAt(0, out bar))
{
// Now we have all bar data
double dValue = bar.Value;
}
事件
除了用户控件的正常事件集之外,HBarChart
还支持四个其他事件:BarClicked
、BarDoubleClicked
、BarMouseEnter
和 BarMouseLeave
。要处理这些事件,您可以遵循以下两种方法之一:
在 Visual Designer 中
右键单击窗体上的图表控件,然后选择属性。在属性窗口的顶部,选择事件按钮。然后转到条形图部分,您应该会看到它们。双击您要处理的任何事件的标题。
手动处理事件
这是分两步完成的;首先注册事件
barChart.BarClicked += new BarChart.HBarChart.OnBarEvent(this.On_BarChart_BarClicked);
其次,添加事件处理函数
private void On_BarChart_BarClicked(object sender, BarChart.BarEventArgs e)
{
MessageBox.Show(String.Format("bar #{0} Clicked!", e.BarIndex);
}
打印
使用 Print
方法打印图表。
barChart.Print(true, "PrintDocumentName");
Print
接收两个参数。第一个参数指示图表是应适应纸张还是应以与显示相同的比例打印。它的行为类似于图表的大小调整模式。第二个参数是打印文档的名称。在我的待办事项列表中,打印标记为未完成。在 BarChart
命名空间中有一个名为 CPrinter
的类,它与 HBarChart
类的 Print
方法一起负责打印。如果您需要更好的打印支持,可以修改它们。
DataSource
图表现在对 Datasource
有最小限度的支持。它可以连接到数据源。它读取数据并响应更改,但目前它是一种单向连接,修改后的图表数据不会反映到数据源。您可以将其视为只读的 DataSource
支持。
图表如何使用 DataSource
目前,当您设置图表数据源时,它期望您提供行和列的组合,其中每行显示一个图表。对于每一列,都会有一个条形图,其值取自该行。本文的演示应用程序在窗体上有一个 DataGridView
控件,它展示了图表如何精确地处理数据。
扩展图表数据源功能
我以一种可以创建您自己的读取和显示数据方式的方式设计了 DataSource
。HBarChart
有一个数据连接类,它连接到数据源并自动检索数据行和列。为了在图表中显示这些行和列,它使用一个实现了 IDataConnectionEvents
的类。如果您想以自己的方式解释数据行和列,只需创建一个实现该接口的类
public class CreateChartMyWay : IDataConnectionEvents
然后告诉图表使用你的类
this.barChart.DataSourceManager.DataEventHandler = new CreateChartMyWay();
这样做,图表将处理数据并在需要时调用您在类中实现的函数。它调用接口中定义的函数。通过实现 IDataConnectionEvents
,您的类将具有这些函数
void DataSource_ItemUpdated(int nRowIndex, int nColIndex);
void DataSource_ItemDeleted(int nItemIndex);
void DataSource_ItemAdded(int nItemIndex);
void DataSource_SelectedRowChanged(int nPosition);
void DataSource_ResetItems();
void DataSource_DataBoundCompleted();
void SetData(object chart, object dataConnection);
当底层数据发生变化时,将调用以 DataSource_
开头的函数。
DataSource_ItemUpdated | 在连接类收到 ListChangedType.ItemChanged 后发送,表示行中的更改。 |
DataSource_ItemDeleted | 在连接类收到 ListChangedType.ItemDeleted 后发送,表示删除了一行。 |
DataSource_ItemAdded | 在连接类收到 ListChangedType.ItemAdded 后发送,表示添加了新行。 |
DataSource_ResetItems | 在连接类收到以下任何 ListChangedTypes 后发送:Reset (多行更改)、ItemMoved (某些行索引更改)、PropertyDescriptorAdded (架构更改,可能是新列)、PropertyDescriptorDeleted (架构更改,可能是列删除)、PropertyDescriptorChanged (架构更改,列更改)。 |
DataSource_SelectedRowChanged | 将在连接类收到 PositionChanged 事件后发送。这意味着新行是 DataSource 的当前行。 |
DataSource_DataBoundCompleted | 当与 DataSource 建立连接并且行和列填充了 DataSource 数据时,将调用此方法。 |
请注意,当调用 DataSource_ItemDeleted
时,数据实际上并未从连接类的行和列中删除,这样您就可以轻松找到要删除的数据。但是,在调用之后,它将被删除。
最后一条重要的注意:SetData
函数在您的类实例化后被调用,并将为您提供图表(类型为 HBarChart
)和连接(类型为 CDataConnection
)类的引用。图表引用可用于与条形图或其他图表 GUI 相关的东西进行交互,连接则用于处理行和列。