VFP 探讨之 OLE 控件(九):图表控件(下)—图表实例
上次和大家聊了图表控件中一些对象、方法的名字,以及引用这些对象的方式。这次就用个实例来看一下它们的具体用法(数据就不列了,可参考图1),大家可以重点关心一下各对象的名称,以及它们之间的上下级关系。图1是表单运行后的图表形态,图2是加入到表单后图表控件的原始形态。弄两个图是为方便大家对比,看看表单的相关代码中到底对图表中的哪些对象进行了设置。
首先,看表单的Init事件中关于图表控件的相关代码(红色部分):
WITH ChartForm
.ShowTips=.T.
WITH .统计图
.ChartType=1
.Plot.Axis(2).AxisScale.Hide=.T.
ENDWITH
WITH .图形选择.年级统计
.SetFocus
.Click &&给出按年级统计的柱形图
ENDWITH
ENDWITH
分析:
1、在该表单中,图表控件被命名为“统计图”,所以后面对图表对象的引用都以“统计图.XXX来表示”;
2、“统计图.ChartType=1”用来设置该图表的类型是“1―2D柱形图”。这个类型是控件的默认类型,在实际编程中可以不用特意设置,除非事先设置了别的类型,现在转换成2D柱形图;
3、“统计图.Plot.Axis(2).AxisScale.Hide=.T.”用来设置隐藏第二Y轴。这里要注意一个问题:对某根坐标轴进行隐藏操作不可以直接用“.Plot.Axis(x).Hide=.T.”,因为在图表控件中,Hide属性只能用在AxisScale对象上,不能用在其它对象上。AxisScale对象可以理解为坐标轴线,它不同于刻度线对象Tick,使用时要注意。
再来看一下“年级统计.Click”事件中关于图表控件的相关代码:
WITH ChartForm.统计图
.ShowLegend=.T. &&需要显示图例
.RowCount=数据表行数
.ColumnCount=数据表列数-1 &&去除“年级”列
WITH .Plot.Axis(0)
*****************************************
*Axis(0)-(3)分别表示X、Y、第二Y,以及Z轴*
*****************************************
WITH .AxisTitle &&对X轴标题进行设置
.Text="年级" &&标题文字
WITH .VtFont
.Name="黑体"
.Size=16 &&设置字体尺寸
.Style=1 &&1为粗体;2为斜体;3为粗斜体
.VtColor.Set(0,0,0) &&设置字体颜色
ENDWITH
ENDWITH
.AxisGrid.MajorPen.Style=3
*********************************************
* 0:无网格线;1:实线;2:虚线;3:点虚线;*
* 4:线点混合虚线;5:一线两点混合虚线; *
* 6:同3; 7:同4; 8:同5; 9:同1。 *
*********************************************
.Tick.Style=0 &&刻度线类型:0:无;1:交叉;2:内部;3:外部
ENDWITH
.Plot.Axis(1).AxisScale.Type=0 &&坐标轴线类型:0:线性;1:对数;2:百分比
.Plot.Axis(1).Tick.Style=2
SCAN
.Row=RECNO()
.RowLabel=EVALUATE(FieldOfSource[1,1])
FOR J=2 TO .ColumnCount+1
.Column=J-1
.ColumnLabel=ChartForm.数据表.Columns(J).Header1.Caption
.Data=EVALUATE(FieldOfSource[J,1]) &&设置每列的数据源
NEXT
ENDSCAN
.Plot.SeriesCollection(2).DataPoints(-1).Brush.FillColor.Set(0,0,255)
ENDWITH
分析:这段代码很重要,是绘出图表的核心。它涵盖了源数据如何反映到图表中,以及对图表部分对象进行设置。
1、“.RowCount=数据表行数”和“.ColumnCount=数据表列数-1”两条命令用来确定图表的数据分布情况:前者设置数据分成多少组,本例为4组,每个年级一组;后者设置每个组中含多少单个数据(即数据点),本例为5个数据点/组,分别对应五门课程。由于数据源中第一列是行标题(是X轴的组标题),不能作为图表数据,所以数据点个数需要减1;
2、蓝色部分是对X轴进行设置,包括设置X轴标题、网格线线型、刻度线类型;红色部分针对Y轴进行了设置,包括坐标轴线类型、刻度线类型;
3、“.Row=RECNO()”和“.RowLabel=EVALUATE(FieldOfSource[1,1])”两条命令是对每个组进行设置。前者设置图表控件当前指向哪个组。一般的做法是对应记录顺序,即,第一条记录就是第一组,第二条记录就是第二组…… 因此,这里直接用当前记录号赋值给图表的Row属性。“.RowLabel”属性用来设置当前组的组标题,本例就是各年级的名称,即,2010、2011、…… 在之前表单的Init代码中,用AFIELDS()函数生成过一个名为“FieldOfSource”的二维数组,其中存放了数据源表文件的结构。这个数组各行的第一列就是字段名,因此可以在设置图表时直接引用。对于存放第一个字段信息的FieldOfSource[1,x]来说,首元素FieldOfSource[1,1]就是第一个字段的字段名,即“年级”。由于需要在各组的标题上显示具体的年级名称,所以外面要套用一个EVALUATE()函数,相当于“EVALUATE(“年级”)”,或“&FieldOfSource[1,1]”。据微软帮助文件所说,EVALUATE()函数执行效率要高于宏代换,因此本例就采用了该函数。那为什么不直接写成“EVALUATE(“年级”)”呢?是因为要考虑到程序代码的通用性。如果换一个题材,字段名不是“年级”了,这一句代码就可以不用修改。本例比较简单,通用性的好处还不明显,但对于复杂程序来说,考虑代码的通用性就很有必要了;
4、“.Column=J-1”和“.ColumnLabel=ChartForm.数据表.Columns(J).Header1.Caption”两条命令的作用与第3条分析中的相仿,用来设置每个组中单个数据点的,这里就不再赘述了。唯一需要说明的是:数据点标题的文字内容是显示在图例中的;
5、“.Data=EVALUATE(FieldOfSource[J,1])”这一句相当关键,它就是用来把源数据反映到图表中的。使用Data属性时必须要事先指定好Row属性和Column属性的值,否则,控件无法确定数据点应该放在哪个组的第几个位置上;
6、“.Plot.SeriesCollection(2).DataPoints(-1).Brush.FillColor.Set(0,0,255)”命令用来设置第二个数据系列(即“普通物理(A)下”课程)的填充色为蓝色。
本例为了达到多角度统计的目的,还设置了按课程统计作图的功能。该功能实现的方法是:先把源数据表进行行列转置,再对转置后的源数据表进行作图。作图方法与上面分析的基本相同,有兴趣的可以下载附件去研究,这里就不再详细介绍了。
关于本人研究的OLE控件在VFP中的用法探讨暂告一段落,将来若再研究出什么新花样来,会继续发帖与大家聊。由于工作比较繁忙,业余时间还要研究摄影什么的,所以断断续续拖了很长时间才完成这部短短的系列,非常感谢大家在百忙之余的关注和支持!
统计图表单.rar
(446.58 KB)