最近项目需要画几个柱状图,对画图表的几个方式进行了尝试,现在记录下我这近一周的心得和成果。
首先说一下配置,vs2010+MFC+X64平台,最开始尝试了Mschart,网上有很多示例,我也在Win32平台上成功画出了柱状图。但一旦转换到X64平台,我就不会使了。大概是因为没在网上找到新版本的Mschart。大家对TeeChart有同样的评价,即能在Win32上画图表,但要在X64上画图表,则需要较新版本,而网上几乎找不到新版本的破解版。
在CSDN论坛上看到有人使用High-speed Charting Control成功在X64平台上画出图表,我就开始尝试用这个控件画柱状图。源码:http://www.codeproject.com/KB/miscctrl/High-speedCharting.aspx?msg=3787437#Thebarseries9,我参考的博客:http://blog.csdn.net/czyt1988/article/details/8740500。配置和生成方式可以参考该博客。
有个问题就是中文参考的博客上博主没有画柱状图,我就参考原博主的代码:
配置控件的方式有两种(参考尘中远博客),我选择了使用控件的方式来创建控件:
一、创建控件
1. 在工程下建立一个文件夹ChartCtrl,里面放置ChartCtrl的源代码:
2.添加控件,修改控件属性
3.添加头文件,为控件添加变量,在DoDataExchange函数里添加关联
#include "ChartCtrl.h"
#include "ChartTitle.h"
#include "ChartAxisLabel.h"
#include "ChartBarSerie.h"
#include "ChartLineSerie.h"
CChartCtrl m_ChartCtrl;
DDX_Control(pDX, IDC_CHARTCTRL, m_ChartCtrl);
此时控件创建成功。
二、初始化控件
三、画柱形图
四、我遇到的几个问题
1、high-speed chart 编译报错GetSerie(size_t) const”:“CChartCtrl”中没有找到重载的成员函数
2、画不同的柱形图,坐标会互相影响的问题。
3、画出的柱形图X坐标方向上乱摆的问题。
4、每次更新数据原柱状图消不掉的问题。
能画出的柱状图效果为:
画出该效果的代码为:
srand((unsigned int)time(NULL));
// Disable the refresh
m_ChartCtrl.EnableRefresh(false);
COleDateTime Min(2008,1,1,0,0,0);
COleDateTime Max(2008,10,1,0,0,0);
// Create the bottom axis and configure it properly
CChartDateTimeAxis* pBottomAxis =
m_ChartCtrl.CreateDateTimeAxis(CChartCtrl::BottomAxis);
pBottomAxis->SetMinMax(Min,Max);
pBottomAxis->SetDiscrete(true);
pBottomAxis->SetTickIncrement(false,CChartDateTimeAxis::tiMonth,1);
pBottomAxis->SetTickLabelFormat(false,_T("%b"));
// Create the left axis and configure it properly
CChartStandardAxis* pLeftAxis =
m_ChartCtrl.CreateStandardAxis(CChartCtrl::LeftAxis);
pLeftAxis->SetMinMax(0,100);
pLeftAxis->GetLabel()->SetText(_T("Units sold"));
// Create the right axis and configure it properly
CChartStandardAxis* pRightAxis =
m_ChartCtrl.CreateStandardAxis(CChartCtrl::RightAxis);
pRightAxis->SetVisible(true);
pRightAxis->GetLabel()->SetText(_T("Income (kEuros)"));
pRightAxis->SetMinMax(0,200);
// Configure the legend
m_ChartCtrl.GetLegend()->SetVisible(true);
m_ChartCtrl.GetLegend()->SetHorizontalMode(true);
m_ChartCtrl.GetLegend()->UndockLegend(80,50);
// Add text to the title and set the font & color
m_ChartCtrl.GetTitle()->AddString(_T("Income over 2008"));
CChartFont titleFont;
titleFont.SetFont(_T("Arial Black"),120,true,false,true);
m_ChartCtrl.GetTitle()->SetFont(titleFont);
m_ChartCtrl.GetTitle()->SetColor(RGB(0,0,128));
// Sets a gradient background
m_ChartCtrl.SetBackGradient(RGB(255,255,255),RGB(150,150,255),gtVertical);
// Create two bar series and a line series and populate them with data
CChartBarSerie* pBarSeries1 = m_ChartCtrl.CreateBarSerie();
CChartBarSerie* pBarSeries2 = m_ChartCtrl.CreateBarSerie();
CChartLineSerie* pLineSeries = m_ChartCtrl.CreateLineSerie(false,true);
int lowIndex = -1;
int lowVal = 999;
for (int i=0;i<9;i++)
{
COleDateTime TimeVal(2008,i+1,1,0,0,0);
int DesktopVal = 20 + rand()%(100-30);
pBarSeries1->AddPoint(TimeVal,DesktopVal);
int LaptopVal = 10 + rand()%(80-20);
pBarSeries2->AddPoint(TimeVal,LaptopVal);
int Income = DesktopVal + LaptopVal*1.5;
if (Income < lowVal)
{
lowVal = Income;
lowIndex = i;
}
pLineSeries->AddPoint(TimeVal,Income);
}
// Configure the series properly
pBarSeries1->SetColor(RGB(255,0,0));
pBarSeries1->SetName(_T("Desktops"));
pBarSeries2->SetColor(RGB(68,68,255));
pBarSeries2->SetGradient(RGB(200,200,255),gtVerticalDouble);
pBarSeries2->SetName(_T("Laptops"));
pBarSeries2->SetBorderColor(RGB(0,0,255));
pBarSeries2->SetBorderWidth(3);
pLineSeries->SetColor(RGB(0,180,0));
pLineSeries->SetName(_T("Total income"));
pLineSeries->SetWidth(2);
pLineSeries->EnableShadow(true);
// Add a label on the line series.
TChartStringStream labelStream;
labelStream << _T("Min income: ") << lowVal;
CChartBalloonLabel* pLabel =
pLineSeries->CreateBalloonLabel(lowIndex, labelStream.str() + _T(" kEuros"));
CChartFont labelFont;
labelFont.SetFont(_T("Microsoft Sans Serif"),100,false,true,false);
pLabel->SetFont(labelFont);
// Re enable the refresh
m_ChartCtrl.EnableRefresh(true);