在协同办公系统中web自定义表单开发工具是核心组件,它可以为协同系统提供数据展现接口,自定义表单开发工具通过调用接口并返回接收数据后显示在页面上,如果需要对页面上的数据进行分析时,图形化的数据展现会更显得直观明了。
在经过验证研究后,决定在web自定义表单开发工具中集成fusioncharts控件,之所以选择FusionCharts图形控件主要是它集成比较灵活、简单,对系统没有特殊的要求。下面的是FusionCharts的简单概述和系统要求:
FusionCharts Overview |
FusionCharts is a flash charting component that can be used to render data-driven animated charts. Made in Adobe Flash 8 (formerly Macromedia Flash), FusionCharts can be used with any web scripting language like HTML, .NET, ASP, JSP, PHP, ColdFusion etc., to deliver interactive and powerful charts. Using XML as its data interface, FusionCharts makes full use of fluid beauty of Flash to create compact, interactive and visually-arresting charts. |
System Requirements |
Server Side: Anything. FusionCharts runs on Windows, Linux, Unix or any other imaginable form of server that you can think of. Just make sure that your server MIME is configured for SWF files to ensure proper streaming. Most servers come pre-configured for SWF files. Client Side: Adobe Flash Player 8 (or above). Adobe Flash Player is a free and light-weight plugin to render Flash movies. It can be downloaded from www.adobe.com. It's one of the most widely installed plugin on this planet. |
如想了解FusionCharts更详细的信息请参见:http://www.fusioncharts.com/ 。下面开始介绍web自定义表单集成FusionCharts的具体过程:
一、 研究用AJAX/JavaScript方式整合
在FusionCharts中提供了接收XML数据并把数据以各种图形展现的方法,具体的示例步骤如下:
1) JavaScript 的调用方法,首先在需要显示图形的页面上引用FusionCharts.js文件,然后在按下面的格式来调用即可。
<script type="text/javascript">
var chart = new FusionCharts("../Charts/Column2D.swf", "ChartId", "500", "300", "0", "0");
chart.setDataURL("Data/Column2D.xml");
chart.render("chartdiv");
</script>
2) FusionCharts接收XML数据的格式如下:
3) JavaScript调用成功后显示的效果:
按上面的步骤便可以用JavaScript调用FusionCharts控件的接口并显示数据,主要工作量就是XML数据的组织,组织数据后直接调用接口就可以显示图形了。知道了主要的工作量就可以把FusionCharts控件集成到Web自定义表单中了。
二、 把FusionCharts控件集成到web自定义表单的设计器中
a) 增加FusionCharts图标到web自定义表单设计器的工具栏上
在Web自定义表单工具的配置文件中增加下面的配置属性即可在工具栏上显示,配置方法和显示效果如下:
配置方法: chart: ["chart控件", "../images/NEW_images/ef_design_chart.gif", false, 'Add("chart")']
显示效果:
b) 设置FusionCharts的基本属性和数据来源
为了Web自定义表单和FusionCharts的集成方便和使用简单,我们把FusionChart的XML数据来源定义为取自Web自定义表单的dataset数据集控件,这样在表单制作时我们只要给数据集赋值,并把dataset数据集的数据和FusionCharts控件进行关联,数据便可以按图形方式展现。
首先需要把图形控件可以增加到自定义表单的设计器上。增加控件到自定义表单设计器上只要实现'Add("chart")接口即可,在Add()方法中增加如下代码:
case "chart":
{
ArrNum[name]++;
var sid = getNewContID(name,oContXml) ;
var sHtml="<img controltype='" + name + "' id="+sid+" type=graph style='position:" + fcpubdata.position + ";Left:0;Top:0; Height:188; Width:326;' src='../images/ef_designer_graph.gif' onmovestart=moveStart() onmoveend=moveEnd() onresizestart=resizeStart() onresizeend=resizeEnd() />";
htmltocont(sHtml,name);
SelectObj(sid);
break;
}
其次要把FusionCharts控件和dataset数据集的数据项进行关联,我们把FusionCharts的基本属性和数据关联属性统一做在了一个页面进行设置,设置方法如下图:
然后按常规的自定义表单的制作方法设计表单即可。如果表单上增加了FusionCharts图形控件,自定义表单设计保存时会自动引用FusionCharts.js文件。
再然后表单运行时会根据设置的属性进行解析后调用FusionCharts提供的方法显示图形。具体的解析过程封装了通用的方法,在表单设计中调用此方法便可以根据数据显示各种图形了。封装方法如下:
function ShowOneGraph(obj) {
var iWidth = obj.style.pixelWidth;
var iHeight = obj.style.pixelHeight;
var dssub1 = eval("window." + obj.getAttribute("datasetdata"));
var sXml = obj.getAttribute("formatxml"); //纵轴字段列表串
var oXml;
if (window.ActiveXObject) {
oXml = new ActiveXObject("Microsoft.XMLDOM");
oXml.async = false;
oXml.loadXML(sXml);
}
else {
oXml = (new DOMParser()).parseFromString(sXml, "text/xml");
}
//debugger;
var Is3D = obj.Is3D; //是否D显示
var IsStack = obj.IsStack; //是否堆积显示
//alert(IsStack);
var IsMulti = (oXml.documentElement.childNodes.length > 2); //是否是多序列图形
var IsShowValue = obj.IsShowValue; //是否显示数据值
var showvalue = '0';
if (IsShowValue == "是") showvalue = '1';
var Is2YAxis = obj.Is2YAxis; //是否显示双轴图形
var myChart = null
//增加显示图形类型的属性(用哪个flash文件)
var chartName = (obj.chartTypeName == "undefined" || typeof obj.chartTypeName == "undefined") ? "" : obj.chartTypeName;
if (chartName == "") {
switch (obj.graphtype) {
case "折线图": //Line.swf
if (IsMulti)
chartName = "ScrollLine2D.swf"; //"MSLine.swf";
else
chartName = "Line.swf";
break;
case "圆饼图": //Pie2D.swf
if (Is3D == "是")
chartName = "Pie3D.swf";
else
chartName = "Pie2D.swf";
break;
case "条形图": //Bar2D.swf
//是否是多序列图形
if (IsMulti) {
//是否堆积显示图形
if (IsStack == "是") {
//是否D显示
if (Is3D == "是")
chartName = "StackedBar3D.swf";
else
chartName = "StackedBar2D.swf";
}
else {
//是否D显示
if (Is3D == "是")
chartName = "MSBar3D.swf";
else
chartName = "MSBar2D.swf";
}
}
else {
chartName = "Bar2D.swf";
}
break;
case "区域图": //Area2D.swf
if (IsMulti) {
if (IsStack == "是")
chartName = "StackedArea2D.swf";
else
chartName = "ScrollArea2D.swf"; //"MSArea.swf";
}
else {
chartName = "Area2D.swf";
}
break;
default: //Column2D.swf
if (IsMulti) {
if (IsStack == "是") {
if (Is3D == "是")
chartName = "StackedColumn3D.swf";
else
chartName = "ScrollStackedColumn2D.swf"; //"StackedColumn2D.swf";
}
else {
if (Is3D == "是")
chartName = "MSColumn3D.swf";
else
//chartName = "MSColumn2D.swf";
chartName = "ScrollColumn2D.swf";
}
}
else {
if (Is3D == "是")
chartName = "Column3D.swf";
else
chartName = "Column2D.swf";
}
}
//双轴图形显示
if (Is2YAxis == "是") {
if (IsStack == "是" && Is3D == "是")
chartName = "StackedColumn3DLineDY.swf";
else {
if (Is3D == "是")
chartName = "MSColumn3DLineDY.swf";
else
chartName = "MSCombiDY2D.swf";
}
}
}
//alert(chartName);
myChart = new FusionCharts("http://www.cnblogs.com/../FusionCharts/" + chartName, "myChartId", iWidth, iHeight, "0", "0");
//把图形控件需要显示的Xml做一个接口属性,在表单中可以直接给图形设置数据并显示。
//如果在表单上给图形控件付了chartXML的属性,则不再按图形控件的属性页的进行属性拼写。
var strXml = "";
if (obj.chartXML == "undefined" || typeof obj.chartXML == "undefined") {
if (parent.Request.QueryString("opentype").toString() == "1") {
dssub1.Open();
}
//增加数据集内容是否为空的判断
var ilen = 0;
if (dssub1.oDom.xml != "")
ilen = dssub1.oDom.documentElement.childNodes.length;
var xfield = obj.xfield;
var colno = dssub1.FieldNameToNo(xfield); //X轴字段序号
var yfield = oXml.documentElement.childNodes(0).childNodes(0).text; //y轴字段
var yno = dssub1.FieldNameToNo(yfield); //Y轴字段序号
//图形属性
var strCaption = (obj.caption == "undefined" || typeof obj.caption == "undefined") ? "" : obj.caption;
var strSubCaption = (obj.subcaption == "undefined" || typeof obj.subcaption == "undefined") ? "" : obj.subcaption;
var strxAxisName = (obj.xAxisName == "undefined" || typeof obj.xAxisName == "undefined") ? "" : obj.xAxisName;
var stryAxisName = (obj.yAxisName == "undefined" || typeof obj.yAxisName == "undefined") ? "" : obj.yAxisName; //主Y轴名称
var strNumPrefix = (obj.numberPrefix == "undefined" || typeof obj.numberPrefix == "undefined") ? "" : obj.numberPrefix;
//增加数据的后缀属性、标准线值、标准线显示值
var strNumSuffix = (obj.numberSuffix == "undefined" || typeof obj.numberSuffix == "undefined") ? "" : obj.numberSuffix;
var strTrendlines = (obj.trendlines == "undefined" || typeof obj.trendlines == "undefined") ? "" : obj.trendlines;
var strDisplayValue = (obj.TrendDisplayValue == "undefined" || typeof obj.TrendDisplayValue == "undefined") ? "标准线" : obj.TrendDisplayValue; //标准线显示值
//增加次Y轴名称
var strSyyAxisName = (obj.SyAxisName == "undefined" || typeof obj.SyAxisName == "undefined") ? "" : obj.SyAxisName;
var bg = "";
if (Is3D == "是" && obj.graphtype == "圆饼图") bg = "bgcolor = '99CCFF,FFFFFF'";
//修改小数位数保留两位
strXml = "<chart " + bg + " decimals='2' formatNumberScale='0' palette='2' caption='" + strCaption + "' baseFontSize='12' baseFont='Arial'";
strXml += "showSum='1' decimals='0' useRoundEdges='1' palette='2' showBorder='1' ";
strXml += " subcaption='" + strSubCaption + "' xAxisName='" + strxAxisName + "' numberPrefix='" + strNumPrefix + "' numberSuffix='" + strNumSuffix + "'";
//增加是否显示双轴图形. 数据集Y轴的最后一个字段做次Y轴数据
if (Is2YAxis == "是" && oXml.documentElement.childNodes.length > 2)
strXml += " PYAxisName = '" + stryAxisName + "' SYAxisName = '" + strSyyAxisName + "'";
else
strXml += " yAxisName='" + stryAxisName + "'";
strXml += ">";
//组织图形数据
if (typeof myChart != "undefined" && myChart != null && ilen > 1) {
var strcategories = "<categories>";
for (var i = 0; i < ilen - 1; i++) {
//图表分类
var strlabel = dssub1.oDom.documentElement.childNodes(i).childNodes(colno).text;
var strvalue = "";
if (IsMulti)
strcategories += "<category label='" + strlabel + "' />";
else
strvalue = dssub1.oDom.documentElement.childNodes(i).childNodes(yno).text;
// 增加点击图形时可以处发其它事件的属性
var strlink = dssub1.oDom.documentElement.childNodes(ilen - 1).childNodes(1).childNodes(yno).childNodes(14).text;
if (strlink.toLowerCase().indexOf("javascript") >= 0)
strlink = strlink.substring(11, strlink.length);
if (strlink.indexOf(";") >= 0)
strlink = strlink.substring(0, strlink.length - 1);
if (strlink.indexOf("(") >= 0) {
var ss = strlink.substring(strlink.indexOf("(") + 1, strlink.length);
strlink = strlink.substring(0, strlink.indexOf("(") + 1) + "\'" + i + "\'";
if (ss.length > 1)
strlink = strlink + "," + ss;
else
strlink = strlink + ss;
}
var slink = " link = \"JavaScript:" + strlink + "\"";
strXml += "<set label='" + strlabel + "' value='" + strvalue + "' " + slink + " />";
}
if (IsMulti) {
strcategories += "</categories>";
strXml += strcategories;
for (var j = 0; j < oXml.documentElement.childNodes.length - 1; j++) {
var ycolno = dssub1.FieldNameToNo(oXml.documentElement.childNodes(j).childNodes(0).text);
var yfieldname = oXml.documentElement.childNodes(j).childNodes(1).text
var strdataset = "<dataset showValues='" + showvalue + "' seriesName='" + yfieldname + "'";
if (Is2YAxis == "是" && oXml.documentElement.childNodes.length > 2 && (j == oXml.documentElement.childNodes.length - 2))
strdataset += " parentYAxis='S' ";
strdataset += ">";
for (var k = 0; k < ilen - 1; k++) {
var strvalue = dssub1.oDom.documentElement.childNodes(k).childNodes(ycolno).text;
strdataset += "<set value='" + strvalue + "' /> ";
}
strdataset += "</dataset>"
strXml += strdataset;
}
}
//增加标准线
if (strTrendlines != "" && strTrendlines != "undefined") {
strXml += "<trendlines>"
strXml += "<line startValue='" + strTrendlines + "' isTrendZone='0' displayValue='" + strDisplayValue + "' color='FF0000' /> "
strXml += "</trendlines>"
}
}
strXml += "</chart>";
}
else {
strXml = obj.chartXML;
}
myChart.setDataXML(strXml);
var sdiv = "<div id='" + obj.id + "' style='position:absolute;left:" + obj.style.left + ";top:" + obj.style.top + ";width:" + obj.style.width + ";height:" + obj.style.height + "'>";
obj.outerHTML = sdiv + "</div>";
myChart.render(obj.id);
}
c) 预留FusionCharts的数据来源接口
- chartTypeName属性接口,用于指定图形显示用哪种类型。例:chart1.chartTypeName = “Doughnut2D.swf”;
- chartXML 属性接口,用于指定图形的XML数据。例:chart1.chartXML = “……”; 数据格式为FusionCharts提供的标准格式,因FusionCharts提供了很多的属性和接口,不能在自定义表单中一一列举出来供设置,特提供此属性接口。标准API参见官方网站上提供的 Chart XML API介绍。
三、 带图形的自定义表单制作过程及展现效果
1、 按常规的表单制作方式设计表单,并在表单上增加图形控件,设计效果如下:
2、 设置图形控件的基本属性和关联的dataset数据集
3、 在表单的onload事件中调用ShowOneGraph(chart1);显示图形的方法。
4、 运行表单显示效果如下: