OWC ChartSpace控件的使用
OWC ChartSpace 控件是微软OWC库中的一种ActiveX控件,主要是用于生成图表。该控件既可以用于服务器端(生成图片),也可以直接嵌入到客户端(Winform或IE)中。说实话,在Asp.net生成图表的方法很多,比如微软的MSChart,图既漂亮,且是原生的Dotnet代码,为什么还要使用老古董的ActiveX控件呢?原因是ActiveX控件有更好的交互性,另外ChartSpace控件可以使用PivotTable控件作为数据源,从而自动生成相应的图表,省了很多的代码。
本文记述了我在使用ChartSpace控件过程中的学习到的一些技术要点。
一. 和PivotTable控件关联
ChartSpace可以直接将PivotTable控件作为数据源,这样只要PivotTable控件的数据发生改变,图表也会发生相应的必变。代码如下:
chartSpace1.DataSource = pivotTable1;
在使用过程中,我发现了chartSpace的一个问题。如果PivotTable本身的数据源发生了改变,则ChartSpace的图形显示会不正常,它的坐标轴和图例是正确的,但是却没相应的图显示出来。解决的办法是先给ChartSpace控件的DataSource属性赋一个空值,然后再次将PivotTable控件赋值给DataSource属性。代码如下:
chart.DataSource = NothingOfVb(); // vbs function
chart.DataSource = pvt;上面代码中的函数NothingOfVb()是一个VBS函数,它返回一个值Nothing,代码如下:
之所以搞的这么复杂,是因为如果直接给ChartSpace.DataSource赋一个null,将会抛出异常“类型不匹配”。<script type="text/vbscript" language="vbscript">
'
' 返回vb中的nothing值
'
function NothingOfVb()
set NothingOfVb = nothing
end function
</script>
二. 设置图表的类型
ChartSpace控件提供了很多种图表类型,具体的可以参考它的API手册。常用的图表类型如下:
- this.chart.Charts.Item(0).Type = this.getChartType();
在使用过程中,有一个问题我至今没有解决。如果图表类型被设置饼图,那么每次只能显示第一个系列的数据,而实际会有多个系列的数据,我希望全部系列都显示出来(多个饼图的形式)或者通过代码指定要显示哪个系列的数据,可这两点我都没能做到。有知道怎么做的朋友麻烦告诉我一声。
三. 设置图表的外观
图表的外观基本上都是通过ChInterior对象来设置的。
下列属性返回 ChInterior 对象:
ChChart 对象的 Interior 属性
ChChartDraw 对象的 Interior 属性
ChartSpace 对象的 Interior 属性
ChDataLabel 对象的 Interior 属性
ChDataLabels 对象的 Interior 属性
ChDropZone 对象的 ButtonInterior 属性
ChDropZone 对象的 WatermarkInterior 属性
ChLegend 对象的 Interior 属性
ChPlotArea 对象的 Interior 属性
ChPoint 对象的 Interior 属性
ChSegmentBoundary 对象的 Interior 属性
ChSeries 对象的 Interior 属性
ChSurface 对象的 Interior 属性
ChTitle 对象的 Interior 属性要设置拆线图的颜色,则需要设置ChSeries.Line.Color的值。要设置饼图的颜色,则要设置ChPoint.Interior返回的ChInterior对象的相关属性的值。以下是我工程中的部分代码:
设置图表外观
- // 柱状图
- if(chartType == chConstants.chChartTypeColumnClustered){
- for(var i=0; i<this.chart.Charts(0).SeriesCollection.Count; i++){
- var series = this.chart.Charts(0).SeriesCollection(i);
- if(i < colors.length)
- series.Interior.SetSolid(colors[i]);
- else
- series.Interior.SetSolid(randColor());
- }
- }
- // 折线图
- else if(chartType == chConstants.chChartTypeLine){
- for(var i=0; i<this.chart.Charts(0).SeriesCollection.Count; i++){
- var series = this.chart.Charts(0).SeriesCollection(i);
- if(i < colors.length)
- series.Line.Color = colors[i];
- else
- series.Line.Color = randColor();
- }
- }
- // 饼图
- else if(chartType == chConstants.chChartTypePie){
- for(var i=0; i<this.chart.Charts(0).SeriesCollection.Count; i++){
- var points = this.chart.Charts(0).SeriesCollection(i).Points;
- for(var j=0; j < points.Count; j++){
- if(j<colors.length)
- points(j).Interior.SetSolid(colors[j]);
- else
- points(j).Interior.SetSolid(randColor());
- }
- }
- }
上面的代码有点啰嗦,总的来说是给不同系列的图表设置颜色。
四. 导出图表
ChartSpace控件提供了一个名为ExportPicture(FileName, FilterName, Width, Height)的方法。从文档上看,应该可以用这个方法导出为图片,不过在实际用时却总是报异常。
ChartSpace控件还有另一个方法GetPicture(FilterName, Width, Height)。这个方法可以获得导出图片的二进制数据。测试中,这个方法倒是没问题,顺利的获得了结果,是一个整数所数组。在Vs2008的监视窗口中也可以看到数组的内容。但神奇的是,我没有任何办法用Javascript或Vbscrip去访问数组的内容。经常一番Baidu,我找到了解决方案,使用MSXML2.DOMDocument。这是一个比较奇特折方法
- var data = this.chart.GetPicture('GIF',800,600);
- var doc = new ActiveXObject('MSXML2.DOMDocument');
- doc.loadXML("<xml xmlns:dt='urn:schemas-microsoft-com:datatypes'></xml>");
- var node = doc.createElement("file1");
- node.dataType = "bin.base64";
- node.nodeTypedValue = data;
- doc.documentElement.appendChild(node);
基本断路是使用MSXML2.DOMDocument将二进制数组转换成base64编码的字符串,编码之后就可以通node.text属性获得结果。那么这个字符串如何保存为图片呢?我的解决方案是将它提交给服务器,然后解码回二进制再作为图片发送回客户端。显然,因为数据量的关系,提交时只能使用POST方式了。
- // 使用一个临时窗体将数据提交给服务器,并显示服务器返回的图片
- var form = '<form action="PivotManager.aspx" name="form1" method="POST" style="visibility:hidden">' +
- '<input type="hidden" name="chart1" id="chart1" value="{0}" />' +
- '<input type="submit" value="exportChart" id="exportChart" name="exportChart"/>' +
- '</form>';
- var script = '<script language="javascript">document.form1.exportChart.click();</script>';
- form = String.format(form,node.text);
- var win = window.open("");
- win.document.write(form);
- win.document.write(script);
其中的String.format函数是Ext提供的,它的功能类似于C#中的Format函数。对应的服务器端代码如下:
- var buffer = Convert.FromBase64String(Request.Form["chart1"]);
- Response.Clear();
- Response.ContentType = "image/gif";
- Response.AddHeader("Content-Disposition", "attachment;filename=chart.gif");
- Response.OutputStream.Write(buffer, 0, buffer.Length);
- Response.End();
整个过程是比较神奇的,先从ChartSpace中获取数据,编码后再提交给服务器,服务解码后再发送回客户端,真是无端的增加了服务器的负荷。