上一课展示了CChart的第一个高级功能,本节课继续第一课的话题,介绍CChart最基本的功能——折线图的绘制。
在第一课中,曲线数据是用AddPoint2D一点一点地加进去的,同学们是不是觉得这个方法有点傻?要是有几百个上千个数据点的话,岂不得累死!
下面介绍CChart类的一个函数。
int AddCurve(double *pX, double *pY, int nLen, int nPlotIndex=0);
从名字就可以看出,这个函数是用来添加曲线的。
首先看看函数的参数。pX和pY是两个double型数组,用来存放曲线的x坐标与y坐标;nLen表示数据点的个数;nIndex参数稍微解释一下,这个表示子视图的序号。CChart可以处理分裂视图、分层视图,这些视图具有子视图,nPlotIndex表示需要往第nPlotIndex个子视图上添加曲线。
再看看函数的返回参数,是一个int值,表示曲线的ID号。
CChart可以绘制多条曲线,在程序内部,多条曲线是用vector的方式存放的。Vector类似数组,可以用下标来存取。但CChart支持曲线的排序、插入、删除等操作,经过这些过程后,曲线在vector中的下标会改变。怎样保证曲线标识的唯一性呢,这就是曲线的ID。
简单地说,曲线的ID号就相当于人的身份证号,人的身份证号在人的一生中是唯一的且不变的(当然,如果你是房爷赵海滨,你可以拥有无数的身份证号,外加无数套房子,但这不在我们的考虑之列)。曲线的ID号也如此,无论曲线经过多少次排序、插入、删除操作,都始终保持不变。
曲线的ID号在CChart中应用非常之多,这是后话,这里暂且跳过。
下面利用AddCurve来增加曲线。
与前面的课程一样,建立一个VC6项目,名称为Lesson05。
把WM_CREATE消息的响应例程写成这样。
case WM_CREATE:
chartWnd.Attach(hWnd, kTypeXY);
{
double pX[360], pY[360];
double Pi = 3.1415926536;
int i;
for(i=0; i<360; i++)
{
pX[i] = i;
pY[i] = 5.0*sin(i*2.0*Pi/360.0*3.0);
}
chartWnd.GetChart()->AddCurve(pX, pY, 360);
}
chartWnd.GetChart()->SetTitle(_T("CChart绘制折线图"));
break;
在Lesson05.cpp文件头部附近加上下面一句。
#include <math.h>
这句话的用途不用笨笨唠叨了吧。
程序的其余部分和前几课的完全一样。
运行程序,效果如图。
这里绘制了一条正弦曲线。
上面的代码首先准备了两个数组pX和pY用来存放数据点,然后用AddCurve把曲线加了进来。
既然上面用的函数叫AddCurve,顾名思义,曲线还能继续加。让我们修改WM_CREATE消息的响应例程如下。
case WM_CREATE:
chartWnd.Attach(hWnd, kTypeXY);
{
double pX[360], pY[360];
double Pi = 3.1415926536;
int i;
for(i=0; i<360; i++)
{
pX[i] = i;
pY[i] = 5.0*sin(i*2.0*Pi/360.0*3.0);
}
chartWnd.GetChart()->AddCurve(pX, pY, 360);
for(i=0; i<360; i++)
{
pX[i] = i;
pY[i] = 2.0*cos(i*2.0*Pi/360.0*3.0);
}
chartWnd.GetChart()->AddCurve(pX, pY, 360);
}
chartWnd.GetChart()->SetTitle(_T("CChart绘制折线图"));
break;
上面又添加了一条曲线,运行效果如图。
第二条曲线画出来啦!
理论上只要你的计算机内存够大,你想加多少条曲线都是可以的,CChart本身对曲线的条数是没有限制的。
下面讨论一些别的问题。
在第三课中,我们利用右键菜单,在屏幕上调出了图例。下面我们用代码的方式调出图例。
同样在WM_CREATE的响应例程里面,在break;这一行的前面,添加下面一句话。
chartWnd.GetChart()->SetUseLegend(true);
运行效果如图。
现在屏幕上有两条曲线,图例里面也有两个标识,图例中标识的颜色和曲线的颜色是对应的。
图例标识中的一串字母和数字就是那条曲线的名称,有需要的话,把名称改成中文的也没有问题。下面我们就试试看,把第一条曲线的名称改成“王菲”,第二条曲线的名称改成“李亚鹏”。
同样在WM_CREATE的break;这一行的前面,添加下面两句话。
chartWnd.GetChart()->SetDataTitle(_T("王菲"), 0);
chartWnd.GetChart()->SetDataTitle(_T("李亚鹏"), 1);
运行程序,效果出来啦!
这里解释一下CChart类的SetDataTitle函数,其原型如下。
void SetDataTitle(const TCHAR* title, int nDataIndex, int nPlotIndex=0);
第一个参数title当然就是要设置的数据名称了;第二个参数nDataIndex表示曲线的序号,按照添加的顺序,从0开始计算;第三个参数nPlotIndex表示子图的序号,从0开始计算,默认为0,也就是第一个子图,这个参数仅仅对于分裂视图、分层视图、共享X轴视图有效。
下面再关注一下坐标轴。从上面的图中,我们看到坐标轴没有标题,现在我们给两个坐标轴都加上标题。
同样在WM_CREATE的break;这一行的前面,添加下面两句话。
chartWnd.GetChart()->SetAxisTitle(_T("横轴"), 1);
chartWnd.GetChart()->SetAxisTitle(_T("纵轴"), 0);
运行效果如图。
SetAxisTitle的定义如下。
void SetAxisTitle(const TCHAR* title, int location, int nPlotIndex=0);
第一个参数title当然就是要设置的坐标轴名称了;第二个参数location表示坐标轴位置,这里需要解释一下,左坐标轴为0,下坐标轴为1,右坐标轴为2,上坐标轴为3,这个问题大家可以打开Chart.h,看看文件头部被注释掉的一些enum定义,就完全清楚了;第三个参数nPlotIndex表示子图的序号,默认为0。
最后我们来看看背景网格。
同样在WM_CREATE的break;这一行的前面,添加下面两句话。
chartWnd.GetChart()->SetGridLine(true, true, true, true);
chartWnd.GetChart()->SetBkgndColor(RGB(224, 224, 224));
这下图像和原来大不一样了。
SetGridLine设置网格的绘制情况,定义如下。
void SetGridLine(bool MajorH=true, bool MajorV=true, bool MinorH=false, bool MinorV=false, int nPlotIndex=0);
CChart的背景网格有两套,分别是主网格和副网格。SetGridLine的前四个参数分别表示是否绘制主网格横线、主网格竖线、副网格横线、副网格竖线,第五个参数是子图序号,前面已经解释。
SetBkgndColor设置背景颜色,定义如下。
void SetBkgndColor(COLORREF color, int nPlotIndex=0);
参数不用笨笨给大家解释了吧。
好了,这节课笨笨快累晕了,赶紧下课吧。