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

CBarChart

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (67投票s)

2007年1月10日

CPOL

5分钟阅读

viewsIcon

304555

downloadIcon

14359

CBarChart 是一个简单的 MFC 控件,派生自 CWnd。它可以使用 ODBC 从表或存储过程中加载数据。

Sample Image - BarChart-Snapshot.jpg

目录

引言

CBarChart 是一个简单的 MFC 控件,派生自 CWnd。它可以帮助您快速开发自己的图表并轻松打印它们。

背景

几天前,我需要在项目中添加一个图表。完成后,我觉得它还不错,于是决定与我的同事们分享到 Code Project,现在就是这样了。

我没有太多时间来开发这个控件,所以我不得不尽量保持简单。我创建这个图表的目的是如下:

  • 开发不应超过两到三天。
  • 图表必须更具吸引力而不是准确。由于用户不熟悉该应用程序甚至计算机,我必须尽我所能来吸引他们的注意力。
  • 它必须易于理解,不要包含大量可能会让新用户感到困惑的数据。
  • 它应该是可打印的。
  • 它应该是可重用的。

有了以上所有假设,我开始了您在这里看到的一切。请尽情享受,并请用您认为可能改进代码质量的宝贵评论、错误报告、想法等来帮助我。

使用代码

创建图表

首先,我们必须创建一个图表

  1. BarChart.cppBarChart.h 添加到您的项目中。
  2. #include "BarChart.h" 添加到您要添加此图表的类的头文件顶部。
  3. 添加一个类型为 CBarChart 的成员变量。
  4. 在您的 cpp 文件中,使用成员变量的 Create 方法来创建图表控件。

// Create a bar chart control
if (!m_chart.Create(
    rcBound,              // Bounding rectangle of the control
    this,                 // A pointer to the parent window to be shown on
    0 ))                  // ID of this control
    {
    // Error, can't create the chart
    }

如果 Create 成功,它将返回 TRUE

标题文本和背景颜色

您可以使用 SetTitleSetBKColor 来添加标题或更改控件的背景颜色。

m_chart.SetTitle("A test chart, displaying some dummy data...");
m_chart.SetBKColor(RGB(255, 255, 240));

添加条形

最后,要向图表添加条形,请使用 AddBar 方法,如下所示:

m_chart.AddBar(
1600.356,           // A value to be shown at the top of the bar
"Jan",              // A label under the bar chart
RGB(255,255,0));    // Color of the bar

请注意,该控件使用此颜色(AddBar 的最后一个参数)来创建条形的渐变,在我看来,这更加精致。

网格、标签和工具提示

您还可以决定是否显示网格线、标签或值

m_chart.ShowGrid(m_bShowGrid, TRUE);            // Show/Hide grids
m_chart.ShowBarText(1, m_bShowText, TRUE);      // Show/Hide values(top)
m_chart.ShowLabel(m_bShowLabel, TRUE);          // Show/Hide labels(bottom)
m_chart.ShowTooltip(m_bShowTip);                // Activate/deactivate tooltips

另请注意,ShowBarText 的第一个参数用于在两种状态之间切换:0 表示在条形顶部显示其值,1 表示显示相对于其他值的百分比。

您还可以更改网格的默认行为。默认情况下,网格会填充图表背景,形成交叉的垂直和水平线,生成宽度和高度均为 10(设备)单位的矩形。要更改此行为,请使用 SetGridLines 成员函数。

SetGridLines(
int nHorLineCount,      // Number of horizontal lines, 0 = ignore
int nVerLineCount,      // Number of vertical lines, 0 = ignore
BOOL bFixedSize,        // If TRUE, first 2 parameters will be ignored
int nFixedSize)         // A fixed value that defines distance between 2 lines,
                        // Will be used if previous parameter is set to TRUE

扩展

如果要求,条形可以自行缩放,但质量会突然下降,因为它使用的是 StretchBlt。这会严重降低质量。我希望您不要介意,因为我没有足够的时间重新绘制整个图表以适应屏幕。

m_chart.SetAutoScale(m_bScale);         // Set chart to be auto scaled
// Reposition window, so it finds out the size to fit into
m_chart.SetWindowPos( 0, 0, 0,
rcClient.Width(),
rcClient.Height() , SWP_NOMOVE);
m_chart.Refresh();                      // Force the chart to redraw itself

// You might also need to override OnSize of the
// Parent to position the chart, so it is always at the size you like

移除条形

您可以使用 RemoveAtRemoveAll 来移除控件中特定零基索引的条形,或者全部移除。

m_chart.RemoveAt(nRemIndex);    // Removes the item indexed nRemIndex.
                                // Index is zero based.
m_chart.RemoveAll();            // Removes all bars

保存到位图文件

调用 SaveToFile 将图表保存为位图文件。该函数接受一个 CString 成员函数,该函数默认为空。如果此字符串为空,函数将通过显示 FileSaveAs 对话框来提示文件路径。如果失败,此函数将返回 False。使用 GetLastErrorMessage() 成员函数获取描述失败原因的字符串。

// Save chart as a bitmap file
if (!m_chart.SaveToFile())
    {
    AfxMessageBox(m_chart.GetLastErrorMessage());
    };

如果有人能检查一下保存到位图的代码,以确保没有错误,那将不胜感激。

打印

使用 Print 函数打印图表。

请谨慎使用此函数:根据 Roger Allen 的文章:PrintingTricksAndTips,如果我们打印位图,最好使用 DIB 而不是 DDB。因此,此函数接受一个布尔类型的参数:bCompatible(默认为 false)。

如果您将参数设置为 true,则表示您要求图表使用 DIB,这是推荐的做法。我只是复制了 Roger Allen 先生提供的代码片段,并创建了 Print 的两个副本:一个直接使用 StretchBlt,另一个使用提到的代码将其转换为 DIB。

对我来说,这两种函数都能正常工作。但不幸的是,我没有足够的时间来正确检查打印过程。因此,如果您发现任何错误或需要进行任何更正,我将不胜感激。我对打印不够熟悉。

m_chart.Print();        // Prints the whole chart fitted in the page.
// If you have a lot of bars, I recommend selecting landscape in the 
// print dialog box.

连接到数据库

CBarChart 使用 ODBC 版本 3 连接到数据库。

要将图表连接到 ODBC 数据源,请使用 ReadFromDatabase 的一种形式

// Use this form to call a stored procedure or a query and use 
// result set as chart input

ReadFromDatabase("DS Name", "Stored proc/Query Name", "List of all parameters",
         "Bars Color", "UserName", "Password"));

// Note that the query or stored procedure MUST have at least 2 columns,
// First column MUST be of type char with maximum length of 50 and
// Second a double. These columns will be used as input data for the chart.

第二种形式可用于连接到表

m_chart.ReadFromDatabase("DS Name", "Table name", "Filter",
"Laabel column name", "dValue column name",
Bars color , "username", "password");

以下是调用这些函数的示例

if (!m_chart.ReadFromDatabase("CHTst", "SpChartGetSale", "1, 12",
                      RGB(0, 0, 0), "hamed", "hamed"))
    {
        AfxMessageBox(m_chart.GetLastDatabaseErrMessage());
    };
or
m_chart.ReadFromDatabase("CHTst", "Sales", "",
"Month", "SaleRate",
RGB(0, 0, 0) , "hamed", "hamed");

我在下载列表中添加了一个示例 Access 数据库文件。您可以将其添加到控制面板中的“ODBC 管理工具”的“系统”或“用户”数据源中。将其命名为 CHTst,然后按示例应用程序上的“FromDatabase”按钮。您看到的是通过一行代码对存储过程进行的调用所得到的结果集。请尽情享用。

历史

  • 2007/01/10
    • 版本(或可能是第一个测试版)。

  • 2007/01/11
    • 修复了一些缩放错误
    • 添加了工具提示。
    • 无符号长双精度转换为双精度

  • 2007/01/15
    • 更改了一些函数。
    • 工具提示已更新。
    • 添加了一些注释。

  • 2007/01/24
    • 工具提示现在非常接近真实工具提示。
    • 添加了数据库连接。

  • 2007/01/26
    • 修复了工具提示错误(控件失去焦点时消失)。

  • 2007/01/31
    • 修复了一些网格错误。

  • 2007/02/3
    • 添加了保存到位图功能
    • 网格已更新

致谢

  • Nishant S. 先生,感谢他关于创建渐变的精彩文章。
  • Chris Maunder 先生,感谢他关于 MFC 网格的精彩文章,这对我的打印工作很有帮助。
  • Roger Allen 先生,感谢他撰写的“战壕里的打印技巧和窍门”一文。
  • David Bennett 先生和 Chuck Wood 先生在 Visual C Unleashed 一书中,感谢他们提供的代码片段和 ODBC 数据库编程方面的帮助。
© . All rights reserved.