65.9K
CodeProject 正在变化。 阅读更多。
Home

HBarChart

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (87投票s)

2008年6月21日

CPOL

10分钟阅读

viewsIcon

287442

downloadIcon

9147

简单的 C# 控件,可以帮助快速开发图表并轻松打印它们。

HBarChartControl_src

目录

引言

HBarChart 是一个简单的 C# 控件。它可以帮助您快速开发自己的图表并轻松打印。

背景

不久前,我创建了一个 MFC 条形图控件并将其发布在 Code Project 上。在那篇文章的讨论中,我承诺会创建一个相同控件的 C# 版本,现在它来了。唯一的问题是,代码可能看起来更像 C++ 而不是 C#。我希望您能原谅我;这是我写过的少数几个 C# 代码之一。

请享受,并请用您认为可以提高此代码质量的宝贵笔记、错误报告、想法等来帮助我。

Using the Code

创建图表

要使用此控件,首先我们需要将其添加到项目中。您可以使用以下两种方法之一来添加它。

向项目添加引用

  1. 将本文附件中的 CPBarChart 源文件夹中的 BarChart 文件夹及其所有内容复制到您的解决方案文件夹中。
  2. 右键单击 Visual Studio 的解决方案资源管理器,然后选择:添加现有项目,并选择 BarChart 文件夹。
  3. 选择您要添加图表的项目,并在解决方案资源管理器中右键单击它。
  4. 选择添加引用,选择打开的对话框的项目选项卡,然后选择BarChart,然后重新编译解决方案。
  5. 在 Visual Studio 工具箱窗口中,您应该能看到一个名为 [您的项目名称] 组件 的新组,其中可见 HBarChart 项。
  6. HBarChart 组件拖到任何 Windows 窗体控件上。

添加 DLL

  1. 在 Visual Studio 工具箱中,右键单击某个类别(如常规)的顶部,然后选择选择项
  2. 在 .NET Framework 组件选项卡中,找到浏览按钮,然后使用浏览窗口选择 BarChart.dll
  3. 现在,将添加到工具箱中的新条形图控件拖到窗体上。

您也可以将 DLL 拖到 Visual Studio 工具箱中。

图表背景

图表的背景可以是线性/径向渐变或纯色。渐变使用两种颜色来绘制图表的背景。

要设置背景模式,请使用 Background.PaintingMode。它是 enum 类型,可以设置为 SolidColorLinearGradientRadialGradient

图表背景还需要定义颜色。颜色取决于当前选择的模式。如果选择了渐变,则需要设置两种颜色:GradientColor1GradientColor2。如果选择纯色作为背景,则应指定 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”。它的作用是描述图表显示的内容。您可以修改其 TextColorFontVisibility

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 大小调整模式以及字体、颜色、文本、BarSizeBarGapSize(条形之间的空白)使得创建完全自定义的图表成为可能。

另一种可能的模式是 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

插入条形

调用 InsertAtItems.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 还支持四个其他事件:BarClickedBarDoubleClickedBarMouseEnterBarMouseLeave。要处理这些事件,您可以遵循以下两种方法之一:

在 Visual Designer 中

右键单击窗体上的图表控件,然后选择属性。在属性窗口的顶部,选择事件按钮。然后转到条形图部分,您应该会看到它们。双击您要处理的任何事件的标题。

HBarChart/events.jpg

手动处理事件

这是分两步完成的;首先注册事件

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 控件,它展示了图表如何精确地处理数据。

扩展图表数据源功能

我以一种可以创建您自己的读取和显示数据方式的方式设计了 DataSourceHBarChart 有一个数据连接类,它连接到数据源并自动检索数据行和列。为了在图表中显示这些行和列,它使用一个实现了 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 相关的东西进行交互,连接则用于处理行和列。

历史

  • 2008/06/20
    • 发布第一个版本
  • 2008/06/24
  • 2008/07/09
    • 支持负数
    • 支持数据源
    • 项目转换为 IList 集合
    • 添加了条形绘制类型(待更改)
    • 为图表添加了边框
    • 为图表添加了阴影
    • 添加了径向渐变背景模式
    • 进行了大量性能优化
© . All rights reserved.