译者说明:欢迎访问我的Blog: http://blog.csdn.net/daidaoke2001/
译文中的错误或不当之处望不吝指出,这也是我坚持翻译工作的最大动力。
我的Email:[email protected]
如需转载,请事先通知。
第三章第二节 图表组件高级功能
我们已经了解了关于图表生成的所有基础知识,现在让我们来研究图表组件一些更高级的功能,尤其是那些在传统的Excel图表生成中没有的功能。许多这些功能都会在本书第二部分所介绍的解决方案中被使用。当我们讨论这些解决方案时,如果您记不清某个特定功能的基础知识,可以回头参考本节,以获得更一般意义上的解释。
“图表空间”中的多重图表
前面提到过,图表控件可以在名为图表空间的地方一次显示多个图表。其实图表控件的顶级编程接口就叫做ChartSpace,当您在容器中插入一个新的图表控件时,控件的缺省名称通常叫做ChartSpace1。
当您需要显示多个相关联的图,并且要能够方便的对各图进行比较时,在一个控件中同时显示多重图表的功能就会很有用。人们常称这种设计为“小型多重设计”,它可以成为一个强大的分析工具。例如,如果您需要同时显示各时间段的销售数据,销售人员,以及地理位置,您就可以为每个国家创建一个图表,在每个图表中将销售人员显示为系列,时间显示为类别。图3-18显示了最后的图表可能的样子。
图表控件可以在同一个图表空间中显示最多16个图表,但是所有的图表必须共享同一组类别。如果两个图表各自包含不同的一组类别,用于所有图表的那组类别将会是每个图表的类别的合集。这是因为小型多重设计依赖各图表中的类别、系列和轴上的刻度的一致性,使得您能够容易的发现各图表之间明显的区别和趋势。
图3-18。一个图表空间中的多重图表。
图表控件不会自动为您在各个图表中设置值轴的刻度,但是您可以使用来自随书光盘中Chap03文件夹下的MultipleCharts.htm文件中的一小段代码十分轻松的完成这个功能。
'------------------------------------------------------------------------
' NormalizeCharts()
'
' 目的: 将图表空间中所有各图表的值轴设为相同,以便您能准确的比较各值。
' 传入参数:cspace = 指向ChartSpace对象的引用
' nAxis = 值轴在WCAxes集合中的索引
'
Sub NormalizeCharts(cspace, nAxis)
' 局部变量
Dim cht ' 指向chart对象的临时引用
Dim ax ' 指向axis对象的临时引用
Dim nMax ' 各轴上的最大值
nMax = 0
' 遍历所有的图表一次,获得所有图表中值轴的最大值
For Each cht In cspace.Charts
Set ax = cht.Axes(nAxis)
If ax.Scaling.Maximum > nMax Then
nMax = ax.Scaling.Maximum
End If
Next 'cht
' 再次遍历各图表,设置最大值
For Each cht In cspace.Charts
Set ax = cht.Axes(nAxis)
ax.Scaling.Maximum = nMax
Next 'cht
End Sub 'NormalizeCharts()
这段代码对图表空间中的所有Chart对象执行两次遍历。第一次遍历确定所有值轴上的最大值,第二次将各图表值轴上的Scaling.Maximum属性设置为获得的最大值,这样所有图表在它们的值轴上都具有相同的最大值。请注意只有在您的图表具有值轴时这种方法才是必要的――因此它并不适用于多重饼图,多重堆积饼图,或多重圆环图。
您也可以通过调整顶层ChartSpace对象的ChartLayout和ChartWrapCount属性来控制控件空间中多重图表的布局。可以通过设置ChartLayout属性来水平平铺或垂直平铺各图表。ChartWrapCount属性控制每行(或每列)在一行(或一列)中显示多少图表。也可以通过调整每个WCChart对象的HeightRatio和WidthRatio属性扩大或缩小特定图表的尺寸。
服务端的应用
除了能够以COM控件的形式寄宿在窗体上之外,每个Office Web组件都能以不可见,位于内存中的方式被使用。但是当运行在一个web server的环境下时,图表组件可能是Office Web组件中最让人关注的部分。当OWC小组在微软内部首次开始发行beta版本时,我们立刻就收到来自公司的许多其它小组的email,他们希望知道如何在服务器上使用Chart控件来生成动态数据的图表(大部分情况下,是为了提供bug的统计报告)。许多商业活动中都包括用于评测产品或运作过程的一组度量标准;商业主管们一直梦想着只要打开他(或她)的web浏览器就可以看到反映实时更新的数据的图表。因为图表控件可以在服务器端使用,并能够产生图表自身的GIF格式的图形拷贝,所以许多开发者发现在服务端利用图表控件来生成既能被用于互联网环境,也能被用于包含各种不同类型客户端电脑的企业环境中的实时数据的图表,是一个非常棒的方法。
当在服务端使用图表控件时,您可以使用它的所有标准功能。还有,之前我们所讨论的那些用于将不同类型的数据装载到图表中的代码在服务端环境中也是可用的。通常,会使用一个服务端对象或服务器上另一段脚本产生的ADO Recordset对象来装载图表控件。您可以引用图表中的所有元素,就好像它们显示在屏幕上一样,在您完成创建图表后,可以使用ChartSpace对象的ExportPicture方法来将GIF图形写入一个文件中。在当前版本中,Chart控件只支持输出为GIF图形格式,不过您可以指定输出图形的任意宽度和高度(以象素为单位)。
关于服务端应用,我需要说明的最后一点是:您应该检查您的Office2000附带的许可证协议,并询问微软应用开发者客户协会(ADCU)的代表关于在web服务器上使用Office Web组件来开发解决方案的更多信息。在本书写作期间,Office市场小组正在将一个特殊的Office Web组件服务端使用许可和Office使用协议合并在一起。虽然很多细节还没有最后确定,但是这个许可预计将不会限制客户端数目,这样您就可以在一个Internet站点上使用这些组件了。
分割轴
另一个普遍需要的图表生成功能是在某一点分割值轴的能力,这使得您可以在同一个值轴上绘制很小的数值和很大的数值,并仍然能够显示局部的变化,图3-19描述了一个常见的分割轴图表。
图3-19。一个分割轴图表。
图表在每个值轴上可以有一个分割点,您可以指定值轴上分割开始和结束的确切值。可以在设计阶段在属性工具箱中完成这个操作:先选择值轴,然后使用属性工具箱中的Split Axis段来设置开始和结束的分割值。您也可以在运行时通过代码来完成:先将轴的Scaling对象的HasSplit属性设置为True,然后再设置SplitMinimum和SplitMaximum属性。
调整轴的刻度
缺省情况下,图表控件会为值轴自动选择一个最小值和最大值,使得所有的数据点均可见,并且在绘图区周围留下一些空白。但如果您需要覆盖这些缺省设置,可以手工调整一个轴的scaling属性来精确的设置您所需要的最小值和最大值。
每个WCAxis对象都有一个Scaling属性,它返回一个WCScaling对象。WCScaling对象具有名为Minimum和Maximum的属性,能够通过这些属性来精确的设置最小值或最大值,或者从这些属性中读取当前值。您还可以通过将HasAutoMinimum和HasAutoMaximum属性设置为True,来强迫轴变回成自动设置刻度的状态。
您还可以利用WCScaling对象来告诉轴使用对数刻度代替线性刻度。将WCScaling的Type属性设置为chScaleTypeLogarithmic常量,可以将刻度变为对数刻度,将Type属性重新设置回chScaleTypeLinear常量,可将刻度又变成线性刻度。您也可以通过调整LogBase属性来设置对数刻度的基数。
另一个您可以调节的有趣设置是Orientation属性,它可以使刻度以从最小值到最大值的相反顺序显示。对于一个值轴它可能有用,也可能没有用,但是这是将类别轴上的各类别以相反的顺序显示的最简单的方法。
Scaling对象的使用中最有趣的部分可能是在一个轴上模拟缩放和位移。如果您的图表中数据点的密度很高,那么它可以用来允许分析者放大轴上的某一特定段,然后在轴上移动来观察各段。您可以通过简单的操作Scaling对象的Minimum和Maximum属性来达到这个目的,这会造成图表缩放和位移的效果,因为操作这两个属性会使图表在屏幕上相同的可视距离中显示较少的数值距离。
自制图表标签
图表组件并不具有您在Excel中肯定看到过的图表标签功能。图表标签是一个较大的屏幕标签,当您将鼠标停留在一个数据点或图表元素上时,它会显示出来。图表标签显示数据点的值,类别,系列,以及其它一些有用的信息。坏消息是这些图表标签并不是图表控件本身的属性;好消息是您可以通过捕捉图表控件触发的一些事件来自己添加这些标签。在本书第二部分,我会解释您如何才能创建这些自制的图表标签。现在,我仅仅讲述它们的工作原理。
图表控件在鼠标在控件上方移动时会触发MouseMove事件。在这个事件中,您可以查询鼠标当前相对于控件左上角点的X和Y坐标。这个X和Y坐标不仅能够帮助您在鼠标所在的位置防止其它元素,您还能将他们传递给ChartSpace对象的RangeFromPoint方法,来获得当前位于鼠标下方的chart对象。例如,如果您的鼠标位于一个数据点的上方,这个方法会返回一个WCPoint对象,利用这个对象,您可以判断这个数据点的父系列,类别,以及使用GetValue方法来获得这个数据点的具体值。您也可以使用这个WCPoint对象来调整这个数据点的格式,这就意味着您能够:例如,改变边框的颜色来高亮显示这个数值,或者将内部颜色改变成一个较暗的颜色或当前填充颜色的一个较浅的阴影。如果鼠标位于一个图表元素之上,例如图例,您就可以从这个方法的返回中获得一个WCLegend对象。使用VBScript和VBA中的TypeName方法来判断您从RangeFromPoint方法的返回中获得的是什么类型的对象。您也可以使用ChartSpace对象的SelectionType属性来判断从Selection属性返回的对象的类型。
请参考随书光盘Chap03文件夹下的ReactingToMouse.htm文件,文件中有使用图表组件事件和响应鼠标的例子。
为什么叫做RangeFromPoint?
当我首次开始注意图表组件编程模型中隐藏的细节时,我问图表组件的项目经理:Jason Cahill,为什么这个方法的名字叫做RangeFromPoint,很明显它和range无关,并且返回的是chart对象。我问道:“为什么不叫做ObjectFromPoint呢?”。
Jason解释说,当微软的辅助功能组初次决定为盲人创建屏幕阅读器时,他们需要Excel中的一个方法能够返回鼠标下方的当前区域,以便他们能够使用计算机的声音系统来阅读单元格中的值。(如果您对此很迷惑,这里有相应的解释信息:辅助功能组的目的是使计算机能够帮助那些残疾人士,屏幕阅读器使用音响来为盲人大声阅读屏幕上的文字。)Excel将这个方法正确的命名为RangeFromPoint,因为它根据一个(X,Y)点返回一个区域。但是,辅助功能组将这个方法的名字写进了他们的应用程序的代码中,结果现在任何希望为屏幕阅读器提供辅助功能的人都必须实现RangeFromPoint方法,即使他或她的应用程序与电子表格的区域没有任何关系。
附录:英文原文
Advanced Functionality of the Chart Component
Now that we've covered all the basics of charting, let's explore a few of the more advanced features of the Chart component, especially those not found in traditional Excel charting. You will see many of these features put to use in the solutions presented in Part II of this book. When we get to those solutions, if you need to refresh your memory on the basics of any particular feature, simply refer back to this section for a more general explanation.
Multiple Charts in "Chart Space"
As noted earlier, the Chart control can display more than one chart at a time in what is known as a chart space. The top-level programming interface for the Chart control is actually called ChartSpace, and when you insert a new Chart control into a container, the default name given the control is usually ChartSpace1.
Showing multiple charts at once in a control is useful for displaying related plots that you want to compare in one glance. This design, often called small multiples, can be a powerful analysis tool. For example, if you need to show sales data across time, salespeople, and geography simultaneously, you might create one chart for each country, each displaying the salespeople as series and the time as categories. Figure 3-18 shows what the resulting charts might look like.
The Chart control can show up to 16 charts in the same chart space, but all the charts must share the same set of categories. If two charts have a different set of categories, the set of categories used for both charts will be the union of the categories from each chart. This is because small-multiple designs rely on the consistency of the categories, series, and axis scalings among the various charts so that you notice large differences and trends easily.
Figure 3-18. Multiple charts in one chart space.
That said, the Chart control will not automatically normalize the value axis scales among all the various charts for you, but you can do this quite easily with a little bit of code from the MultipleCharts.htm file in the Chap03 folder on the companion CD:
'------------------------------------------------------------------------ ' NormalizeCharts() ' ' Purpose: Makes all value axes of charts in a chart space the same ' so that you can accurately compare values ' In: cspace = reference to the ChartSpace object ' nAxis = index of the value axis in the WCAxes collection ' Sub NormalizeCharts(cspace, nAxis) ' Local variables Dim cht ' Temporary chart object reference Dim ax ' Temporary axis object reference Dim nMax ' Maximum value across the axes nMax = 0 ' Loop through all the charts once to determine the overall maximum For Each cht In cspace.Charts Set ax = cht.Axes(nAxis) If ax.Scaling.Maximum > nMax Then nMax = ax.Scaling.Maximum End If Next 'cht ' Loop again to set the maximum For Each cht In cspace.Charts Set ax = cht.Axes(nAxis) ax.Scaling.Maximum = nMax Next 'cht End Sub 'NormalizeCharts() |
The code here performs two loops over all the Chart objects in the chart space. The first determines the maximum value across all the value axes, and the second sets the Scaling.Maximum property to the maximum value so that all charts have the same maximum on their value axis. Note that this kind of method is necessary only when your chart has a value axis—so it does not apply to multiple Pie, multiple Stacked Pie, or multiple Doughnut charts.
You can also control the layout of multiple charts within the chart space by adjusting the ChartLayout and ChartWrapCount properties of the top-level ChartSpace object. You can set the ChartLayout property to make the charts lay out horizontally or vertically. ChartWrapCount controls how many charts appear in each row or in each column before wrapping to the next. You can also adjust the HeightRatio and WidthRatio properties of each WCChart object to allow more or less room for specific charts.
Each of the Office Web Components can be used as a nonvisible, in-memory object in addition to a COM control hosted on a form. But when it comes to running on a web server, the Chart component is probably the most desirable of the Office Web Components. When the OWC team first started releasing beta builds internally at Microsoft, we immediately began to receive e-mail from other groups in the company that wanted to know how to use the Chart control on the server to generate charts of live data (in most cases, to report bug statistics). Many businesses have a set of metrics they use to measure a production or operational process; it's a manager's dream to simply open his or her web browser and see a chart with up-to-the-minute data. Since the Chart control can be used on the server and can emit a GIF image of itself, many developers find utilizing the Chart control on the server a compelling way to generate charts of live data that can be used across the Internet or in enterprises where the client desktop is heterogeneous.
You will find this type of solution implemented in Chapter 6, where we will examine it in much greater detail. For now, I will familiarize you with what the Chart control can do when running on the server and show you the basics of saving the Chart control's contents as a GIF image.
You can employ all the normal features of the Chart control when using it on the server. Also, all the code we discussed earlier that is used to load the chart with different data is applicable in that environment. Typically, you load the Chart control from an ADO Recordset object obtained from either a server-side object or another script on the server. You can refer to all the elements of the chart as if they were on the screen, and when you are finished creating the chart, you can use the ChartSpace object's ExportPicture method to write the GIF image to a file. The Chart control supports exporting to only the GIF image format in this release, but you can specify any width and height you want in pixels.
The last point I want to make about server-side usage is that you should check the license agreement that comes with your copy of Office 2000 and ask a Microsoft Application Developer Customer Unit (ADCU) representative for more information on distributing a solution that uses the Office Web Components on a web server. At the time of this writing, the Office marketing group was putting together a special server-side usage license for the Office Web Components. Although the details had not been finalized, this fee was intended to cover an unlimited number of clients so that you could use these components on an Internet site.
Another commonly requested charting feature is the ability to split a value axis at a certain point so that you can portray small and large numbers on the same value axis and still show the local variation. Figure 3-19 depicts a common Split-Axis chart.
Figure 3-19. A Split-Axis chart.
Charts can have one split per value axis, and you can specify the exact values where the value axis's split starts and ends. You can do this in the Property Toolbox at design time by selecting the value axis and using the Split Axis section of the Property Toolbox to set the start and end split values. You can also do this with code at runtime by setting the HasSplit property of the axis's Scaling object to True and then setting the SplitMinimum and SplitMaximum properties.
The Chart control by default will choose an automatic minimum and maximum for a value axis that will make all the data points visible and leave a little bit of margin around the plot area. However, sometimes you will want to override these defaults and manually adjust an axis's scaling attributes to get precisely the minimum and maximum you want.
Every WCAxis object has a Scaling property that returns a WCScaling object. The WCScaling object has properties called Minimum and Maximum for setting an explicit minimum and an explicit maximum or for reading the current values. You can also set the HasAutoMinimum and HasAutoMaximum properties to True to force the axis to return to automatic scaling behavior.
The WCScaling object also lets you tell the axis to use a logarithmic scale instead of a linear one. Set the Type property of WCScaling to the chScaleTypeLogarithmic constant to make the scale logarithmic, or restore it to the chScaleTypeLinear constant to make it linear again. You can also adjust the LogBase property to set the base of the logarithmic scale.
Another interesting setting you can adjust is the Orientation property, which makes a scale display backwards, from minimum to maximum, rather than vice versa. This might or might not be useful for a value axis, but it is the easiest way to make a category axis show the categories in reverse order.
Probably the most interesting use of the Scaling object is to simulate zooming and panning on an axis. If your chart is densely packed with data points, it is useful to allow an analyst to zoom into a specific section of the axis and then pan across the axis to see various sections. You can do this by simply manipulating the Minimum and Maximum properties of the Scaling object, which has the effect of zooming and panning in the chart because the chart shows less numerical distance in the same visual distance on the screen.
The Chart component does not yet have the chart tips feature that you have no doubt seen in Excel. Chart tips are the larger ScreenTips that show up when you hover the mouse over a data point or chart element. Chart tips show the data point's value, category, series, and other useful information. The bad news is that these chart tips are not a native feature of the Chart control; the good news is that you can add them yourself by catching a few events raised by the Chart control. In Part II of the book, I will explain how you can create these homemade chart tips. For now, I will just give you the basics of how they work.
The Chart control raises the MouseMove event whenever the mouse is moved over the control. During this event, you can ask for the mouse's current X and Y coordinates with respect to the control's top-left pixel. These X and Y coordinates not only help you position other elements where the mouse is, but you can also feed them to the ChartSpace object's RangeFromPoint method to get the chart object that is currently under the mouse. For example, if your mouse is positioned over a data point, this method will return a WCPoint object, with which you can determine the parent series, the category, and the exact value of the point using the GetValue method. You can also adjust the formatting for that specific data point using the WCPoint object, which means you can, for instance, change the border color to highlight the value or change the interior color to a slightly darker or lighter shade of the current fill color. If the mouse is positioned over a chart element such as the legend, you will get a WCLegend object back from this method. Use the TypeName method in VBScript and VBA to determine what kind of object you get back from the RangeFromPoint method. You can also use the ChartSpace object's SelectionType property to determine the type of object returned from the Selection property.
For an example of using the Chart component's events and reacting to the mouse, see the file ReactingToMouse.htm in the Chap03 folder on the companion CD.
Why Is It Called RangeFromPoint?
When I first started looking into the nooks and crannies of the Chart component's programming model, I asked Jason Cahill, the Chart component's program manager, why this method was called RangeFromPoint when it clearly had nothing to do with ranges and instead returned chart objects. "Shouldn't this be called ObjectFromPoint?" I asked.
Jason explained that when Microsoft's accessibility group first decided to build screen readers for the blind, they wanted a method in Excel that would return the current range underneath the mouse so that they could read the values in the cells over the computer's audio system. (In case you were wondering, the accessibility group makes computers accessible to people with disabilities. Screen readers use audio to "read" onscreen text aloud for blind users.) Excel correctly named the method RangeFromPoint since it returned a range from an (X,Y) point. However, the accessibility group coded that method name into their application, and now anyone who wants accessibility to the screen reader must implement the RangeFromPoint method even though his or her application might not have anything to do with spreadsheet ranges.
本文地址:http://com.8s8s.com/it/it44185.htm